-
-
Notifications
You must be signed in to change notification settings - Fork 138
/
Copy pathPostgresMetaExtensions.ts
110 lines (102 loc) · 2.88 KB
/
PostgresMetaExtensions.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
import { ident, literal } from 'pg-format'
import extensionsSql from './sql/extensions.sql'
import { PostgresMetaResult, PostgresExtension } from './types.js'
export default class PostgresMetaExtensions {
query: (sql: string) => Promise<PostgresMetaResult<any>>
constructor(query: (sql: string) => Promise<PostgresMetaResult<any>>) {
this.query = query
}
async list({
limit,
offset,
}: {
limit?: number
offset?: number
} = {}): Promise<PostgresMetaResult<PostgresExtension[]>> {
let sql = extensionsSql
if (limit) {
sql = `${sql} LIMIT ${limit}`
}
if (offset) {
sql = `${sql} OFFSET ${offset}`
}
return await this.query(sql)
}
async retrieve({ name }: { name: string }): Promise<PostgresMetaResult<PostgresExtension>> {
const sql = `${extensionsSql} WHERE name = ${literal(name)};`
const { data, error } = await this.query(sql)
if (error) {
return { data, error }
} else if (data.length === 0) {
return { data: null, error: { message: `Cannot find an extension named ${name}` } }
} else {
return { data: data[0], error }
}
}
async create({
name,
schema,
version,
cascade = false,
}: {
name: string
schema?: string
version?: string
cascade?: boolean
}): Promise<PostgresMetaResult<PostgresExtension>> {
const sql = `
CREATE EXTENSION ${ident(name)}
${schema === undefined ? '' : `SCHEMA ${ident(schema)}`}
${version === undefined ? '' : `VERSION ${literal(version)}`}
${cascade ? 'CASCADE' : ''};`
const { error } = await this.query(sql)
if (error) {
return { data: null, error }
}
return await this.retrieve({ name })
}
async update(
name: string,
{
update = false,
version,
schema,
}: {
update?: boolean
version?: string
schema?: string
}
): Promise<PostgresMetaResult<PostgresExtension>> {
let updateSql = ''
if (update) {
updateSql = `ALTER EXTENSION ${ident(name)} UPDATE ${
version === undefined ? '' : `TO ${literal(version)}`
};`
}
const schemaSql =
schema === undefined ? '' : `ALTER EXTENSION ${ident(name)} SET SCHEMA ${ident(schema)};`
const sql = `BEGIN; ${updateSql} ${schemaSql} COMMIT;`
const { error } = await this.query(sql)
if (error) {
return { data: null, error }
}
return await this.retrieve({ name })
}
async remove(
name: string,
{ cascade = false } = {}
): Promise<PostgresMetaResult<PostgresExtension>> {
const { data: extension, error } = await this.retrieve({ name })
if (error) {
return { data: null, error }
}
const sql = `DROP EXTENSION ${ident(name)} ${cascade ? 'CASCADE' : 'RESTRICT'};`
{
const { error } = await this.query(sql)
if (error) {
return { data: null, error }
}
}
return { data: extension!, error: null }
}
}