ModelQuery: fix backticks on ORDER BY and remove extra useless spaces

This commit is contained in:
Alice Gaudon 2020-09-05 16:09:30 +02:00
parent e403dfa863
commit 27bd7400e2
3 changed files with 24 additions and 16 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "wms-core", "name": "wms-core",
"version": "0.21.13-rc.2", "version": "0.21.13-rc.3",
"description": "Node web application framework and toolbelt.", "description": "Node web application framework and toolbelt.",
"repository": "https://gitlab.com/ArisuOngaku/wms-core", "repository": "https://gitlab.com/ArisuOngaku/wms-core",
"author": "Alice Gaudon <alice@gaudon.pro>", "author": "Alice Gaudon <alice@gaudon.pro>",

View File

@ -95,7 +95,7 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
} }
public sortBy(field: string, direction: 'ASC' | 'DESC' = 'ASC'): this { public sortBy(field: string, direction: 'ASC' | 'DESC' = 'ASC'): this {
this._sortBy = field; this._sortBy = field.split('.').map(v => v.startsWith('`') ? v : `\`${v}\``).join('.');
this._sortDirection = direction; this._sortDirection = direction;
return this; return this;
} }
@ -140,8 +140,9 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
let join = ''; let join = '';
if (this._leftJoin) { if (this._leftJoin) {
const alias = this._leftJoinAlias ? ` AS \`${this._leftJoinAlias}\`` : ''; join = ` LEFT JOIN \`${this._leftJoin}\``
join = `LEFT JOIN \`${this._leftJoin}\`${alias} ON ${this._leftJoinOn[0]}`; + (this._leftJoinAlias ? ` AS \`${this._leftJoinAlias}\`` : '')
+ ` ON ${this._leftJoinOn[0]}`;
for (let i = 1; i < this._leftJoinOn.length; i++) { for (let i = 1; i < this._leftJoinOn.length; i++) {
join += this._leftJoinOn[i].toString(false); join += this._leftJoinOn[i].toString(false);
} }
@ -149,7 +150,7 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
let where = ''; let where = '';
if (this._where.length > 0) { if (this._where.length > 0) {
where = `WHERE ${this._where[0]}`; where = ` WHERE ${this._where[0]}`;
for (let i = 1; i < this._where.length; i++) { for (let i = 1; i < this._where.length; i++) {
where += this._where[i].toString(false); where += this._where[i].toString(false);
} }
@ -157,7 +158,7 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
let limit = ''; let limit = '';
if (typeof this._limit === 'number') { if (typeof this._limit === 'number') {
limit = `LIMIT ${this._limit}`; limit = ` LIMIT ${this._limit}`;
if (typeof this._offset === 'number' && this._offset !== 0) { if (typeof this._offset === 'number' && this._offset !== 0) {
limit += ` OFFSET ${this._offset}`; limit += ` OFFSET ${this._offset}`;
} }
@ -165,7 +166,8 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
let orderBy = ''; let orderBy = '';
if (typeof this._sortBy === 'string') { if (typeof this._sortBy === 'string') {
orderBy = `ORDER BY \`${this._sortBy}\` ${this._sortDirection}`; orderBy = ` ORDER BY ${this._sortBy}`
+ (this._sortDirection ? ' ' + this._sortDirection : '');
} }
const table = `\`${this.table}\``; const table = `\`${this.table}\``;
@ -175,19 +177,19 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
if (this._recursiveRelation) { if (this._recursiveRelation) {
const cteFields = fields.replace(RegExp(`${table}`, 'g'), 'o'); const cteFields = fields.replace(RegExp(`${table}`, 'g'), 'o');
query = `WITH RECURSIVE cte AS (` query = `WITH RECURSIVE cte AS (`
+ `SELECT ${fields} FROM ${table} ${where}` + `SELECT ${fields} FROM ${table}${where}`
+ ` UNION ` + ` UNION `
+ `SELECT ${cteFields} FROM ${table} AS o, cte AS c WHERE o.\`${this._recursiveRelation.foreignKey}\`=c.\`${this._recursiveRelation.localKey}\`` + `SELECT ${cteFields} FROM ${table} AS o, cte AS c WHERE o.\`${this._recursiveRelation.foreignKey}\`=c.\`${this._recursiveRelation.localKey}\``
+ `) SELECT * FROM cte ${join} ${orderBy} ${limit}`; + `) SELECT * FROM cte${join}${orderBy}${limit}`;
} else { } else {
query = `SELECT ${fields} FROM ${table} ${join} ${where} ${orderBy} ${limit}`; query = `SELECT ${fields} FROM ${table}${join}${where}${orderBy}${limit}`;
} }
break; break;
case QueryType.UPDATE: case QueryType.UPDATE:
query = `UPDATE ${table} SET ${fields} ${where} ${orderBy} ${limit}`; query = `UPDATE ${table} SET ${fields}${where}${orderBy}${limit}`;
break; break;
case QueryType.DELETE: case QueryType.DELETE:
query = `DELETE FROM ${table} ${where} ${orderBy} ${limit}`; query = `DELETE FROM ${table}${where}${orderBy}${limit}`;
break; break;
} }

View File

@ -3,19 +3,25 @@ import ModelFactory from "../src/db/ModelFactory";
import Model from "../src/db/Model"; import Model from "../src/db/Model";
describe('Test ModelQuery', () => { describe('Test ModelQuery', () => {
test('order by', () => {
const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory<Model>)
.sortBy('model.f2', 'ASC');
expect(query.toString(true)).toBe('SELECT `model`.* FROM `model` ORDER BY `model`.`f2` ASC');
});
test('update', () => { test('update', () => {
const query = ModelQuery.update({table: 'model'} as unknown as ModelFactory<Model>, { const query = ModelQuery.update({table: 'model'} as unknown as ModelFactory<Model>, {
'f1': 'v1', 'f1': 'v1',
'f2': 'v2', 'f2': 'v2',
'f3': 'v3', 'f3': 'v3',
}).where('f4', 'v4'); }).where('f4', 'v4');
expect(query.toString(true)).toBe('UPDATE `model` SET `model`.`f1`=?,`model`.`f2`=?,`model`.`f3`=? WHERE `f4`=? '); expect(query.toString(true)).toBe('UPDATE `model` SET `model`.`f1`=?,`model`.`f2`=?,`model`.`f3`=? WHERE `f4`=?');
expect(query.variables).toStrictEqual(['v1','v2','v3','v4']); expect(query.variables).toStrictEqual(['v1','v2','v3','v4']);
}); });
test('function select', () => { test('function select', () => {
const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory<Model>, 'f1', new SelectFieldValue('_count', 'COUNT(*)', true)); const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory<Model>, 'f1', new SelectFieldValue('_count', 'COUNT(*)', true));
expect(query.toString(true)).toBe('SELECT `model`.`f1`,(COUNT(*)) AS `_count` FROM `model` '); expect(query.toString(true)).toBe('SELECT `model`.`f1`,(COUNT(*)) AS `_count` FROM `model`');
expect(query.variables).toStrictEqual([]); expect(query.variables).toStrictEqual([]);
}); });
@ -23,7 +29,7 @@ describe('Test ModelQuery', () => {
const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory<Model>, 'f1'); const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory<Model>, 'f1');
query.pivot('pivot.f2', 'f3'); query.pivot('pivot.f2', 'f3');
expect(query.toString(true)).toBe('SELECT `model`.`f1`,`pivot`.`f2`,`model`.`f3` FROM `model` '); expect(query.toString(true)).toBe('SELECT `model`.`f1`,`pivot`.`f2`,`model`.`f3` FROM `model`');
expect(query.variables).toStrictEqual([]); expect(query.variables).toStrictEqual([]);
}); });
@ -34,7 +40,7 @@ describe('Test ModelQuery', () => {
.groupWhere(q => q.where('f4', 'v4'), WhereOperator.OR)) .groupWhere(q => q.where('f4', 'v4'), WhereOperator.OR))
.where('f5', 'v5'); .where('f5', 'v5');
expect(query.toString(true)).toBe('SELECT `model`.* FROM `model` WHERE `f1`=? AND (`f2`=? AND `f3`=? OR (`f4`=?)) AND `f5`=? '); expect(query.toString(true)).toBe('SELECT `model`.* FROM `model` WHERE `f1`=? AND (`f2`=? AND `f3`=? OR (`f4`=?)) AND `f5`=?');
expect(query.variables).toStrictEqual(['v1','v2','v3','v4','v5']); expect(query.variables).toStrictEqual(['v1','v2','v3','v4','v5']);
}); });