Getting relationship aliasing working.

This commit is contained in:
mike12345567 2023-11-28 18:43:38 +00:00
parent 20dae6ed82
commit 65cddae9da
3 changed files with 46 additions and 11 deletions

View File

@ -58,6 +58,16 @@ export default class AliasTables {
} }
} }
aliasMap(tableNames: (string | undefined)[]) {
const map: Record<string, string> = {}
for (let tableName of tableNames) {
if (tableName) {
map[tableName] = this.getAlias(tableName)
}
}
return map
}
async queryWithAliasing(json: QueryJson) { async queryWithAliasing(json: QueryJson) {
json = cloneDeep(json) json = cloneDeep(json)
const aliasField = (field: string) => this.aliasField(field) const aliasField = (field: string) => this.aliasField(field)
@ -86,7 +96,11 @@ export default class AliasTables {
if (json.relationships) { if (json.relationships) {
json.relationships = json.relationships.map(relationship => ({ json.relationships = json.relationships.map(relationship => ({
...relationship, ...relationship,
alias: this.getAlias(relationship.tableName), aliases: this.aliasMap([
relationship.through,
relationship.tableName,
json.endpoint.entityId,
]),
})) }))
} }
if (json.meta?.table) { if (json.meta?.table) {

View File

@ -330,6 +330,17 @@ class InternalBuilder {
return query return query
} }
tableNameWithSchema(
tableName: string,
opts?: { alias?: string; schema?: string }
) {
let withSchema = opts?.schema ? `${opts.schema}.${tableName}` : tableName
if (opts?.alias) {
withSchema += ` as ${opts.alias}`
}
return withSchema
}
addRelationships( addRelationships(
query: KnexQuery, query: KnexQuery,
fromTable: string, fromTable: string,
@ -339,9 +350,12 @@ class InternalBuilder {
if (!relationships) { if (!relationships) {
return query return query
} }
const tableSets: Record<string, [any]> = {} const tableSets: Record<string, [RelationshipsJson]> = {}
// add up all aliases
let aliases: Record<string, string> = {}
// aggregate into table sets (all the same to tables) // aggregate into table sets (all the same to tables)
for (let relationship of relationships) { for (let relationship of relationships) {
aliases = { ...aliases, ...relationship.aliases }
const keyObj: { toTable: string; throughTable: string | undefined } = { const keyObj: { toTable: string; throughTable: string | undefined } = {
toTable: relationship.tableName, toTable: relationship.tableName,
throughTable: undefined, throughTable: undefined,
@ -358,10 +372,17 @@ class InternalBuilder {
} }
for (let [key, relationships] of Object.entries(tableSets)) { for (let [key, relationships] of Object.entries(tableSets)) {
const { toTable, throughTable } = JSON.parse(key) const { toTable, throughTable } = JSON.parse(key)
const toTableWithSchema = schema ? `${schema}.${toTable}` : toTable const toAlias = aliases[toTable],
const throughTableWithSchema = schema throughAlias = aliases[throughTable],
? `${schema}.${throughTable}` fromAlias = aliases[fromTable]
: throughTable let toTableWithSchema = this.tableNameWithSchema(toTable, {
alias: toAlias,
schema,
})
let throughTableWithSchema = this.tableNameWithSchema(throughTable, {
alias: throughAlias,
schema,
})
if (!throughTable) { if (!throughTable) {
// @ts-ignore // @ts-ignore
query = query.leftJoin(toTableWithSchema, function () { query = query.leftJoin(toTableWithSchema, function () {
@ -369,7 +390,7 @@ class InternalBuilder {
const from = relationship.from, const from = relationship.from,
to = relationship.to to = relationship.to
// @ts-ignore // @ts-ignore
this.orOn(`${fromTable}.${from}`, "=", `${toTable}.${to}`) this.orOn(`${fromTable}.${from}`, "=", `${toAlias}.${to}`)
} }
}) })
} else { } else {
@ -381,9 +402,9 @@ class InternalBuilder {
const from = relationship.from const from = relationship.from
// @ts-ignore // @ts-ignore
this.orOn( this.orOn(
`${fromTable}.${fromPrimary}`, `${fromAlias}.${fromPrimary}`,
"=", "=",
`${throughTable}.${from}` `${throughAlias}.${from}`
) )
} }
}) })
@ -392,7 +413,7 @@ class InternalBuilder {
const toPrimary = relationship.toPrimary const toPrimary = relationship.toPrimary
const to = relationship.to const to = relationship.to
// @ts-ignore // @ts-ignore
this.orOn(`${toTable}.${toPrimary}`, `${throughTable}.${to}`) this.orOn(`${toAlias}.${toPrimary}`, `${throughAlias}.${to}`)
} }
}) })
} }

View File

@ -67,7 +67,7 @@ export interface RelationshipsJson {
fromPrimary?: string fromPrimary?: string
toPrimary?: string toPrimary?: string
tableName: string tableName: string
alias?: string aliases?: Record<string, string>
column: string column: string
} }