ModelRelation: sort recursive relations by tree
This commit is contained in:
parent
892b830dc4
commit
e08f4fb875
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wms-core",
|
||||
"version": "0.22.0-rc.8",
|
||||
"version": "0.22.0-rc.9",
|
||||
"description": "Node web application framework and toolbelt.",
|
||||
"repository": "https://gitlab.com/ArisuOngaku/wms-core",
|
||||
"author": "Alice Gaudon <alice@gaudon.pro>",
|
||||
|
@ -2,7 +2,7 @@ import {query, QueryResult} from "./MysqlConnectionManager";
|
||||
import {Connection} from "mysql";
|
||||
import Model from "./Model";
|
||||
import Pagination from "../Pagination";
|
||||
import ModelRelation, {RelationDatabaseProperties} from "./ModelRelation";
|
||||
import ModelRelation, {RecursiveRelationDatabaseProperties} from "./ModelRelation";
|
||||
import ModelFactory from "./ModelFactory";
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
|
||||
private readonly subRelations: { [relation: string]: string[] } = {};
|
||||
private _pivot?: string[];
|
||||
private _union?: ModelQueryUnion;
|
||||
private _recursiveRelation?: RelationDatabaseProperties;
|
||||
private _recursiveRelation?: RecursiveRelationDatabaseProperties;
|
||||
|
||||
private constructor(type: QueryType, factory: ModelFactory<M>, fields?: SelectFields) {
|
||||
this.type = type;
|
||||
@ -135,7 +135,7 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
|
||||
return this;
|
||||
}
|
||||
|
||||
public recursive(relation: RelationDatabaseProperties): this {
|
||||
public recursive(relation: RecursiveRelationDatabaseProperties): this {
|
||||
if (this.type !== QueryType.SELECT) throw new Error('Recursive queries are only implemented with SELECT.');
|
||||
this._recursiveRelation = relation;
|
||||
return this;
|
||||
@ -191,10 +191,10 @@ export default class ModelQuery<M extends Model> implements WhereFieldConsumer<M
|
||||
if (this._recursiveRelation) {
|
||||
const cteFields = fields.replace(RegExp(`${table}`, 'g'), 'o');
|
||||
query = `WITH RECURSIVE cte AS (`
|
||||
+ `SELECT ${fields} FROM ${table}${where}`
|
||||
+ `SELECT ${fields},1 AS __depth, ARRAY[\`${this._recursiveRelation.idKey}\`] AS __path FROM ${table}${where}`
|
||||
+ ` UNION `
|
||||
+ `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 ${cteFields}, c.__depth + 1,c.__path || o.\`${this._recursiveRelation.idKey}\` FROM ${table} AS o, cte AS c WHERE o.\`${this._recursiveRelation.foreignKey}\`=c.\`${this._recursiveRelation.localKey}\``
|
||||
+ `) SELECT * FROM cte${join}${orderBy || ` ORDER BY __path`}${limit}`;
|
||||
} else {
|
||||
query = `SELECT ${fields} FROM ${table}${join}${where}${orderBy}${limit}`;
|
||||
}
|
||||
|
@ -201,8 +201,11 @@ export class ManyThroughModelRelation<S extends Model, O extends Model> extends
|
||||
}
|
||||
|
||||
export class RecursiveModelRelation<M extends Model> extends ManyModelRelation<M, M> {
|
||||
public constructor(model: M, foreignModelType: ModelType<M>, dbProperties: RelationDatabaseProperties) {
|
||||
protected readonly dbProperties: RecursiveRelationDatabaseProperties;
|
||||
|
||||
public constructor(model: M, foreignModelType: ModelType<M>, dbProperties: RecursiveRelationDatabaseProperties) {
|
||||
super(model, foreignModelType, dbProperties);
|
||||
this.dbProperties = dbProperties;
|
||||
this.constraint(query => query.recursive(this.dbProperties));
|
||||
}
|
||||
|
||||
@ -240,3 +243,7 @@ export type PivotRelationDatabaseProperties = RelationDatabaseProperties & {
|
||||
localPivotKey: string;
|
||||
foreignPivotKey: string;
|
||||
};
|
||||
|
||||
export type RecursiveRelationDatabaseProperties = RelationDatabaseProperties & {
|
||||
idKey: string;
|
||||
};
|
||||
|
@ -59,10 +59,10 @@ describe('Test ModelQuery', () => {
|
||||
const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory<Model>, '*');
|
||||
query.where('f1', 'v1');
|
||||
query.leftJoin('test').on('model.j1', 'test.j2');
|
||||
query.recursive({localKey: 'local', foreignKey: 'foreign'});
|
||||
query.recursive({localKey: 'local', foreignKey: 'foreign', idKey: 'foreign'});
|
||||
query.sortBy('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.toString(true)).toBe("WITH RECURSIVE cte AS (SELECT `model`.*,1 AS __depth, ARRAY[`foreign`] AS __path FROM `model` WHERE `f1`=? UNION SELECT o.*, c.__depth + 1,c.__path || o.`foreign` 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']);
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user