/* eslint-disable no-console */ import { JSONSchema4 } from 'json-schema'; import { PgTable, TableSmartTags } from './abstractions'; import { separateProperties } from './pg-models/json-schema-parse-utils'; import { isReservedPgWord } from './pg-models/pg-sql-gen-utils'; import { ContentEntityTable, ObjectPropertyTable } from './pg-models/tables'; import { PublishSchemaToDbOptions } from './publish-schema-to-db-options'; export class ContentEntityModel { public name: string; public contentEntity: PgTable; public relatedObjects: PgTable[] = []; constructor(options: PublishSchemaToDbOptions, schema: JSONSchema4) { if (!schema.title) { throw Error('Content type schema title is undefined.'); } // TODO: Too restrictive. this.name = schema.title.substring( 0, schema.title.indexOf('_published_event'), ); // 1. Split properties into primitive and object properties. const [primitiveProperties, objectProperties] = separateProperties( schema, options.ignoredProperties, ); // 2. Create the content entity table. this.contentEntity = new ContentEntityTable( options, this.name, primitiveProperties, schema.description, ); // 3. Create related object property tables. for (const key in objectProperties) { this.relatedObjects.push( new ObjectPropertyTable( options, key, objectProperties[key], this.contentEntity.pk, ), ); } } public validate(): void { console.log(`Validating content entity model for ${this.name}`); const tables = [this.contentEntity, ...this.relatedObjects]; for (const table of tables) { if (isReservedPgWord(table.name)) { throw new Error( `Table name ${table.name} is a reserved word. Please specify a name override in the postprocessor.`, ); } for (const column of table.columns) { if (isReservedPgWord(column.name)) { throw new Error( `Column name ${table.name}.${column.name} is a reserved word. Please specify a name override in the postprocessor.`, ); } } } } public buildStatements(): string[] { return ([] as string[]).concat( `--`, `-- #${this.name}`, `--`, ...[this.contentEntity, ...this.relatedObjects].map((t) => t.buildStatements(), ), `--`, `--`, `--`, ); } public buildSmartTags(): { [name: string]: TableSmartTags } { return [this.contentEntity, ...this.relatedObjects].reduce((acc, t) => { if (t.buildSmartTags()) { acc[t.name] = t.buildSmartTags(); } return acc; }, {} as { [name: string]: TableSmartTags }); } }