@dbml/core
Version:
> TODO: description
339 lines (338 loc) • 18.2 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _lodash = _interopRequireDefault(require("lodash"));
var _utils = require("./utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
var SqlServerExporter = /*#__PURE__*/function () {
function SqlServerExporter() {
_classCallCheck(this, SqlServerExporter);
}
_createClass(SqlServerExporter, null, [{
key: "getFieldLines",
value: function getFieldLines(tableId, model) {
var table = model.tables[tableId];
var lines = table.fieldIds.map(function (fieldId) {
var field = model.fields[fieldId];
var line = '';
if (field.enumId) {
var _enum = model.enums[field.enumId];
line = "[".concat(field.name, "] nvarchar(255) NOT NULL CHECK ([").concat(field.name, "] IN (");
var enumValues = _enum.valueIds.map(function (valueId) {
var value = model.enumValues[valueId];
return "'".concat(value.name, "'");
});
line += "".concat(enumValues.join(', '), "))");
} else {
line = "[".concat(field.name, "] ").concat(field.type.type_name !== 'varchar' ? field.type.type_name : 'nvarchar(255)');
}
if (field.unique) {
line += ' UNIQUE';
}
if (field.pk) {
line += ' PRIMARY KEY';
}
if (field.not_null) {
line += ' NOT NULL';
}
if (field.increment) {
line += ' IDENTITY(1, 1)';
}
if (field.dbdefault) {
if (field.dbdefault.type === 'expression') {
line += " DEFAULT (".concat(field.dbdefault.value, ")");
} else if (field.dbdefault.type === 'string') {
line += " DEFAULT '".concat(field.dbdefault.value, "'");
} else {
line += " DEFAULT (".concat(field.dbdefault.value, ")");
}
}
return line;
});
return lines;
}
}, {
key: "getCompositePKs",
value: function getCompositePKs(tableId, model) {
var table = model.tables[tableId];
var compositePkIds = table.indexIds ? table.indexIds.filter(function (indexId) {
return model.indexes[indexId].pk;
}) : [];
var lines = compositePkIds.map(function (keyId) {
var key = model.indexes[keyId];
var line = 'PRIMARY KEY';
var columnArr = [];
key.columnIds.forEach(function (columnId) {
var column = model.indexColumns[columnId];
var columnStr = '';
if (column.type === 'expression') {
columnStr = "(".concat(column.value, ")");
} else {
columnStr = "[".concat(column.value, "]");
}
columnArr.push(columnStr);
});
line += " (".concat(columnArr.join(', '), ")");
return line;
});
return lines;
}
}, {
key: "getTableContentArr",
value: function getTableContentArr(tableIds, model) {
var tableContentArr = tableIds.map(function (tableId) {
var fieldContents = SqlServerExporter.getFieldLines(tableId, model);
var compositePKs = SqlServerExporter.getCompositePKs(tableId, model);
return {
tableId: tableId,
fieldContents: fieldContents,
compositePKs: compositePKs
};
});
return tableContentArr;
}
}, {
key: "exportTables",
value: function exportTables(tableIds, model) {
var tableContentArr = SqlServerExporter.getTableContentArr(tableIds, model);
var tableStrs = tableContentArr.map(function (tableContent) {
var content = [].concat(_toConsumableArray(tableContent.fieldContents), _toConsumableArray(tableContent.compositePKs));
var table = model.tables[tableContent.tableId];
var schema = model.schemas[table.schemaId];
var tableStr = "CREATE TABLE ".concat((0, _utils.shouldPrintSchema)(schema, model) ? "[".concat(schema.name, "].") : '', "[").concat(table.name, "] (\n").concat(content.map(function (line) {
return " ".concat(line);
}).join(',\n'), "\n)\nGO\n");
return tableStr;
});
return tableStrs;
}
}, {
key: "buildTableManyToMany",
value: function buildTableManyToMany(firstTableFieldsMap, secondTableFieldsMap, tableName, refEndpointSchema, model) {
var line = "CREATE TABLE ".concat((0, _utils.shouldPrintSchema)(refEndpointSchema, model) ? "[".concat(refEndpointSchema.name, "].") : '', "[").concat(tableName, "] (\n");
var key1s = _toConsumableArray(firstTableFieldsMap.keys()).join('], [');
var key2s = _toConsumableArray(secondTableFieldsMap.keys()).join('], [');
firstTableFieldsMap.forEach(function (fieldType, fieldName) {
line += " [".concat(fieldName, "] ").concat(fieldType, ",\n");
});
secondTableFieldsMap.forEach(function (fieldType, fieldName) {
line += " [".concat(fieldName, "] ").concat(fieldType, ",\n");
});
line += " PRIMARY KEY ([".concat(key1s, "], [").concat(key2s, "])\n");
line += ');\nGO\n\n';
return line;
}
}, {
key: "buildForeignKeyManyToMany",
value: function buildForeignKeyManyToMany(fieldsMap, foreignEndpointFields, refEndpointTableName, foreignEndpointTableName, refEndpointSchema, foreignEndpointSchema, model) {
var refEndpointFields = _toConsumableArray(fieldsMap.keys()).join('], [');
var line = "ALTER TABLE ".concat((0, _utils.shouldPrintSchema)(refEndpointSchema, model) ? "[".concat(refEndpointSchema.name, "].") : '', "[").concat(refEndpointTableName, "] ADD FOREIGN KEY ([").concat(refEndpointFields, "]) REFERENCES ").concat((0, _utils.shouldPrintSchema)(foreignEndpointSchema, model) ? "[".concat(foreignEndpointSchema.name, "].") : '', "[").concat(foreignEndpointTableName, "] ").concat(foreignEndpointFields, ";\nGO\n\n");
return line;
}
}, {
key: "buildFieldName",
value: function buildFieldName(fieldIds, model) {
var fieldNames = fieldIds.map(function (fieldId) {
return "[".concat(model.fields[fieldId].name, "]");
}).join(', ');
return "(".concat(fieldNames, ")");
}
}, {
key: "exportRefs",
value: function exportRefs(refIds, model, usedTableNames) {
var _this = this;
var strArr = refIds.map(function (refId) {
var line = '';
var ref = model.refs[refId];
var refOneIndex = ref.endpointIds.findIndex(function (endpointId) {
return model.endpoints[endpointId].relation === '1';
});
var refEndpointIndex = refOneIndex === -1 ? 0 : refOneIndex;
var foreignEndpointId = ref.endpointIds[1 - refEndpointIndex];
var refEndpointId = ref.endpointIds[refEndpointIndex];
var foreignEndpoint = model.endpoints[foreignEndpointId];
var refEndpoint = model.endpoints[refEndpointId];
var refEndpointField = model.fields[refEndpoint.fieldIds[0]];
var refEndpointTable = model.tables[refEndpointField.tableId];
var refEndpointSchema = model.schemas[refEndpointTable.schemaId];
var refEndpointFieldName = _this.buildFieldName(refEndpoint.fieldIds, model, 'mssql');
var foreignEndpointField = model.fields[foreignEndpoint.fieldIds[0]];
var foreignEndpointTable = model.tables[foreignEndpointField.tableId];
var foreignEndpointSchema = model.schemas[foreignEndpointTable.schemaId];
var foreignEndpointFieldName = _this.buildFieldName(foreignEndpoint.fieldIds, model, 'mssql');
if (refOneIndex === -1) {
// many to many relationship
var firstTableFieldsMap = (0, _utils.buildJunctionFields1)(refEndpoint.fieldIds, model);
var secondTableFieldsMap = (0, _utils.buildJunctionFields2)(foreignEndpoint.fieldIds, model, firstTableFieldsMap);
var newTableName = (0, _utils.buildNewTableName)(refEndpointTable.name, foreignEndpointTable.name, usedTableNames);
line += _this.buildTableManyToMany(firstTableFieldsMap, secondTableFieldsMap, newTableName, refEndpointSchema, model);
line += _this.buildForeignKeyManyToMany(firstTableFieldsMap, refEndpointFieldName, newTableName, refEndpointTable.name, refEndpointSchema, refEndpointSchema, model);
line += _this.buildForeignKeyManyToMany(secondTableFieldsMap, foreignEndpointFieldName, newTableName, foreignEndpointTable.name, refEndpointSchema, foreignEndpointSchema, model);
} else {
line = "ALTER TABLE ".concat((0, _utils.shouldPrintSchema)(foreignEndpointSchema, model) ? "[".concat(foreignEndpointSchema.name, "].") : '', "[").concat(foreignEndpointTable.name, "] ADD ");
if (ref.name) {
line += "CONSTRAINT [".concat(ref.name, "] ");
}
line += "FOREIGN KEY ".concat(foreignEndpointFieldName, " REFERENCES ").concat((0, _utils.shouldPrintSchema)(refEndpointSchema, model) ? "[".concat(refEndpointSchema.name, "].") : '', "[").concat(refEndpointTable.name, "] ").concat(refEndpointFieldName);
if (ref.onDelete) {
line += " ON DELETE ".concat(ref.onDelete.toUpperCase());
}
if (ref.onUpdate) {
line += " ON UPDATE ".concat(ref.onUpdate.toUpperCase());
}
line += '\nGO\n';
}
return line;
});
return strArr;
}
}, {
key: "exportIndexes",
value: function exportIndexes(indexIds, model) {
// exclude composite pk index
var indexArr = indexIds.filter(function (indexId) {
return !model.indexes[indexId].pk;
}).map(function (indexId, i) {
var index = model.indexes[indexId];
var table = model.tables[index.tableId];
var schema = model.schemas[table.schemaId];
var line = 'CREATE';
if (index.unique) {
line += ' UNIQUE';
}
var indexName = index.name ? "[".concat(index.name, "]") : "".concat((0, _utils.shouldPrintSchema)(schema, model) ? "[".concat(schema.name, "].") : '', "[").concat(table.name, "_index_").concat(i, "]");
line += " INDEX ".concat(indexName, " ON ").concat((0, _utils.shouldPrintSchema)(schema, model) ? "[".concat(schema.name, "].") : '', "[").concat(table.name, "]");
var columnArr = [];
index.columnIds.forEach(function (columnId) {
var column = model.indexColumns[columnId];
var columnStr = '';
if (column.type === 'expression') {
columnStr = "(".concat(column.value, ")");
} else {
columnStr = "\"".concat(column.value, "\"");
}
columnArr.push(columnStr);
});
line += " (".concat(columnArr.join(', '), ")");
line += '\nGO\n';
return line;
});
return indexArr;
}
}, {
key: "exportComments",
value: function exportComments(comments, model) {
var commentArr = comments.map(function (comment) {
var table = model.tables[comment.tableId];
var schema = model.schemas[table.schemaId];
var line = '';
line = 'EXEC sp_addextendedproperty\n';
switch (comment.type) {
case 'table':
{
line += "@name = N'Table_Description',\n";
line += "@value = '".concat(table.note.replace(/'/g, "''"), "',\n");
line += "@level0type = N'Schema', @level0name = '".concat((0, _utils.shouldPrintSchema)(schema, model) ? "".concat(schema.name) : 'dbo', "',\n");
line += "@level1type = N'Table', @level1name = '".concat(table.name, "';\n");
break;
}
case 'column':
{
var field = model.fields[comment.fieldId];
line += "@name = N'Column_Description',\n";
line += "@value = '".concat(field.note.replace(/'/g, "''"), "',\n");
line += "@level0type = N'Schema', @level0name = '".concat((0, _utils.shouldPrintSchema)(schema, model) ? "".concat(schema.name) : 'dbo', "',\n");
line += "@level1type = N'Table', @level1name = '".concat(table.name, "',\n");
line += "@level2type = N'Column', @level2name = '".concat(field.name, "';\n");
break;
}
default:
break;
}
line += 'GO\n';
return line;
});
return commentArr;
}
}, {
key: "export",
value: function _export(model) {
var database = model.database['1'];
var usedTableNames = new Set(Object.values(model.tables).map(function (table) {
return table.name;
}));
var statements = database.schemaIds.reduce(function (prevStatements, schemaId) {
var schema = model.schemas[schemaId];
var tableIds = schema.tableIds,
refIds = schema.refIds;
if ((0, _utils.shouldPrintSchema)(schema, model)) {
prevStatements.schemas.push("CREATE SCHEMA [".concat(schema.name, "]\nGO\n"));
}
if (!_lodash["default"].isEmpty(tableIds)) {
var _prevStatements$table;
(_prevStatements$table = prevStatements.tables).push.apply(_prevStatements$table, _toConsumableArray(SqlServerExporter.exportTables(tableIds, model)));
}
var indexIds = _lodash["default"].flatten(tableIds.map(function (tableId) {
return model.tables[tableId].indexIds;
}));
if (!_lodash["default"].isEmpty(indexIds)) {
var _prevStatements$index;
(_prevStatements$index = prevStatements.indexes).push.apply(_prevStatements$index, _toConsumableArray(SqlServerExporter.exportIndexes(indexIds, model)));
}
var commentNodes = _lodash["default"].flatten(tableIds.map(function (tableId) {
var _model$tables$tableId = model.tables[tableId],
fieldIds = _model$tables$tableId.fieldIds,
note = _model$tables$tableId.note;
var fieldObjects = fieldIds.filter(function (fieldId) {
return model.fields[fieldId].note;
}).map(function (fieldId) {
return {
type: 'column',
fieldId: fieldId,
tableId: tableId
};
});
return note ? [{
type: 'table',
tableId: tableId
}].concat(fieldObjects) : fieldObjects;
}));
if (!_lodash["default"].isEmpty(commentNodes)) {
var _prevStatements$comme;
(_prevStatements$comme = prevStatements.comments).push.apply(_prevStatements$comme, _toConsumableArray(SqlServerExporter.exportComments(commentNodes, model)));
}
if (!_lodash["default"].isEmpty(refIds)) {
var _prevStatements$refs;
(_prevStatements$refs = prevStatements.refs).push.apply(_prevStatements$refs, _toConsumableArray(SqlServerExporter.exportRefs(refIds, model, usedTableNames)));
}
return prevStatements;
}, {
schemas: [],
enums: [],
tables: [],
indexes: [],
comments: [],
refs: []
});
var res = _lodash["default"].concat(statements.schemas, statements.enums, statements.tables, statements.indexes, statements.comments, statements.refs).join('\n');
return res;
}
}]);
return SqlServerExporter;
}();
var _default = SqlServerExporter;
exports["default"] = _default;
;