Skip to content

Commit c4e1fb1

Browse files
committed
wip: refactor queries for root filtering
1 parent 56a1f74 commit c4e1fb1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+520
-642
lines changed

schema-filter-demo.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

src/lib/PostgresMetaColumnPrivileges.ts

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ident, literal } from 'pg-format'
22
import { DEFAULT_SYSTEM_SCHEMAS } from './constants.js'
3-
import { filterByList } from './helpers.js'
4-
import { columnPrivilegesSql } from './sql/index.js'
3+
import { filterByValue, filterByList } from './helpers.js'
4+
import { COLUMN_PRIVILEGES_SQL } from './sql/column_privileges.sql.js'
55
import {
66
PostgresMetaResult,
77
PostgresColumnPrivileges,
@@ -29,25 +29,12 @@ export default class PostgresMetaColumnPrivileges {
2929
limit?: number
3030
offset?: number
3131
} = {}): Promise<PostgresMetaResult<PostgresColumnPrivileges[]>> {
32-
let sql = `
33-
with column_privileges as (${columnPrivilegesSql})
34-
select *
35-
from column_privileges
36-
`
37-
const filter = filterByList(
32+
const schemaFilter = filterByList(
3833
includedSchemas,
3934
excludedSchemas,
4035
!includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : undefined
4136
)
42-
if (filter) {
43-
sql += ` where relation_schema ${filter}`
44-
}
45-
if (limit) {
46-
sql += ` limit ${limit}`
47-
}
48-
if (offset) {
49-
sql += ` offset ${offset}`
50-
}
37+
const sql = COLUMN_PRIVILEGES_SQL({ schemaFilter, limit, offset })
5138
return await this.query(sql)
5239
}
5340

@@ -86,12 +73,8 @@ end $$;
8673

8774
// Return the updated column privileges for modified columns.
8875
const columnIds = [...new Set(grants.map(({ column_id }) => column_id))]
89-
sql = `
90-
with column_privileges as (${columnPrivilegesSql})
91-
select *
92-
from column_privileges
93-
where column_id in (${columnIds.map(literal).join(',')})
94-
`
76+
const columnIdsFilter = filterByValue(columnIds)
77+
sql = COLUMN_PRIVILEGES_SQL({ schemaFilter: undefined, columnIdsFilter })
9578
return await this.query(sql)
9679
}
9780

@@ -130,12 +113,8 @@ end $$;
130113

131114
// Return the updated column privileges for modified columns.
132115
const columnIds = [...new Set(revokes.map(({ column_id }) => column_id))]
133-
sql = `
134-
with column_privileges as (${columnPrivilegesSql})
135-
select *
136-
from column_privileges
137-
where column_id in (${columnIds.map(literal).join(',')})
138-
`
116+
const columnIdsFilter = filterByValue(columnIds)
117+
sql = COLUMN_PRIVILEGES_SQL({ schemaFilter: undefined, columnIdsFilter })
139118
return await this.query(sql)
140119
}
141120
}

src/lib/PostgresMetaColumns.ts

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ident, literal } from 'pg-format'
22
import PostgresMetaTables from './PostgresMetaTables.js'
33
import { DEFAULT_SYSTEM_SCHEMAS } from './constants.js'
44
import { PostgresMetaResult, PostgresColumn } from './types.js'
5-
import { filterByList } from './helpers.js'
5+
import { filterByValue, filterByList } from './helpers.js'
66
import { COLUMNS_SQL } from './sql/columns.sql.js'
77

88
export default class PostgresMetaColumns {
@@ -34,24 +34,8 @@ export default class PostgresMetaColumns {
3434
excludedSchemas,
3535
!includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : undefined
3636
)
37-
let sql = `
38-
WITH
39-
columns AS (${COLUMNS_SQL(schemaFilter)})
40-
SELECT
41-
*
42-
FROM
43-
columns
44-
WHERE
45-
true`
46-
if (tableId !== undefined) {
47-
sql += ` AND table_id = ${literal(tableId)}`
48-
}
49-
if (limit) {
50-
sql += ` LIMIT ${limit}`
51-
}
52-
if (offset) {
53-
sql += ` OFFSET ${offset}`
54-
}
37+
const tableIdFilter = tableId ? filterByValue([`${tableId}`]) : undefined
38+
const sql = COLUMNS_SQL({ schemaFilter, tableIdFilter, limit, offset })
5539
return await this.query(sql)
5640
}
5741

