UNPKG

@gsb-core/core

Version:

GSB core services and classes for platform-independent web applications

248 lines 10.7 kB
"use strict"; 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