-
-
Notifications
You must be signed in to change notification settings - Fork 137
/
Copy pathPostgresMetaForeignTables.ts
117 lines (112 loc) · 3.44 KB
/
PostgresMetaForeignTables.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { literal } from 'pg-format'
import { coalesceRowsToArray, filterByList } from './helpers.js'
import columnsSql from './sql/columns.sql'
import foreignTablesSql from './sql/foreign_tables.sql'
import { PostgresMetaResult, PostgresForeignTable } from './types.js'
export default class PostgresMetaForeignTables {
query: (sql: string) => Promise<PostgresMetaResult<any>>
constructor(query: (sql: string) => Promise<PostgresMetaResult<any>>) {
this.query = query
}
async list(options: {
includedSchemas?: string[]
excludedSchemas?: string[]
limit?: number
offset?: number
includeColumns: false
}): Promise<PostgresMetaResult<(PostgresForeignTable & { columns: never })[]>>
async list(options?: {
includedSchemas?: string[]
excludedSchemas?: string[]
limit?: number
offset?: number
includeColumns?: boolean
}): Promise<PostgresMetaResult<(PostgresForeignTable & { columns: unknown[] })[]>>
async list({
includedSchemas,
excludedSchemas,
limit,
offset,
includeColumns = true,
}: {
includedSchemas?: string[]
excludedSchemas?: string[]
limit?: number
offset?: number
includeColumns?: boolean
} = {}): Promise<PostgresMetaResult<PostgresForeignTable[]>> {
let sql = generateEnrichedForeignTablesSql({ includeColumns })
const filter = filterByList(includedSchemas, excludedSchemas)
if (filter) {
sql += ` where schema ${filter}`
}
if (limit) {
sql += ` limit ${limit}`
}
if (offset) {
sql += ` offset ${offset}`
}
return await this.query(sql)
}
async retrieve({ id }: { id: number }): Promise<PostgresMetaResult<PostgresForeignTable>>
async retrieve({
name,
schema,
}: {
name: string
schema: string
}): Promise<PostgresMetaResult<PostgresForeignTable>>
async retrieve({
id,
name,
schema = 'public',
}: {
id?: number
name?: string
schema?: string
}): Promise<PostgresMetaResult<PostgresForeignTable>> {
if (id) {
const sql = `${generateEnrichedForeignTablesSql({
includeColumns: true,
})} where foreign_tables.id = ${literal(id)};`
const { data, error } = await this.query(sql)
if (error) {
return { data, error }
} else if (data.length === 0) {
return { data: null, error: { message: `Cannot find a foreign table with ID ${id}` } }
} else {
return { data: data[0], error }
}
} else if (name) {
const sql = `${generateEnrichedForeignTablesSql({
includeColumns: true,
})} where foreign_tables.name = ${literal(name)} and foreign_tables.schema = ${literal(
schema
)};`
const { data, error } = await this.query(sql)
if (error) {
return { data, error }
} else if (data.length === 0) {
return {
data: null,
error: { message: `Cannot find a foreign table named ${name} in schema ${schema}` },
}
} else {
return { data: data[0], error }
}
} else {
return { data: null, error: { message: 'Invalid parameters on foreign table retrieve' } }
}
}
}
const generateEnrichedForeignTablesSql = ({ includeColumns }: { includeColumns: boolean }) => `
with foreign_tables as (${foreignTablesSql})
${includeColumns ? `, columns as (${columnsSql})` : ''}
select
*
${
includeColumns
? `, ${coalesceRowsToArray('columns', 'columns.table_id = foreign_tables.id')}`
: ''
}
from foreign_tables`