diff --git a/lib/MySQL/connector.js b/lib/MySQL/connector.js index 0efd37e..13c8840 100644 --- a/lib/MySQL/connector.js +++ b/lib/MySQL/connector.js @@ -1,46 +1,47 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MySqlConnector = void 0; -var tslib_1 = require("tslib"); -var mysql2_1 = tslib_1.__importDefault(require("mysql2")); -var uuid_1 = require("uuid"); -var assert_1 = tslib_1.__importDefault(require("assert")); -var MySqlConnector = /** @class */ (function () { - function MySqlConnector(configuration) { +const tslib_1 = require("tslib"); +const mysql2_1 = tslib_1.__importDefault(require("mysql2")); +const uuid_1 = require("uuid"); +const assert_1 = tslib_1.__importDefault(require("assert")); +class MySqlConnector { + pool; + configuration; + txnDict; + constructor(configuration) { this.configuration = configuration; this.txnDict = {}; } - MySqlConnector.prototype.connect = function () { + connect() { this.pool = mysql2_1.default.createPool(this.configuration); - }; - MySqlConnector.prototype.disconnect = function () { + } + disconnect() { this.pool.end(); - }; - MySqlConnector.prototype.startTransaction = function (option) { - var _this = this; - return new Promise(function (resolve, reject) { - _this.pool.getConnection(function (err, connection) { + } + startTransaction(option) { + return new Promise((resolve, reject) => { + this.pool.getConnection((err, connection) => { if (err) { return reject(err); } - var isolationLevel = (option || {}).isolationLevel; - var startTxn = function () { - var sql = 'START TRANSACTION;'; - connection.query(sql, function (err2) { - var _a; + const { isolationLevel } = option || {}; + const startTxn = () => { + let sql = 'START TRANSACTION;'; + connection.query(sql, (err2) => { if (err2) { connection.release(); return reject(err2); } - var id = (0, uuid_1.v4)(); - Object.assign(_this.txnDict, (_a = {}, - _a[id] = connection, - _a)); + const id = (0, uuid_1.v4)(); + Object.assign(this.txnDict, { + [id]: connection, + }); resolve(id); }); }; if (isolationLevel) { - connection.query("SET TRANSACTION ISOLATION LEVEL ".concat(isolationLevel, ";"), function (err2) { + connection.query(`SET TRANSACTION ISOLATION LEVEL ${isolationLevel};`, (err2) => { if (err2) { connection.release(); return reject(err2); @@ -53,51 +54,44 @@ var MySqlConnector = /** @class */ (function () { } }); }); - }; - MySqlConnector.prototype.exec = function (sql, txn) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var connection_1; - var _this = this; - return tslib_1.__generator(this, function (_a) { - if (process.env.NODE_ENV === 'development') { - console.log(sql); - } - if (txn) { - connection_1 = this.txnDict[txn]; - (0, assert_1.default)(connection_1); - return [2 /*return*/, new Promise(function (resolve, reject) { - connection_1.query(sql, function (err, result) { - if (err) { - console.error("sql exec err: ".concat(sql), err); - return reject(err); - } - resolve(result); - }); - })]; - } - else { - return [2 /*return*/, new Promise(function (resolve, reject) { - // if (process.env.DEBUG) { - // console.log(sql); - //} - _this.pool.query(sql, function (err, result) { - if (err) { - console.error("sql exec err: ".concat(sql), err); - return reject(err); - } - resolve(result); - }); - })]; - } - return [2 /*return*/]; + } + async exec(sql, txn) { + if (process.env.NODE_ENV === 'development') { + console.log(sql); + } + if (txn) { + const connection = this.txnDict[txn]; + (0, assert_1.default)(connection); + return new Promise((resolve, reject) => { + connection.query(sql, (err, result) => { + if (err) { + console.error(`sql exec err: ${sql}`, err); + return reject(err); + } + resolve(result); + }); }); - }); - }; - MySqlConnector.prototype.commitTransaction = function (txn) { - var connection = this.txnDict[txn]; + } + else { + return new Promise((resolve, reject) => { + // if (process.env.DEBUG) { + // console.log(sql); + //} + this.pool.query(sql, (err, result) => { + if (err) { + console.error(`sql exec err: ${sql}`, err); + return reject(err); + } + resolve(result); + }); + }); + } + } + commitTransaction(txn) { + const connection = this.txnDict[txn]; (0, assert_1.default)(connection); - return new Promise(function (resolve, reject) { - connection.query('COMMIT;', function (err) { + return new Promise((resolve, reject) => { + connection.query('COMMIT;', (err) => { if (err) { return reject(err); } @@ -105,12 +99,12 @@ var MySqlConnector = /** @class */ (function () { resolve(); }); }); - }; - MySqlConnector.prototype.rollbackTransaction = function (txn) { - var connection = this.txnDict[txn]; + } + rollbackTransaction(txn) { + const connection = this.txnDict[txn]; (0, assert_1.default)(connection); - return new Promise(function (resolve, reject) { - connection.query('ROLLBACK;', function (err) { + return new Promise((resolve, reject) => { + connection.query('ROLLBACK;', (err) => { if (err) { return reject(err); } @@ -118,7 +112,6 @@ var MySqlConnector = /** @class */ (function () { resolve(); }); }); - }; - return MySqlConnector; -}()); + } +} exports.MySqlConnector = MySqlConnector; diff --git a/lib/MySQL/store.js b/lib/MySQL/store.js index 09eb469..3f52137 100644 --- a/lib/MySQL/store.js +++ b/lib/MySQL/store.js @@ -1,71 +1,61 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MysqlStore = void 0; -var tslib_1 = require("tslib"); -var CascadeStore_1 = require("oak-domain/lib/store/CascadeStore"); -var connector_1 = require("./connector"); -var translator_1 = require("./translator"); -var lodash_1 = require("lodash"); -var assert_1 = tslib_1.__importDefault(require("assert")); -var relation_1 = require("oak-domain/lib/store/relation"); +const tslib_1 = require("tslib"); +const CascadeStore_1 = require("oak-domain/lib/store/CascadeStore"); +const connector_1 = require("./connector"); +const translator_1 = require("./translator"); +const lodash_1 = require("lodash"); +const assert_1 = tslib_1.__importDefault(require("assert")); +const relation_1 = require("oak-domain/lib/store/relation"); function convertGeoTextToObject(geoText) { if (geoText.startsWith('POINT')) { - var coord = geoText.match((/(\d|\.)+(?=\)|\s)/g)); + const coord = geoText.match((/(\d|\.)+(?=\)|\s)/g)); return { type: 'Point', - coordinate: coord.map(function (ele) { return parseFloat(ele); }), + coordinate: coord.map(ele => parseFloat(ele)), }; } else { throw new Error('only support Point now'); } } -var MysqlStore = /** @class */ (function (_super) { - tslib_1.__extends(MysqlStore, _super); - function MysqlStore(storageSchema, configuration) { - var _this = _super.call(this, storageSchema) || this; - _this.connector = new connector_1.MySqlConnector(configuration); - _this.translator = new translator_1.MySqlTranslator(storageSchema); - return _this; +class MysqlStore extends CascadeStore_1.CascadeStore { + aggregateSync(entity, aggregation, context, option) { + throw new Error('MySQL store不支持同步取数据,不应该跑到这儿'); } - MysqlStore.prototype.aggregateSync = function (entity, aggregation, context, option) { + selectAbjointRow(entity, selection, context, option) { throw new Error('MySQL store不支持同步取数据,不应该跑到这儿'); - }; - MysqlStore.prototype.selectAbjointRow = function (entity, selection, context, option) { - throw new Error('MySQL store不支持同步取数据,不应该跑到这儿'); - }; - MysqlStore.prototype.updateAbjointRow = function (entity, operation, context, option) { + } + updateAbjointRow(entity, operation, context, option) { throw new Error('MySQL store不支持同步更新数据,不应该跑到这儿'); - }; - MysqlStore.prototype.exec = function (script, txnId) { + } + exec(script, txnId) { return this.connector.exec(script, txnId); - }; - MysqlStore.prototype.aggregateAsync = function (entity, aggregation, context, option) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var sql, result; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - sql = this.translator.translateAggregate(entity, aggregation, option); - return [4 /*yield*/, this.connector.exec(sql, context.getCurrentTxnId())]; - case 1: - result = _a.sent(); - return [2 /*return*/, this.formResult(entity, result)]; - } - }); - }); - }; - MysqlStore.prototype.aggregate = function (entity, aggregation, context, option) { + } + connector; + translator; + constructor(storageSchema, configuration) { + super(storageSchema); + this.connector = new connector_1.MySqlConnector(configuration); + this.translator = new translator_1.MySqlTranslator(storageSchema); + } + async aggregateAsync(entity, aggregation, context, option) { + const sql = this.translator.translateAggregate(entity, aggregation, option); + const result = await this.connector.exec(sql, context.getCurrentTxnId()); + return this.formResult(entity, result); + } + aggregate(entity, aggregation, context, option) { return this.aggregateAsync(entity, aggregation, context, option); - }; - MysqlStore.prototype.supportManyToOneJoin = function () { + } + supportManyToOneJoin() { return true; - }; - MysqlStore.prototype.supportMultipleCreate = function () { + } + supportMultipleCreate() { return true; - }; - MysqlStore.prototype.formResult = function (entity, result) { - var schema = this.getSchema(); + } + formResult(entity, result) { + const schema = this.getSchema(); /* function resolveObject(r: Record, path: string, value: any) { const i = path.indexOf("."); const bs = path.indexOf('['); @@ -86,14 +76,13 @@ var MysqlStore = /** @class */ (function (_super) { } } */ function resolveAttribute(entity2, r, attr, value) { - var _a; - var _b = schema[entity2], attributes = _b.attributes, view = _b.view; + const { attributes, view } = schema[entity2]; if (!view) { - var i = attr.indexOf("."); + const i = attr.indexOf("."); if (i !== -1) { - var attrHead = attr.slice(0, i); - var attrTail = attr.slice(i + 1); - var rel = (0, relation_1.judgeRelation)(schema, entity2, attrHead); + const attrHead = attr.slice(0, i); + const attrTail = attr.slice(i + 1); + const rel = (0, relation_1.judgeRelation)(schema, entity2, attrHead); if (rel === 1) { (0, lodash_1.set)(r, attr, value); } @@ -114,7 +103,7 @@ var MysqlStore = /** @class */ (function (_super) { } } else if (attributes[attr]) { - var type = attributes[attr].type; + const { type } = attributes[attr]; switch (type) { case 'date': case 'time': { @@ -148,7 +137,7 @@ var MysqlStore = /** @class */ (function (_super) { case 'function': { if (typeof value === 'string') { // 函数的执行环境需要的参数只有创建函数者知悉,只能由上层再创建Function - r[attr] = "return ".concat(Buffer.from(value, 'base64').toString()); + r[attr] = `return ${Buffer.from(value, 'base64').toString()}`; } else { r[attr] = value; @@ -189,31 +178,31 @@ var MysqlStore = /** @class */ (function (_super) { } } else { - (0, lodash_1.assign)(r, (_a = {}, - _a[attr] = value, - _a)); + (0, lodash_1.assign)(r, { + [attr]: value, + }); } } function removeNullObjects(r, e) { // assert(r.id && typeof r.id === 'string', `对象${e}取数据时发现id为非法值${r.id},rowId是${r.id}`) - for (var attr in r) { - var rel = (0, relation_1.judgeRelation)(schema, e, attr); + for (let attr in r) { + const rel = (0, relation_1.judgeRelation)(schema, e, attr); if (rel === 2) { // 边界,如果是toModi的对象,这里的外键确实有可能为空 - (0, assert_1.default)(schema[e].toModi || r.entity !== attr || r.entityId === r[attr].id, "\u5BF9\u8C61".concat(e, "\u53D6\u6570\u636E\u65F6\uFF0C\u53D1\u73B0entityId\u4E0E\u8FDE\u63A5\u7684\u5BF9\u8C61\u7684\u4E3B\u952E\u4E0D\u4E00\u81F4\uFF0CrowId\u662F").concat(r.id, "\uFF0C\u5176entityId\u503C\u4E3A").concat(r.entityId, "\uFF0C\u8FDE\u63A5\u7684\u5BF9\u8C61\u7684\u4E3B\u952E\u4E3A").concat(r[attr].id)); + (0, assert_1.default)(schema[e].toModi || r.entity !== attr || r.entityId === r[attr].id, `对象${e}取数据时,发现entityId与连接的对象的主键不一致,rowId是${r.id},其entityId值为${r.entityId},连接的对象的主键为${r[attr].id}`); if (r[attr].id === null) { (0, assert_1.default)(schema[e].toModi || r.entity !== attr); delete r[attr]; continue; } - (0, assert_1.default)(r.entity === attr, "\u5BF9\u8C61".concat(e, "\u53D6\u6570\u636E\u65F6\uFF0C\u53D1\u73B0entity\u503C\u4E0E\u8FDE\u63A5\u7684\u5916\u952E\u5BF9\u8C61\u4E0D\u4E00\u81F4\uFF0CrowId\u662F").concat(r.id, "\uFF0C\u5176entity\u503C\u4E3A").concat(r.entity, "\uFF0C\u8FDE\u63A5\u7684\u5BF9\u8C61\u4E3A").concat(attr)); + (0, assert_1.default)(r.entity === attr, `对象${e}取数据时,发现entity值与连接的外键对象不一致,rowId是${r.id},其entity值为${r.entity},连接的对象为${attr}`); removeNullObjects(r[attr], attr); } else if (typeof rel === 'string') { // 边界,如果是toModi的对象,这里的外键确实有可能为空 - (0, assert_1.default)(schema[e].toModi || r["".concat(attr, "Id")] === r[attr].id, "\u5BF9\u8C61".concat(e, "\u53D6\u6570\u636E\u65F6\uFF0C\u53D1\u73B0\u5176\u5916\u952E\u4E0E\u8FDE\u63A5\u7684\u5BF9\u8C61\u7684\u4E3B\u952E\u4E0D\u4E00\u81F4\uFF0CrowId\u662F").concat(r.id, "\uFF0C\u5176").concat(attr, "Id\u503C\u4E3A").concat(r["".concat(attr, "Id")], "\uFF0C\u8FDE\u63A5\u7684\u5BF9\u8C61\u7684\u4E3B\u952E\u4E3A").concat(r[attr].id)); + (0, assert_1.default)(schema[e].toModi || r[`${attr}Id`] === r[attr].id, `对象${e}取数据时,发现其外键与连接的对象的主键不一致,rowId是${r.id},其${attr}Id值为${r[`${attr}Id`]},连接的对象的主键为${r[attr].id}`); if (r[attr].id === null) { - (0, assert_1.default)(schema[e].toModi || r["".concat(attr, "Id")] === null); + (0, assert_1.default)(schema[e].toModi || r[`${attr}Id`] === null); delete r[attr]; continue; } @@ -222,218 +211,110 @@ var MysqlStore = /** @class */ (function (_super) { } } function formSingleRow(r) { - var result2 = {}; - for (var attr in r) { - var value = r[attr]; + let result2 = {}; + for (let attr in r) { + const value = r[attr]; resolveAttribute(entity, result2, attr, value); } removeNullObjects(result2, entity); return result2; } if (result instanceof Array) { - return result.map(function (r) { return formSingleRow(r); }); + return result.map(r => formSingleRow(r)); } return formSingleRow(result); - }; - MysqlStore.prototype.selectAbjointRowAsync = function (entity, selection, context, option) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var sql, result; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - sql = this.translator.translateSelect(entity, selection, option); - return [4 /*yield*/, this.connector.exec(sql, context.getCurrentTxnId())]; - case 1: - result = _a.sent(); - return [2 /*return*/, this.formResult(entity, result)]; + } + async selectAbjointRowAsync(entity, selection, context, option) { + const sql = this.translator.translateSelect(entity, selection, option); + const result = await this.connector.exec(sql, context.getCurrentTxnId()); + return this.formResult(entity, result); + } + async updateAbjointRowAsync(entity, operation, context, option) { + const { translator, connector } = this; + const { action } = operation; + const txn = context.getCurrentTxnId(); + switch (action) { + case 'create': { + const { data } = operation; + const sql = translator.translateInsert(entity, data instanceof Array ? data : [data]); + await connector.exec(sql, txn); + if (!option?.dontCollect) { + context.opRecords.push({ + a: 'c', + d: data, + e: entity, + }); } - }); - }); - }; - MysqlStore.prototype.updateAbjointRowAsync = function (entity, operation, context, option) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var _a, translator, connector, action, txn, _b, data, sql, sql, sql; - return tslib_1.__generator(this, function (_c) { - switch (_c.label) { - case 0: - _a = this, translator = _a.translator, connector = _a.connector; - action = operation.action; - txn = context.getCurrentTxnId(); - _b = action; - switch (_b) { - case 'create': return [3 /*break*/, 1]; - case 'remove': return [3 /*break*/, 3]; - } - return [3 /*break*/, 5]; - case 1: - data = operation.data; - sql = translator.translateInsert(entity, data instanceof Array ? data : [data]); - return [4 /*yield*/, connector.exec(sql, txn)]; - case 2: - _c.sent(); - if (!(option === null || option === void 0 ? void 0 : option.dontCollect)) { - context.opRecords.push({ - a: 'c', - d: data, - e: entity, - }); - } - return [2 /*return*/, data instanceof Array ? data.length : 1]; - case 3: - sql = translator.translateRemove(entity, operation, option); - return [4 /*yield*/, connector.exec(sql, txn)]; - case 4: - _c.sent(); - // todo 这里对sorter和indexfrom/count的支持不完整 - if (!(option === null || option === void 0 ? void 0 : option.dontCollect)) { - context.opRecords.push({ - a: 'r', - e: entity, - f: operation.filter, - }); - } - return [2 /*return*/, 1]; - case 5: - (0, assert_1.default)(!['select', 'download', 'stat'].includes(action)); - sql = translator.translateUpdate(entity, operation, option); - return [4 /*yield*/, connector.exec(sql, txn)]; - case 6: - _c.sent(); - // todo 这里对sorter和indexfrom/count的支持不完整 - if (!(option === null || option === void 0 ? void 0 : option.dontCollect)) { - context.opRecords.push({ - a: 'u', - e: entity, - d: operation.data, - f: operation.filter, - }); - } - return [2 /*return*/, 1]; + return data instanceof Array ? data.length : 1; + } + case 'remove': { + const sql = translator.translateRemove(entity, operation, option); + await connector.exec(sql, txn); + // todo 这里对sorter和indexfrom/count的支持不完整 + if (!option?.dontCollect) { + context.opRecords.push({ + a: 'r', + e: entity, + f: operation.filter, + }); } - }); - }); - }; - MysqlStore.prototype.operate = function (entity, operation, context, option) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var action; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - action = operation.action; - (0, assert_1.default)(!['select', 'download', 'stat'].includes(action), '现在不支持使用select operation'); - return [4 /*yield*/, _super.prototype.operateAsync.call(this, entity, operation, context, option)]; - case 1: return [2 /*return*/, _a.sent()]; + return 1; + } + default: { + (0, assert_1.default)(!['select', 'download', 'stat'].includes(action)); + const sql = translator.translateUpdate(entity, operation, option); + await connector.exec(sql, txn); + // todo 这里对sorter和indexfrom/count的支持不完整 + if (!option?.dontCollect) { + context.opRecords.push({ + a: 'u', + e: entity, + d: operation.data, + f: operation.filter, + }); } - }); - }); - }; - MysqlStore.prototype.select = function (entity, selection, context, option) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var result; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, _super.prototype.selectAsync.call(this, entity, selection, context, option)]; - case 1: - result = _a.sent(); - return [2 /*return*/, result]; - } - }); - }); - }; - MysqlStore.prototype.count = function (entity, selection, context, option) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var sql, result; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - sql = this.translator.translateCount(entity, selection, option); - return [4 /*yield*/, this.connector.exec(sql, context.getCurrentTxnId())]; - case 1: - result = _a.sent(); - return [2 /*return*/, result[0].cnt]; - } - }); - }); - }; - MysqlStore.prototype.begin = function (option) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var txn; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, this.connector.startTransaction(option)]; - case 1: - txn = _a.sent(); - return [2 /*return*/, txn]; - } - }); - }); - }; - MysqlStore.prototype.commit = function (txnId) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, this.connector.commitTransaction(txnId)]; - case 1: - _a.sent(); - return [2 /*return*/]; - } - }); - }); - }; - MysqlStore.prototype.rollback = function (txnId) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, this.connector.rollbackTransaction(txnId)]; - case 1: - _a.sent(); - return [2 /*return*/]; - } - }); - }); - }; - MysqlStore.prototype.connect = function () { + return 1; + } + } + } + async operate(entity, operation, context, option) { + const { action } = operation; + (0, assert_1.default)(!['select', 'download', 'stat'].includes(action), '现在不支持使用select operation'); + return await super.operateAsync(entity, operation, context, option); + } + async select(entity, selection, context, option) { + const result = await super.selectAsync(entity, selection, context, option); + return result; + } + async count(entity, selection, context, option) { + const sql = this.translator.translateCount(entity, selection, option); + const result = await this.connector.exec(sql, context.getCurrentTxnId()); + return result[0].cnt; + } + async begin(option) { + const txn = await this.connector.startTransaction(option); + return txn; + } + async commit(txnId) { + await this.connector.commitTransaction(txnId); + } + async rollback(txnId) { + await this.connector.rollbackTransaction(txnId); + } + connect() { this.connector.connect(); - }; - MysqlStore.prototype.disconnect = function () { + } + disconnect() { this.connector.disconnect(); - }; - MysqlStore.prototype.initialize = function (dropIfExists) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var schema, _a, _b, _i, entity, sqls, _c, sqls_1, sql; - return tslib_1.__generator(this, function (_d) { - switch (_d.label) { - case 0: - schema = this.getSchema(); - _a = []; - for (_b in schema) - _a.push(_b); - _i = 0; - _d.label = 1; - case 1: - if (!(_i < _a.length)) return [3 /*break*/, 6]; - entity = _a[_i]; - sqls = this.translator.translateCreateEntity(entity, { replace: dropIfExists }); - _c = 0, sqls_1 = sqls; - _d.label = 2; - case 2: - if (!(_c < sqls_1.length)) return [3 /*break*/, 5]; - sql = sqls_1[_c]; - return [4 /*yield*/, this.connector.exec(sql)]; - case 3: - _d.sent(); - _d.label = 4; - case 4: - _c++; - return [3 /*break*/, 2]; - case 5: - _i++; - return [3 /*break*/, 1]; - case 6: return [2 /*return*/]; - } - }); - }); - }; - return MysqlStore; -}(CascadeStore_1.CascadeStore)); + } + async initialize(dropIfExists) { + const schema = this.getSchema(); + for (const entity in schema) { + const sqls = this.translator.translateCreateEntity(entity, { replace: dropIfExists }); + for (const sql of sqls) { + await this.connector.exec(sql); + } + } + } +} exports.MysqlStore = MysqlStore; diff --git a/lib/MySQL/translator.js b/lib/MySQL/translator.js index c494cd4..68eb861 100644 --- a/lib/MySQL/translator.js +++ b/lib/MySQL/translator.js @@ -1,12 +1,12 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MySqlTranslator = void 0; -var tslib_1 = require("tslib"); -var assert_1 = tslib_1.__importDefault(require("assert")); -var util_1 = require("util"); -var lodash_1 = require("lodash"); -var sqlTranslator_1 = require("../sqlTranslator"); -var GeoTypes = [ +const tslib_1 = require("tslib"); +const assert_1 = tslib_1.__importDefault(require("assert")); +const util_1 = require("util"); +const lodash_1 = require("lodash"); +const sqlTranslator_1 = require("../sqlTranslator"); +const GeoTypes = [ { type: 'point', name: "Point" @@ -39,65 +39,54 @@ var GeoTypes = [ ]; function transformGeoData(data) { if (data instanceof Array) { - var element_1 = data[0]; - if (element_1 instanceof Array) { - return " GeometryCollection(".concat(data.map(function (ele) { return transformGeoData(ele); }).join(','), ")"); + const element = data[0]; + if (element instanceof Array) { + return ` GeometryCollection(${data.map(ele => transformGeoData(ele)).join(',')})`; } else { - var geoType_1 = GeoTypes.find(function (ele) { return ele.type === element_1.type; }); - if (!geoType_1) { - throw new Error("".concat(element_1.type, " is not supported in MySQL")); + const geoType = GeoTypes.find(ele => ele.type === element.type); + if (!geoType) { + throw new Error(`${element.type} is not supported in MySQL`); } - var multiGeoType = GeoTypes.find(function (ele) { return ele.element === geoType_1.type && ele.multiple; }); - return " ".concat(multiGeoType.name, "(").concat(data.map(function (ele) { return transformGeoData(ele); }).join(','), ")"); + const multiGeoType = GeoTypes.find(ele => ele.element === geoType.type && ele.multiple); + return ` ${multiGeoType.name}(${data.map(ele => transformGeoData(ele)).join(',')})`; } } else { - var type_1 = data.type, coordinate = data.coordinate; - var geoType = GeoTypes.find(function (ele) { return ele.type === type_1; }); + const { type, coordinate } = data; + const geoType = GeoTypes.find(ele => ele.type === type); if (!geoType) { - throw new Error("".concat(data.type, " is not supported in MySQL")); + throw new Error(`${data.type} is not supported in MySQL`); } - var element_2 = geoType.element, name_1 = geoType.name; - if (!element_2) { + const { element, name } = geoType; + if (!element) { // Point - return " ".concat(name_1, "(").concat(coordinate.join(','), ")"); + return ` ${name}(${coordinate.join(',')})`; } // Polygon or Linestring - return " ".concat(name_1, "(").concat(coordinate.map(function (ele) { return transformGeoData({ - type: element_2, + return ` ${name}(${coordinate.map((ele) => transformGeoData({ + type: element, coordinate: ele, - }); }), ")"); + }))})`; } } -var MySqlTranslator = /** @class */ (function (_super) { - tslib_1.__extends(MySqlTranslator, _super); - function MySqlTranslator(schema) { - var _this = _super.call(this, schema) || this; - _this.maxAliasLength = 63; - // MySQL为geometry属性默认创建索引 - _this.makeUpSchema(); - return _this; - } - MySqlTranslator.prototype.getDefaultSelectFilter = function (alias, option) { - if (option === null || option === void 0 ? void 0 : option.includedDeleted) { +class MySqlTranslator extends sqlTranslator_1.SqlTranslator { + getDefaultSelectFilter(alias, option) { + if (option?.includedDeleted) { return ''; } - return " (`".concat(alias, "`.`$$deleteAt$$` is null)"); - }; - MySqlTranslator.prototype.makeUpSchema = function () { - for (var entity in this.schema) { - var _a = this.schema[entity], attributes = _a.attributes, indexes = _a.indexes; - var geoIndexes = []; - var _loop_1 = function (attr) { + return ` (\`${alias}\`.\`$$deleteAt$$\` is null)`; + } + makeUpSchema() { + for (const entity in this.schema) { + const { attributes, indexes } = this.schema[entity]; + const geoIndexes = []; + for (const attr in attributes) { if (attributes[attr].type === 'geometry') { - var geoIndex = indexes === null || indexes === void 0 ? void 0 : indexes.find(function (idx) { - var _a; - return ((_a = idx.config) === null || _a === void 0 ? void 0 : _a.type) === 'spatial' && idx.attributes.find(function (attrDef) { return attrDef.name === attr; }); - }); + const geoIndex = indexes?.find((idx) => idx.config?.type === 'spatial' && idx.attributes.find((attrDef) => attrDef.name === attr)); if (!geoIndex) { geoIndexes.push({ - name: "".concat(entity, "_geo_").concat(attr), + name: `${entity}_geo_${attr}`, attributes: [{ name: attr, }], @@ -107,13 +96,10 @@ var MySqlTranslator = /** @class */ (function (_super) { }); } } - }; - for (var attr in attributes) { - _loop_1(attr); } if (geoIndexes.length > 0) { if (indexes) { - indexes.push.apply(indexes, geoIndexes); + indexes.push(...geoIndexes); } else { (0, lodash_1.assign)(this.schema[entity], { @@ -122,8 +108,153 @@ var MySqlTranslator = /** @class */ (function (_super) { } } } + } + constructor(schema) { + super(schema); + // MySQL为geometry属性默认创建索引 + this.makeUpSchema(); + } + static supportedDataTypes = [ + // numeric types + "bit", + "int", + "integer", + "tinyint", + "smallint", + "mediumint", + "bigint", + "float", + "double", + "double precision", + "real", + "decimal", + "dec", + "numeric", + "fixed", + "bool", + "boolean", + // date and time types + "date", + "datetime", + "timestamp", + "time", + "year", + // string types + "char", + "nchar", + "national char", + "varchar", + "nvarchar", + "national varchar", + "blob", + "text", + "tinyblob", + "tinytext", + "mediumblob", + "mediumtext", + "longblob", + "longtext", + "enum", + "set", + "binary", + "varbinary", + // json data type + "json", + // spatial data types + "geometry", + "point", + "linestring", + "polygon", + "multipoint", + "multilinestring", + "multipolygon", + "geometrycollection" + ]; + static spatialTypes = [ + "geometry", + "point", + "linestring", + "polygon", + "multipoint", + "multilinestring", + "multipolygon", + "geometrycollection" + ]; + static withLengthDataTypes = [ + "char", + "varchar", + "nvarchar", + "binary", + "varbinary" + ]; + static withPrecisionDataTypes = [ + "decimal", + "dec", + "numeric", + "fixed", + "float", + "double", + "double precision", + "real", + "time", + "datetime", + "timestamp" + ]; + static withScaleDataTypes = [ + "decimal", + "dec", + "numeric", + "fixed", + "float", + "double", + "double precision", + "real" + ]; + static unsignedAndZerofillTypes = [ + "int", + "integer", + "smallint", + "tinyint", + "mediumint", + "bigint", + "decimal", + "dec", + "numeric", + "fixed", + "float", + "double", + "double precision", + "real" + ]; + static withWidthDataTypes = [ + 'int', + ]; + static dataTypeDefaults = { + "varchar": { length: 255 }, + "nvarchar": { length: 255 }, + "national varchar": { length: 255 }, + "char": { length: 1 }, + "binary": { length: 1 }, + "varbinary": { length: 255 }, + "decimal": { precision: 10, scale: 0 }, + "dec": { precision: 10, scale: 0 }, + "numeric": { precision: 10, scale: 0 }, + "fixed": { precision: 10, scale: 0 }, + "float": { precision: 12 }, + "double": { precision: 22 }, + "time": { precision: 0 }, + "datetime": { precision: 0 }, + "timestamp": { precision: 0 }, + "bit": { width: 1 }, + "int": { width: 11 }, + "integer": { width: 11 }, + "tinyint": { width: 4 }, + "smallint": { width: 6 }, + "mediumint": { width: 9 }, + "bigint": { width: 20 } }; - MySqlTranslator.prototype.populateDataTypeDef = function (type, params, enumeration) { + maxAliasLength = 63; + populateDataTypeDef(type, params, enumeration) { if (['date', 'datetime', 'time', 'sequence'].includes(type)) { return 'bigint '; } @@ -141,37 +272,37 @@ var MySqlTranslator = /** @class */ (function (_super) { } if (type === 'enum') { (0, assert_1.default)(enumeration); - return "enum(".concat(enumeration.map(function (ele) { return "'".concat(ele, "'"); }).join(','), ")"); + return `enum(${enumeration.map(ele => `'${ele}'`).join(',')})`; } if (MySqlTranslator.withLengthDataTypes.includes(type)) { if (params) { - var length_1 = params.length; - return "".concat(type, "(").concat(length_1, ") "); + const { length } = params; + return `${type}(${length}) `; } else { - var length_2 = MySqlTranslator.dataTypeDefaults[type].length; - return "".concat(type, "(").concat(length_2, ") "); + const { length } = MySqlTranslator.dataTypeDefaults[type]; + return `${type}(${length}) `; } } if (MySqlTranslator.withPrecisionDataTypes.includes(type)) { if (params) { - var precision = params.precision, scale = params.scale; + const { precision, scale } = params; if (typeof scale === 'number') { - return "".concat(type, "(").concat(precision, ", ").concat(scale, ") "); + return `${type}(${precision}, ${scale}) `; } - return "".concat(type, "(").concat(precision, ")"); + return `${type}(${precision})`; } else { - var _a = MySqlTranslator.dataTypeDefaults[type], precision = _a.precision, scale = _a.scale; + const { precision, scale } = MySqlTranslator.dataTypeDefaults[type]; if (typeof scale === 'number') { - return "".concat(type, "(").concat(precision, ", ").concat(scale, ") "); + return `${type}(${precision}, ${scale}) `; } - return "".concat(type, "(").concat(precision, ")"); + return `${type}(${precision})`; } } if (MySqlTranslator.withWidthDataTypes.includes(type)) { (0, assert_1.default)(type === 'int'); - var width = params.width; + const { width } = params; switch (width) { case 1: { return 'tinyint'; @@ -190,23 +321,22 @@ var MySqlTranslator = /** @class */ (function (_super) { } } } - return "".concat(type, " "); - }; - MySqlTranslator.prototype.translateAttrProjection = function (dataType, alias, attr) { + return `${type} `; + } + translateAttrProjection(dataType, alias, attr) { switch (dataType) { case 'geometry': { - return " st_astext(`".concat(alias, "`.`").concat(attr, "`)"); + return ` st_astext(\`${alias}\`.\`${attr}\`)`; } default: { - return " `".concat(alias, "`.`").concat(attr, "`"); + return ` \`${alias}\`.\`${attr}\``; } } - }; - MySqlTranslator.prototype.translateObjectPredicate = function (predicate, alias, attr) { - var _this = this; - var stmt = ''; - var translatePredicate = function (o, p) { - var predicate2 = Object.keys(o)[0]; + } + translateObjectPredicate(predicate, alias, attr) { + let stmt = ''; + const translatePredicate = (o, p) => { + const predicate2 = Object.keys(o)[0]; if (predicate2.startsWith('$')) { if (stmt) { stmt += ' and '; @@ -214,16 +344,16 @@ var MySqlTranslator = /** @class */ (function (_super) { // todo if (predicate2 === '$contains') { // json_contains,多值的包含关系 - var value = JSON.stringify(o[predicate2]); - stmt += "JSON_CONTAINS(".concat(alias, ".").concat(attr, "->>\"$").concat(p, "\", CAST('").concat(value, "' AS JSON)) "); + const value = JSON.stringify(o[predicate2]); + stmt += `JSON_CONTAINS(${alias}.${attr}->>"$${p}", CAST('${value}' AS JSON)) `; } else if (predicate2 === '$overlaps') { // json_overlaps,多值的交叉关系 - var value = JSON.stringify(o[predicate2]); - stmt += "JSON_OVERLAPS(".concat(alias, ".").concat(attr, "->>\"$").concat(p, "\", CAST('").concat(value, "' AS JSON)) "); + const value = JSON.stringify(o[predicate2]); + stmt += `JSON_OVERLAPS(${alias}.${attr}->>"$${p}", CAST('${value}' AS JSON)) `; } else { - stmt += "".concat(alias, ".").concat(attr, "->>\"$").concat(p, "\" ").concat(_this.translatePredicate(predicate2, o[predicate2])); + stmt += `${alias}.${attr}->>"$${p}" ${this.translatePredicate(predicate2, o[predicate2])}`; } } else { @@ -231,21 +361,21 @@ var MySqlTranslator = /** @class */ (function (_super) { translateInner(o, p); } }; - var translateInner = function (o, p) { + const translateInner = (o, p) => { if (o instanceof Array) { - o.forEach(function (item, idx) { - var p2 = "".concat(p, "[").concat(idx, "]"); + o.forEach((item, idx) => { + const p2 = `${p}[${idx}]`; if (typeof item !== 'object') { if (item !== null && item !== undefined) { if (stmt) { stmt += ' and '; } - stmt += "".concat(alias, ".").concat(attr, "->>\"$").concat(p2, "\""); + stmt += `${alias}.${attr}->>"$${p2}"`; if (typeof item === 'string') { - stmt += " = '".concat(item, "'"); + stmt += ` = '${item}'`; } else { - stmt += " = ".concat(item); + stmt += ` = ${item}`; } } } @@ -255,19 +385,19 @@ var MySqlTranslator = /** @class */ (function (_super) { }); } else { - for (var key in o) { - var p2 = "".concat(p, ".").concat(key); + for (const key in o) { + const p2 = `${p}.${key}`; if (typeof o[key] !== 'object') { if (o[key] !== null && o[key] !== undefined) { if (stmt) { stmt += ', '; } - stmt += "".concat(alias, ".").concat(attr, "->>\"$").concat(p2, "\""); + stmt += `${alias}.${attr}->>"$${p2}"`; if (typeof o[key] === 'string') { - stmt += " = '".concat(o[key], "'"); + stmt += ` = '${o[key]}'`; } else { - stmt += " = ".concat(o[key]); + stmt += ` = ${o[key]}`; } } } @@ -279,19 +409,19 @@ var MySqlTranslator = /** @class */ (function (_super) { }; translatePredicate(predicate, ''); return stmt; - }; - MySqlTranslator.prototype.translateObjectProjection = function (projection, alias, attr, prefix) { - var stmt = ''; - var translateInner = function (o, p) { + } + translateObjectProjection(projection, alias, attr, prefix) { + let stmt = ''; + const translateInner = (o, p) => { if (o instanceof Array) { - o.forEach(function (item, idx) { - var p2 = "".concat(p, "[").concat(idx, "]"); + o.forEach((item, idx) => { + const p2 = `${p}[${idx}]`; if (typeof item === 'number') { if (stmt) { stmt += ', '; } - stmt += "".concat(alias, ".").concat(attr, "->>\"$").concat(p2, "\""); - stmt += prefix ? " as `".concat(prefix, ".").concat(attr).concat(p2, "`") : " as `".concat(attr).concat(p2, "`"); + stmt += `${alias}.${attr}->>"$${p2}"`; + stmt += prefix ? ` as \`${prefix}.${attr}${p2}\`` : ` as \`${attr}${p2}\``; } else if (typeof item === 'object') { translateInner(item, p2); @@ -299,14 +429,14 @@ var MySqlTranslator = /** @class */ (function (_super) { }); } else { - for (var key in o) { - var p2 = "".concat(p, ".").concat(key); + for (const key in o) { + const p2 = `${p}.${key}`; if (typeof o[key] === 'number') { if (stmt) { stmt += ', '; } - stmt += "".concat(alias, ".").concat(attr, "->>\"$").concat(p2, "\""); - stmt += prefix ? " as `".concat(prefix, ".").concat(attr).concat(p2, "`") : " as `".concat(attr).concat(p2, "`"); + stmt += `${alias}.${attr}->>"$${p2}"`; + stmt += prefix ? ` as \`${prefix}.${attr}${p2}\`` : ` as \`${attr}${p2}\``; } else { translateInner(o[key], p2); @@ -316,8 +446,8 @@ var MySqlTranslator = /** @class */ (function (_super) { }; translateInner(projection, ''); return stmt; - }; - MySqlTranslator.prototype.translateAttrValue = function (dataType, value) { + } + translateAttrValue(dataType, value) { if (value === null || value === undefined) { return 'null'; } @@ -329,12 +459,12 @@ var MySqlTranslator = /** @class */ (function (_super) { case 'time': case 'date': { if (value instanceof Date) { - return "".concat(value.valueOf()); + return `${value.valueOf()}`; } else if (typeof value === 'number') { - return "".concat(value); + return `${value}`; } - return "'".concat((new Date(value)).valueOf(), "'"); + return `'${(new Date(value)).valueOf()}'`; } case 'object': case 'array': { @@ -350,37 +480,33 @@ var MySqlTranslator = /** @class */ (function (_super) { return value; } } - }; - MySqlTranslator.prototype.translateFullTextSearch = function (value, entity, alias) { - var $search = value.$search; - var indexes = this.schema[entity].indexes; - var ftIndex = indexes && indexes.find(function (ele) { - var config = ele.config; + } + translateFullTextSearch(value, entity, alias) { + const { $search } = value; + const { indexes } = this.schema[entity]; + const ftIndex = indexes && indexes.find((ele) => { + const { config } = ele; return config && config.type === 'fulltext'; }); (0, assert_1.default)(ftIndex); - var attributes = ftIndex.attributes; - var columns2 = attributes.map(function (_a) { - var name = _a.name; - return "".concat(alias, ".").concat(name); - }); - return " match(".concat(columns2.join(','), ") against ('").concat($search, "' in natural language mode)"); - }; - MySqlTranslator.prototype.translateCreateEntity = function (entity, options) { - var _this = this; - var replace = options === null || options === void 0 ? void 0 : options.replace; - var schema = this.schema; - var entityDef = schema[entity]; - var storageName = entityDef.storageName, attributes = entityDef.attributes, indexes = entityDef.indexes, view = entityDef.view; - var hasSequence = false; + const { attributes } = ftIndex; + const columns2 = attributes.map(({ name }) => `${alias}.${name}`); + return ` match(${columns2.join(',')}) against ('${$search}' in natural language mode)`; + } + translateCreateEntity(entity, options) { + const replace = options?.replace; + const { schema } = this; + const entityDef = schema[entity]; + const { storageName, attributes, indexes, view } = entityDef; + let hasSequence = false; // todo view暂还不支持 - var entityType = view ? 'view' : 'table'; - var sql = "create ".concat(entityType, " "); + const entityType = view ? 'view' : 'table'; + let sql = `create ${entityType} `; if (storageName) { - sql += "`".concat(storageName, "` "); + sql += `\`${storageName}\` `; } else { - sql += "`".concat(entity, "` "); + sql += `\`${entity}\` `; } if (view) { throw new Error(' view unsupported yet'); @@ -388,11 +514,11 @@ var MySqlTranslator = /** @class */ (function (_super) { else { sql += '('; // 翻译所有的属性 - Object.keys(attributes).forEach(function (attr, idx) { - var attrDef = attributes[attr]; - var type = attrDef.type, params = attrDef.params, defaultValue = attrDef.default, unique = attrDef.unique, notNull = attrDef.notNull, sequenceStart = attrDef.sequenceStart, enumeration = attrDef.enumeration; - sql += "`".concat(attr, "` "); - sql += _this.populateDataTypeDef(type, params, enumeration); + Object.keys(attributes).forEach((attr, idx) => { + const attrDef = attributes[attr]; + const { type, params, default: defaultValue, unique, notNull, sequenceStart, enumeration, } = attrDef; + sql += `\`${attr}\` `; + sql += this.populateDataTypeDef(type, params, enumeration); if (notNull || type === 'geometry') { sql += ' not null '; } @@ -401,14 +527,14 @@ var MySqlTranslator = /** @class */ (function (_super) { } if (sequenceStart) { if (hasSequence) { - throw new Error("\u300C".concat(entity, "\u300D\u53EA\u80FD\u6709\u4E00\u4E2Asequence\u5217")); + throw new Error(`「${entity}」只能有一个sequence列`); } hasSequence = sequenceStart; sql += ' auto_increment unique '; } if (defaultValue !== undefined) { (0, assert_1.default)(type !== 'ref'); - sql += " default ".concat(_this.translateAttrValue(type, defaultValue)); + sql += ` default ${this.translateAttrValue(type, defaultValue)}`; } if (attr === 'id') { sql += ' primary key'; @@ -420,9 +546,8 @@ var MySqlTranslator = /** @class */ (function (_super) { // 翻译索引信息 if (indexes) { sql += ',\n'; - indexes.forEach(function (_a, idx) { - var name = _a.name, attributes = _a.attributes, config = _a.config; - var _b = config || {}, unique = _b.unique, type = _b.type, parser = _b.parser; + indexes.forEach(({ name, attributes, config }, idx) => { + const { unique, type, parser } = config || {}; // 因为有deleteAt的存在,这里的unique没意义,只能框架自己去建立checker来处理 /* if (unique) { sql += ' unique '; @@ -433,20 +558,19 @@ var MySqlTranslator = /** @class */ (function (_super) { else if (type === 'spatial') { sql += ' spatial '; } - sql += "index ".concat(name, " "); + sql += `index ${name} `; if (type === 'hash') { - sql += " using hash "; + sql += ` using hash `; } sql += '('; - var includeDeleteAt = false; - attributes.forEach(function (_a, idx2) { - var name = _a.name, size = _a.size, direction = _a.direction; - sql += "`".concat(name, "`"); + let includeDeleteAt = false; + attributes.forEach(({ name, size, direction }, idx2) => { + sql += `\`${name}\``; if (size) { - sql += " (".concat(size, ")"); + sql += ` (${size})`; } if (direction) { - sql += " ".concat(direction); + sql += ` ${direction}`; } if (idx2 < attributes.length - 1) { sql += ','; @@ -460,7 +584,7 @@ var MySqlTranslator = /** @class */ (function (_super) { } sql += ')'; if (parser) { - sql += " with parser ".concat(parser); + sql += ` with parser ${parser}`; } if (idx < indexes.length - 1) { sql += ',\n'; @@ -470,17 +594,17 @@ var MySqlTranslator = /** @class */ (function (_super) { } sql += ')'; if (typeof hasSequence === 'number') { - sql += "auto_increment = ".concat(hasSequence); + sql += `auto_increment = ${hasSequence}`; } if (!replace) { return [sql]; } - return ["drop ".concat(entityType, " if exists `").concat(storageName || entity, "`;"), sql]; - }; - MySqlTranslator.prototype.translateFnName = function (fnName, argumentNumber) { + return [`drop ${entityType} if exists \`${storageName || entity}\`;`, sql]; + } + translateFnName(fnName, argumentNumber) { switch (fnName) { case '$add': { - var result = '%s'; + let result = '%s'; while (--argumentNumber > 0) { result += ' + %s'; } @@ -491,7 +615,7 @@ var MySqlTranslator = /** @class */ (function (_super) { return '%s - %s'; } case '$multiply': { - var result = '%s'; + let result = '%s'; while (--argumentNumber > 0) { result += ' * %s'; } @@ -560,8 +684,8 @@ var MySqlTranslator = /** @class */ (function (_super) { return '%s = false'; } case '$and': { - var result = ''; - for (var iter = 0; iter < argumentNumber; iter++) { + let result = ''; + for (let iter = 0; iter < argumentNumber; iter++) { result += '%s'; if (iter < argumentNumber - 1) { result += ' and '; @@ -570,8 +694,8 @@ var MySqlTranslator = /** @class */ (function (_super) { return result; } case '$or': { - var result = ''; - for (var iter = 0; iter < argumentNumber; iter++) { + let result = ''; + for (let iter = 0; iter < argumentNumber; iter++) { result += '%s'; if (iter < argumentNumber - 1) { result += ' or '; @@ -619,7 +743,7 @@ var MySqlTranslator = /** @class */ (function (_super) { return 'ST_DISTANCE(%s, %s)'; } case '$concat': { - var result = ' concat(%s'; + let result = ' concat(%s'; while (--argumentNumber > 0) { result += ', %s'; } @@ -627,53 +751,52 @@ var MySqlTranslator = /** @class */ (function (_super) { return result; } default: { - throw new Error("unrecoganized function ".concat(fnName)); + throw new Error(`unrecoganized function ${fnName}`); } } - }; - MySqlTranslator.prototype.translateAttrInExpression = function (entity, attr, exprText) { - var attributes = this.schema[entity].attributes; - var type = attributes[attr].type; + } + translateAttrInExpression(entity, attr, exprText) { + const { attributes } = this.schema[entity]; + const { type } = attributes[attr]; if (['date', 'time', 'datetime'].includes(type)) { // 从unix时间戵转成date类型参加expr的运算 - return "from_unixtime(".concat(exprText, " / 1000)"); + return `from_unixtime(${exprText} / 1000)`; } return exprText; - }; - MySqlTranslator.prototype.translateExpression = function (entity, alias, expression, refDict) { - var _this = this; - var translateConstant = function (constant) { + } + translateExpression(entity, alias, expression, refDict) { + const translateConstant = (constant) => { if (constant instanceof Date) { - return " from_unixtime(".concat(constant.valueOf(), "/1000)"); + return ` from_unixtime(${constant.valueOf()}/1000)`; } else if (typeof constant === 'string') { - return " '".concat(constant, "'"); + return ` '${constant}'`; } else { (0, assert_1.default)(typeof constant === 'number'); - return " ".concat(constant); + return ` ${constant}`; } }; - var translateInner = function (expr) { - var k = Object.keys(expr); - var result; + const translateInner = (expr) => { + const k = Object.keys(expr); + let result; if (k.includes('#attr')) { - var attrText = "`".concat(alias, "`.`").concat((expr)['#attr'], "`"); - result = _this.translateAttrInExpression(entity, (expr)['#attr'], attrText); + const attrText = `\`${alias}\`.\`${(expr)['#attr']}\``; + result = this.translateAttrInExpression(entity, (expr)['#attr'], attrText); } else if (k.includes('#refId')) { - var refId = (expr)['#refId']; - var refAttr = (expr)['#refAttr']; + const refId = (expr)['#refId']; + const refAttr = (expr)['#refAttr']; (0, assert_1.default)(refDict[refId]); - var attrText = "`".concat(refDict[refId][0], "`.`").concat(refAttr, "`"); - result = _this.translateAttrInExpression(entity, (expr)['#refAttr'], attrText); + const attrText = `\`${refDict[refId][0]}\`.\`${refAttr}\``; + result = this.translateAttrInExpression(entity, (expr)['#refAttr'], attrText); } else { (0, assert_1.default)(k.length === 1); if ((expr)[k[0]] instanceof Array) { - var fnName = _this.translateFnName(k[0], (expr)[k[0]].length); - var args = [fnName]; - args.push.apply(args, (expr)[k[0]].map(function (ele) { + const fnName = this.translateFnName(k[0], (expr)[k[0]].length); + const args = [fnName]; + args.push(...(expr)[k[0]].map((ele) => { if (['string', 'number'].includes(typeof ele) || ele instanceof Date) { return translateConstant(ele); } @@ -684,9 +807,9 @@ var MySqlTranslator = /** @class */ (function (_super) { result = util_1.format.apply(null, args); } else { - var fnName = _this.translateFnName(k[0], 1); - var args = [fnName]; - var arg = (expr)[k[0]]; + const fnName = this.translateFnName(k[0], 1); + const args = [fnName]; + const arg = (expr)[k[0]]; if (['string', 'number'].includes(typeof arg) || arg instanceof Date) { args.push(translateConstant(arg)); } @@ -699,214 +822,74 @@ var MySqlTranslator = /** @class */ (function (_super) { return result; }; return translateInner(expression); - }; - MySqlTranslator.prototype.populateSelectStmt = function (projectionText, fromText, aliasDict, filterText, sorterText, groupByText, indexFrom, count, option) { + } + populateSelectStmt(projectionText, fromText, aliasDict, filterText, sorterText, groupByText, indexFrom, count, option) { // todo hint of use index - var sql = "select ".concat(projectionText, " from ").concat(fromText); + let sql = `select ${projectionText} from ${fromText}`; if (filterText) { - sql += " where ".concat(filterText); + sql += ` where ${filterText}`; } if (sorterText) { - sql += " order by ".concat(sorterText); + sql += ` order by ${sorterText}`; } if (groupByText) { - sql += " group by ".concat(groupByText); + sql += ` group by ${groupByText}`; } if (typeof indexFrom === 'number') { (0, assert_1.default)(typeof count === 'number'); - sql += " limit ".concat(indexFrom, ", ").concat(count); + sql += ` limit ${indexFrom}, ${count}`; } - if (option === null || option === void 0 ? void 0 : option.forUpdate) { + if (option?.forUpdate) { sql += ' for update'; } return sql; - }; - MySqlTranslator.prototype.populateUpdateStmt = function (updateText, fromText, aliasDict, filterText, sorterText, indexFrom, count, option) { + } + populateUpdateStmt(updateText, fromText, aliasDict, filterText, sorterText, indexFrom, count, option) { // todo using index (0, assert_1.default)(updateText); - var sql = "update ".concat(fromText, " set ").concat(updateText); + let sql = `update ${fromText} set ${updateText}`; if (filterText) { - sql += " where ".concat(filterText); + sql += ` where ${filterText}`; } if (sorterText) { - sql += " order by ".concat(sorterText); + sql += ` order by ${sorterText}`; } if (typeof indexFrom === 'number') { (0, assert_1.default)(typeof count === 'number'); - sql += " limit ".concat(indexFrom, ", ").concat(count); + sql += ` limit ${indexFrom}, ${count}`; } return sql; - }; - MySqlTranslator.prototype.populateRemoveStmt = function (removeText, fromText, aliasDict, filterText, sorterText, indexFrom, count, option) { + } + populateRemoveStmt(removeText, fromText, aliasDict, filterText, sorterText, indexFrom, count, option) { // todo using index - var alias = aliasDict['./']; - if (option === null || option === void 0 ? void 0 : option.deletePhysically) { - var sql_1 = "delete ".concat(alias, " from ").concat(fromText, " "); + const alias = aliasDict['./']; + if (option?.deletePhysically) { + let sql = `delete ${alias} from ${fromText} `; if (filterText) { - sql_1 += " where ".concat(filterText); + sql += ` where ${filterText}`; } if (sorterText) { - sql_1 += " order by ".concat(sorterText); + sql += ` order by ${sorterText}`; } if (typeof indexFrom === 'number') { (0, assert_1.default)(typeof count === 'number'); - sql_1 += " limit ".concat(indexFrom, ", ").concat(count); + sql += ` limit ${indexFrom}, ${count}`; } - return sql_1; + return sql; } - var now = Date.now(); - var sql = "update ".concat(fromText, " set `").concat(alias, "`.`$$deleteAt$$` = '").concat(now, "'"); + const now = Date.now(); + let sql = `update ${fromText} set \`${alias}\`.\`$$deleteAt$$\` = '${now}'`; if (filterText) { - sql += " where ".concat(filterText); + sql += ` where ${filterText}`; } if (sorterText) { - sql += " order by ".concat(sorterText); + sql += ` order by ${sorterText}`; } if (typeof indexFrom === 'number') { (0, assert_1.default)(typeof count === 'number'); - sql += " limit ".concat(indexFrom, ", ").concat(count); + sql += ` limit ${indexFrom}, ${count}`; } return sql; - }; - MySqlTranslator.supportedDataTypes = [ - // numeric types - "bit", - "int", - "integer", - "tinyint", - "smallint", - "mediumint", - "bigint", - "float", - "double", - "double precision", - "real", - "decimal", - "dec", - "numeric", - "fixed", - "bool", - "boolean", - // date and time types - "date", - "datetime", - "timestamp", - "time", - "year", - // string types - "char", - "nchar", - "national char", - "varchar", - "nvarchar", - "national varchar", - "blob", - "text", - "tinyblob", - "tinytext", - "mediumblob", - "mediumtext", - "longblob", - "longtext", - "enum", - "set", - "binary", - "varbinary", - // json data type - "json", - // spatial data types - "geometry", - "point", - "linestring", - "polygon", - "multipoint", - "multilinestring", - "multipolygon", - "geometrycollection" - ]; - MySqlTranslator.spatialTypes = [ - "geometry", - "point", - "linestring", - "polygon", - "multipoint", - "multilinestring", - "multipolygon", - "geometrycollection" - ]; - MySqlTranslator.withLengthDataTypes = [ - "char", - "varchar", - "nvarchar", - "binary", - "varbinary" - ]; - MySqlTranslator.withPrecisionDataTypes = [ - "decimal", - "dec", - "numeric", - "fixed", - "float", - "double", - "double precision", - "real", - "time", - "datetime", - "timestamp" - ]; - MySqlTranslator.withScaleDataTypes = [ - "decimal", - "dec", - "numeric", - "fixed", - "float", - "double", - "double precision", - "real" - ]; - MySqlTranslator.unsignedAndZerofillTypes = [ - "int", - "integer", - "smallint", - "tinyint", - "mediumint", - "bigint", - "decimal", - "dec", - "numeric", - "fixed", - "float", - "double", - "double precision", - "real" - ]; - MySqlTranslator.withWidthDataTypes = [ - 'int', - ]; - MySqlTranslator.dataTypeDefaults = { - "varchar": { length: 255 }, - "nvarchar": { length: 255 }, - "national varchar": { length: 255 }, - "char": { length: 1 }, - "binary": { length: 1 }, - "varbinary": { length: 255 }, - "decimal": { precision: 10, scale: 0 }, - "dec": { precision: 10, scale: 0 }, - "numeric": { precision: 10, scale: 0 }, - "fixed": { precision: 10, scale: 0 }, - "float": { precision: 12 }, - "double": { precision: 22 }, - "time": { precision: 0 }, - "datetime": { precision: 0 }, - "timestamp": { precision: 0 }, - "bit": { width: 1 }, - "int": { width: 11 }, - "integer": { width: 11 }, - "tinyint": { width: 4 }, - "smallint": { width: 6 }, - "mediumint": { width: 9 }, - "bigint": { width: 20 } - }; - return MySqlTranslator; -}(sqlTranslator_1.SqlTranslator)); + } +} exports.MySqlTranslator = MySqlTranslator; diff --git a/lib/index.js b/lib/index.js index 319f9d4..75b4f47 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,4 +1,4 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var tslib_1 = require("tslib"); +const tslib_1 = require("tslib"); tslib_1.__exportStar(require("./MySQL/store"), exports); diff --git a/lib/sqlTranslator.js b/lib/sqlTranslator.js index 3eff168..fdf5c87 100644 --- a/lib/sqlTranslator.js +++ b/lib/sqlTranslator.js @@ -1,23 +1,24 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SqlTranslator = void 0; -var tslib_1 = require("tslib"); -var assert_1 = tslib_1.__importDefault(require("assert")); -var sqlstring_1 = tslib_1.__importDefault(require("sqlstring")); -var lodash_1 = require("lodash"); -var types_1 = require("oak-domain/lib/types"); -var relation_1 = require("oak-domain/lib/store/relation"); -var filter_1 = require("oak-domain/lib/store/filter"); +const tslib_1 = require("tslib"); +const assert_1 = tslib_1.__importDefault(require("assert")); +const sqlstring_1 = tslib_1.__importDefault(require("sqlstring")); +const lodash_1 = require("lodash"); +const types_1 = require("oak-domain/lib/types"); +const relation_1 = require("oak-domain/lib/store/relation"); +const filter_1 = require("oak-domain/lib/store/filter"); ; ; -var SqlTranslator = /** @class */ (function () { - function SqlTranslator(schema) { +class SqlTranslator { + schema; + constructor(schema) { this.schema = this.makeFullSchema(schema); } - SqlTranslator.prototype.makeFullSchema = function (schema2) { - var schema = (0, lodash_1.cloneDeep)(schema2); - for (var entity in schema) { - var _a = schema[entity], attributes = _a.attributes, indexes = _a.indexes; + makeFullSchema(schema2) { + const schema = (0, lodash_1.cloneDeep)(schema2); + for (const entity in schema) { + const { attributes, indexes } = schema[entity]; // 增加默认的属性 (0, lodash_1.assign)(attributes, { id: { @@ -49,23 +50,23 @@ var SqlTranslator = /** @class */ (function () { }, }); // 增加默认的索引 - var intrinsticIndexes = [ + const intrinsticIndexes = [ { - name: "".concat(entity, "_create_at_auto_create"), + name: `${entity}_create_at_auto_create`, attributes: [{ name: '$$createAt$$', }, { name: '$$deleteAt$$', }] }, { - name: "".concat(entity, "_update_at_auto_create"), + name: `${entity}_update_at_auto_create`, attributes: [{ name: '$$updateAt$$', }, { name: '$$deleteAt$$', }], }, { - name: "".concat(entity, "_trigger_ts_auto_create"), + name: `${entity}_trigger_ts_auto_create`, attributes: [{ name: '$$triggerTimestamp$$', }, { @@ -73,11 +74,12 @@ var SqlTranslator = /** @class */ (function () { }], } ]; - var _loop_1 = function (attr) { + // 增加外键等相关属性上的索引 + for (const attr in attributes) { if (attributes[attr].type === 'ref') { - if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { return ele.attributes[0].name === attr; }))) { + if (!(indexes?.find(ele => ele.attributes[0].name === attr))) { intrinsticIndexes.push({ - name: "".concat(entity, "_fk_").concat(attr, "_auto_create"), + name: `${entity}_fk_${attr}_auto_create`, attributes: [{ name: attr, }, { @@ -87,11 +89,11 @@ var SqlTranslator = /** @class */ (function () { } } if (attr === 'entity' && attributes[attr].type === 'varchar') { - var entityIdDef = attributes.entityId; - if ((entityIdDef === null || entityIdDef === void 0 ? void 0 : entityIdDef.type) === 'varchar') { - if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { var _a; return ele.attributes[0].name === 'entity' && ((_a = ele.attributes[1]) === null || _a === void 0 ? void 0 : _a.name) === 'entityId'; }))) { + const entityIdDef = attributes.entityId; + if (entityIdDef?.type === 'varchar') { + if (!(indexes?.find(ele => ele.attributes[0].name === 'entity' && ele.attributes[1]?.name === 'entityId'))) { intrinsticIndexes.push({ - name: "".concat(entity, "_fk_entity_entityId_auto_create"), + name: `${entity}_fk_entity_entityId_auto_create`, attributes: [{ name: 'entity', }, { @@ -104,9 +106,9 @@ var SqlTranslator = /** @class */ (function () { } } if (attr.endsWith('State') && attributes[attr].type === 'varchar') { - if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { return ele.attributes[0].name === attr; }))) { + if (!(indexes?.find(ele => ele.attributes[0].name === attr))) { intrinsticIndexes.push({ - name: "".concat(entity, "_").concat(attr, "_auto_create"), + name: `${entity}_${attr}_auto_create`, attributes: [{ name: attr, }, { @@ -116,11 +118,11 @@ var SqlTranslator = /** @class */ (function () { } } if (attr === 'expired' && attributes[attr].type === 'boolean') { - var expiresAtDef = attributes.expiresAt; - if ((expiresAtDef === null || expiresAtDef === void 0 ? void 0 : expiresAtDef.type) === 'datetime') { - if (!(indexes === null || indexes === void 0 ? void 0 : indexes.find(function (ele) { var _a; return ele.attributes[0].name === 'expired' && ((_a = ele.attributes[1]) === null || _a === void 0 ? void 0 : _a.name) === 'expiresAt'; }))) { + const expiresAtDef = attributes.expiresAt; + if (expiresAtDef?.type === 'datetime') { + if (!(indexes?.find(ele => ele.attributes[0].name === 'expired' && ele.attributes[1]?.name === 'expiresAt'))) { intrinsticIndexes.push({ - name: "".concat(entity, "_expires_expiredAt_auto_create"), + name: `${entity}_expires_expiredAt_auto_create`, attributes: [{ name: 'expired', }, { @@ -132,13 +134,9 @@ var SqlTranslator = /** @class */ (function () { } } } - }; - // 增加外键等相关属性上的索引 - for (var attr in attributes) { - _loop_1(attr); } if (indexes) { - indexes.push.apply(indexes, intrinsticIndexes); + indexes.push(...intrinsticIndexes); } else { (0, lodash_1.assign)(schema[entity], { @@ -147,34 +145,33 @@ var SqlTranslator = /** @class */ (function () { } } return schema; - }; - SqlTranslator.prototype.getStorageName = function (entity) { - var storageName = this.schema[entity].storageName; + } + getStorageName(entity) { + const { storageName } = this.schema[entity]; return (storageName || entity); - }; - SqlTranslator.prototype.translateInsert = function (entity, data) { - var _this = this; - var schema = this.schema; - var _a = schema[entity], attributes = _a.attributes, _b = _a.storageName, storageName = _b === void 0 ? entity : _b; - var sql = "insert into `".concat(storageName, "`("); + } + translateInsert(entity, data) { + const { schema } = this; + const { attributes, storageName = entity } = schema[entity]; + let sql = `insert into \`${storageName}\`(`; /** * 这里的attrs要用所有行的union集合 */ - var dataFull = data.reduce(function (prev, cur) { return Object.assign({}, cur, prev); }, {}); - var attrs = Object.keys(dataFull).filter(function (ele) { return attributes.hasOwnProperty(ele); }); - attrs.forEach(function (attr, idx) { - sql += " `".concat(attr, "`"); + const dataFull = data.reduce((prev, cur) => Object.assign({}, cur, prev), {}); + const attrs = Object.keys(dataFull).filter(ele => attributes.hasOwnProperty(ele)); + attrs.forEach((attr, idx) => { + sql += ` \`${attr}\``; if (idx < attrs.length - 1) { sql += ','; } }); sql += ') values '; - data.forEach(function (d, dataIndex) { + data.forEach((d, dataIndex) => { sql += '('; - attrs.forEach(function (attr, attrIdx) { - var attrDef = attributes[attr]; - var dataType = attrDef.type; - var value = _this.translateAttrValue(dataType, d[attr]); + attrs.forEach((attr, attrIdx) => { + const attrDef = attributes[attr]; + const { type: dataType } = attrDef; + const value = this.translateAttrValue(dataType, d[attr]); sql += value; if (attrIdx < attrs.length - 1) { sql += ','; @@ -188,7 +185,7 @@ var SqlTranslator = /** @class */ (function () { } }); return sql; - }; + } /** * analyze the join relations in projection/query/sort * 所有的层次关系都当成left join处理,如果有内表为空的情况,请手动处理 @@ -202,52 +199,47 @@ var SqlTranslator = /** @class */ (function () { * 这样的query会把内表为空的行也返回 * @param param0 */ - SqlTranslator.prototype.analyzeJoin = function (entity, _a, initialNumber) { - var _this = this; - var projection = _a.projection, filter = _a.filter, sorter = _a.sorter, aggregation = _a.aggregation; - var schema = this.schema; - var number = initialNumber || 1; - var projectionRefAlias = {}; - var filterRefAlias = {}; - var alias = "".concat(entity, "_").concat(number++); - var from = " `".concat(this.getStorageName(entity), "` `").concat(alias, "` "); - var aliasDict = { + analyzeJoin(entity, { projection, filter, sorter, aggregation }, initialNumber) { + const { schema } = this; + let number = initialNumber || 1; + const projectionRefAlias = {}; + const filterRefAlias = {}; + const alias = `${entity}_${number++}`; + let from = ` \`${this.getStorageName(entity)}\` \`${alias}\` `; + const aliasDict = { './': alias, }; - var analyzeFilterNode = function (_a) { - var _b; - var node = _a.node, path = _a.path, entityName = _a.entityName, alias = _a.alias; - Object.keys(node).forEach(function (op) { - var _a, _b; + const analyzeFilterNode = ({ node, path, entityName, alias }) => { + Object.keys(node).forEach((op) => { if (['$and', '$or'].includes(op)) { - node[op].forEach(function (subNode) { return analyzeFilterNode({ + node[op].forEach((subNode) => analyzeFilterNode({ node: subNode, - path: path, - entityName: entityName, - alias: alias, - }); }); + path, + entityName, + alias, + })); } else if (['$not'].includes(op)) { analyzeFilterNode({ node: node[op], - path: path, - entityName: entityName, - alias: alias, + path, + entityName, + alias, }); } else if (['$text'].includes(op)) { } else { - var rel = (0, relation_1.judgeRelation)(_this.schema, entityName, op); + const rel = (0, relation_1.judgeRelation)(this.schema, entityName, op); if (typeof rel === 'string') { - var alias2 = void 0; - var pathAttr = "".concat(path).concat(op, "/"); + let alias2; + const pathAttr = `${path}${op}/`; if (!aliasDict.hasOwnProperty(pathAttr)) { - alias2 = "".concat(rel, "_").concat(number++); - (0, lodash_1.assign)(aliasDict, (_a = {}, - _a[pathAttr] = alias2, - _a)); - from += " left join `".concat(_this.getStorageName(rel), "` `").concat(alias2, "` on `").concat(alias, "`.`").concat(op, "Id` = `").concat(alias2, "`.`id`"); + alias2 = `${rel}_${number++}`; + (0, lodash_1.assign)(aliasDict, { + [pathAttr]: alias2, + }); + from += ` left join \`${this.getStorageName(rel)}\` \`${alias2}\` on \`${alias}\`.\`${op}Id\` = \`${alias2}\`.\`id\``; } else { alias2 = aliasDict[pathAttr]; @@ -260,14 +252,14 @@ var SqlTranslator = /** @class */ (function () { }); } else if (rel === 2) { - var alias2 = void 0; - var pathAttr = "".concat(path).concat(op, "/"); + let alias2; + const pathAttr = `${path}${op}/`; if (!aliasDict.hasOwnProperty(pathAttr)) { - alias2 = "".concat(op, "_").concat(number++); - (0, lodash_1.assign)(aliasDict, (_b = {}, - _b[pathAttr] = alias2, - _b)); - from += " left join `".concat(_this.getStorageName(op), "` `").concat(alias2, "` on `").concat(alias, "`.`entityId` = `").concat(alias2, "`.`id` and `").concat(alias, "`.`entity` = '").concat(op, "'"); + alias2 = `${op}_${number++}`; + (0, lodash_1.assign)(aliasDict, { + [pathAttr]: alias2, + }); + from += ` left join \`${this.getStorageName(op)}\` \`${alias2}\` on \`${alias}\`.\`entityId\` = \`${alias2}\`.\`id\` and \`${alias}\`.\`entity\` = '${op}'`; } else { alias2 = aliasDict[pathAttr]; @@ -287,9 +279,9 @@ var SqlTranslator = /** @class */ (function () { }); if (node['#id']) { (0, assert_1.default)(!filterRefAlias[node['#id']]); - (0, lodash_1.assign)(filterRefAlias, (_b = {}, - _b[node['#id']] = [alias, entityName], - _b)); + (0, lodash_1.assign)(filterRefAlias, { + [node['#id']]: [alias, entityName], + }); } }; if (filter) { @@ -297,23 +289,21 @@ var SqlTranslator = /** @class */ (function () { node: filter, path: './', entityName: entity, - alias: alias, + alias, }); } - var analyzeSortNode = function (_a) { - var _b, _c; - var node = _a.node, path = _a.path, entityName = _a.entityName, alias = _a.alias; - var attr = (0, lodash_1.keys)(node)[0]; - var rel = (0, relation_1.judgeRelation)(_this.schema, entityName, attr); + const analyzeSortNode = ({ node, path, entityName, alias }) => { + const attr = (0, lodash_1.keys)(node)[0]; + const rel = (0, relation_1.judgeRelation)(this.schema, entityName, attr); if (typeof rel === 'string') { - var pathAttr = "".concat(path).concat(attr, "/"); - var alias2 = void 0; + const pathAttr = `${path}${attr}/`; + let alias2; if (!aliasDict.hasOwnProperty(pathAttr)) { - alias2 = "".concat(rel, "_").concat(number++); - (0, lodash_1.assign)(aliasDict, (_b = {}, - _b[pathAttr] = alias2, - _b)); - from += " left join `".concat(_this.getStorageName(rel), "` `").concat(alias2, "` on `").concat(alias, "`.`").concat(attr, "Id` = `").concat(alias2, "`.`id`"); + alias2 = `${rel}_${number++}`; + (0, lodash_1.assign)(aliasDict, { + [pathAttr]: alias2, + }); + from += ` left join \`${this.getStorageName(rel)}\` \`${alias2}\` on \`${alias}\`.\`${attr}Id\` = \`${alias2}\`.\`id\``; } else { alias2 = aliasDict[pathAttr]; @@ -326,14 +316,14 @@ var SqlTranslator = /** @class */ (function () { }); } else if (rel === 2) { - var pathAttr = "".concat(path).concat(attr, "/"); - var alias2 = void 0; + const pathAttr = `${path}${attr}/`; + let alias2; if (!aliasDict.hasOwnProperty(pathAttr)) { - alias2 = "".concat(attr, "_").concat(number++); - (0, lodash_1.assign)(aliasDict, (_c = {}, - _c[pathAttr] = alias2, - _c)); - from += " left join `".concat(_this.getStorageName(attr), "` `").concat(alias2, "` on `").concat(alias, "`.`entityId` = `").concat(alias2, "`.`id` and `").concat(alias, "`.`entity` = '").concat(attr, "'"); + alias2 = `${attr}_${number++}`; + (0, lodash_1.assign)(aliasDict, { + [pathAttr]: alias2, + }); + from += ` left join \`${this.getStorageName(attr)}\` \`${alias2}\` on \`${alias}\`.\`entityId\` = \`${alias2}\`.\`id\` and \`${alias}\`.\`entity\` = '${attr}'`; } else { alias2 = aliasDict[pathAttr]; @@ -350,31 +340,28 @@ var SqlTranslator = /** @class */ (function () { } }; if (sorter) { - sorter.forEach(function (sortNode) { + sorter.forEach((sortNode) => { analyzeSortNode({ node: sortNode.$attr, path: './', entityName: entity, - alias: alias, + alias, }); }); } - var analyzeProjectionNode = function (_a) { - var _b; - var node = _a.node, path = _a.path, entityName = _a.entityName, alias = _a.alias; - var attributes = schema[entityName].attributes; - Object.keys(node).forEach(function (attr) { - var _a, _b; - var rel = (0, relation_1.judgeRelation)(_this.schema, entityName, attr); + const analyzeProjectionNode = ({ node, path, entityName, alias }) => { + const { attributes } = schema[entityName]; + Object.keys(node).forEach((attr) => { + const rel = (0, relation_1.judgeRelation)(this.schema, entityName, attr); if (typeof rel === 'string') { - var pathAttr = "".concat(path).concat(attr, "/"); - var alias2 = void 0; + const pathAttr = `${path}${attr}/`; + let alias2; if (!aliasDict.hasOwnProperty(pathAttr)) { - alias2 = "".concat(rel, "_").concat(number++); - (0, lodash_1.assign)(aliasDict, (_a = {}, - _a[pathAttr] = alias2, - _a)); - from += " left join `".concat(_this.getStorageName(rel), "` `").concat(alias2, "` on `").concat(alias, "`.`").concat(attr, "Id` = `").concat(alias2, "`.`id`"); + alias2 = `${rel}_${number++}`; + (0, lodash_1.assign)(aliasDict, { + [pathAttr]: alias2, + }); + from += ` left join \`${this.getStorageName(rel)}\` \`${alias2}\` on \`${alias}\`.\`${attr}Id\` = \`${alias2}\`.\`id\``; } else { alias2 = aliasDict[pathAttr]; @@ -387,14 +374,14 @@ var SqlTranslator = /** @class */ (function () { }); } else if (rel === 2) { - var pathAttr = "".concat(path).concat(attr, "/"); - var alias2 = void 0; + const pathAttr = `${path}${attr}/`; + let alias2; if (!aliasDict.hasOwnProperty(pathAttr)) { - alias2 = "".concat(attr, "_").concat(number++); - (0, lodash_1.assign)(aliasDict, (_b = {}, - _b[pathAttr] = alias2, - _b)); - from += " left join `".concat(_this.getStorageName(attr), "` `").concat(alias2, "` on `").concat(alias, "`.`entityId` = `").concat(alias2, "`.`id` and `").concat(alias, "`.`entity` = '").concat(attr, "'"); + alias2 = `${attr}_${number++}`; + (0, lodash_1.assign)(aliasDict, { + [pathAttr]: alias2, + }); + from += ` left join \`${this.getStorageName(attr)}\` \`${alias2}\` on \`${alias}\`.\`entityId\` = \`${alias2}\`.\`id\` and \`${alias}\`.\`entity\` = '${attr}'`; } else { alias2 = aliasDict[pathAttr]; @@ -408,35 +395,35 @@ var SqlTranslator = /** @class */ (function () { } }); if (node['#id']) { - (0, assert_1.default)(!projectionRefAlias[node['#id']], "projection\u4E0A\u6709\u91CD\u590D\u7684#id\u5B9A\u4E49\u300C".concat(node['#id'], "\u300D")); - (0, lodash_1.assign)(projectionRefAlias, (_b = {}, - _b[node['#id']] = [alias, entityName], - _b)); + (0, assert_1.default)(!projectionRefAlias[node['#id']], `projection上有重复的#id定义「${node['#id']}」`); + (0, lodash_1.assign)(projectionRefAlias, { + [node['#id']]: [alias, entityName], + }); } }; if (projection) { - analyzeProjectionNode({ node: projection, path: './', entityName: entity, alias: alias }); + analyzeProjectionNode({ node: projection, path: './', entityName: entity, alias }); } else if (aggregation) { - for (var k in aggregation) { + for (const k in aggregation) { analyzeProjectionNode({ node: aggregation[k], path: './', entityName: entity, - alias: alias, + alias, }); } } return { - aliasDict: aliasDict, - from: from, - projectionRefAlias: projectionRefAlias, - filterRefAlias: filterRefAlias, + aliasDict, + from, + projectionRefAlias, + filterRefAlias, currentNumber: number, }; - }; - SqlTranslator.prototype.translateComparison = function (attr, value, type) { - var SQL_OP = { + } + translateComparison(attr, value, type) { + const SQL_OP = { $gt: '>', $lt: '<', $gte: '>=', @@ -446,32 +433,32 @@ var SqlTranslator = /** @class */ (function () { }; if (Object.keys(SQL_OP).includes(attr)) { if (type) { - return " ".concat(SQL_OP[attr], " ").concat(this.translateAttrValue(type, value)); + return ` ${SQL_OP[attr]} ${this.translateAttrValue(type, value)}`; } else { - return " ".concat(SQL_OP[attr], " ").concat(value); + return ` ${SQL_OP[attr]} ${value}`; } } switch (attr) { case '$startsWith': { - return " like '".concat(value, "%'"); + return ` like '${value}%'`; } case '$endsWith': { - return " like '%".concat(value, "'"); + return ` like '%${value}'`; } case '$includes': { - return " like '%".concat(value, "%'"); + return ` like '%${value}%'`; } default: { - throw new Error("unrecoganized comparison operator ".concat(attr)); + throw new Error(`unrecoganized comparison operator ${attr}`); } } - }; - SqlTranslator.prototype.translateEvaluation = function (attr, value, entity, alias, type, initialNumber, refAlias) { + } + translateEvaluation(attr, value, entity, alias, type, initialNumber, refAlias) { switch (attr) { case '$in': case '$nin': { - var IN_OP = { + const IN_OP = { $in: 'in', $nin: 'not in', }; @@ -492,30 +479,30 @@ var SqlTranslator = /** @class */ (function () { } } default: { - throw new Error("".concat(attr, " is not evaluation predicate")); + throw new Error(`${attr} is not evaluation predicate`); } } - }; - SqlTranslator.prototype.translatePredicate = function (predicate, value, type) { + } + translatePredicate(predicate, value, type) { if (['$gt', '$gte', '$lt', '$lte', '$eq', '$ne', '$startsWith', '$endsWith', '$includes'].includes(predicate)) { return this.translateComparison(predicate, value, type); } else if (['$in', '$nin'].includes(predicate)) { (0, assert_1.default)(value instanceof Array); - var IN_OP = { + const IN_OP = { $in: 'in', $nin: 'not in', }; - var values = value.map(function (v) { + const values = value.map((v) => { if (type && ['varchar', 'char', 'text', 'nvarchar', 'ref', 'enum'].includes(type) || typeof v === 'string') { - return "'".concat(v, "'"); + return `'${v}'`; } else { - return "".concat(v); + return `${v}`; } }); if (values.length > 0) { - return " ".concat(IN_OP[predicate], "(").concat(values.join(','), ")"); + return ` ${IN_OP[predicate]}(${values.join(',')})`; } if (predicate === '$in') { return ' in (null)'; @@ -523,16 +510,16 @@ var SqlTranslator = /** @class */ (function () { return ' is not null'; } else if (predicate === '$between') { - var values = value.map(function (v) { + const values = value.map((v) => { if (type && ['varchar', 'char', 'text', 'nvarchar', 'ref', 'enum'].includes(type) || typeof v === 'string') { - return "'".concat(v, "'"); + return `'${v}'`; } else { - return "".concat(v); + return `${v}`; } }); // between是所有数据库都支持的语法吗? - return " between ".concat(values[0], " and ").concat(values[1]); + return ` between ${values[0]} and ${values[1]}`; } else { (0, assert_1.default)(predicate === '$exists'); @@ -541,19 +528,17 @@ var SqlTranslator = /** @class */ (function () { } return ' is null'; } - }; - SqlTranslator.prototype.translateFilter = function (entity, filter, aliasDict, filterRefAlias, initialNumber, option) { - var _this = this; - var schema = this.schema; - var currentNumber = initialNumber; - var translateInner = function (entity2, path, filter2, type) { - var alias = aliasDict[path]; - var attributes = schema[entity2].attributes; - var whereText = type ? '' : _this.getDefaultSelectFilter(alias, option); + } + translateFilter(entity, filter, aliasDict, filterRefAlias, initialNumber, option) { + const { schema } = this; + let currentNumber = initialNumber; + const translateInner = (entity2, path, filter2, type) => { + const alias = aliasDict[path]; + const { attributes } = schema[entity2]; + let whereText = type ? '' : this.getDefaultSelectFilter(alias, option); if (filter2) { - var attrs = Object.keys(filter2).filter(function (ele) { return !ele.startsWith('#'); }); - attrs.forEach(function (attr) { - var _a; + const attrs = Object.keys(filter2).filter(ele => !ele.startsWith('#')); + attrs.forEach((attr) => { if (whereText) { whereText += ' and '; } @@ -563,13 +548,13 @@ var SqlTranslator = /** @class */ (function () { case '$and': case '$or': case '$xor': { - var logicQueries_1 = filter2[attr]; - logicQueries_1.forEach(function (logicQuery, index) { - var sql = translateInner(entity2, path, logicQuery, 'ref'); // 只要传个值就行了,应该无所谓 + const logicQueries = filter2[attr]; + logicQueries.forEach((logicQuery, index) => { + const sql = translateInner(entity2, path, logicQuery, 'ref'); // 只要传个值就行了,应该无所谓 if (sql) { - whereText += " (".concat(sql, ")"); - if (index < logicQueries_1.length - 1) { - whereText += " ".concat(attr.slice(1)); + whereText += ` (${sql})`; + if (index < logicQueries.length - 1) { + whereText += ` ${attr.slice(1)}`; } } }); @@ -577,10 +562,10 @@ var SqlTranslator = /** @class */ (function () { } default: { (0, assert_1.default)(attr === '$not'); - var logicQuery = filter2[attr]; - var sql = translateInner(entity2, path, logicQuery, 'ref'); // 只要传个值就行了,应该无所谓 + const logicQuery = filter2[attr]; + const sql = translateInner(entity2, path, logicQuery, 'ref'); // 只要传个值就行了,应该无所谓 if (sql) { - whereText += " not (".concat(sql, ")"); + whereText += ` not (${sql})`; break; } } @@ -588,23 +573,23 @@ var SqlTranslator = /** @class */ (function () { whereText += ')'; } else if (attr === '$text') { - whereText += "(".concat(_this.translateFullTextSearch(filter2[attr], entity2, alias), ")"); + whereText += `(${this.translateFullTextSearch(filter2[attr], entity2, alias)})`; } else if (attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) { // expression - whereText += " (".concat(_this.translateExpression(entity2, alias, filter2[attr], filterRefAlias), ")"); + whereText += ` (${this.translateExpression(entity2, alias, filter2[attr], filterRefAlias)})`; } else { - var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr); + const rel = (0, relation_1.judgeRelation)(this.schema, entity2, attr); if (rel === 2) { - whereText += " (".concat(translateInner(attr, "".concat(path).concat(attr, "/"), filter2[attr]), ")"); + whereText += ` (${translateInner(attr, `${path}${attr}/`, filter2[attr])})`; } else if (typeof rel === 'string') { - whereText += " (".concat(translateInner(rel, "".concat(path).concat(attr, "/"), filter2[attr]), ")"); + whereText += ` (${translateInner(rel, `${path}${attr}/`, filter2[attr])})`; } else if (rel instanceof Array) { - var subEntity = rel[0], foreignKey = rel[1]; - var predicate = (filter2[attr]['#sqp'] || 'in'); + const [subEntity, foreignKey] = rel; + const predicate = (filter2[attr]['#sqp'] || 'in'); /** * * in代表外键连接后至少有一行数据 @@ -615,16 +600,16 @@ var SqlTranslator = /** @class */ (function () { * 目前将这种子查询翻译成了exists查询,当外表很大而子查询结果集很小时可能有性能问题,取决于MySQL执行器的能力 * by Xc 20230726 */ - var refAlia = Object.keys(filterRefAlias).find(function (ele) { return filterRefAlias[ele][0] === alias; }); - var refAlia2 = refAlia || alias; // alias一定是唯一的,可以用来作为node id + const refAlia = Object.keys(filterRefAlias).find(ele => filterRefAlias[ele][0] === alias); + const refAlia2 = refAlia || alias; // alias一定是唯一的,可以用来作为node id if (!refAlia) { (0, assert_1.default)(!filterRefAlias[refAlia2]); - Object.assign(filterRefAlias, (_a = {}, - _a[refAlia2] = [alias, entity2], - _a)); + Object.assign(filterRefAlias, { + [refAlia2]: [alias, entity2], + }); } - var fk = foreignKey || 'entityId'; - var joinFilter = ['not in', 'in'].includes(predicate) ? { + const fk = foreignKey || 'entityId'; + const joinFilter = ['not in', 'in'].includes(predicate) ? { $expr12: { $eq: [ { @@ -654,42 +639,42 @@ var SqlTranslator = /** @class */ (function () { entity: entity2, }); } - var _b = _this.translateSelectInner(subEntity, { + const { stmt, currentNumber: ct2 } = this.translateSelectInner(subEntity, { data: { id: 1, }, - filter: (0, filter_1.combineFilters)(subEntity, _this.schema, [joinFilter, filter2[attr]]), + filter: (0, filter_1.combineFilters)(subEntity, this.schema, [joinFilter, filter2[attr]]), indexFrom: 0, count: 1, - }, currentNumber, filterRefAlias, option), stmt = _b.stmt, ct2 = _b.currentNumber; + }, currentNumber, filterRefAlias, option); currentNumber = ct2; - var PREDICATE_DICT = { + const PREDICATE_DICT = { 'in': 'exists', 'not in': 'not exists', 'all': 'not exists', 'not all': 'exists', }; - whereText += " ".concat(PREDICATE_DICT[predicate], " (").concat(stmt, ")"); + whereText += ` ${PREDICATE_DICT[predicate]} (${stmt})`; } else { - (0, assert_1.default)(attributes.hasOwnProperty(attr), "\u975E\u6CD5\u7684\u5C5E\u6027".concat(attr)); - var type2 = attributes[attr].type; + (0, assert_1.default)(attributes.hasOwnProperty(attr), `非法的属性${attr}`); + const { type: type2 } = attributes[attr]; // assert (type2 !== 'ref'); if (typeof filter2[attr] === 'object') { if (['object', 'array'].includes(type2)) { // 对object数据的深层次查询,这里调用数据库所支持的属性对象级查询,如mysql中的json查询 - whereText += "(".concat(_this.translateObjectPredicate(filter2[attr], alias, attr), ")"); + whereText += `(${this.translateObjectPredicate(filter2[attr], alias, attr)})`; } else { (0, assert_1.default)(Object.keys(filter2[attr]).length === 1); - var predicate = Object.keys(filter2[attr])[0]; + const predicate = Object.keys(filter2[attr])[0]; (0, assert_1.default)(predicate.startsWith('$')); // 对属性上的谓词处理 - whereText += " (`".concat(alias, "`.`").concat(attr, "` ").concat(_this.translatePredicate(predicate, filter2[attr][predicate], type2), ")"); + whereText += ` (\`${alias}\`.\`${attr}\` ${this.translatePredicate(predicate, filter2[attr][predicate], type2)})`; } } else { - whereText += " (`".concat(alias, "`.`").concat(attr, "` = ").concat(_this.translateAttrValue(type2, filter2[attr]), ")"); + whereText += ` (\`${alias}\`.\`${attr}\` = ${this.translateAttrValue(type2, filter2[attr])})`; } } } @@ -700,102 +685,100 @@ var SqlTranslator = /** @class */ (function () { } return whereText; }; - var where = translateInner(entity, './', filter); + const where = translateInner(entity, './', filter); return { stmt: where, - currentNumber: currentNumber, + currentNumber, }; - }; - SqlTranslator.prototype.translateSorter = function (entity, sorter, aliasDict) { - var _this = this; - var translateInner = function (entity2, sortAttr, path) { + } + translateSorter(entity, sorter, aliasDict) { + const translateInner = (entity2, sortAttr, path) => { (0, assert_1.default)(Object.keys(sortAttr).length === 1); - var attr = Object.keys(sortAttr)[0]; - var alias = aliasDict[path]; + const attr = Object.keys(sortAttr)[0]; + const alias = aliasDict[path]; if (attr.toLocaleLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) { - return _this.translateExpression(entity2, alias, sortAttr[attr], {}); + return this.translateExpression(entity2, alias, sortAttr[attr], {}); } else if (sortAttr[attr] === 1) { - return "`".concat(alias, "`.`").concat(attr, "`"); + return `\`${alias}\`.\`${attr}\``; } else { - var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr); + const rel = (0, relation_1.judgeRelation)(this.schema, entity2, attr); if (typeof rel === 'string') { - return translateInner(rel, sortAttr[attr], "".concat(path).concat(attr, "/")); + return translateInner(rel, sortAttr[attr], `${path}${attr}/`); } else { (0, assert_1.default)(rel === 2); - return translateInner(attr, sortAttr[attr], "".concat(path).concat(attr, "/")); + return translateInner(attr, sortAttr[attr], `${path}${attr}/`); } } }; - var sortText = ''; - sorter.forEach(function (sortNode, index) { - var $attr = sortNode.$attr, $direction = sortNode.$direction; + let sortText = ''; + sorter.forEach((sortNode, index) => { + const { $attr, $direction } = sortNode; sortText += translateInner(entity, $attr, './'); if ($direction) { - sortText += " ".concat($direction); + sortText += ` ${$direction}`; } if (index < sorter.length - 1) { sortText += ','; } }); return sortText; - }; - SqlTranslator.prototype.translateProjection = function (entity, projection, aliasDict, projectionRefAlias, commonPrefix, disableAs) { - var _this = this; - var schema = this.schema; - var as = ''; - var translateInner = function (entity2, projection2, path) { - var alias = aliasDict[path]; - var attributes = schema[entity2].attributes; - var projText = ''; - var prefix = path.slice(2).replace(/\//g, '.'); - var attrs = Object.keys(projection2).filter(function (attr) { + } + translateProjection(entity, projection, aliasDict, projectionRefAlias, commonPrefix, disableAs) { + const { schema } = this; + let as = ''; + const translateInner = (entity2, projection2, path) => { + const alias = aliasDict[path]; + const { attributes } = schema[entity2]; + let projText = ''; + let prefix = path.slice(2).replace(/\//g, '.'); + const attrs = Object.keys(projection2).filter((attr) => { if (attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) { return true; } - var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr); + const rel = (0, relation_1.judgeRelation)(this.schema, entity2, attr); return [1, 2].includes(rel) || typeof rel === 'string'; }); - attrs.forEach(function (attr, idx) { - var prefix2 = commonPrefix ? "".concat(commonPrefix, ".").concat(prefix) : prefix; + attrs.forEach((attr, idx) => { + const prefix2 = commonPrefix ? `${commonPrefix}.${prefix}` : prefix; if (attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) { - var exprText = _this.translateExpression(entity2, alias, projection2[attr], projectionRefAlias); + const exprText = this.translateExpression(entity2, alias, projection2[attr], projectionRefAlias); if (disableAs) { - projText += " ".concat(exprText); + projText += ` ${exprText}`; } else { - projText += " ".concat(exprText, " as `").concat(prefix2).concat(attr, "`"); + projText += ` ${exprText} as \`${prefix2}${attr}\``; if (!as) { - as = "`".concat(prefix2).concat(attr, "`"); + as = `\`${prefix2}${attr}\``; } else { - as += ", `".concat(prefix2).concat(attr, "`"); + as += `, \`${prefix2}${attr}\``; } } } else { - var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr); + const rel = (0, relation_1.judgeRelation)(this.schema, entity2, attr); if (typeof rel === 'string') { - projText += translateInner(rel, projection2[attr], "".concat(path).concat(attr, "/")); + projText += translateInner(rel, projection2[attr], `${path}${attr}/`); } else if (rel === 2) { - projText += translateInner(attr, projection2[attr], "".concat(path).concat(attr, "/")); + projText += translateInner(attr, projection2[attr], `${path}${attr}/`); } else if (rel === 1) { - var type = attributes[attr].type; + const { type } = attributes[attr]; if (projection2[attr] === 1) { if (disableAs) { - projText += " ".concat(_this.translateAttrProjection(type, alias, attr)); + projText += ` ${this.translateAttrProjection(type, alias, attr)}`; } else { - projText += " ".concat(_this.translateAttrProjection(type, alias, attr), " as `").concat(prefix2).concat(attr, "`"); + projText += ` ${this.translateAttrProjection(type, alias, attr)} as \`${prefix2}${attr}\``; if (!as) { - as = "`".concat(prefix2).concat(attr, "`"); + as = `\`${prefix2}${attr}\``; } else { - as += ", `".concat(prefix2).concat(attr, "`"); + as += `, \`${prefix2}${attr}\``; } } } @@ -803,20 +786,20 @@ var SqlTranslator = /** @class */ (function () { // 对JSON对象的取值 (0, assert_1.default)(!disableAs); (0, assert_1.default)(['object', 'array'].includes(type)); - projText += " ".concat(_this.translateObjectProjection(projection2[attr], alias, attr, prefix2)); + projText += ` ${this.translateObjectProjection(projection2[attr], alias, attr, prefix2)}`; } else { (0, assert_1.default)(typeof projection2 === 'string'); if (disableAs) { - projText += " ".concat(_this.translateAttrProjection(type, alias, attr)); + projText += ` ${this.translateAttrProjection(type, alias, attr)}`; } else { - projText += " ".concat(_this.translateAttrProjection(type, alias, attr), " as `").concat(prefix2).concat(projection2[attr], "`"); + projText += ` ${this.translateAttrProjection(type, alias, attr)} as \`${prefix2}${projection2[attr]}\``; if (!as) { - as = "`".concat(prefix2).concat(projection2[attr], "`"); + as = `\`${prefix2}${projection2[attr]}\``; } else { - as += "`".concat(prefix2).concat(projection2[attr], "`"); + as += `\`${prefix2}${projection2[attr]}\``; } } } @@ -830,143 +813,142 @@ var SqlTranslator = /** @class */ (function () { }; return { projText: translateInner(entity, projection, './'), - as: as, + as, }; - }; - SqlTranslator.prototype.translateSelectInner = function (entity, selection, initialNumber, refAlias, option) { - var data = selection.data, filter = selection.filter, sorter = selection.sorter, indexFrom = selection.indexFrom, count = selection.count; - var _a = this.analyzeJoin(entity, { + } + translateSelectInner(entity, selection, initialNumber, refAlias, option) { + const { data, filter, sorter, indexFrom, count } = selection; + const { from: fromText, aliasDict, projectionRefAlias, filterRefAlias, currentNumber } = this.analyzeJoin(entity, { projection: data, - filter: filter, - sorter: sorter, - }, initialNumber), fromText = _a.from, aliasDict = _a.aliasDict, projectionRefAlias = _a.projectionRefAlias, filterRefAlias = _a.filterRefAlias, currentNumber = _a.currentNumber; + filter, + sorter, + }, initialNumber); (0, assert_1.default)((0, lodash_1.intersection)((0, lodash_1.keys)(refAlias), (0, lodash_1.keys)(filterRefAlias)).length === 0, 'filter中的#node结点定义有重复'); (0, lodash_1.assign)(refAlias, filterRefAlias); - var projText = this.translateProjection(entity, data, aliasDict, projectionRefAlias).projText; - var _b = this.translateFilter(entity, filter, aliasDict, refAlias, currentNumber, option), filterText = _b.stmt, currentNumber2 = _b.currentNumber; - var sorterText = sorter && this.translateSorter(entity, sorter, aliasDict); + const { projText } = this.translateProjection(entity, data, aliasDict, projectionRefAlias); + const { stmt: filterText, currentNumber: currentNumber2 } = this.translateFilter(entity, filter, aliasDict, refAlias, currentNumber, option); + const sorterText = sorter && this.translateSorter(entity, sorter, aliasDict); return { stmt: this.populateSelectStmt(projText, fromText, aliasDict, filterText, sorterText, undefined, indexFrom, count, option, selection), currentNumber: currentNumber2, filterStmt: filterText, }; - }; - SqlTranslator.prototype.translateSelect = function (entity, selection, option) { - var stmt = this.translateSelectInner(entity, selection, 1, {}, option).stmt; + } + translateSelect(entity, selection, option) { + const { stmt } = this.translateSelectInner(entity, selection, 1, {}, option); return stmt; - }; - SqlTranslator.prototype.translateWhere = function (entity, selection, option) { - var filterStmt = this.translateSelectInner(entity, selection, 1, {}, option).filterStmt; + } + translateWhere(entity, selection, option) { + const { filterStmt } = this.translateSelectInner(entity, selection, 1, {}, option); return filterStmt; - }; - SqlTranslator.prototype.translateAggregate = function (entity, aggregation, option) { - var data = aggregation.data, filter = aggregation.filter, sorter = aggregation.sorter, indexFrom = aggregation.indexFrom, count = aggregation.count; - var _a = this.analyzeJoin(entity, { + } + translateAggregate(entity, aggregation, option) { + const { data, filter, sorter, indexFrom, count } = aggregation; + const { from: fromText, aliasDict, projectionRefAlias, filterRefAlias, currentNumber } = this.analyzeJoin(entity, { aggregation: data, - filter: filter, - sorter: sorter, - }, 1), fromText = _a.from, aliasDict = _a.aliasDict, projectionRefAlias = _a.projectionRefAlias, filterRefAlias = _a.filterRefAlias, currentNumber = _a.currentNumber; - var projText = ''; - var groupByText = ''; - for (var k in data) { + filter, + sorter, + }, 1); + let projText = ''; + let groupByText = ''; + for (const k in data) { if (k === '#aggr') { - var _b = this.translateProjection(entity, data[k], aliasDict, projectionRefAlias, '#data'), projSubText = _b.projText, as = _b.as; + const { projText: projSubText, as } = this.translateProjection(entity, data[k], aliasDict, projectionRefAlias, '#data'); if (!projText) { projText = projSubText; } else { - projText += ", ".concat(projSubText); + projText += `, ${projSubText}`; } groupByText = as; } else { - var projSubText = this.translateProjection(entity, data[k], aliasDict, projectionRefAlias, undefined, true).projText; - var projSubText2 = ''; + const { projText: projSubText } = this.translateProjection(entity, data[k], aliasDict, projectionRefAlias, undefined, true); + let projSubText2 = ''; if (k.startsWith('#max')) { - projSubText2 = "max(".concat(projSubText, ") as `").concat(k, "`"); + projSubText2 = `max(${projSubText}) as \`${k}\``; } else if (k.startsWith('#min')) { - projSubText2 = "min(".concat(projSubText, ") as `").concat(k, "`"); + projSubText2 = `min(${projSubText}) as \`${k}\``; } else if (k.startsWith('#count')) { - projSubText2 = "count(".concat(projSubText, ") as `").concat(k, "`"); + projSubText2 = `count(${projSubText}) as \`${k}\``; } else if (k.startsWith('#sum')) { - projSubText2 = "sum(".concat(projSubText, ") as `").concat(k, "`"); + projSubText2 = `sum(${projSubText}) as \`${k}\``; } else { (0, assert_1.default)(k.startsWith('#avg')); - projSubText2 = "avg(".concat(projSubText, ") as `").concat(k, "`"); + projSubText2 = `avg(${projSubText}) as \`${k}\``; } if (!projText) { projText = projSubText2; } else { - projText += ", ".concat(projSubText2); + projText += `, ${projSubText2}`; } } } - var filterText = this.translateFilter(entity, filter, aliasDict, {}, currentNumber, option).stmt; - var sorterText = sorter && this.translateSorter(entity, sorter, aliasDict); + const { stmt: filterText } = this.translateFilter(entity, filter, aliasDict, {}, currentNumber, option); + const sorterText = sorter && this.translateSorter(entity, sorter, aliasDict); return this.populateSelectStmt(projText, fromText, aliasDict, filterText, sorterText, groupByText, indexFrom, count, option, undefined, aggregation); - }; - SqlTranslator.prototype.translateCount = function (entity, selection, option) { - var filter = selection.filter, count = selection.count; - var _a = this.analyzeJoin(entity, { - filter: filter, - }), fromText = _a.from, aliasDict = _a.aliasDict, filterRefAlias = _a.filterRefAlias, currentNumber = _a.currentNumber; - var projText = 'count(1) cnt'; - var filterText = this.translateFilter(entity, filter, aliasDict, filterRefAlias, currentNumber, option).stmt; + } + translateCount(entity, selection, option) { + const { filter, count } = selection; + const { from: fromText, aliasDict, filterRefAlias, currentNumber } = this.analyzeJoin(entity, { + filter, + }); + const projText = 'count(1) cnt'; + const { stmt: filterText } = this.translateFilter(entity, filter, aliasDict, filterRefAlias, currentNumber, option); if (count) { - var subQuerySql = this.populateSelectStmt('1', fromText, aliasDict, filterText, undefined, undefined, undefined, undefined, option, Object.assign({}, selection, { indexFrom: 0, count: count })); - return "select count(1) cnt from (".concat(subQuerySql, ") __tmp"); + const subQuerySql = this.populateSelectStmt('1', fromText, aliasDict, filterText, undefined, undefined, undefined, undefined, option, Object.assign({}, selection, { indexFrom: 0, count })); + return `select count(1) cnt from (${subQuerySql}) __tmp`; } return this.populateSelectStmt(projText, fromText, aliasDict, filterText, undefined, undefined, undefined, undefined, option, selection); - }; - SqlTranslator.prototype.translateRemove = function (entity, operation, option) { - var filter = operation.filter, sorter = operation.sorter, indexFrom = operation.indexFrom, count = operation.count; + } + translateRemove(entity, operation, option) { + const { filter, sorter, indexFrom, count } = operation; (0, assert_1.default)(!sorter, '当前remove不支持sorter行为'); - var _a = this.analyzeJoin(entity, { filter: filter, sorter: sorter }), aliasDict = _a.aliasDict, filterRefAlias = _a.filterRefAlias, fromText = _a.from, currentNumber = _a.currentNumber; - var alias = aliasDict['./']; - var filterText = this.translateFilter(entity, filter, aliasDict, filterRefAlias, currentNumber, { includedDeleted: true }).stmt; + const { aliasDict, filterRefAlias, from: fromText, currentNumber } = this.analyzeJoin(entity, { filter, sorter }); + const alias = aliasDict['./']; + const { stmt: filterText } = this.translateFilter(entity, filter, aliasDict, filterRefAlias, currentNumber, { includedDeleted: true }); // const sorterText = sorter && sorter.length > 0 ? this.translateSorter(entity, sorter, aliasDict) : undefined; return this.populateRemoveStmt(alias, fromText, aliasDict, filterText, /* sorterText */ undefined, indexFrom, count, option); - }; - SqlTranslator.prototype.translateUpdate = function (entity, operation, option) { - var attributes = this.schema[entity].attributes; - var filter = operation.filter, sorter = operation.sorter, indexFrom = operation.indexFrom, count = operation.count, data = operation.data; + } + translateUpdate(entity, operation, option) { + const { attributes } = this.schema[entity]; + const { filter, sorter, indexFrom, count, data } = operation; (0, assert_1.default)(!sorter, '当前update不支持sorter行为'); - var _a = this.analyzeJoin(entity, { filter: filter, sorter: sorter }), aliasDict = _a.aliasDict, filterRefAlias = _a.filterRefAlias, fromText = _a.from, currentNumber = _a.currentNumber; - var alias = aliasDict['./']; - var updateText = ''; - for (var attr in data) { + const { aliasDict, filterRefAlias, from: fromText, currentNumber } = this.analyzeJoin(entity, { filter, sorter }); + const alias = aliasDict['./']; + let updateText = ''; + for (const attr in data) { if (updateText) { updateText += ','; } (0, assert_1.default)(attributes.hasOwnProperty(attr)); - var value = this.translateAttrValue(attributes[attr].type, data[attr]); - updateText += "`".concat(alias, "`.`").concat(attr, "` = ").concat(value); + const value = this.translateAttrValue(attributes[attr].type, data[attr]); + updateText += `\`${alias}\`.\`${attr}\` = ${value}`; } - var filterText = this.translateFilter(entity, filter, aliasDict, filterRefAlias, currentNumber).stmt; + const { stmt: filterText } = this.translateFilter(entity, filter, aliasDict, filterRefAlias, currentNumber); // const sorterText = sorter && this.translateSorter(entity, sorter, aliasDict); return this.populateUpdateStmt(updateText, fromText, aliasDict, filterText, /* sorterText */ undefined, indexFrom, count, option); - }; - SqlTranslator.prototype.translateDestroyEntity = function (entity, truncate) { - var schema = this.schema; - var _a = schema[entity], _b = _a.storageName, storageName = _b === void 0 ? entity : _b, view = _a.view; - var sql; + } + translateDestroyEntity(entity, truncate) { + const { schema } = this; + const { storageName = entity, view } = schema[entity]; + let sql; if (view) { - sql = "drop view if exists `".concat(storageName, "`"); + sql = `drop view if exists \`${storageName}\``; } else { - sql = truncate ? "truncate table `".concat(storageName, "`") : "drop table if exists `".concat(storageName, "`"); + sql = truncate ? `truncate table \`${storageName}\`` : `drop table if exists \`${storageName}\``; } return sql; - }; - SqlTranslator.prototype.escapeStringValue = function (value) { - var result = sqlstring_1.default.escape(value); + } + escapeStringValue(value) { + const result = sqlstring_1.default.escape(value); return result; - }; - return SqlTranslator; -}()); + } +} exports.SqlTranslator = SqlTranslator; diff --git a/package.json b/package.json index 02f6f0a..9d6451f 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,10 @@ "@types/sqlstring": "^2.3.0", "@types/uuid": "^8.3.4", "cross-env": "^7.0.3", - "mocha": "^10.0.0", + "mocha": "^10.2.0", "oak-general-business": "file:../oak-general-business", - "ts-node": "~10.9.1", + "ts-node": "^10.9.1", "tslib": "^2.4.0", - "typescript": "~4.7.4" + "typescript": "^4.7.4" } } diff --git a/tsconfig.json b/tsconfig.json index eff5e68..172ab0e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "module": "CommonJS", - "target": "es5", + "target": "ESNext", "declaration": true, "allowJs": false, "allowSyntheticDefaultImports": true, @@ -11,7 +11,7 @@ "skipLibCheck": true, "importHelpers": true, "lib": [ - "ES2020", + "ESNext", "DOM" ], "outDir": "lib", /* Redirect output structure to the directory. */