sql-ddl-to-json-schema
Version:
Parse and convert SQL DDL statements to a JSON Schema.
154 lines (153 loc) • 4.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.UniqueKey = void 0;
const utils_1 = require("../../../../shared/utils");
const index_options_1 = require("./index-options");
const index_column_1 = require("./index-column");
/**
* Unique key of a table.
*/
class UniqueKey {
name;
indexType;
columns = [];
options;
/**
* Creates a unique key from a JSON def.
*
* @param json JSON format parsed from SQL.
*/
static fromDef(json) {
if (json.id === 'O_CREATE_TABLE_CREATE_DEFINITION') {
return UniqueKey.fromObject(json.def.uniqueKey);
}
if (json.id === 'P_CREATE_INDEX') {
return UniqueKey.fromObject(json.def);
}
throw new TypeError(`Unknown json id to build unique key from: ${json.id}`);
}
/**
* Creates an unique key from an object containing needed properties.
*
* @param json Object containing properties.
*/
static fromObject(json) {
const uniqueKey = new UniqueKey();
uniqueKey.columns = json.columns.map(index_column_1.IndexColumn.fromDef);
if (json.name) {
uniqueKey.name = json.name;
}
if (json.index) {
uniqueKey.indexType = json.index.def.toLowerCase();
}
if ((0, utils_1.isDefined)(json.options) && json.options.length) {
uniqueKey.options = index_options_1.IndexOptions.fromArray(json.options);
}
return uniqueKey;
}
/**
* JSON casting of this object calls this method.
*/
toJSON() {
const json = {
columns: this.columns.map((c) => c.toJSON()),
};
if ((0, utils_1.isDefined)(this.name)) {
json.name = this.name;
}
if ((0, utils_1.isDefined)(this.indexType)) {
json.indexType = this.indexType;
}
if ((0, utils_1.isDefined)(this.options)) {
json.options = this.options.toJSON();
}
return json;
}
/**
* Create a deep clone of this model.
*/
clone() {
const key = new UniqueKey();
key.columns = this.columns.map((c) => c.clone());
if ((0, utils_1.isDefined)(this.name)) {
key.name = this.name;
}
if ((0, utils_1.isDefined)(this.indexType)) {
key.indexType = this.indexType;
}
if ((0, utils_1.isDefined)(this.options)) {
key.options = this.options.clone();
}
return key;
}
/**
* Drops a column from key. Returns 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
* unique 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));
}
/**
* Whether the given table has all of this unique key's columns.
*
* @param table Table in question.
*/
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.
*
* @param table Table to search size for.
*/
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;
}
});
}
/**
* Rename index column name.
*
* @param column Column being renamed.
* @param newName New column name.
*/
renameColumn(column, newName) {
this.columns
.filter((c) => c.column === column.name)
.forEach((c) => {
c.column = newName;
});
}
}
exports.UniqueKey = UniqueKey;