Skip to content

Commit e75bf58

Browse files
committed
feat(views, foreign-tables): retrieve
1 parent 2d45993 commit e75bf58

File tree

4 files changed

+172
-0
lines changed

4 files changed

+172
-0
lines changed

src/lib/PostgresMetaForeignTables.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { literal } from 'pg-format'
12
import { coalesceRowsToArray } from './helpers.js'
23
import { columnsSql, foreignTablesSql } from './sql/index.js'
34
import { PostgresMetaResult, PostgresForeignTable } from './types.js'
@@ -37,6 +38,57 @@ export default class PostgresMetaForeignTables {
3738
}
3839
return await this.query(sql)
3940
}
41+
42+
async retrieve({ id }: { id: number }): Promise<PostgresMetaResult<PostgresForeignTable>>
43+
async retrieve({
44+
name,
45+
schema,
46+
}: {
47+
name: string
48+
schema: string
49+
}): Promise<PostgresMetaResult<PostgresForeignTable>>
50+
async retrieve({
51+
id,
52+
name,
53+
schema = 'public',
54+
}: {
55+
id?: number
56+
name?: string
57+
schema?: string
58+
}): Promise<PostgresMetaResult<PostgresForeignTable>> {
59+
if (id) {
60+
const sql = `${generateEnrichedForeignTablesSql({
61+
includeColumns: true,
62+
})} where foreign_tables.id = ${literal(id)};`
63+
const { data, error } = await this.query(sql)
64+
if (error) {
65+
return { data, error }
66+
} else if (data.length === 0) {
67+
return { data: null, error: { message: `Cannot find a foreign table with ID ${id}` } }
68+
} else {
69+
return { data: data[0], error }
70+
}
71+
} else if (name) {
72+
const sql = `${generateEnrichedForeignTablesSql({
73+
includeColumns: true,
74+
})} where foreign_tables.name = ${literal(name)} and foreign_tables.schema = ${literal(
75+
schema
76+
)};`
77+
const { data, error } = await this.query(sql)
78+
if (error) {
79+
return { data, error }
80+
} else if (data.length === 0) {
81+
return {
82+
data: null,
83+
error: { message: `Cannot find a foreign table named ${name} in schema ${schema}` },
84+
}
85+
} else {
86+
return { data: data[0], error }
87+
}
88+
} else {
89+
return { data: null, error: { message: 'Invalid parameters on foreign table retrieve' } }
90+
}
91+
}
4092
}
4193

4294
const generateEnrichedForeignTablesSql = ({ includeColumns }: { includeColumns: boolean }) => `

src/lib/PostgresMetaViews.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { literal } from 'pg-format'
12
import { DEFAULT_SYSTEM_SCHEMAS } from './constants.js'
23
import { coalesceRowsToArray, filterByList } from './helpers.js'
34
import { columnsSql, viewsSql } from './sql/index.js'
@@ -58,6 +59,55 @@ export default class PostgresMetaViews {
5859
}
5960
return await this.query(sql)
6061
}
62+
63+
async retrieve({ id }: { id: number }): Promise<PostgresMetaResult<PostgresView>>
64+
async retrieve({
65+
name,
66+
schema,
67+
}: {
68+
name: string
69+
schema: string
70+
}): Promise<PostgresMetaResult<PostgresView>>
71+
async retrieve({
72+
id,
73+
name,
74+
schema = 'public',
75+
}: {
76+
id?: number
77+
name?: string
78+
schema?: string
79+
}): Promise<PostgresMetaResult<PostgresView>> {
80+
if (id) {
81+
const sql = `${generateEnrichedViewsSql({
82+
includeColumns: true,
83+
})} where views.id = ${literal(id)};`
84+
const { data, error } = await this.query(sql)
85+
if (error) {
86+
return { data, error }
87+
} else if (data.length === 0) {
88+
return { data: null, error: { message: `Cannot find a view with ID ${id}` } }
89+
} else {
90+
return { data: data[0], error }
91+
}
92+
} else if (name) {
93+
const sql = `${generateEnrichedViewsSql({
94+
includeColumns: true,
95+
})} where views.name = ${literal(name)} and views.schema = ${literal(schema)};`
96+
const { data, error } = await this.query(sql)
97+
if (error) {
98+
return { data, error }
99+
} else if (data.length === 0) {
100+
return {
101+
data: null,
102+
error: { message: `Cannot find a view named ${name} in schema ${schema}` },
103+
}
104+
} else {
105+
return { data: data[0], error }
106+
}
107+
} else {
108+
return { data: null, error: { message: 'Invalid parameters on view retrieve' } }
109+
}
110+
}
61111
}
62112

63113
const generateEnrichedViewsSql = ({ includeColumns }: { includeColumns: boolean }) => `

src/server/routes/foreign-tables.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,40 @@ const route: FastifyPluginAsyncTypebox = async (fastify) => {
4444
return data
4545
}
4646
)
47+
48+
fastify.get(
49+
'/:id(\\d+)',
50+
{
51+
schema: {
52+
headers: Type.Object({
53+
pg: Type.String(),
54+
}),
55+
params: Type.Object({
56+
id: Type.Integer(),
57+
}),
58+
response: {
59+
200: postgresForeignTableSchema,
60+
404: Type.Object({
61+
error: Type.String(),
62+
}),
63+
},
64+
},
65+
},
66+
async (request, reply) => {
67+
const connectionString = request.headers.pg
68+
const id = request.params.id
69+
70+
const pgMeta = new PostgresMeta({ ...DEFAULT_POOL_CONFIG, connectionString })
71+
const { data, error } = await pgMeta.foreignTables.retrieve({ id })
72+
await pgMeta.end()
73+
if (error) {
74+
request.log.error({ error, request: extractRequestForLogging(request) })
75+
reply.code(404)
76+
return { error: error.message }
77+
}
78+
79+
return data
80+
}
81+
)
4782
}
4883
export default route

src/server/routes/views.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,40 @@ const route: FastifyPluginAsyncTypebox = async (fastify) => {
5858
return data
5959
}
6060
)
61+
62+
fastify.get(
63+
'/:id(\\d+)',
64+
{
65+
schema: {
66+
headers: Type.Object({
67+
pg: Type.String(),
68+
}),
69+
params: Type.Object({
70+
id: Type.Integer(),
71+
}),
72+
response: {
73+
200: postgresViewSchema,
74+
404: Type.Object({
75+
error: Type.String(),
76+
}),
77+
},
78+
},
79+
},
80+
async (request, reply) => {
81+
const connectionString = request.headers.pg
82+
const id = request.params.id
83+
84+
const pgMeta = new PostgresMeta({ ...DEFAULT_POOL_CONFIG, connectionString })
85+
const { data, error } = await pgMeta.views.retrieve({ id })
86+
await pgMeta.end()
87+
if (error) {
88+
request.log.error({ error, request: extractRequestForLogging(request) })
89+
reply.code(404)
90+
return { error: error.message }
91+
}
92+
93+
return data
94+
}
95+
)
6196
}
6297
export default route

0 commit comments

Comments
 (0)