fix many to many reference query

This commit is contained in:
dswbx
2025-02-27 11:43:12 +01:00
parent dd48962901
commit 3e28124494
7 changed files with 22 additions and 19 deletions

View File

@@ -48,6 +48,7 @@ function __tty(type: any, args: any[]) {
},
debug: {
prefix: colors.yellow,
args: colors.dim,
},
} as const;
const prefix = styles[type].prefix(`[${type.toUpperCase()}]`);

View File

@@ -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.offset) validated.offset = options.offset;
//$console.debug("Repository: options", { entity: entity.name, options, validated });
return validated;
}
protected async performQuery(qb: RepositoryQB): Promise<RepositoryResponse> {
const entity = this.entity;
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 selector = (as = "count") => this.conn.fn.countAll<number>().as(as);

View File

@@ -79,26 +79,29 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
return selfField;
}
private getQueryInfo(entity: Entity) {
protected getQueryInfo(entity: Entity) {
const other = this.other(entity);
const conn = this.connectionEntity;
const entityField = this.getField(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 = [
conn.name,
`${other.entity.name}.${other.entity.getPrimaryField().name}`,
`${conn.name}.${otherField.name}`,
otherRef,
] as const;
const entityRef = `${entity.name}.${entity.getPrimaryField().name}`;
const otherRef = `${conn.name}.${entityField.name}`;
const groupBy = `${entity.name}.${entity.getPrimaryField().name}`;
return {
other,
join,
entityRef,
selfRef,
otherRef,
groupBy,
};
@@ -116,10 +119,10 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
}
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
.innerJoin(other.entity.name, entityRef, otherRef)
.innerJoin(other.entity.name, entityRef, selfRef)
.innerJoin(...join)
.groupBy(groupBy);
}
@@ -134,7 +137,7 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
}
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(
(f) => !(f instanceof RelationField || f instanceof PrimaryField),
);
@@ -157,7 +160,7 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
return select;
})
.whereRef(entityRef, "=", otherRef)
.whereRef(entityRef, "=", selfRef)
.innerJoin(...join)
.limit(limit);
}

View File

@@ -107,7 +107,7 @@ export class ManyToOneRelation extends EntityRelation<typeof ManyToOneRelation.s
return field;
}
private queryInfo(entity: Entity, reference: string) {
protected queryInfo(entity: Entity, reference: string) {
const side = this.source.reference === reference ? "source" : "target";
const self = this[side];
const other = this[side === "source" ? "target" : "source"];

View File

@@ -9,12 +9,6 @@ import { type RelationType, RelationTypes } from "./relation-types";
*/
export type OneToOneRelationConfig = ManyToOneRelationConfig;
/* export type OneToOneRelationConfig = {
mappedBy?: string; // author|users
inversedBy?: string; // posts
required?: boolean;
}; */
export class OneToOneRelation extends ManyToOneRelation {
constructor(source: Entity, target: Entity, config?: OneToOneRelationConfig) {
const { mappedBy, inversedBy, required } = config || {};

View File

@@ -50,7 +50,10 @@ export class RelationAccessor {
*/
relationOf(entity: Entity, reference: string): EntityRelation | undefined {
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)
);
});
}

View File

@@ -33,6 +33,6 @@
"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"]
}