Skip to content

Commit f0ad3e8

Browse files
committed
feat(tables): allow include/exclude schema(s)
1 parent b787e81 commit f0ad3e8

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

src/lib/PostgresMetaTables.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,33 @@ export default class PostgresMetaTables {
1313

1414
async list({
1515
includeSystemSchemas = false,
16+
includedSchemas,
17+
excludedSchemas,
1618
limit,
1719
offset,
1820
}: {
1921
includeSystemSchemas?: boolean
22+
includedSchemas?: string[]
23+
excludedSchemas?: string[]
2024
limit?: number
2125
offset?: number
2226
} = {}): Promise<PostgresMetaResult<PostgresTable[]>> {
2327
let sql = enrichedTablesSql
24-
if (!includeSystemSchemas) {
28+
29+
if (includedSchemas?.length) {
30+
sql = `${sql} WHERE (schema IN (${includedSchemas.map(literal).join(',')}))`
31+
} else if (!includeSystemSchemas) {
2532
sql = `${sql} WHERE NOT (schema IN (${DEFAULT_SYSTEM_SCHEMAS.map(literal).join(',')}))`
2633
}
34+
35+
if (excludedSchemas?.length) {
36+
if (includedSchemas?.length || !includeSystemSchemas) {
37+
sql = `${sql} AND NOT (schema IN (${excludedSchemas.map(literal).join(',')}))`
38+
} else {
39+
sql = `${sql} WHERE NOT (schema IN (${excludedSchemas.map(literal).join(',')}))`
40+
}
41+
}
42+
2743
if (limit) {
2844
sql = `${sql} LIMIT ${limit}`
2945
}

src/server/routes/tables.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,22 @@ export default async (fastify: FastifyInstance) => {
88
Headers: { pg: string }
99
Querystring: {
1010
include_system_schemas?: string
11+
// Note: this only supports comma separated values (e.g., ".../tables?included_schemas=public,core")
12+
included_schemas?: string
13+
excluded_schemas?: string
1114
limit?: number
1215
offset?: number
1316
}
1417
}>('/', async (request, reply) => {
1518
const connectionString = request.headers.pg
1619
const includeSystemSchemas = request.query.include_system_schemas === 'true'
20+
const includedSchemas = request.query.included_schemas?.split(',')
21+
const excludedSchemas = request.query.excluded_schemas?.split(',')
1722
const limit = request.query.limit
1823
const offset = request.query.offset
1924

2025
const pgMeta = new PostgresMeta({ ...DEFAULT_POOL_CONFIG, connectionString })
21-
const { data, error } = await pgMeta.tables.list({ includeSystemSchemas, limit, offset })
26+
const { data, error } = await pgMeta.tables.list({ includeSystemSchemas, includedSchemas, excludedSchemas, limit, offset })
2227
await pgMeta.end()
2328
if (error) {
2429
request.log.error({ error, request: extractRequestForLogging(request) })

test/lib/tables.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,41 @@ test('list', async () => {
129129
)
130130
})
131131

132+
test('list tables with included schemas', async () => {
133+
let res = await pgMeta.tables.list({
134+
includedSchemas: ['public']
135+
})
136+
137+
expect(res.data?.length).toBeGreaterThan(0)
138+
139+
res.data?.forEach((table) => {
140+
expect(table.schema).toBe('public')
141+
})
142+
})
143+
144+
test('list tables with excluded schemas', async () => {
145+
let res = await pgMeta.tables.list({
146+
excludedSchemas: ['public'],
147+
})
148+
149+
res.data?.forEach((table) => {
150+
expect(table.schema).not.toBe('public')
151+
})
152+
})
153+
154+
test('list tables with excluded schemas and include System Schemas', async () => {
155+
let res = await pgMeta.tables.list({
156+
excludedSchemas: ['public'],
157+
includeSystemSchemas: true,
158+
})
159+
160+
expect(res.data?.length).toBeGreaterThan(0)
161+
162+
res.data?.forEach((table) => {
163+
expect(table.schema).not.toBe('public')
164+
})
165+
})
166+
132167
test('retrieve, create, update, delete', async () => {
133168
let res = await pgMeta.tables.create({ name: 'test', comment: 'foo' })
134169
expect(cleanNondet(res)).toMatchInlineSnapshot(

0 commit comments

Comments
 (0)