UNPKG

@dbml/core

Version:
312 lines (311 loc) 16.8 kB
"use strict"; 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 MySQLExporter = /*#__PURE__*/function () { function MySQLExporter() { _classCallCheck(this, MySQLExporter); } _createClass(MySQLExporter, 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, "` ENUM ("); var enumValues = _enum.valueIds.map(function (valueId) { return "'".concat(model.enumValues[valueId].name, "'"); }); line += "".concat(enumValues.join(', '), ")"); } else { line = "`".concat(field.name, "` ").concat(field.type.type_name !== 'varchar' ? field.type.type_name : 'varchar(255)'); } if (field.unique) { line += ' UNIQUE'; } if (field.pk) { line += ' PRIMARY KEY'; } if (field.not_null) { line += ' NOT NULL'; } if (field.increment) { line += ' AUTO_INCREMENT'; } 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); } } if (field.note) { line += " COMMENT '".concat(field.note.replace(/'/g, "''"), "'"); } 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 = MySQLExporter.getFieldLines(tableId, model); var compositePKs = MySQLExporter.getCompositePKs(tableId, model); return { tableId: tableId, fieldContents: fieldContents, compositePKs: compositePKs }; }); return tableContentArr; } }, { key: "exportTables", value: function exportTables(tableIds, model) { var tableContentArr = MySQLExporter.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);\n"); return tableStr; }); return tableStrs; } }, { key: "buildFieldName", value: function buildFieldName(fieldIds, model) { var fieldNames = fieldIds.map(function (fieldId) { return "`".concat(model.fields[fieldId].name, "`"); }).join(', '); return "(".concat(fieldNames, ")"); } }, { 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 += ');\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, ";\n\n"); return line; } }, { 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, 'mysql'); 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, 'mysql'); if (refOneIndex === -1) { 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 += ';\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(', '), ")"); if (index.type) { line += " USING ".concat(index.type.toUpperCase()); } line += ';\n'; return line; }); return indexArr; } }, { key: "exportComments", value: function exportComments(comments, model) { var commentArr = comments.map(function (comment) { var line = ''; if (comment.type === 'table') { var table = model.tables[comment.tableId]; var schema = model.schemas[table.schemaId]; line += "ALTER TABLE ".concat((0, _utils.shouldPrintSchema)(schema, model) ? "`".concat(schema.name, "`.") : '', "`").concat(table.name, "` COMMENT = '").concat(table.note.replace(/'/g, "''"), "'"); } line += ';\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, "`;\n")); } if (!_lodash["default"].isEmpty(tableIds)) { var _prevStatements$table; (_prevStatements$table = prevStatements.tables).push.apply(_prevStatements$table, _toConsumableArray(MySQLExporter.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(MySQLExporter.exportIndexes(indexIds, model))); } var commentNodes = _lodash["default"].flatten(tableIds.map(function (tableId) { var note = model.tables[tableId].note; return note ? [{ type: 'table', tableId: tableId }] : []; })); if (!_lodash["default"].isEmpty(commentNodes)) { var _prevStatements$comme; (_prevStatements$comme = prevStatements.comments).push.apply(_prevStatements$comme, _toConsumableArray(MySQLExporter.exportComments(commentNodes, model))); } if (!_lodash["default"].isEmpty(refIds)) { var _prevStatements$refs; (_prevStatements$refs = prevStatements.refs).push.apply(_prevStatements$refs, _toConsumableArray(MySQLExporter.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 MySQLExporter; }(); var _default = MySQLExporter; exports["default"] = _default;