@@ -84,7 +68,8 @@ WHERE
8468
}
8569
const matches = id.match(regexp) as RegExpMatchArray
8670
const [tableId, ordinalPos] = matches.slice(1).map(Number)
87-
const sql = `${COLUMNS_SQL(schemaFilter)} AND c.oid = ${tableId} AND a.attnum = ${ordinalPos};`
71+
const idsFilter = filterByValue([`${tableId}.${ordinalPos}`])
72+
const sql = COLUMNS_SQL({ idsFilter })
8873
const { data, error } = await this.query(sql)
8974
if (error) {
9075
return { data, error }
@@ -94,9 +79,8 @@ WHERE
9479
return { data: data[0], error }
9580
}
9681
} else if (name && table) {
97-
const sql = `${COLUMNS_SQL(schemaFilter)} AND a.attname = ${literal(name)} AND c.relname = ${literal(
98-
table
99-
)};`
82+
const columnNameFilter = filterByValue([`${table}.${name}`])
83+
const sql = `${COLUMNS_SQL({ schemaFilter, columnNameFilter })};`
10084
const { data, error } = await this.query(sql)
10185
if (error) {
10286
return { data, error }

src/lib/PostgresMetaConfig.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { configSql } from './sql/index.js'
1+
import { CONFIG_SQL } from './sql/index.js'
22
import { PostgresMetaResult, PostgresConfig } from './types.js'
33

44
export default class PostgresMetaConfig {
@@ -15,13 +15,7 @@ export default class PostgresMetaConfig {
1515
limit?: number
1616
offset?: number
1717
} = {}): Promise<PostgresMetaResult<PostgresConfig[]>> {
18-
let sql = configSql
19-
if (limit) {
20-
sql = `${sql} LIMIT ${limit}`
21-
}
22-
if (offset) {
23-
sql = `${sql} OFFSET ${offset}`
24-
}
18+
let sql = CONFIG_SQL({ limit, offset })
2519
return await this.query(sql)
2620
}
2721
}

src/lib/PostgresMetaExtensions.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ident, literal } from 'pg-format'
2-
import { extensionsSql } from './sql/index.js'
32
import { PostgresMetaResult, PostgresExtension } from './types.js'
3+
import { EXTENSIONS_SQL } from './sql/index.js'
4+
import { filterByValue } from './helpers.js'
45

56
export default class PostgresMetaExtensions {
67
query: (sql: string) => Promise<PostgresMetaResult<any>>
@@ -16,18 +17,13 @@ export default class PostgresMetaExtensions {
1617
limit?: number
1718
offset?: number
1819
} = {}): Promise<PostgresMetaResult<PostgresExtension[]>> {
19-
let sql = extensionsSql
20-
if (limit) {
21-
sql = `${sql} LIMIT ${limit}`
22-
}
23-
if (offset) {
24-
sql = `${sql} OFFSET ${offset}`
25-
}
20+
const sql = EXTENSIONS_SQL({ limit, offset })
2621
return await this.query(sql)
2722
}
2823

