@dbml/core
Version:
> TODO: description
1,317 lines (1,261 loc) • 56.5 kB
JavaScript
"use strict";
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); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _lodash = require("lodash");
var _TSqlParserVisitor2 = _interopRequireDefault(require("../../parsers/mssql/TSqlParserVisitor"));
var _constants = require("../constants");
var _helpers = require("../helpers");
var _AST = require("../AST");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
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); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
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 _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 _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure 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 _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 _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } /* eslint-disable class-methods-use-this */
var ADD_DESCRIPTION_FUNCTION_NAME = 'sp_addextendedproperty';
var CHECK_CONSTRAINT_CONDITION_TYPE = {
RAW: 'raw',
ENUM: 'enum'
};
var getSchemaAndTableName = function getSchemaAndTableName(names) {
var tableName = (0, _lodash.last)(names);
var schemaName = names.length > 1 ? (0, _lodash.nth)(names, -2) : undefined;
return {
schemaName: schemaName,
tableName: tableName
};
};
var getStringFromRawString = function getStringFromRawString(rawString) {
if (rawString.startsWith("N'")) {
return rawString;
}
return rawString.slice(1, rawString.length - 1);
};
/**
* @param {any[]} columnDefTableConstraints
* @returns {{
* fieldsData: any[],
* indexes: any[],
* tableRefs: any[],
* columnDefaults: any[],
* checkConstraints: any[],
* }}
*/
var splitColumnDefTableConstraints = function splitColumnDefTableConstraints(columnDefTableConstraints) {
var _columnDefTableConstr = columnDefTableConstraints.reduce(function (acc, columnDefTableConstraint) {
switch (columnDefTableConstraint.kind) {
case _constants.TABLE_CONSTRAINT_KIND.FIELD:
acc[0].push(columnDefTableConstraint.value);
break;
case _constants.TABLE_CONSTRAINT_KIND.INDEX:
case _constants.TABLE_CONSTRAINT_KIND.PK:
case _constants.TABLE_CONSTRAINT_KIND.UNIQUE:
acc[1].push(columnDefTableConstraint.value);
break;
case _constants.TABLE_CONSTRAINT_KIND.FK:
acc[2].push(columnDefTableConstraint.value);
break;
case _constants.TABLE_CONSTRAINT_KIND.DEFAULT:
acc[3].push(columnDefTableConstraint.value);
break;
case _constants.TABLE_CONSTRAINT_KIND.CHECK:
acc[4].push(columnDefTableConstraint.value);
break;
default:
break;
}
return acc;
}, [[], [], [], [], []]),
_columnDefTableConstr2 = _slicedToArray(_columnDefTableConstr, 5),
fieldsData = _columnDefTableConstr2[0],
indexes = _columnDefTableConstr2[1],
tableRefs = _columnDefTableConstr2[2],
columnDefaults = _columnDefTableConstr2[3],
checkConstraints = _columnDefTableConstr2[4];
return {
fieldsData: fieldsData,
indexes: indexes,
tableRefs: tableRefs,
columnDefaults: columnDefaults,
checkConstraints: checkConstraints
};
};
var parseFieldsAndInlineRefsFromFieldsData = function parseFieldsAndInlineRefsFromFieldsData(fieldsData, tableName, schemaName) {
var _fieldsData$reduce = fieldsData.reduce(function (acc, fieldData) {
var _acc$;
var inlineRefs = fieldData.inline_refs.map(function (inlineRef) {
inlineRef.endpoints[0].tableName = tableName;
inlineRef.endpoints[0].schemaName = schemaName;
inlineRef.endpoints[0].fieldNames = [fieldData.field.name];
return inlineRef;
});
acc[0].push(inlineRefs);
acc[1].push(fieldData.field);
(_acc$ = acc[2]).push.apply(_acc$, _toConsumableArray(fieldData.checkConstraints));
return acc;
}, [[], [], []]),
_fieldsData$reduce2 = _slicedToArray(_fieldsData$reduce, 3),
resInlineRefs = _fieldsData$reduce2[0],
fields = _fieldsData$reduce2[1],
checkConstraints = _fieldsData$reduce2[2];
return {
inlineRefs: resInlineRefs,
fields: fields,
checkConstraints: checkConstraints
};
};
var MssqlASTGen = /*#__PURE__*/function (_TSqlParserVisitor) {
_inherits(MssqlASTGen, _TSqlParserVisitor);
var _super = _createSuper(MssqlASTGen);
function MssqlASTGen() {
var _this;
_classCallCheck(this, MssqlASTGen);
_this = _super.call(this);
_this.data = {
schemas: [],
tables: [],
refs: [],
enums: [],
tableGroups: [],
aliases: [],
project: {},
records: []
};
return _this;
}
// tsql_file
// : batch* EOF
// | execute_body_batch go_statement* EOF
// ;
_createClass(MssqlASTGen, [{
key: "visitTsql_file",
value: function visitTsql_file(ctx) {
var _this2 = this;
ctx.batch().forEach(function (batch) {
return batch.accept(_this2);
});
return this.data;
}
// batch
// : go_statement
// | execute_body_batch? (go_statement | sql_clauses+) go_statement*
// | batch_level_statement go_statement*
// ;
}, {
key: "visitBatch",
value: function visitBatch(ctx) {
var _this3 = this;
if (ctx.sql_clauses()) {
ctx.sql_clauses().forEach(function (sqlClause) {
return sqlClause.accept(_this3);
});
}
}
// sql_clauses
// : dml_clause SEMI?
// | cfl_statement SEMI?
// | another_statement SEMI?
// | ddl_clause SEMI?
// | dbcc_clause SEMI?
// | backup_statement SEMI?
// | SEMI
// ;
}, {
key: "visitSql_clauses",
value: function visitSql_clauses(ctx) {
if (ctx.ddl_clause()) {
ctx.ddl_clause().accept(this);
return;
}
if (ctx.dml_clause()) {
ctx.dml_clause().accept(this);
return;
}
if (ctx.another_statement()) {
ctx.another_statement().accept(this);
}
}
// dml_clause
// : merge_statement
// | delete_statement
// | insert_statement
// | select_statement_standalone
// | update_statement
// ;
}, {
key: "visitDml_clause",
value: function visitDml_clause(ctx) {
if (ctx.insert_statement()) {
ctx.insert_statement().accept(this);
}
}
// insert_statement
// : with_expression? INSERT (TOP '(' expression ')' PERCENT?)? INTO? (
// ddl_object
// | rowset_function_limited
// ) with_table_hints? ('(' insert_column_name_list ')')? output_clause? insert_statement_value for_clause? option_clause? ';'?
// ;
}, {
key: "visitInsert_statement",
value: function visitInsert_statement(ctx) {
// [ 'users' ]
// [ 'test', 'users' ]
// [ 'db', 'test', 'users' ]
// [ 'server', 'db', 'test', 'users' ]
// The last: table name
// The second-last: schema name
var names = ctx.ddl_object().accept(this);
var tableName = (0, _lodash.last)(names);
var schemaName = names.length > 1 ? (0, _lodash.nth)(names, -2) : undefined;
var columns = ctx.insert_column_name_list() ? ctx.insert_column_name_list().accept(this) : [];
var values = ctx.insert_statement_value().accept(this);
var record = new _AST.TableRecord({
tableName: tableName,
schemaName: schemaName,
columns: columns,
values: values
});
this.data.records.push(record);
}
// ddl_object
// : full_table_name
// | LOCAL_ID
// ;
}, {
key: "visitDdl_object",
value: function visitDdl_object(ctx) {
return ctx.full_table_name().accept(this);
}
// full_table_name
// : (
// linkedServer = id_ '.' '.' schema = id_ '.'
// | server = id_ '.' database = id_ '.' schema = id_ '.'
// | database = id_ '.' schema = id_? '.'
// | schema = id_ '.'
// )? table = id_
// ;
}, {
key: "visitFull_table_name",
value: function visitFull_table_name(ctx) {
var _this4 = this;
return ctx.id_().map(function (id) {
return id.accept(_this4);
});
}
// id_
// : ID
// | TEMP_ID
// | DOUBLE_QUOTE_ID
// | DOUBLE_QUOTE_BLANK
// | SQUARE_BRACKET_ID
// | keyword
// | RAW
// ;
}, {
key: "visitId_",
value: function visitId_(ctx) {
if (ctx.DOUBLE_QUOTE_ID() || ctx.SQUARE_BRACKET_ID()) return (0, _helpers.getOriginalText)(ctx).slice(1, -1);
return (0, _helpers.getOriginalText)(ctx);
}
// insert_column_name_list
// : col += insert_column_id (',' col += insert_column_id)*
// ;
}, {
key: "visitInsert_column_name_list",
value: function visitInsert_column_name_list(ctx) {
var _this5 = this;
var columns = ctx.insert_column_id().map(function (column) {
return column.accept(_this5);
});
return (0, _lodash.flattenDepth)(columns, 1);
}
// insert_column_id
// : (ignore += id_? '.')* id_
// ;
// insert_statement_value
// : table_value_constructor
// | derived_table
// | execute_statement
// | DEFAULT VALUES
// ;
}, {
key: "visitInsert_statement_value",
value: function visitInsert_statement_value(ctx) {
if (!ctx.table_value_constructor()) return [];
var rawValues = ctx.table_value_constructor().accept(this);
return rawValues;
}
// table_value_constructor
// : VALUES '(' exps += expression_list_ ')' (',' '(' exps += expression_list_ ')')*
// ;
}, {
key: "visitTable_value_constructor",
value: function visitTable_value_constructor(ctx) {
var _this6 = this;
return ctx.expression_list_().map(function (expression) {
return expression.accept(_this6);
});
}
// expression_list_
// : exp += expression (',' exp += expression)*
// ;
}, {
key: "visitExpression_list_",
value: function visitExpression_list_(ctx) {
var _this7 = this;
return ctx.expression().map(function (expression) {
return expression.accept(_this7);
});
}
// expression
// : primitive_expression
// | function_call
// | expression '.' (value_call | query_call | exist_call | modify_call)
// | expression '.' hierarchyid_call
// | expression COLLATE id_
// | case_expression
// | full_column_name
// | bracket_expression
// | unary_operator_expression
// | expression op = ('*' | '/' | '%') expression
// | expression op = ('+' | '-' | '&' | '^' | '|' | '||') expression
// | expression time_zone
// | over_clause
// | DOLLAR_ACTION
// ;
}, {
key: "visitExpression",
value: function visitExpression(ctx) {
if (ctx.primitive_expression()) {
return ctx.primitive_expression().accept(this);
}
if (ctx.function_call()) {
return ctx.function_call().accept(this);
}
if (ctx.unary_operator_expression()) {
return ctx.unary_operator_expression().accept(this);
}
if (ctx.bracket_expression()) {
return ctx.bracket_expression().accept(this);
}
if (ctx.full_column_name()) {
return ctx.full_column_name().accept(this);
}
// Default case for any other expression type
return {
value: (0, _helpers.getOriginalText)(ctx),
type: _constants.DATA_TYPE.EXPRESSION
};
}
// bracket_expression
// : '(' expression ')'
// | '(' subquery ')'
// ;
}, {
key: "visitBracket_expression",
value: function visitBracket_expression(ctx) {
return ctx.expression() ? ctx.expression().accept(this) : null;
}
// full_column_name
// : ((DELETED | INSERTED | full_table_name) '.')? (
// column_name = id_
// | ('$' (IDENTITY | ROWGUID))
// )
// ;
}, {
key: "visitFull_column_name",
value: function visitFull_column_name(ctx) {
var columnName = ctx.id_().accept(this);
var fullTableName = ctx.full_table_name() ? ctx.full_table_name().accept(this) : [];
return {
value: [].concat(_toConsumableArray(fullTableName), [columnName]),
type: _constants.DATA_TYPE.EXPRESSION
};
}
// primitive_constant
// : STRING // string, datetime or uniqueidentifier
// | BINARY
// | (DECIMAL | REAL | FLOAT) // float or decimal
// | dollar = '$' ('-' | '+')? (DECIMAL | FLOAT) // money
// | parameter
// ;
}, {
key: "visitPrimitive_constant",
value: function visitPrimitive_constant(ctx) {
if (ctx.STRING() || ctx.BINARY()) {
var value = getStringFromRawString(ctx.getText());
return {
value: value,
type: value.startsWith("N'") ? _constants.DATA_TYPE.EXPRESSION : _constants.DATA_TYPE.STRING
};
}
if (ctx.DOLLAR()) {
var dollar = (0, _lodash.first)(ctx.children).getText();
var sign = ctx.children.length > 2 ? (0, _lodash.nth)(ctx.children, -2) : '';
var _value = (0, _lodash.last)(ctx.children).getText();
return {
value: "".concat(dollar).concat(sign).concat(_value),
type: _constants.DATA_TYPE.STRING
};
}
if (ctx.REAL() || ctx.DECIMAL() || ctx.FLOAT()) {
return {
value: ctx.getText(),
type: _constants.DATA_TYPE.NUMBER
};
}
return {
value: (0, _helpers.getOriginalText)(ctx),
type: _constants.DATA_TYPE.EXPRESSION
};
}
// function_call
// : ranking_windowed_function # RANKING_WINDOWED_FUNC
// | aggregate_windowed_function # AGGREGATE_WINDOWED_FUNC
// | analytic_windowed_function # ANALYTIC_WINDOWED_FUNC
// | built_in_functions # BUILT_IN_FUNC
// | scalar_function_name '(' expression_list_? ')' # SCALAR_FUNCTION
// | freetext_function # FREE_TEXT
// | partition_function # PARTITION_FUNC
// | hierarchyid_static_method # HIERARCHYID_METHOD
// ;
// See packages/dbml-core/src/parse/ANTLR/parsers/mssql/TSqlParser.g4 at line 4338
}, {
key: "visitBUILT_IN_FUNC",
value: function visitBUILT_IN_FUNC(ctx) {
return {
value: (0, _helpers.getOriginalText)(ctx),
type: _constants.DATA_TYPE.EXPRESSION
};
}
}, {
key: "visitSCALAR_FUNCTION",
value: function visitSCALAR_FUNCTION(ctx) {
return {
value: (0, _helpers.getOriginalText)(ctx),
type: _constants.DATA_TYPE.EXPRESSION
};
}
// unary_operator_expression
// : '~' expression
// | op = ('+' | '-') expression
// ;
}, {
key: "visitUnary_operator_expression",
value: function visitUnary_operator_expression(ctx) {
var operator = ctx.children[0].getText();
var expression = ctx.expression().accept(this);
return {
value: "".concat(operator).concat(expression.value),
type: expression.type
};
}
// data_type
// : scaled = (VARCHAR | NVARCHAR | BINARY_KEYWORD | VARBINARY_KEYWORD | SQUARE_BRACKET_ID) '(' MAX ')'
// | ext_type = id_ '(' scale = DECIMAL ',' prec = DECIMAL ')'
// | ext_type = id_ '(' scale = DECIMAL ')'
// | ext_type = id_ IDENTITY ('(' seed = DECIMAL ',' inc = DECIMAL ')')?
// | double_prec = DOUBLE PRECISION?
// | unscaled_type = id_
// ;
}, {
key: "visitData_type",
value: function visitData_type(ctx) {
if (ctx.MAX()) {
var type = '';
if (ctx.SQUARE_BRACKET_ID()) {
type = ctx.SQUARE_BRACKET_ID().getText().slice(1, -1);
} else {
var typeNode = ctx.VARCHAR() || ctx.NVARCHAR() || ctx.BINARY_KEYWORD() || ctx.VARBINARY_KEYWORD() || ctx.SQUARE_BRACKET_ID();
type = typeNode.getText();
}
return "".concat(type, "(MAX)");
}
if (ctx.DOUBLE()) {
var _double = ctx.DOUBLE().getText();
var precision = ctx.PRECISION() ? " ".concat(ctx.PRECISION().getText()) : '';
return "".concat(_double).concat(precision);
}
var id = ctx.id_().accept(this);
if (ctx.IDENTITY()) {
if (ctx.DECIMAL().length) {
var seedAndInc = ctx.DECIMAL().map(function (decimal) {
return decimal.getText();
});
return "".concat(id, " IDENTITY(").concat(seedAndInc, ")");
}
return "".concat(id, " IDENTITY");
}
if (ctx.DECIMAL().length) {
var scaleAndPrec = ctx.DECIMAL().map(function (decimal) {
return decimal.getText();
});
return "".concat(id, "(").concat(scaleAndPrec.join(','), ")");
}
return id;
}
}, {
key: "visitPrimitive_expression",
value: function visitPrimitive_expression(ctx) {
if (ctx.NULL_()) {
return {
value: ctx.getText(),
type: _constants.DATA_TYPE.BOOLEAN
};
}
if (ctx.primitive_constant()) {
return ctx.primitive_constant().accept(this);
}
return {
value: ctx.getText(),
type: _constants.DATA_TYPE.EXPRESSION
};
}
// ddl_clause
// | alter_table
// | create_index
// | create_table
// ;
// more details at: packages/dbml-core/src/parse/ANTLR/parsers/mssql/TSqlParser.g4 line 73
}, {
key: "visitDdl_clause",
value: function visitDdl_clause(ctx) {
if (ctx.create_table()) {
ctx.create_table().accept(this);
return;
}
if (ctx.alter_table()) {
ctx.alter_table().accept(this);
return;
}
if (ctx.create_index()) {
ctx.create_index().accept(this);
}
}
// create_table
// : CREATE TABLE table_name '(' column_def_table_constraints (','? table_indices)* ','? ')' (
// LOCK simple_id
// )? table_options* (ON id_ | DEFAULT | on_partition_or_filegroup)? (TEXTIMAGE_ON id_ | DEFAULT)? ';'?
// ;
}, {
key: "visitCreate_table",
value: function visitCreate_table(ctx) {
var _this8 = this,
_this$data$refs,
_this$data$refs2;
var _getSchemaAndTableNam = getSchemaAndTableName(ctx.table_name().accept(this)),
schemaName = _getSchemaAndTableNam.schemaName,
tableName = _getSchemaAndTableNam.tableName;
var columnDefTableConstraints = ctx.column_def_table_constraints().accept(this);
var tableIndices = ctx.table_indices().map(function (tableIndex) {
return tableIndex.accept(_this8);
});
var _splitColumnDefTableC = splitColumnDefTableConstraints(columnDefTableConstraints),
fieldsData = _splitColumnDefTableC.fieldsData,
indexes = _splitColumnDefTableC.indexes,
tableRefs = _splitColumnDefTableC.tableRefs,
tableCheckConstraints = _splitColumnDefTableC.checkConstraints;
var _parseFieldsAndInline = parseFieldsAndInlineRefsFromFieldsData(fieldsData, tableName, schemaName),
inlineRefs = _parseFieldsAndInline.inlineRefs,
fields = _parseFieldsAndInline.fields,
columnCheckConstraints = _parseFieldsAndInline.checkConstraints;
(_this$data$refs = this.data.refs).push.apply(_this$data$refs, _toConsumableArray((0, _lodash.flatten)(inlineRefs)));
(_this$data$refs2 = this.data.refs).push.apply(_this$data$refs2, _toConsumableArray(tableRefs.map(function (tableRef) {
tableRef.endpoints[0].tableName = tableName;
tableRef.endpoints[0].schemaName = schemaName;
return tableRef;
})));
// these check constraints represent enums
var checkConstraints = columnCheckConstraints.concat(tableCheckConstraints);
checkConstraints.forEach(function (checkConstraint) {
var field = fields.find(function (fieldItem) {
return fieldItem.name === checkConstraint.column;
});
if (!field) return;
var enumObject = new _AST.Enum({
name: "".concat(tableName, "_").concat(field.name, "_enum"),
values: checkConstraint.columnValues.map(function (value) {
return {
name: value
};
}),
schemaName: schemaName
});
_this8.data.enums.push(enumObject);
// TODO: handle multiple enums for the same field
field.type.type_name = enumObject.name;
field.type.schemaName = enumObject.schemaName;
});
var table = new _AST.Table({
name: tableName,
schemaName: schemaName,
fields: fields,
indexes: tableIndices.concat(indexes)
});
this.data.tables.push(table);
}
// table_name
// : (database = id_ '.' schema = id_? '.' | schema = id_ '.')? (
// table = id_
// | blocking_hierarchy = BLOCKING_HIERARCHY
// )
// ;
}, {
key: "visitTable_name",
value: function visitTable_name(ctx) {
var _this9 = this;
return ctx.id_().map(function (id) {
return id.accept(_this9);
});
}
// column_def_table_constraints
// : column_def_table_constraint (','? column_def_table_constraint)*
// ;
}, {
key: "visitColumn_def_table_constraints",
value: function visitColumn_def_table_constraints(ctx) {
var _this10 = this;
return ctx.column_def_table_constraint().map(function (columnDef) {
return columnDef.accept(_this10);
}).filter(function (columnDef) {
return columnDef;
});
}
// column_def_table_constraint
// : column_definition
// | materialized_column_definition
// | table_constraint
// ;
}, {
key: "visitColumn_def_table_constraint",
value: function visitColumn_def_table_constraint(ctx) {
if (ctx.column_definition()) {
return ctx.column_definition().accept(this);
}
if (ctx.table_constraint()) {
return ctx.table_constraint().accept(this);
}
return null;
}
// column_definition
// : id_ (data_type | AS expression PERSISTED?) column_definition_element* column_index?
// ;
}, {
key: "visitColumn_definition",
value: function visitColumn_definition(ctx) {
var _this11 = this;
var columnName = ctx.id_().accept(this);
var type = '';
if (ctx.data_type()) {
type = ctx.data_type().accept(this);
} else if (ctx.expression()) {
// { value: "(first_name + ' ' + last_name)", type: 'expression' }
var expression = ctx.expression().accept(this);
var as = ctx.AS().getText();
var persisted = ctx.PERSISTED() ? " ".concat(ctx.PERSISTED().getText()) : '';
type = "".concat(as, " ").concat(expression.value).concat(persisted);
}
var field = new _AST.Field({
name: columnName,
type: {
type_name: type,
schemaName: null
}
});
var definition = {
kind: _constants.TABLE_CONSTRAINT_KIND.FIELD,
value: {
field: field,
inline_refs: [],
checkConstraints: []
}
};
var columnDefinitions = ctx.column_definition_element().map(function (columnDef) {
return columnDef.accept(_this11);
});
// e.g.
// [
// { kind: 'not_null', value: true },
// { kind: 'dbdefault', value: { value: 'GETDATE()', type: 'expression' } }
// ]
columnDefinitions.filter(function (columnDef) {
return columnDef;
}).forEach(function (columnDef) {
switch (columnDef.kind) {
case _constants.COLUMN_CONSTRAINT_KIND.DEFAULT:
field.dbdefault = columnDef.value;
break;
case _constants.COLUMN_CONSTRAINT_KIND.INCREMENT:
field.increment = columnDef.value;
break;
case _constants.COLUMN_CONSTRAINT_KIND.NOT_NULL:
field.not_null = columnDef.value;
break;
case _constants.COLUMN_CONSTRAINT_KIND.PK:
field.pk = columnDef.value;
break;
case _constants.COLUMN_CONSTRAINT_KIND.UNIQUE:
field.unique = columnDef.value;
break;
case _constants.COLUMN_CONSTRAINT_KIND.INLINE_REF:
definition.value.inline_refs.push(columnDef.value);
break;
case _constants.COLUMN_CONSTRAINT_KIND.CHECK:
{
var _columnDef$value = columnDef.value,
columnDefType = _columnDef$value.type,
value = _columnDef$value.value;
// we keep the current behavior: when a field has a check constraints cannot be converted to enum, we will ignore it
if (columnDefType !== CHECK_CONSTRAINT_CONDITION_TYPE.ENUM) return;
definition.value.checkConstraints.push(value);
break;
}
default:
break;
}
});
// skip column index since it is just the name of the index that a column belongs to
return definition;
}
// column_definition_element
// : FILESTREAM
// | COLLATE collation_name = id_
// | SPARSE
// | MASKED WITH '(' FUNCTION '=' mask_function = STRING ')'
// | (CONSTRAINT constraint = id_)? DEFAULT constant_expr = expression
// | IDENTITY ('(' seed = DECIMAL ',' increment = DECIMAL ')')?
// | NOT FOR REPLICATION
// | GENERATED ALWAYS AS (ROW | TRANSACTION_ID | SEQUENCE_NUMBER) (START | END) HIDDEN_KEYWORD?
// // NULL / NOT NULL is a constraint
// | ROWGUIDCOL
// | ENCRYPTED WITH '(' COLUMN_ENCRYPTION_KEY '=' key_name = STRING ',' ENCRYPTION_TYPE '=' (
// DETERMINISTIC
// | RANDOMIZED
// ) ',' ALGORITHM '=' algo = STRING ')'
// | column_constraint
// ;
}, {
key: "visitColumn_definition_element",
value: function visitColumn_definition_element(ctx) {
if (ctx.DEFAULT()) {
return {
kind: _constants.COLUMN_CONSTRAINT_KIND.DEFAULT,
value: ctx.expression().accept(this)
};
}
if (ctx.IDENTITY()) {
return {
kind: _constants.COLUMN_CONSTRAINT_KIND.INCREMENT,
value: true
};
}
if (ctx.column_constraint()) {
return ctx.column_constraint().accept(this);
}
return null;
}
// column_constraint
// : (CONSTRAINT constraint = id_)? (
// null_notnull
// | ( (PRIMARY KEY | UNIQUE) clustered? primary_key_options)
// | ( (FOREIGN KEY)? foreign_key_options)
// | check_constraint
// )
// ;
}, {
key: "visitColumn_constraint",
value: function visitColumn_constraint(ctx) {
if (ctx.null_notnull()) {
var notNull = false;
var nullNotnull = ctx.null_notnull().accept(this);
if (nullNotnull.includes('NOT')) notNull = true;
return {
kind: _constants.COLUMN_CONSTRAINT_KIND.NOT_NULL,
value: notNull
};
}
if (ctx.UNIQUE()) {
return {
kind: _constants.COLUMN_CONSTRAINT_KIND.UNIQUE,
value: true
};
}
if (ctx.PRIMARY()) {
return {
kind: _constants.COLUMN_CONSTRAINT_KIND.PK,
value: true
};
}
if (ctx.foreign_key_options()) {
var _ctx$foreign_key_opti = ctx.foreign_key_options().accept(this),
refTableName = _ctx$foreign_key_opti.refTableName,
refSchemaName = _ctx$foreign_key_opti.refSchemaName,
fieldNames = _ctx$foreign_key_opti.fieldNames,
onDelete = _ctx$foreign_key_opti.onDelete,
onUpdate = _ctx$foreign_key_opti.onUpdate;
return {
kind: _constants.COLUMN_CONSTRAINT_KIND.INLINE_REF,
value: {
endpoints: [{
tableName: null,
schemaName: null,
fieldNames: null,
relation: '*'
}, {
tableName: refTableName,
schemaName: refSchemaName,
fieldNames: fieldNames,
relation: '1'
}],
onDelete: onDelete,
onUpdate: onUpdate
}
};
}
// we do not handle check constraint since it is complicated and hard to extract enum from it
if (ctx.check_constraint()) {
return {
kind: _constants.COLUMN_CONSTRAINT_KIND.CHECK,
value: ctx.check_constraint().accept(this)
};
}
return null;
}
// check_constraint
// : CHECK (NOT FOR REPLICATION)? '(' search_condition ')'
// ;
}, {
key: "visitCheck_constraint",
value: function visitCheck_constraint(ctx) {
return ctx.search_condition().accept(this);
}
// search_condition
// : NOT* (predicate | '(' search_condition ')')
// | search_condition AND search_condition // AND takes precedence over OR
// | search_condition OR search_condition
// ;
}, {
key: "visitSearch_condition",
value: function visitSearch_condition(ctx) {
// we will parse the enum from the most basic condition - map to the old behavior
// others, we will get the check constraint to ensure the constraint is applied - enhance the old behavior
if (!ctx.predicate() || ctx.NOT().length) {
return {
type: CHECK_CONSTRAINT_CONDITION_TYPE.RAW,
value: (0, _helpers.getOriginalText)(ctx)
};
}
var predicate = ctx.predicate().accept(this);
if (!predicate) {
return {
type: CHECK_CONSTRAINT_CONDITION_TYPE.RAW,
value: (0, _helpers.getOriginalText)(ctx)
};
}
return {
type: CHECK_CONSTRAINT_CONDITION_TYPE.ENUM,
value: predicate
};
}
// predicate
// : EXISTS '(' subquery ')'
// | freetext_predicate
// | expression comparison_operator expression
// | expression MULT_ASSIGN expression ////SQL-82 syntax for left outer joins; '*='. See https://stackoverflow.com/questions/40665/in-sybase-sql
// | expression comparison_operator (ALL | SOME | ANY) '(' subquery ')'
// | expression NOT* BETWEEN expression AND expression
// | expression NOT* IN '(' (subquery | expression_list_) ')'
// | expression NOT* LIKE expression (ESCAPE expression)?
// | expression IS null_notnull
// ;
}, {
key: "visitPredicate",
value: function visitPredicate(ctx) {
var _this12 = this;
if (ctx.IN() && ctx.expression_list_() && ctx.NOT().length === 0) {
var _expression$value;
var _ctx$expression$map = ctx.expression().map(function (e) {
return e.accept(_this12);
}),
_ctx$expression$map2 = _slicedToArray(_ctx$expression$map, 1),
_ctx$expression$map2$ = _ctx$expression$map2[0],
expression = _ctx$expression$map2$ === void 0 ? {} : _ctx$expression$map2$;
// {
// value: [ 'myschema', 'sample_table', 'column_name' ],
// type: 'expression'
// }
var column = (0, _lodash.last)((_expression$value = expression.value) !== null && _expression$value !== void 0 ? _expression$value : []);
var expressionList = ctx.expression_list_().accept(this).map(function (e) {
return e.value;
});
return {
column: column,
columnValues: expressionList
};
}
return null;
}
}, {
key: "visitNull_notnull",
value: function visitNull_notnull(ctx) {
return (0, _helpers.getOriginalText)(ctx);
}
// foreign_key_options
// : REFERENCES table_name '(' pk = column_name_list ')' (on_delete | on_update)* (
// NOT FOR REPLICATION
// )?
// ;
}, {
key: "visitForeign_key_options",
value: function visitForeign_key_options(ctx) {
var _this13 = this;
var names = ctx.table_name().accept(this);
var _getSchemaAndTableNam2 = getSchemaAndTableName(names),
refSchemaName = _getSchemaAndTableNam2.schemaName,
refTableName = _getSchemaAndTableNam2.tableName;
var fieldNames = ctx.column_name_list().accept(this);
var onDelete = ctx.on_delete() ? ctx.on_delete().map(function (action) {
return action.accept(_this13);
})[0] : null;
var onUpdate = ctx.on_update() ? ctx.on_update().map(function (action) {
return action.accept(_this13);
})[0] : null;
return {
refTableName: refTableName,
refSchemaName: refSchemaName,
onDelete: onDelete,
onUpdate: onUpdate,
fieldNames: fieldNames
};
}
// column_name_list
// : col += id_ (',' col += id_)*
// ;
}, {
key: "visitColumn_name_list",
value: function visitColumn_name_list(ctx) {
var _this14 = this;
return ctx.id_().map(function (id) {
return id.accept(_this14);
});
}
// on_delete
// : ON DELETE (NO ACTION | CASCADE | SET NULL_ | SET DEFAULT)
// ;
}, {
key: "visitOn_delete",
value: function visitOn_delete(ctx) {
if (ctx.NO()) {
return 'NO ACTION';
}
if (ctx.CASCADE()) {
return 'CASCADE';
}
if (ctx.NULL_()) {
return 'SET NULL';
}
return 'SET DEFAULT';
}
// on_update
// : ON UPDATE (NO ACTION | CASCADE | SET NULL_ | SET DEFAULT)
// ;
}, {
key: "visitOn_update",
value: function visitOn_update(ctx) {
if (ctx.NO()) {
return 'NO ACTION';
}
if (ctx.CASCADE()) {
return 'CASCADE';
}
if (ctx.NULL_()) {
return 'SET NULL';
}
return 'SET DEFAULT';
}
// table_constraint
// : (CONSTRAINT constraint = id_)? (
// ((PRIMARY KEY | UNIQUE) clustered? '(' column_name_list_with_order ')' primary_key_options)
// | ( FOREIGN KEY '(' fk = column_name_list ')' foreign_key_options)
// | ( CONNECTION '(' connection_node ( ',' connection_node)* ')')
// | ( DEFAULT constant_expr = expression FOR column = id_ (WITH VALUES)?)
// | check_constraint
// )
// ;
}, {
key: "visitTable_constraint",
value: function visitTable_constraint(ctx) {
var _this15 = this;
var name = ctx.id_() ? ctx.id_().map(function (id) {
return id.accept(_this15);
})[0] : '';
if (ctx.PRIMARY() || ctx.UNIQUE()) {
var columns = ctx.column_name_list_with_order().accept(this);
var index = new _AST.Index({
name: name,
columns: columns
});
if (ctx.PRIMARY()) {
index.pk = true;
}
if (ctx.UNIQUE()) {
index.unique = true;
}
return {
kind: ctx.PRIMARY() ? _constants.TABLE_CONSTRAINT_KIND.PK : _constants.TABLE_CONSTRAINT_KIND.UNIQUE,
value: index
};
}
if (ctx.FOREIGN()) {
var _columns = ctx.column_name_list().accept(this);
var _ctx$foreign_key_opti2 = ctx.foreign_key_options().accept(this),
refTableName = _ctx$foreign_key_opti2.refTableName,
refSchemaName = _ctx$foreign_key_opti2.refSchemaName,
fieldNames = _ctx$foreign_key_opti2.fieldNames,
onDelete = _ctx$foreign_key_opti2.onDelete,
onUpdate = _ctx$foreign_key_opti2.onUpdate;
return {
kind: _constants.TABLE_CONSTRAINT_KIND.FK,
value: {
name: name,
endpoints: [{
tableName: null,
schemaName: null,
fieldNames: _columns,
relation: '*'
}, {
tableName: refTableName,
schemaName: refSchemaName,
fieldNames: fieldNames,
relation: '1'
}],
onDelete: onDelete,
onUpdate: onUpdate
}
};
}
if (ctx.DEFAULT()) {
var column = ctx.column.accept(this);
var expression = ctx.expression().accept(this);
return {
kind: _constants.TABLE_CONSTRAINT_KIND.DEFAULT,
value: {
column: column,
defaultValue: expression
}
};
}
if (ctx.check_constraint()) {
var checkConstraint = ctx.check_constraint().accept(this);
if (checkConstraint.type !== CHECK_CONSTRAINT_CONDITION_TYPE.ENUM) return null;
return {
kind: _constants.TABLE_CONSTRAINT_KIND.CHECK,
value: checkConstraint.value
};
}
return null;
}
// column_name_list_with_order
// : id_ (ASC | DESC)? (',' id_ (ASC | DESC)?)*
// ;
}, {
key: "visitColumn_name_list_with_order",
value: function visitColumn_name_list_with_order(ctx) {
var _this16 = this;
return ctx.id_().map(function (id) {
return {
value: id.accept(_this16),
type: 'column'
};
});
}
// table_indices
// : INDEX id_ UNIQUE? clustered? '(' column_name_list_with_order ')'
// | INDEX id_ CLUSTERED COLUMNSTORE
// | INDEX id_ NONCLUSTERED? COLUMNSTORE '(' column_name_list ')' create_table_index_options? (
// ON id_
// )?
// ;
}, {
key: "visitTable_indices",
value: function visitTable_indices(ctx) {
var _this17 = this;
var index = new _AST.Index({
name: ctx.id_().map(function (id) {
return id.accept(_this17);
})[0],
unique: !!ctx.UNIQUE(),
columns: ctx.column_name_list_with_order().accept(this)
});
return index;
}
// alter_table
// : ALTER TABLE table_name (
// SET '(' LOCK_ESCALATION '=' (AUTO | TABLE | DISABLE) ')'
// | ADD column_def_table_constraints
// | ALTER COLUMN (column_definition | column_modifier)
// | DROP COLUMN id_ (',' id_)*
// | DROP CONSTRAINT constraint = id_
// | WITH (CHECK | NOCHECK) ADD (CONSTRAINT constraint = id_)? (
// FOREIGN KEY '(' fk = column_name_list ')' REFERENCES table_name (
// '(' pk = column_name_list ')'
// )? (on_delete | on_update)*
// | CHECK '(' search_condition ')'
// )
// | (NOCHECK | CHECK) CONSTRAINT constraint = id_
// | (ENABLE | DISABLE) TRIGGER id_?
// | REBUILD table_options
// | SWITCH switch_partition
// ) ';'?
// ;
}, {
key: "visitAlter_table",
value: function visitAlter_table(ctx) {
var _this$data$refs3,
_this$data$refs4,
_table$fields,
_table$indexes,
_this18 = this;
// table_name() returns an array because there are multiple table_name in the clause (REFERENCES table_name ...)
var names = ctx.table_name()[0].accept(this);
var _getSchemaAndTableNam3 = getSchemaAndTableName(names),
schemaName = _getSchemaAndTableNam3.schemaName,
tableName = _getSchemaAndTableNam3.tableName;
var table = this.data.tables.find(function (t) {
return t.name === tableName && t.schemaName === schemaName;
});
if (!table) return; // ALTER TABLE should appear after CREATE TABLE, so skip if table is not created yet
var columnDefTableConstraints = ctx.column_def_table_constraints() ? ctx.column_def_table_constraints().accept(this) : [];
var _splitColumnDefTableC2 = splitColumnDefTableConstraints(columnDefTableConstraints),
fieldsData = _splitColumnDefTableC2.fieldsData,
indexes = _splitColumnDefTableC2.indexes,
tableRefs = _splitColumnDefTableC2.tableRefs,
columnDefaults = _splitColumnDefTableC2.columnDefaults,
checkConstraints = _splitColumnDefTableC2.checkConstraints;
var _parseFieldsAndInline2 = parseFieldsAndInlineRefsFromFieldsData(fieldsData, tableName, schemaName),
inlineRefs = _parseFieldsAndInline2.inlineRefs,
fields = _parseFieldsAndInline2.fields;
(_this$data$refs3 = this.data.refs).push.apply(_this$data$refs3, _toConsumableArray((0, _lodash.flatten)(inlineRefs)));
(_this$data$refs4 = this.data.refs).push.apply(_this$data$refs4, _toConsumableArray(tableRefs.map(function (tableRef) {
tableRef.endpoints[0].tableName = tableName;
tableRef.endpoints[0].schemaName = schemaName;
return tableRef;
})));
(_table$fields = table.fields).push.apply(_table$fields, _toConsumableArray(fields));
(_table$indexes = table.indexes).push.apply(_table$indexes, _toConsumableArray(indexes));
columnDefaults.forEach(function (columnDefault) {
var field = table.fields.find(function (f) {
return f.name === columnDefault.column;
});
if (!field) return;
field.dbdefault = columnDefault.defaultValue;
});
checkConstraints.forEach(function (checkConstraint) {
var field = table.fields.find(function (fieldItem) {
return fieldItem.name === checkConstraint.column;
});
if (!field) return;
var enumObject = new _AST.Enum({
name: "".concat(tableName, "_").concat(field.name, "_enum"),
values: checkConstraint.columnValues.map(function (value) {
return {
name: value
};
}),
schemaName: schemaName
});
_this18.data.enums.push(enumObject);
// TODO: handle multiple enums for the same field
field.type.type_name = enumObject.name;
field.type.schemaName = enumObject.schemaName;
});
}
// create_index
// : CREATE UNIQUE? clustered? INDEX id_ ON table_name '(' column_name_list_with_order ')' (
// INCLUDE '(' column_name_list ')'
// )? (WHERE where = search_condition)? (create_index_options)? (ON id_)? ';'?
// ;
}, {
key: "visitCreate_index",
value: function visitCreate_index(ctx) {
var _getSchemaAndTableNam4 = getSchemaAndTableName(ctx.table_name().accept(this)),
schemaName = _getSchemaAndTableNam4.schemaName,
tableName = _getSchemaAndTableNam4.tableName;
var table = this.data.tables.find(function (t) {
return t.name === tableName && t.schemaName === schemaName;
});
if (!table) return; // ALTER TABLE should appear after CREATE TABLE, so skip if table is not created yet
var index = new _AST.Index({
name: ctx.id_()[0].accept(this),
unique: !!ctx.UNIQUE(),
columns: ctx.column_name_list_with_order().accept(this)
});
table.indexes.push(index);
}
// another_statement
// : alter_queue
// | checkpoint_statement
// | conversation_statement
// | create_contract
// | create_queue
// | cursor_statement
// | declare_statement
// | execute_statement
// | kill_statement
// | message_statement
// | reconfigure_statement
// | security_statement
// | set_statement
// | setuser_statement
// | shutdown_statement
// | transaction_statement
// | use_statement
// ;
}, {
key: "visitAnother_statement",
value: function visitAnother_statement(ctx) {
if (ctx.execute_statement()) {
ctx.execute_statement().accept(this);
}
}
// execute_statement
// : EXECUTE execute_body ';'?
// ;
}, {
key: "visitExecute_statement",
value: function visitExecute_statement(ctx) {
ctx.execute_body().accept(this);
}
// execute_body
// : (return_status = LOCAL_ID '=')? (func_proc_name_server_database_schema | execute_var_string) execute_statement_arg?
// | '(' execute_var_string (',' execute_var_string)* ')' (AS (LOGIN | USER) '=' STRING)? (
// AT_KEYWORD linkedServer = id_
// )?
// | AS ( (LOGIN | USER) '=' STRING | CALLER)
// ;
}, {
key: "visitExecute_body",
value: function visitExecute_body(ctx) {
var funcNames = ctx.func_proc_name_server_database_schema() ? ctx.func_proc_name_server_database_schema().accept(this) : [];
var funcName = (0, _lodash.last)(funcNames);
if (funcName !