ModelQuery: add union()
This commit is contained in:
parent
3a4606b328
commit
4c482fb148
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wms-core",
|
"name": "wms-core",
|
||||||
"version": "0.22.0-rc.2",
|
"version": "0.22.0-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>",
|
||||||
|
@ -42,6 +42,7 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
|
|||||||
private _sortDirection?: 'ASC' | 'DESC';
|
private _sortDirection?: 'ASC' | 'DESC';
|
||||||
private readonly relations: string[] = [];
|
private readonly relations: string[] = [];
|
||||||
private _pivot?: string[];
|
private _pivot?: string[];
|
||||||
|
private _union?: ModelQueryUnion;
|
||||||
private _recursiveRelation?: RelationDatabaseProperties;
|
private _recursiveRelation?: RelationDatabaseProperties;
|
||||||
|
|
||||||
private constructor(type: QueryType, factory: ModelFactory<M>, fields?: SelectFields) {
|
private constructor(type: QueryType, factory: ModelFactory<M>, fields?: SelectFields) {
|
||||||
@ -94,7 +95,7 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public sortBy(field: string, direction: 'ASC' | 'DESC' = 'ASC', raw: boolean = false): this {
|
public sortBy(field: string, direction: SortDirection = 'ASC', raw: boolean = false): this {
|
||||||
this._sortBy = raw ? field : field.split('.').map(v => v.startsWith('`') ? v : `\`${v}\``).join('.');
|
this._sortBy = raw ? field : field.split('.').map(v => v.startsWith('`') ? v : `\`${v}\``).join('.');
|
||||||
this._sortDirection = direction;
|
this._sortDirection = direction;
|
||||||
return this;
|
return this;
|
||||||
@ -113,6 +114,18 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public union(query: ModelQuery<any>, sortBy: string, direction: SortDirection = 'ASC', raw: boolean = false, limit?: number): this {
|
||||||
|
if (this.type !== QueryType.SELECT) throw new Error('Union queries are only implemented with SELECT.');
|
||||||
|
|
||||||
|
this._union = {
|
||||||
|
query: query,
|
||||||
|
sortBy: raw ? sortBy : sortBy.split('.').map(v => v.startsWith('`') ? v : `\`${v}\``).join('.'),
|
||||||
|
direction: direction,
|
||||||
|
limit: limit,
|
||||||
|
};
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public recursive(relation: RelationDatabaseProperties): this {
|
public recursive(relation: RelationDatabaseProperties): this {
|
||||||
if (this.type !== QueryType.SELECT) throw new Error('Recursive queries are only implemented with SELECT.');
|
if (this.type !== QueryType.SELECT) throw new Error('Recursive queries are only implemented with SELECT.');
|
||||||
this._recursiveRelation = relation;
|
this._recursiveRelation = relation;
|
||||||
@ -166,8 +179,7 @@ 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}`
|
orderBy = ` ORDER BY ${this._sortBy} ${this._sortDirection!}`;
|
||||||
+ (this._sortDirection ? ' ' + this._sortDirection : '');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const table = `\`${this.table}\``;
|
const table = `\`${this.table}\``;
|
||||||
@ -184,6 +196,12 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
|
|||||||
} else {
|
} else {
|
||||||
query = `SELECT ${fields} FROM ${table}${join}${where}${orderBy}${limit}`;
|
query = `SELECT ${fields} FROM ${table}${join}${where}${orderBy}${limit}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._union) {
|
||||||
|
const unionOrderBy = this._union.sortBy ? ` ORDER BY ${this._union.sortBy} ${this._union.direction}` : '';
|
||||||
|
const unionLimit = typeof this._union.limit === 'number' ? ` LIMIT ${this._union.limit}` : '';
|
||||||
|
query = `(${query}) UNION ${this._union.query.toString(false)}${unionOrderBy}${unionLimit}`;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case QueryType.UPDATE:
|
case QueryType.UPDATE:
|
||||||
query = `UPDATE ${table} SET ${fields}${where}${orderBy}${limit}`;
|
query = `UPDATE ${table} SET ${fields}${where}${orderBy}${limit}`;
|
||||||
@ -418,3 +436,12 @@ interface WhereFieldConsumer<M extends Model> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type SelectFields = (string | SelectFieldValue | UpdateFieldValue)[];
|
export type SelectFields = (string | SelectFieldValue | UpdateFieldValue)[];
|
||||||
|
|
||||||
|
export type SortDirection = 'ASC' | 'DESC';
|
||||||
|
|
||||||
|
type ModelQueryUnion = {
|
||||||
|
query: ModelQuery<any>,
|
||||||
|
sortBy: string,
|
||||||
|
direction: SortDirection,
|
||||||
|
limit?: number,
|
||||||
|
};
|
||||||
|
@ -58,4 +58,12 @@ describe('Test ModelQuery', () => {
|
|||||||
expect(query.toString(true)).toBe("WITH RECURSIVE cte AS (SELECT `model`.* FROM `model` WHERE `f1`=? UNION SELECT o.* FROM `model` AS o, cte AS c WHERE o.`foreign`=c.`local`) SELECT * FROM cte LEFT JOIN `test` ON `model`.`j1`=`test`.`j2` ORDER BY `f2` ASC LIMIT 8");
|
expect(query.toString(true)).toBe("WITH RECURSIVE cte AS (SELECT `model`.* FROM `model` WHERE `f1`=? UNION SELECT o.* FROM `model` AS o, cte AS c WHERE o.`foreign`=c.`local`) SELECT * FROM cte LEFT JOIN `test` ON `model`.`j1`=`test`.`j2` ORDER BY `f2` ASC LIMIT 8");
|
||||||
expect(query.variables).toStrictEqual(['v1']);
|
expect(query.variables).toStrictEqual(['v1']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('union queries', () => {
|
||||||
|
const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory<Model>, '*');
|
||||||
|
const query2 = ModelQuery.select({table: 'model2'} as unknown as ModelFactory<Model>, '*');
|
||||||
|
query.union(query2, 'model.f1', 'DESC', false, 8);
|
||||||
|
|
||||||
|
expect(query.toString(true)).toBe("(SELECT `model`.* FROM `model`) UNION (SELECT `model2`.* FROM `model2`) ORDER BY `model`.`f1` DESC LIMIT 8");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user