Getting relationship aliasing working.
This commit is contained in:
parent
20dae6ed82
commit
65cddae9da
|
@ -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) {
|
||||||
|
|
|
@ -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}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue