UNPKG

rawsql-ts

Version:

[beta]High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.

194 lines 7.08 kB
/** * Schema Manager for rawsql-ts * Provides unified schema definition and automatic conversion to various formats * Eliminates code duplication and provides type-safe schema management */ // === Schema Manager Class === /** * Central schema management utility for rawsql-ts * Converts user-defined schemas to various internal formats */ export class SchemaManager { constructor(schemas) { this.schemas = schemas; this.validateSchemas(); } /** * Validate schema definitions for consistency * Ensures each table has a primary key (required for UPDATE/DELETE operations) * and validates relationship references */ validateSchemas() { const tableNames = Object.keys(this.schemas); const errors = []; // Validate each table Object.entries(this.schemas).forEach(([tableName, table]) => { var _a; // Check primary key exists (required for UPDATE/DELETE WHERE conditions) const primaryKeys = Object.entries(table.columns) .filter(([_, col]) => col.isPrimaryKey) .map(([name, _]) => name); if (primaryKeys.length === 0) { errors.push(`Table '${tableName}' has no primary key defined`); } // Validate foreign key references (_a = table.relationships) === null || _a === void 0 ? void 0 : _a.forEach(rel => { if (!tableNames.includes(rel.table)) { errors.push(`Table '${tableName}' references unknown table '${rel.table}' in relationship`); } }); }); if (errors.length > 0) { throw new Error(`Schema validation failed:\\n${errors.join('\\n')}`); } } /** * Get table column names for SqlParamInjector TableColumnResolver * @param tableName Name of the table * @returns Array of column names */ getTableColumns(tableName) { const table = this.schemas[tableName]; if (!table) { return []; } return Object.keys(table.columns); } /** * Create TableColumnResolver function for SqlParamInjector * @returns Function compatible with SqlParamInjector */ createTableColumnResolver() { return (tableName) => this.getTableColumns(tableName); } /** * Generate JSON mapping configuration for PostgresJsonQueryBuilder * @param rootTableName Root table for the JSON structure * @returns JSON mapping configuration */ createJsonMapping(rootTableName) { var _a; const rootTable = this.schemas[rootTableName]; if (!rootTable) { throw new Error(`Table '${rootTableName}' not found in schema registry`); } // Build root entity columns mapping const rootColumns = {}; Object.entries(rootTable.columns).forEach(([columnName, column]) => { rootColumns[columnName] = column.jsonAlias || column.name; }); // Build nested entities from relationships const nestedEntities = []; (_a = rootTable.relationships) === null || _a === void 0 ? void 0 : _a.forEach(rel => { const relatedTable = this.schemas[rel.table]; if (!relatedTable) { throw new Error(`Related table '${rel.table}' not found in schema registry`); } // Build columns mapping for related table const relatedColumns = {}; Object.entries(relatedTable.columns).forEach(([columnName, column]) => { relatedColumns[columnName] = column.jsonAlias || column.name; }); // Determine relationship type for JSON builder const relationshipType = rel.type; nestedEntities.push({ id: rel.propertyName, name: relatedTable.displayName || rel.table, parentId: rootTableName, propertyName: rel.propertyName, relationshipType: relationshipType, columns: relatedColumns }); }); return { rootName: rootTableName, rootEntity: { id: rootTableName, name: rootTable.displayName || rootTableName, columns: rootColumns }, nestedEntities, useJsonb: true, resultFormat: "single" }; } /** * Get all table names in the schema * @returns Array of table names */ getTableNames() { return Object.keys(this.schemas); } /** * Get table definition by name * @param tableName Name of the table * @returns Table definition or undefined */ getTable(tableName) { return this.schemas[tableName]; } /** * Get primary key column name for a table * Used by QueryBuilder.buildUpdateQuery for WHERE clause conditions * @param tableName Name of the table * @returns Primary key column name or undefined */ getPrimaryKey(tableName) { const table = this.schemas[tableName]; if (!table) return undefined; const primaryKeyEntry = Object.entries(table.columns) .find(([_, col]) => col.isPrimaryKey); return primaryKeyEntry ? primaryKeyEntry[0] : undefined; } /** * Get foreign key relationships for a table * @param tableName Name of the table * @returns Array of foreign key relationships */ getForeignKeys(tableName) { const table = this.schemas[tableName]; if (!table) return []; const foreignKeys = []; Object.entries(table.columns).forEach(([columnName, column]) => { if (column.foreignKey) { foreignKeys.push({ column: columnName, referencedTable: column.foreignKey.table, referencedColumn: column.foreignKey.column }); } }); return foreignKeys; } } // === Convenience Functions === /** * Create a SchemaManager instance from schema definitions * @param schemas Schema registry object * @returns SchemaManager instance */ export function createSchemaManager(schemas) { return new SchemaManager(schemas); } /** * Create TableColumnResolver function from schema definitions * @param schemas Schema registry object * @returns TableColumnResolver function for SqlParamInjector */ export function createTableColumnResolver(schemas) { const manager = new SchemaManager(schemas); return manager.createTableColumnResolver(); } /** * Create JSON mapping from schema definitions * @param schemas Schema registry object * @param rootTableName Root table name * @returns JSON mapping for PostgresJsonQueryBuilder */ export function createJsonMappingFromSchema(schemas, rootTableName) { const manager = new SchemaManager(schemas); return manager.createJsonMapping(rootTableName); } //# sourceMappingURL=SchemaManager.js.map