From 8b327b0693a567e21d4f0dfa2f8289d429c3c92d Mon Sep 17 00:00:00 2001 From: prostgles Date: Sat, 14 Oct 2023 12:06:24 +0000 Subject: [PATCH] fix repeating existsJoined tables bug --- .../ViewHandler/getExistsCondition.ts | 1 - .../ViewHandler/getTableJoinQuery.ts | 14 ++--- lib/PublishParser.ts | 63 ++++++++++++++++++- package-lock.json | 4 +- package.json | 2 +- tests/client/PID.txt | 2 +- tests/isomorphic_queries.ts | 12 +++- tests/server/package-lock.json | 2 +- 8 files changed, 85 insertions(+), 15 deletions(-) diff --git a/lib/DboBuilder/ViewHandler/getExistsCondition.ts b/lib/DboBuilder/ViewHandler/getExistsCondition.ts index 19d9475f..3b563b68 100644 --- a/lib/DboBuilder/ViewHandler/getExistsCondition.ts +++ b/lib/DboBuilder/ViewHandler/getExistsCondition.ts @@ -60,7 +60,6 @@ export async function getExistsCondition(this: ViewHandler, eConfig: ExistsFilte if(eConfig.isJoined){ const { query } = getTableJoinQuery({ path: eConfig.parsedPath, - aliasSufix: "jd", rootTableAlias: thisTable, type: "EXISTS", finalWhere, diff --git a/lib/DboBuilder/ViewHandler/getTableJoinQuery.ts b/lib/DboBuilder/ViewHandler/getTableJoinQuery.ts index 29cdf021..859a6ba4 100644 --- a/lib/DboBuilder/ViewHandler/getTableJoinQuery.ts +++ b/lib/DboBuilder/ViewHandler/getTableJoinQuery.ts @@ -2,25 +2,25 @@ import { asName } from "prostgles-types"; import { ParsedJoinPath } from "./parseJoinPath"; type getTableJoinsArgs = { - aliasSufix: string; rootTableAlias: string; type: "INNER" | "LEFT" | "EXISTS"; finalWhere?: string; path: ParsedJoinPath[]; } -export const getTableJoinQuery = ({ path, type, aliasSufix, rootTableAlias, finalWhere }: getTableJoinsArgs): { targetAlias: string; query: string } => { +export const getTableJoinQuery = ({ path, type, rootTableAlias, finalWhere }: getTableJoinsArgs): { targetAlias: string; query: string } => { const [firstPath] = path; if(!firstPath){ throw `Cannot create join query for empty path`; } - const getTableAlias = (table: string) => asName(`${aliasSufix}_${table}`); + const aliasSufix = "jd"; + const getTableAlias = (table: string, pathIndex: number) => asName(`${aliasSufix}_${pathIndex}_${table}`); const query = path.map(({ table, on }, i) => { if(!on) throw "on missing"; const tableName = table; - const tableAlias = getTableAlias(table); - const prevTableAlias = i === 0? rootTableAlias : getTableAlias(path[i-1]!.table); + const tableAlias = getTableAlias(table, i); + const prevTableAlias = i === 0? rootTableAlias : getTableAlias(path[i-1]!.table, i-1); const onCondition = getJoinOnCondition({ on, leftAlias: prevTableAlias, rightAlias: tableAlias }); @@ -38,7 +38,7 @@ export const getTableJoinQuery = ({ path, type, aliasSufix, rootTableAlias, fina `WHERE (${getJoinOnCondition({ on: firstPath.on, leftAlias: rootTableAlias, - rightAlias: getTableAlias(firstPath.table) + rightAlias: getTableAlias(firstPath.table, 0) })})` : ""; const tableSelect = (isExists && isLast)? [ @@ -66,7 +66,7 @@ export const getTableJoinQuery = ({ path, type, aliasSufix, rootTableAlias, fina return { query, - targetAlias: getTableAlias(path.at(-1)!.table) + targetAlias: getTableAlias(path.at(-1)!.table, path.length - 1) } } diff --git a/lib/PublishParser.ts b/lib/PublishParser.ts index e1353bde..4b6183b2 100644 --- a/lib/PublishParser.ts +++ b/lib/PublishParser.ts @@ -1,7 +1,7 @@ import { getKeys, RULE_METHODS, AnyObject, get, TableSchemaForClient, DBSchemaTable, MethodKey, TableInfo, FullFilter, isObject, Method, DBSchema } from "prostgles-types"; import { AuthResult, SessionUser } from "./AuthHandler"; import { CommonTableRules, Filter, isPlainObject, LocalParams, PRGLIOSocket, TableOrViewInfo, TableSchemaColumn } from "./DboBuilder"; -import { Prostgles, DBHandlerServer, DB, TABLE_METHODS } from "./Prostgles"; +import { Prostgles, DBHandlerServer, DB, TABLE_METHODS, ProstglesInitOptions } from "./Prostgles"; import type { DBOFullyTyped, PublishFullyTyped } from "./DBSchemaBuilder"; export type PublishMethods = (params: PublishParams) => { [key: string]: Method } | Promise<{ [key: string]: Method } | null>; @@ -101,6 +101,7 @@ import { FieldFilter, SelectParams } from "prostgles-types"; import { DEFAULT_SYNC_BATCH_SIZE } from "./PubSubManager/PubSubManager"; import { TableHandler } from "./DboBuilder/TableHandler"; import { ViewHandler } from "./DboBuilder/ViewHandler/ViewHandler"; +import { parseFieldFilter } from "./DboBuilder/ViewHandler/parseFieldFilter"; export type InsertRequestData = { data: object | object[] @@ -796,4 +797,64 @@ function applyParamsIfFunc(maybeFunc: any, ...params: any): any { } return maybeFunc; +} + +export async function getFileTableRules (this: PublishParser, socket: PRGLIOSocket, clientInfo: AuthResult | undefined) { + const opts = this.prostgles.opts; + const forcedDeleteFilters: FullFilter[] = []; + const forcedSelectFilters: FullFilter[] = []; + if(opts.fileTable?.referencedTables){ + Object.entries(opts.fileTable.referencedTables).forEach(async ([tableName, refCols]) => { + if(isObject(refCols)){ + const table_rules = await this.getTableRules({ localParams: { socket }, tableName }, clientInfo); + if(table_rules){ + Object.keys(refCols).map(column => { + + if(table_rules.delete){ + forcedDeleteFilters.push({ + $existsJoined: { + path: [{ table: tableName, on: [{ [column]: "id" }] }], + filter: table_rules.delete.forcedFilter ?? {}, + } + }) + } + if(table_rules.select){ + const parsedFields = parseFieldFilter(table_rules.select.fields, false, [column]); + /** Must be allowed to view this column */ + if(parsedFields.includes(column as any)){ + forcedSelectFilters.push({ + $existsJoined: { + path: [{ table: tableName, on: [{ [column]: "id" }] }], + filter: table_rules.select.forcedFilter ?? {}, + } + }); + } + } + + }) + } + } + }) + } + + + const fileTableRule: TableRule = {}; + if(forcedSelectFilters.length){ + fileTableRule.select = { + fields: "*", + forcedFilter: { + $or: forcedSelectFilters + } + } + } + if(forcedDeleteFilters.length){ + fileTableRule.delete = { + filterFields: "*", + forcedFilter: { + $or: forcedSelectFilters + } + } + } + + return fileTableRule; } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b7642f8c..dfc72585 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "prostgles-server", - "version": "4.1.87", + "version": "4.1.88", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "prostgles-server", - "version": "4.1.87", + "version": "4.1.88", "license": "MIT", "dependencies": { "@types/express": "^4.17.13", diff --git a/package.json b/package.json index 38a9cfc8..cb42175d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prostgles-server", - "version": "4.1.87", + "version": "4.1.88", "description": "", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/tests/client/PID.txt b/tests/client/PID.txt index c334027f..72c9c412 100644 --- a/tests/client/PID.txt +++ b/tests/client/PID.txt @@ -1 +1 @@ -1782762 +2319940 diff --git a/tests/isomorphic_queries.ts b/tests/isomorphic_queries.ts index cc135ae5..3500771c 100644 --- a/tests/isomorphic_queries.ts +++ b/tests/isomorphic_queries.ts @@ -946,7 +946,7 @@ export default async function isomorphic(db: Required | Require }] }]); - const exists = await db[`"""quoted0"""`].find({ + const exists1 = await db[`"""quoted0"""`].find({ $existsJoined: { path: ['"""quoted1"""', '"""quoted2"""'], filter: { @@ -954,6 +954,16 @@ export default async function isomorphic(db: Required | Require } } }, { select: "*" }); + /** Duplicated tables */ + const exists2 = await db[`"""quoted0"""`].find({ + $existsJoined: { + path: ['"""quoted1"""', '"""quoted2"""','"""quoted1"""', '"""quoted2"""'], + filter: { + '"id2"': 1, + } + } + }, { select: "*" }); + assert.deepStrictEqual(exists1, exists2) }) await tryRun("Reverse join with agg", async () => { diff --git a/tests/server/package-lock.json b/tests/server/package-lock.json index 1e90a54a..affbec1f 100644 --- a/tests/server/package-lock.json +++ b/tests/server/package-lock.json @@ -21,7 +21,7 @@ }, "../..": { "name": "prostgles-server", - "version": "4.1.87", + "version": "4.1.88", "license": "MIT", "dependencies": { "@types/express": "^4.17.13",