UNPKG

sql-ddl-to-json-schema

Version:

Parse and convert SQL DDL statements to a JSON Schema.

182 lines (181 loc) 6.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ForeignKey = void 0; const utils_1 = require("../../../../shared/utils"); const column_reference_1 = require("./column-reference"); const index_column_1 = require("./index-column"); /** * Foreign key of a table. */ class ForeignKey { name; columns = []; reference; /** * Creates a foreign key from a JSON def. * * @param json JSON format parsed from SQL. */ static fromDef(json) { if (json.id === 'O_CREATE_TABLE_CREATE_DEFINITION') { if ((0, utils_1.isDefined)(json.def.foreignKey)) { return ForeignKey.fromObject(json.def.foreignKey); } throw new TypeError(`Statement ${json.id} has undefined foreignKey. Cannot format foreignKey.`); } throw new TypeError(`Unknown json id to build foreign key from: ${json.id}`); } /** * Creates a foreign key from an object containing needed properties. * * @param json Object containing properties. */ static fromObject(json) { const foreignKey = new ForeignKey(); foreignKey.columns = json.columns.map(index_column_1.IndexColumn.fromDef); foreignKey.reference = column_reference_1.ColumnReference.fromDef(json.reference); if (json.name) { foreignKey.name = json.name; } return foreignKey; } /** * JSON casting of this object calls this method. */ toJSON() { const json = { columns: this.columns.map((c) => c.toJSON()), reference: this.reference.toJSON(), }; if ((0, utils_1.isDefined)(this.name)) { json.name = this.name; } return json; } /** * Create a deep clone of this model. */ clone() { const key = new ForeignKey(); key.columns = this.columns.map((c) => c.clone()); key.reference = this.reference.clone(); if ((0, utils_1.isDefined)(this.name)) { key.name = this.name; } return key; } /** * Push an index column to columns array. * * @param indexColumn Index column to be pushed. */ pushColumn(indexColumn) { this.columns.push(indexColumn); } /** * Drops an index column, returning a boolean to whether column was removed. * * @param name Column name to be dropped. */ dropColumn(name) { let pos = -1; const found = this.columns.some((c, i) => { pos = i; return c.column === name; }); if (!found || pos < 0) { return false; } const end = this.columns.splice(pos); end.shift(); this.columns = this.columns.concat(end); return true; } /** * Get the columns in given table which this foreign key's index columns refer to. * * @param table Table in question. */ getColumnsFromTable(table) { return (table.columns ?? []).filter((tableColumn) => this.columns.some((indexColumn) => indexColumn.column === tableColumn.name)); } /** * Get whether the given table has all of this foreign key's owner table columns. */ hasAllColumnsFromTable(table) { return ((table.columns ?? []).filter((tableColumn) => this.columns.some((indexColumn) => indexColumn.column === tableColumn.name)).length === this.columns.length); } /** * Set size of this index to the size of index's column in given * table, if the size of this index is not already set. */ setIndexSizeFromTable(table) { this.columns .filter((i) => !(0, utils_1.isDefined)(i.length)) .forEach((indexColumn) => { const column = (table.columns ?? []).find((c) => c.name === indexColumn.column); if (!column) { return; } const indexableSize = column.type.getMaxIndexableSize(); if (indexableSize > 0) { indexColumn.length = indexableSize; } }); } /** * Get whether the given table has all of this foreign key's referenced table columns. */ hasAllColumnsFromRefTable(table) { return ((table.columns ?? []).filter((tableColumn) => this.reference.columns?.some((indexColumn) => indexColumn.column === tableColumn.name)).length === this.reference.columns?.length); } /** * Get referenced table by this foreign key, from array * of given tables. Returns null if no table was found. * * @param tables Table array to search. */ getReferencedTable(tables) { return tables.find((t) => t.name === this.reference.table) ?? undefined; } /** * Checks and returns whether this foreign key references given table and column. * * @param table Table to be checked whether there is reference to. * @param column Column to be checked in given table. */ referencesTableAndColumn(table, column) { return (this.reference.table === table.name && (this.reference.columns ?? []).some((indexColumn) => indexColumn.column === column.name)); } /** * Checks and returns whether this foreign key references given table. * * @param table Table to be checked whether there is reference to. */ referencesTable(table) { return this.reference.table === table.name; } /** * Rename index column name. * * @param column Column being renamed. * @param newName New column name. */ renameColumn(column, newName) { return this.reference.columns ?.filter((c) => c.column === column.name) .forEach((c) => { c.column = newName; }); } /** * Update referenced table name. * * @param newName New table name. */ updateReferencedTableName(newName) { this.reference.table = newName; } } exports.ForeignKey = ForeignKey;