2924
async retrieve({ name }: { name: string }): Promise<PostgresMetaResult<PostgresExtension>> {
30-
const sql = `${extensionsSql} WHERE name = ${literal(name)};`
25+
const nameFilter = filterByValue([`${name}`])
26+
const sql = EXTENSIONS_SQL({ nameFilter })
3127
const { data, error } = await this.query(sql)
3228
if (error) {
3329
return { data, error }

src/lib/PostgresMetaForeignTables.ts

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { literal } from 'pg-format'
2-
import { coalesceRowsToArray, filterByList } from './helpers.js'
3-
import { columnsSql, foreignTablesSql } from './sql/index.js'
1+
import { coalesceRowsToArray, filterByList, filterByValue } from './helpers.js'
42
import { PostgresMetaResult, PostgresForeignTable } from './types.js'
3+
import { FOREIGN_TABLES_SQL } from './sql/foreign_tables.sql.js'
4+
import { COLUMNS_SQL } from './sql/columns.sql.js'
55

66
export default class PostgresMetaForeignTables {
77
query: (sql: string) => Promise<PostgresMetaResult<any>>
@@ -37,11 +37,8 @@ export default class PostgresMetaForeignTables {
3737
offset?: number
3838
includeColumns?: boolean
3939
} = {}): Promise<PostgresMetaResult<PostgresForeignTable[]>> {
40-
let sql = generateEnrichedForeignTablesSql({ includeColumns })
4140
const filter = filterByList(includedSchemas, excludedSchemas)
42-
if (filter) {
43-
sql += ` where schema ${filter}`
44-
}
41+
let sql = generateEnrichedForeignTablesSql({ includeColumns, schemaFilter: filter })
4542
if (limit) {
4643
sql += ` limit ${limit}`
4744
}
@@ -68,10 +65,13 @@ export default class PostgresMetaForeignTables {
6865
name?: string
6966
schema?: string
7067
}): Promise<PostgresMetaResult<PostgresForeignTable>> {
68+
const schemaFilter = schema ? filterByList([schema], []) : undefined
7169
if (id) {
72-
const sql = `${generateEnrichedForeignTablesSql({
70+
const idsFilter = filterByValue([`${id}`])
71+
const sql = generateEnrichedForeignTablesSql({
7372
includeColumns: true,
74-
})} where foreign_tables.id = ${literal(id)};`
73+
idsFilter,
74+
})
7575
const { data, error } = await this.query(sql)
7676
if (error) {
7777
return { data, error }
@@ -81,11 +81,12 @@ export default class PostgresMetaForeignTables {
8181
return { data: data[0], error }
8282
}
8383
} else if (name) {
84-
const sql = `${generateEnrichedForeignTablesSql({
84+
const nameFilter = filterByValue([`${schema}.${name}`])
85+
const sql = generateEnrichedForeignTablesSql({
8586
includeColumns: true,
86-
})} where foreign_tables.name = ${literal(name)} and foreign_tables.schema = ${literal(
87-
schema
88-
)};`
87+
schemaFilter,
88+
tableIdentifierFilter: nameFilter,
89+
})
8990
const { data, error } = await this.query(sql)
9091
if (error) {
9192
return { data, error }
@@ -103,9 +104,19 @@ export default class PostgresMetaForeignTables {
103104
}
104105
}
105106

106-
const generateEnrichedForeignTablesSql = ({ includeColumns }: { includeColumns: boolean }) => `
107-
with foreign_tables as (${foreignTablesSql})
108-
${includeColumns ? `, columns as (${columnsSql})` : ''}
107+
const generateEnrichedForeignTablesSql = ({
108+
includeColumns,
109+
schemaFilter,
110+
idsFilter,
111+
tableIdentifierFilter,
112+
}: {
113+
includeColumns: boolean
114+
schemaFilter?: string
115+
idsFilter?: string
116+
tableIdentifierFilter?: string
117+
}) => `
118+
with foreign_tables as (${FOREIGN_TABLES_SQL({ schemaFilter, tableIdentifierFilter })})
119+
${includeColumns ? `, columns as (${COLUMNS_SQL({ schemaFilter, tableIdentifierFilter, tableIdFilter: idsFilter })})` : ''}
109120
select
110121
*
111122
${

src/lib/PostgresMetaFunctions.ts

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { ident, literal } from 'pg-format'
22
import { DEFAULT_SYSTEM_SCHEMAS } from './constants.js'
3-
import { filterByList } from './helpers.js'
4-
import { functionsSql } from './sql/index.js'
3+
import { filterByList, filterByValue } from './helpers.js'
54
import { PostgresMetaResult, PostgresFunction, PostgresFunctionCreate } from './types.js'
5+
import { FUNCTIONS_SQL } from './sql/index.js'
66

77
export default class PostgresMetaFunctions {
88
query: (sql: string) => Promise<PostgresMetaResult<any>>
@@ -24,21 +24,12 @@ export default class PostgresMetaFunctions {
2424
limit?: number
2525
offset?: number
2626
} = {}): Promise<PostgresMetaResult<PostgresFunction[]>> {
27-
let sql = enrichedFunctionsSql
28-
const filter = filterByList(
27+
const schemaFilter = filterByList(
2928
includedSchemas,
3029
excludedSchemas,
3130
!includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : undefined
3231
)
33-
if (filter) {
34-
sql += ` WHERE schema ${filter}`
35-
}
36-
if (limit) {
37-
sql = `${sql} LIMIT ${limit}`
38-
}
39-
if (offset) {
40-
sql = `${sql} OFFSET ${offset}`
41-
}
32+
let sql = FUNCTIONS_SQL({ schemaFilter, limit, offset })
4233
return await this.query(sql)
4334
}
4435

@@ -63,8 +54,10 @@ export default class PostgresMetaFunctions {
6354
schema?: string
6455
args?: string[]
6556
}): Promise<PostgresMetaResult<PostgresFunction>> {
57+
const schemaFilter = schema ? filterByList([schema], []) : undefined
6658
if (id) {
67-
const sql = `${enrichedFunctionsSql} WHERE id = ${literal(id)};`
59+
const idsFilter = filterByValue([`${id}`])
60+
const sql = FUNCTIONS_SQL({ idsFilter })
6861
const { data, error } = await this.query(sql)
6962
if (error) {
7063
return { data, error }
@@ -74,7 +67,8 @@ export default class PostgresMetaFunctions {
7467
return { data: data[0], error }
7568
}
7669
} else if (name && schema && args) {
77-
const sql = this.generateRetrieveFunctionSql({ name, schema, args })
70+
const nameFilter = filterByValue([name])
71+
const sql = this.generateRetrieveFunctionSql({ schemaFilter, nameFilter, schema, name, args })
7872
const { data, error } = await this.query(sql)
7973
if (error) {
8074
return { data, error }
@@ -177,7 +171,7 @@ export default class PostgresMetaFunctions {
177171
178172
IF (
179173
SELECT id
180-
FROM (${functionsSql}) AS f
174+
FROM (${FUNCTIONS_SQL({})}) AS f
181175
WHERE f.schema = ${literal(currentFunc!.schema)}
182176
AND f.name = ${literal(currentFunc!.name)}
183177
AND f.identity_argument_types = ${literal(identityArgs)}
@@ -264,17 +258,17 @@ export default class PostgresMetaFunctions {
264258
}
265259

266260
private generateRetrieveFunctionSql({
267-
schema,
268-
name,
261+
schemaFilter,
262+
nameFilter,
269263
args,
270264
}: {
265+
schemaFilter?: string
266+
nameFilter?: string
271267
schema: string
272268
name: string
273269
args: string[]
274270
}): string {
275-
return `${enrichedFunctionsSql} JOIN pg_proc AS p ON id = p.oid WHERE schema = ${literal(
276-
schema
277-
)} AND name = ${literal(name)} AND p.proargtypes::text = ${
271+
return `${FUNCTIONS_SQL({ schemaFilter, nameFilter })} JOIN pg_proc AS p ON f.oid = p.oid WHERE p.proargtypes::text = ${
278272
args.length
279273
? `(
280274
SELECT STRING_AGG(type_oid::text, ' ') FROM (
@@ -299,12 +293,3 @@ export default class PostgresMetaFunctions {
299293
}`
300294
}
301295
}
302-
303-
const enrichedFunctionsSql = `
304-
WITH f AS (
305-
${functionsSql}
306-
)
307-
SELECT
308-
f.*
309-
FROM f
310-
`

0 commit comments

Comments
 (0)