@gsb-core/core
Version:
GSB core services and classes for platform-independent web applications
248 lines • 10.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SchemaManagerService = void 0;
const entity_def_service_1 = require("./entity-def.service");
const gsb_utils_1 = require("../../utils/gsb-utils");
const gsb_cache_service_1 = require("../cache/gsb-cache.service");
const gsb_entity_service_1 = require("./gsb-entity.service");
const query_params_1 = require("../../types/query-params");
const query_1 = require("../../types/query");
/**
* Service for managing schema creation and updates with intelligent reference property handling
*/
class SchemaManagerService {
constructor(useCache = true) {
this.useCache = useCache;
//todo: fix cache problems and set useCache to useCache
this.entityDefService = entity_def_service_1.EntityDefService.getInstance(false);
this.cacheService = gsb_cache_service_1.GsbCacheService.getInstance();
this.entityService = gsb_entity_service_1.GsbEntityService.getInstance();
}
/**
* Get the singleton instance of SchemaManagerService
* @param useCache Whether to use cache for entity definitions
* @returns The SchemaManagerService instance
*/
static getInstance(useCache = true) {
if (!SchemaManagerService.instance) {
SchemaManagerService.instance = new SchemaManagerService(useCache);
}
return SchemaManagerService.instance;
}
/**
* Create or update schema entities and properties
* @param entityDefs Array of entity definitions to process
*/
async createOrUpdateSchema(entityDefs, authToken, tenantCode) {
var _a, _b;
let existingDefs = [];
const result = {
createdEntities: [],
updatedEntities: [],
errors: []
};
const updateDefs = [];
const createDefs = [];
const refProps = [];
if (!this.useCache) {
try {
let req = new query_params_1.QueryParams("GsbEntityDef").
select(p => p.id).select(p => p.name).
filter(p => p.id, entityDefs.filter(d => d.id).map(d => d.id), query_1.QueryFunction.In, query_1.QueryRelation.Or).
filter(p => p.name, entityDefs.filter(d => d.name).map(d => d.name), query_1.QueryFunction.In, query_1.QueryRelation.Or);
let resp = await this.entityService.query(req, authToken, tenantCode);
existingDefs = resp.entities || [];
}
catch (error) {
result.errors.push("Error getting existing entity definitions: " + error.message);
}
}
else {
existingDefs = await this.cacheService.getAllDefinitions(authToken, tenantCode);
}
for (let def of entityDefs) {
if (!def.id) {
let existing = existingDefs.find(d => d.name === def.name);
def.id = (_a = existing === null || existing === void 0 ? void 0 : existing.id) !== null && _a !== void 0 ? _a : gsb_utils_1.GsbUtils.newId();
}
}
for (let def of entityDefs) {
const defCopy = { ...def };
const reducedProps = [];
let existing = existingDefs.find(d => d.id === def.id);
for (let prop of def.properties || []) {
prop.ownerEntDef_id = defCopy.id;
if (prop.definition_id === gsb_utils_1.GsbUtils.ReferencePropertyDefinitionId) {
if (!prop.refEntDef_id) {
throw new Error('Reference entity definition ID is required for reference properties');
}
if (!prop.refEntDef_id.includes("-")) {
const refDef = (_b = entityDefs.find(d => d.name === prop.refEntDef_id)) !== null && _b !== void 0 ? _b : existingDefs.find(d => d.name === prop.refEntDef_id);
if (!refDef) {
throw new Error('Reference entity definition not found');
}
prop.refEntDef_id = refDef.id;
}
//gsb automatically creates corresponding reference properties for reference entities
if (refProps.find(p => p.name === prop.refEntPropName && p.refEntDef_id === prop.ownerEntDef_id)) {
continue;
}
//if it not a self reference or a reference to a new entity definition, save it later
if (!existingDefs.find(d => d.id === prop.refEntDef_id) && prop.refEntDef_id !== def.id) {
refProps.push(prop);
}
else {
reducedProps.push(prop);
}
}
else {
reducedProps.push(prop);
}
}
defCopy.properties = reducedProps;
if (existing) {
updateDefs.push(defCopy);
}
else {
createDefs.push(defCopy);
}
}
for (let def of updateDefs) {
try {
await this.entityDefService.updateEntityDef(def, authToken, tenantCode);
result.updatedEntities.push(def);
}
catch (error) {
result.errors.push(error.message);
}
}
for (let def of createDefs) {
try {
await this.entityDefService.createEntityDef(def, authToken, tenantCode);
result.createdEntities.push(def);
}
catch (error) {
result.errors.push(error.message);
}
}
const savedRefProps = [];
if (refProps.length > 0) {
//wait for createDefs to be cached acrooss all servers
await new Promise(resolve => setTimeout(resolve, 6000));
for (let refProp of refProps) {
try {
if (savedRefProps.find(p => p.name === refProp.refEntPropName && p.refEntDef_id === refProp.ownerEntDef_id)) {
continue;
}
if (refProp.ownerEntDef_id) {
await this.entityDefService.addProperty(refProp, undefined, authToken, tenantCode);
savedRefProps.push(refProp);
}
}
catch (error) {
result.errors.push(error.message);
}
}
}
if (result.errors.length > 0) {
console.error('Error creating or updating schema:', result.errors);
}
if (result.createdEntities.length > 0) {
console.log('Created entities:', result.createdEntities.map(e => e.name));
}
if (result.updatedEntities.length > 0) {
console.log('Updated entities:', result.updatedEntities.map(e => e.name));
}
if (refProps.length > 0) {
console.log('Referenced properties:', refProps.map(p => p.name));
}
return result;
}
/**
* Delete schema entities
* @param entityDefs Array of entity definitions to delete
*/
async deleteSchema(entityDefs, authToken, tenantCode) {
for (let def of entityDefs) {
if (def.id) {
await this.entityDefService.deleteEntityDef(def.id, authToken, tenantCode);
}
}
}
/**
* Create or update a table
* @param entityDef The entity definition to create or update
*/
async creaateOrUpdateTable(entityDef, authToken, tenantCode) {
var _a;
if (!entityDef.id && !entityDef.name) {
throw new Error('Entity definition must have either id or name');
}
let existing;
if (this.useCache) {
existing = await this.cacheService.getEntityDef(entityDef, authToken, tenantCode);
}
else {
existing = ((_a = (await this.entityService.query(new query_params_1.QueryParams("GsbEntityDef").
filter(entityDef.id ? new query_1.Filter("id", entityDef.id) : new query_1.Filter("name", entityDef.name)).
select(p => p.id), authToken, tenantCode)).entities) === null || _a === void 0 ? void 0 : _a[0]) || null;
}
if (existing) {
await this.entityDefService.updateEntityDef(entityDef, authToken, tenantCode);
}
else {
await this.entityDefService.createEntityDef(entityDef, authToken, tenantCode);
}
}
/**
* Delete a table
* @param entityDef The entity definition to delete
*/
async deleteTable(entityDef, authToken, tenantCode) {
if (!entityDef)
throw new Error('Entity definition is required');
if (!entityDef.id) {
throw new Error('Entity definition must have an id');
}
if (entityDef.id) {
await this.entityDefService.deleteEntityDef(entityDef.id, authToken, tenantCode);
}
}
/**
* Create or update a column
* @param property The property to create or update
*/
async createOrUpdateColumn(property, authToken, tenantCode) {
if (!property.ownerEntDef_id) {
throw new Error('Owner entity definition ID is required');
}
const existing = await this.cacheService.getEntityDef({ id: property.ownerEntDef_id }, authToken, tenantCode);
if (!existing) {
throw new Error('Entity definition not found');
}
if (existing.properties) {
const existingProp = existing.properties.find(p => p.name === property.name || p.id === property.id);
if (existingProp) {
await this.entityDefService.updateProperty(property, existing, authToken, tenantCode);
}
else {
await this.entityDefService.addProperty(property, existing, authToken, tenantCode);
}
}
else {
await this.entityDefService.addProperty(property, existing, authToken, tenantCode);
}
}
/**
* Delete a column
* @param property The property to delete
*/
async deleteColumn(property, authToken, tenantCode) {
if (!property.ownerEntDef_id) {
throw new Error('Owner entity definition ID is required');
}
await this.entityDefService.removeProperty(property, undefined, authToken, tenantCode);
}
}
exports.SchemaManagerService = SchemaManagerService;
//# sourceMappingURL=schema-manager.service.js.map