mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
fix many to many reference query
This commit is contained in:
@@ -48,6 +48,7 @@ function __tty(type: any, args: any[]) {
|
|||||||
},
|
},
|
||||||
debug: {
|
debug: {
|
||||||
prefix: colors.yellow,
|
prefix: colors.yellow,
|
||||||
|
args: colors.dim,
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
const prefix = styles[type].prefix(`[${type.toUpperCase()}]`);
|
const prefix = styles[type].prefix(`[${type.toUpperCase()}]`);
|
||||||
|
|||||||
@@ -166,13 +166,15 @@ export class Repository<TBD extends object = DefaultDB, TB extends keyof TBD = a
|
|||||||
if (options.limit) validated.limit = options.limit;
|
if (options.limit) validated.limit = options.limit;
|
||||||
if (options.offset) validated.offset = options.offset;
|
if (options.offset) validated.offset = options.offset;
|
||||||
|
|
||||||
|
//$console.debug("Repository: options", { entity: entity.name, options, validated });
|
||||||
|
|
||||||
return validated;
|
return validated;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async performQuery(qb: RepositoryQB): Promise<RepositoryResponse> {
|
protected async performQuery(qb: RepositoryQB): Promise<RepositoryResponse> {
|
||||||
const entity = this.entity;
|
const entity = this.entity;
|
||||||
const compiled = qb.compile();
|
const compiled = qb.compile();
|
||||||
//$console.log("performQuery", compiled.sql, compiled.parameters);
|
//$console.debug(`Repository: query\n${compiled.sql}\n`, compiled.parameters);
|
||||||
|
|
||||||
const start = performance.now();
|
const start = performance.now();
|
||||||
const selector = (as = "count") => this.conn.fn.countAll<number>().as(as);
|
const selector = (as = "count") => this.conn.fn.countAll<number>().as(as);
|
||||||
|
|||||||
@@ -79,26 +79,29 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
|
|||||||
return selfField;
|
return selfField;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getQueryInfo(entity: Entity) {
|
protected getQueryInfo(entity: Entity) {
|
||||||
const other = this.other(entity);
|
const other = this.other(entity);
|
||||||
const conn = this.connectionEntity;
|
const conn = this.connectionEntity;
|
||||||
const entityField = this.getField(entity);
|
const entityField = this.getField(entity);
|
||||||
const otherField = this.getField(other.entity);
|
const otherField = this.getField(other.entity);
|
||||||
|
|
||||||
|
const entityRef = `${entity.name}.${entity.getPrimaryField().name}`;
|
||||||
|
const selfRef = `${conn.name}.${entityField.name}`;
|
||||||
|
const otherRef = `${conn.name}.${otherField.name}`;
|
||||||
|
|
||||||
const join = [
|
const join = [
|
||||||
conn.name,
|
conn.name,
|
||||||
`${other.entity.name}.${other.entity.getPrimaryField().name}`,
|
`${other.entity.name}.${other.entity.getPrimaryField().name}`,
|
||||||
`${conn.name}.${otherField.name}`,
|
otherRef,
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
const entityRef = `${entity.name}.${entity.getPrimaryField().name}`;
|
|
||||||
const otherRef = `${conn.name}.${entityField.name}`;
|
|
||||||
|
|
||||||
const groupBy = `${entity.name}.${entity.getPrimaryField().name}`;
|
const groupBy = `${entity.name}.${entity.getPrimaryField().name}`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
other,
|
other,
|
||||||
join,
|
join,
|
||||||
entityRef,
|
entityRef,
|
||||||
|
selfRef,
|
||||||
otherRef,
|
otherRef,
|
||||||
groupBy,
|
groupBy,
|
||||||
};
|
};
|
||||||
@@ -116,10 +119,10 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildJoin(entity: Entity, qb: KyselyQueryBuilder) {
|
buildJoin(entity: Entity, qb: KyselyQueryBuilder) {
|
||||||
const { other, join, entityRef, otherRef, groupBy } = this.getQueryInfo(entity);
|
const { other, join, entityRef, selfRef, groupBy } = this.getQueryInfo(entity);
|
||||||
|
|
||||||
return qb
|
return qb
|
||||||
.innerJoin(other.entity.name, entityRef, otherRef)
|
.innerJoin(other.entity.name, entityRef, selfRef)
|
||||||
.innerJoin(...join)
|
.innerJoin(...join)
|
||||||
.groupBy(groupBy);
|
.groupBy(groupBy);
|
||||||
}
|
}
|
||||||
@@ -134,7 +137,7 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
|
|||||||
}
|
}
|
||||||
|
|
||||||
const limit = 5;
|
const limit = 5;
|
||||||
const { other, join, entityRef, otherRef } = this.getQueryInfo(entity);
|
const { other, join, entityRef, selfRef } = this.getQueryInfo(entity);
|
||||||
const additionalFields = this.connectionEntity.fields.filter(
|
const additionalFields = this.connectionEntity.fields.filter(
|
||||||
(f) => !(f instanceof RelationField || f instanceof PrimaryField),
|
(f) => !(f instanceof RelationField || f instanceof PrimaryField),
|
||||||
);
|
);
|
||||||
@@ -157,7 +160,7 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
|
|||||||
|
|
||||||
return select;
|
return select;
|
||||||
})
|
})
|
||||||
.whereRef(entityRef, "=", otherRef)
|
.whereRef(entityRef, "=", selfRef)
|
||||||
.innerJoin(...join)
|
.innerJoin(...join)
|
||||||
.limit(limit);
|
.limit(limit);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export class ManyToOneRelation extends EntityRelation<typeof ManyToOneRelation.s
|
|||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
private queryInfo(entity: Entity, reference: string) {
|
protected queryInfo(entity: Entity, reference: string) {
|
||||||
const side = this.source.reference === reference ? "source" : "target";
|
const side = this.source.reference === reference ? "source" : "target";
|
||||||
const self = this[side];
|
const self = this[side];
|
||||||
const other = this[side === "source" ? "target" : "source"];
|
const other = this[side === "source" ? "target" : "source"];
|
||||||
|
|||||||
@@ -9,12 +9,6 @@ import { type RelationType, RelationTypes } from "./relation-types";
|
|||||||
*/
|
*/
|
||||||
export type OneToOneRelationConfig = ManyToOneRelationConfig;
|
export type OneToOneRelationConfig = ManyToOneRelationConfig;
|
||||||
|
|
||||||
/* export type OneToOneRelationConfig = {
|
|
||||||
mappedBy?: string; // author|users
|
|
||||||
inversedBy?: string; // posts
|
|
||||||
required?: boolean;
|
|
||||||
}; */
|
|
||||||
|
|
||||||
export class OneToOneRelation extends ManyToOneRelation {
|
export class OneToOneRelation extends ManyToOneRelation {
|
||||||
constructor(source: Entity, target: Entity, config?: OneToOneRelationConfig) {
|
constructor(source: Entity, target: Entity, config?: OneToOneRelationConfig) {
|
||||||
const { mappedBy, inversedBy, required } = config || {};
|
const { mappedBy, inversedBy, required } = config || {};
|
||||||
|
|||||||
@@ -50,7 +50,10 @@ export class RelationAccessor {
|
|||||||
*/
|
*/
|
||||||
relationOf(entity: Entity, reference: string): EntityRelation | undefined {
|
relationOf(entity: Entity, reference: string): EntityRelation | undefined {
|
||||||
return this.relationsOf(entity).find((r) => {
|
return this.relationsOf(entity).find((r) => {
|
||||||
return r.source.reference === reference || r.target.reference === reference;
|
return (
|
||||||
|
(r.target.entity.name === entity.name && r.source.reference === reference) ||
|
||||||
|
(r.source.entity.name === entity.name && r.target.reference === reference)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,6 @@
|
|||||||
"bknd": ["./src/*"]
|
"bknd": ["./src/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["./src/**/*.ts", "./src/**/*.tsx", "vite.dev.ts", "build.ts"],
|
"include": ["./src/**/*.ts", "./src/**/*.tsx", "vite.dev.ts", "build.ts", "__test__"],
|
||||||
"exclude": ["node_modules", "dist", "dist/types", "**/*.d.ts"]
|
"exclude": ["node_modules", "dist", "dist/types", "**/*.d.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user