SQL server relationship fix for tables in schema (#9103)
* Add schema to LEFT JOIN * lint
This commit is contained in:
parent
221f9e3813
commit
033094cf30
|
@ -313,7 +313,8 @@ class InternalBuilder {
|
||||||
addRelationships(
|
addRelationships(
|
||||||
query: KnexQuery,
|
query: KnexQuery,
|
||||||
fromTable: string,
|
fromTable: string,
|
||||||
relationships: RelationshipsJson[] | undefined
|
relationships: RelationshipsJson[] | undefined,
|
||||||
|
schema: string | undefined
|
||||||
): KnexQuery {
|
): KnexQuery {
|
||||||
if (!relationships) {
|
if (!relationships) {
|
||||||
return query
|
return query
|
||||||
|
@ -337,9 +338,13 @@ 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 throughTableWithSchema = schema
|
||||||
|
? `${schema}.${throughTable}`
|
||||||
|
: throughTable
|
||||||
if (!throughTable) {
|
if (!throughTable) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
query = query.leftJoin(toTable, function () {
|
query = query.leftJoin(toTableWithSchema, function () {
|
||||||
for (let relationship of relationships) {
|
for (let relationship of relationships) {
|
||||||
const from = relationship.from,
|
const from = relationship.from,
|
||||||
to = relationship.to
|
to = relationship.to
|
||||||
|
@ -350,7 +355,7 @@ class InternalBuilder {
|
||||||
} else {
|
} else {
|
||||||
query = query
|
query = query
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
.leftJoin(throughTable, function () {
|
.leftJoin(throughTableWithSchema, function () {
|
||||||
for (let relationship of relationships) {
|
for (let relationship of relationships) {
|
||||||
const fromPrimary = relationship.fromPrimary
|
const fromPrimary = relationship.fromPrimary
|
||||||
const from = relationship.from
|
const from = relationship.from
|
||||||
|
@ -362,7 +367,7 @@ class InternalBuilder {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.leftJoin(toTable, function () {
|
.leftJoin(toTableWithSchema, function () {
|
||||||
for (let relationship of relationships) {
|
for (let relationship of relationships) {
|
||||||
const toPrimary = relationship.toPrimary
|
const toPrimary = relationship.toPrimary
|
||||||
const to = relationship.to
|
const to = relationship.to
|
||||||
|
@ -456,7 +461,12 @@ class InternalBuilder {
|
||||||
preQuery = this.addSorting(preQuery, json)
|
preQuery = this.addSorting(preQuery, json)
|
||||||
}
|
}
|
||||||
// handle joins
|
// handle joins
|
||||||
query = this.addRelationships(preQuery, tableName, relationships)
|
query = this.addRelationships(
|
||||||
|
preQuery,
|
||||||
|
tableName,
|
||||||
|
relationships,
|
||||||
|
endpoint.schema
|
||||||
|
)
|
||||||
return this.addFilters(query, filters, { relationship: true })
|
return this.addFilters(query, filters, { relationship: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,72 @@ function generateDeleteJson(table = TABLE_NAME, filters = {}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateRelationshipJson(config: { schema?: string } = {}) {
|
||||||
|
return {
|
||||||
|
endpoint: {
|
||||||
|
datasourceId: "Postgres",
|
||||||
|
entityId: "brands",
|
||||||
|
operation: "READ",
|
||||||
|
schema: config.schema,
|
||||||
|
},
|
||||||
|
resource: {
|
||||||
|
fields: [
|
||||||
|
"brands.brand_id",
|
||||||
|
"brands.brand_name",
|
||||||
|
"products.product_id",
|
||||||
|
"products.product_name",
|
||||||
|
"products.brand_id",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
filters: {},
|
||||||
|
sort: {},
|
||||||
|
paginate: {},
|
||||||
|
relationships: [
|
||||||
|
{
|
||||||
|
from: "brand_id",
|
||||||
|
to: "brand_id",
|
||||||
|
tableName: "products",
|
||||||
|
column: "products",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
extra: { idFilter: {} },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateManyRelationshipJson(config: { schema?: string } = {}) {
|
||||||
|
return {
|
||||||
|
endpoint: {
|
||||||
|
datasourceId: "Postgres",
|
||||||
|
entityId: "stores",
|
||||||
|
operation: "READ",
|
||||||
|
schema: config.schema,
|
||||||
|
},
|
||||||
|
resource: {
|
||||||
|
fields: [
|
||||||
|
"stores.store_id",
|
||||||
|
"stores.store_name",
|
||||||
|
"products.product_id",
|
||||||
|
"products.product_name",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
filters: {},
|
||||||
|
sort: {},
|
||||||
|
paginate: {},
|
||||||
|
relationships: [
|
||||||
|
{
|
||||||
|
from: "store_id",
|
||||||
|
to: "product_id",
|
||||||
|
tableName: "products",
|
||||||
|
column: "products",
|
||||||
|
through: "stocks",
|
||||||
|
fromPrimary: "store_id",
|
||||||
|
toPrimary: "product_id",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
extra: { idFilter: {} },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
describe("SQL query builder", () => {
|
describe("SQL query builder", () => {
|
||||||
const limit = 500
|
const limit = 500
|
||||||
const client = SqlClient.POSTGRES
|
const client = SqlClient.POSTGRES
|
||||||
|
@ -425,4 +491,30 @@ describe("SQL query builder", () => {
|
||||||
sql: `select * from (select * from \"${TABLE_NAME}\" where \"${TABLE_NAME}\".\"age\"::jsonb ?| array [20,25] and \"${TABLE_NAME}\".\"name\"::jsonb ?| array ['John','Mary'] limit $1) as \"${TABLE_NAME}\"`,
|
sql: `select * from (select * from \"${TABLE_NAME}\" where \"${TABLE_NAME}\".\"age\"::jsonb ?| array [20,25] and \"${TABLE_NAME}\".\"name\"::jsonb ?| array ['John','Mary'] limit $1) as \"${TABLE_NAME}\"`,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should add the schema to the LEFT JOIN", () => {
|
||||||
|
const query = sql._query(generateRelationshipJson({ schema: "production" }))
|
||||||
|
expect(query).toEqual({
|
||||||
|
bindings: [500, 5000],
|
||||||
|
sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "production"."brands" limit $1) as "brands" left join "production"."products" on "brands"."brand_id" = "products"."brand_id" limit $2`,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should handle if the schema is not present when doing a LEFT JOIN", () => {
|
||||||
|
const query = sql._query(generateRelationshipJson())
|
||||||
|
expect(query).toEqual({
|
||||||
|
bindings: [500, 5000],
|
||||||
|
sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "brands" limit $1) as "brands" left join "products" on "brands"."brand_id" = "products"."brand_id" limit $2`,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should add the schema to both the toTable and throughTable in many-to-many join", () => {
|
||||||
|
const query = sql._query(
|
||||||
|
generateManyRelationshipJson({ schema: "production" })
|
||||||
|
)
|
||||||
|
expect(query).toEqual({
|
||||||
|
bindings: [500, 5000],
|
||||||
|
sql: `select "stores"."store_id" as "stores.store_id", "stores"."store_name" as "stores.store_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name" from (select * from "production"."stores" limit $1) as "stores" left join "production"."stocks" on "stores"."store_id" = "stocks"."store_id" left join "production"."products" on "products"."product_id" = "stocks"."product_id" limit $2`,
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue