@eggjs/dal-runtime
Version:
tegg dal decorator
310 lines (302 loc) • 20.3 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseSqlMapGenerator = void 0;
const lodash_1 = __importDefault(require("lodash"));
const tegg_types_1 = require("@eggjs/tegg-types");
const TemplateUtil_1 = require("./TemplateUtil");
class BaseSqlMapGenerator {
constructor(tableModel, logger) {
this.tableModel = tableModel;
this.logger = logger;
}
generateAllColumns(countIf) {
const str = this.tableModel.columns.map(t => `\`${t.columnName}\``)
.join(',');
return countIf ? `{% if $$count == true %}0{% else %}${str}{% endif %}` : str;
}
generateFindByPrimary() {
const result = [];
const primary = this.tableModel.getPrimary();
if (!primary) {
this.logger.warn(`表 \`${this.tableModel.name}\` 没有主键,无法生成主键查询语句。`);
return result;
}
let sql = `SELECT ${this.generateAllColumns(true)}
FROM \`${this.tableModel.name}\`
WHERE `;
sql += primary.keys.map(indexKey => `\`${indexKey.columnName}\` = {{$${indexKey.propertyName}}}`)
.join(' AND ');
if (primary.keys.length === 1) {
result.push({
type: tegg_types_1.SqlType.SELECT,
name: `findBy${lodash_1.default.upperFirst(primary.keys[0].propertyName)}`,
sql,
});
}
result.push({
name: 'findByPrimary',
type: tegg_types_1.SqlType.SELECT,
sql,
});
return result;
}
// TODO index 的左匹配
generateFindByIndexes() {
const sqlMaps = [];
for (const index of this.tableModel.indices) {
if (index.type === tegg_types_1.IndexType.PRIMARY)
continue;
let sql = `SELECT ${this.generateAllColumns(true)}
FROM \`${this.tableModel.name}\`
WHERE `;
sql += index.keys.map(indexKey => {
const s = `\`${indexKey.columnName}\` {{ "IS" if $${indexKey.propertyName} == null else "=" }} {{$${indexKey.propertyName}}}`;
return s;
})
.join(' AND ');
const tempName = lodash_1.default.upperFirst(lodash_1.default.camelCase(index.keys.length === 1 ? index.keys[0].propertyName : index.name));
sqlMaps.push({
name: `findBy${tempName}`,
type: tegg_types_1.SqlType.SELECT,
sql,
});
sqlMaps.push({
name: `findOneBy${tempName}`,
type: tegg_types_1.SqlType.SELECT,
sql: `${sql} LIMIT 0, 1`,
});
}
return sqlMaps;
}
generateInsert() {
let sql = `INSERT INTO \`${this.tableModel.name}\` `;
sql += '{% set ___first = true %}';
const keys = [];
const values = [];
for (const column of this.tableModel.columns) {
const { propertyName, columnName, type } = column;
if (column.propertyName !== 'gmtCreate' && column.propertyName !== 'gmtModified') {
// Add filter for Spatial Type
// - toPoint
// - toLine
// - toPolygon
// - toGeometry
// - toMultiPoint
// - toMultiLine
// - toMultiPolygon
// - toGeometryCollection
keys.push((`
{% if $${propertyName} !== undefined %}
{% if ___first %}
{% set ___first = false %}
{% else %}
,
{% endif %}
\`${columnName}\`
{% endif %}
`).trim());
if (TemplateUtil_1.TemplateUtil.isSpatialType(column)) {
const filter = TemplateUtil_1.TemplateUtil.getSpatialFilter(column.type.type);
values.push((`
{% if $${propertyName} !== undefined %}
{% if ___first %}
{% set ___first = false %}
{% else %}
,
{% endif %}
{{$${propertyName} | ${filter}}}
{% endif %}
`).trim());
}
else if (column.type.type === tegg_types_1.ColumnType.JSON) {
values.push((`
{% if $${propertyName} !== undefined %}
{% if ___first %}
{% set ___first = false %}
{% else %}
,
{% endif %}
{{$${propertyName} | toJson}}
{% endif %}
`).trim());
}
else {
values.push((`
{% if $${propertyName} !== undefined %}
{% if ___first %}
{% set ___first = false %}
{% else %}
,
{% endif %}
{{$${propertyName}}}
{% endif %}
`).trim());
}
}
else {
let now;
// Default value for gmtCreate/gmtModified
// int:UNIX_TEIMESTAMP
// bigint: ROUND(UNIX_TIMESTAMP(CURTIME(4)) * 1000)
// datetime/timestamp Now()
if (type.type === tegg_types_1.ColumnType.INT) {
// 秒级时间戳
now = 'UNIX_TIMESTAMP()';
}
else if (type.type === tegg_types_1.ColumnType.BIGINT) {
// 毫秒级时间戳
now = 'ROUND(UNIX_TIMESTAMP(CURTIME(4)) * 1000)';
}
else if (type.type === tegg_types_1.ColumnType.DATETIME || type.type === tegg_types_1.ColumnType.TIMESTAMP) {
now = type.precision ? `NOW(${type.precision})` : 'NOW()';
}
else {
this.logger.warn(`unknown type ${type.type} for ${propertyName}`);
}
keys.push((`
{% if ___first %}
{% set ___first = false %}
{% else %}
,
{% endif %}
\`${columnName}\`
`).trim());
values.push((`
{% if ___first %}
{% set ___first = false %}
{% else %}
,
{% endif %}
{{ $${propertyName} if $${propertyName} !== undefined else '${now}' }}
`).trim());
}
}
sql += `(${keys.join('')})`;
sql += '{% set ___first = true %}';
sql += `VALUES(${values.join('')});`;
return sql;
}
generateUpdate() {
const primary = this.tableModel.getPrimary();
if (!primary) {
this.logger.warn(`表 \`${this.tableModel.name}\` 没有主键,无法生成主键更新语句。`);
return;
}
let sql = `UPDATE \`${this.tableModel.name}\` SET`;
sql += '{% set ___first = true %}';
const kv = [];
for (const column of this.tableModel.columns) {
const { type, propertyName, columnName } = column;
let now;
if (type.type === tegg_types_1.ColumnType.INT) {
// 秒级时间戳
now = 'UNIX_TIMESTAMP()';
}
else if (type.type === tegg_types_1.ColumnType.BIGINT) {
// 毫秒级时间戳
now = 'ROUND(UNIX_TIMESTAMP(CURTIME(4)) * 1000)';
}
else if (type.type === tegg_types_1.ColumnType.TIMESTAMP || type.type === tegg_types_1.ColumnType.DATETIME) {
now = type.precision ? `NOW(${type.precision})` : 'NOW()';
}
// 若无更新时间字段,则自动更新该字段
const temp = propertyName !== 'gmtModified' ?
`
{% if $${propertyName} !== undefined %}
{% if ___first %}
{% set ___first = false %}
{% else %}
,
{% endif %}
\`${columnName}\` = {{$${propertyName}}}
{% endif %}
` :
`
{% if ___first %}
{% set ___first = false %}
{% else %}
,
{% endif %}
\`${columnName}\` =
{{ $${propertyName} if $${propertyName} !== undefined else '${now}' }}
`;
kv.push(temp);
}
sql += kv.join('');
sql += `WHERE ${primary.keys.map(indexKey => `\`${indexKey.columnName}\` = {{primary.${indexKey.propertyName}}}`)
.join(' AND ')}`;
return sql;
}
generateDelete() {
const primary = this.tableModel.getPrimary();
if (!primary) {
this.logger.warn(`表 \`${this.tableModel.name}\` 没有主键,无法生成主键删除语句。`);
return;
}
let sql = `DELETE
FROM \`${this.tableModel.name}\`
WHERE `;
sql += primary.keys.map(indexKey => `\`${indexKey.columnName}\` = {{${indexKey.propertyName}}}`)
.join(' AND ');
return sql;
}
load() {
const map = {};
map.allColumns = {
type: tegg_types_1.SqlType.BLOCK,
content: this.generateAllColumns(false),
};
const sqlMaps = [
/**
* 以主键进行索引
*
* + `findByPrimary`
* + 若为单主键,则再加 `findBy键名`
*/
...this.generateFindByPrimary(),
/**
* findBy 各索引
*
* + 若为多列索引,则为 `findBy索引名`
* + 若为单列索引,则为 `findBy列名`
*/
...this.generateFindByIndexes(),
/**
* 插入
*/
{
name: 'insert',
type: tegg_types_1.SqlType.INSERT,
sql: this.generateInsert(),
},
/**
* 主键更新
*/
{
name: 'update',
type: tegg_types_1.SqlType.UPDATE,
sql: this.generateUpdate(),
},
/**
* 主键删除
*/
{
name: 'delete',
type: tegg_types_1.SqlType.DELETE,
sql: this.generateDelete(),
},
];
for (const sqlMap of sqlMaps) {
map[sqlMap.name] = {
type: sqlMap.type,
sql: sqlMap.sql,
};
}
return map;
}
}
exports.BaseSqlMapGenerator = BaseSqlMapGenerator;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQmFzZVNxbE1hcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9CYXNlU3FsTWFwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLG9EQUF1QjtBQUV2QixrREFBMkU7QUFFM0UsaURBQThDO0FBRTlDLE1BQWEsbUJBQW1CO0lBSTlCLFlBQVksVUFBc0IsRUFBRSxNQUFjO1FBQ2hELElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxPQUFnQjtRQUNqQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxVQUFVLElBQUksQ0FBQzthQUNoRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDYixPQUFPLE9BQU8sQ0FBQyxDQUFDLENBQUMsc0NBQXNDLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDaEYsQ0FBQztJQUVELHFCQUFxQjtRQUNuQixNQUFNLE1BQU0sR0FBMEIsRUFBRSxDQUFDO1FBQ3pDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDN0MsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUkscUJBQXFCLENBQUMsQ0FBQztZQUNuRSxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO1FBRUQsSUFBSSxHQUFHLEdBQUcsVUFBVSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDO3dCQUM3QixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUk7c0JBQ3RCLENBQUM7UUFFbkIsR0FBRyxJQUFJLE9BQU8s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