1
- import { literal } from 'pg-format'
1
+ import { ident , literal } from 'pg-format'
2
2
import { DEFAULT_SYSTEM_SCHEMAS } from './constants'
3
3
import { functionsSql } from './sql'
4
4
import { PostgresMetaResult , PostgresFunction } from './types'
@@ -22,13 +22,21 @@ export default class PostgresMetaFunctions {
22
22
}
23
23
24
24
async retrieve ( { id } : { id : number } ) : Promise < PostgresMetaResult < PostgresFunction > >
25
- async retrieve ( { name } : { name : string } ) : Promise < PostgresMetaResult < PostgresFunction > >
25
+ async retrieve ( {
26
+ name,
27
+ schema,
28
+ } : {
29
+ name : string
30
+ schema : string
31
+ } ) : Promise < PostgresMetaResult < PostgresFunction > >
26
32
async retrieve ( {
27
33
id,
28
34
name,
35
+ schema = 'public' ,
29
36
} : {
30
37
id ?: number
31
38
name ?: string
39
+ schema ?: string
32
40
} ) : Promise < PostgresMetaResult < PostgresFunction > > {
33
41
if ( id ) {
34
42
const sql = `${ functionsSql } WHERE p.oid = ${ literal ( id ) } ;`
@@ -41,14 +49,16 @@ export default class PostgresMetaFunctions {
41
49
return { data : data [ 0 ] , error }
42
50
}
43
51
} else if ( name ) {
44
- const sql = `${ functionsSql } WHERE p.proname = ${ literal ( name ) } ;`
52
+ const sql = `${ functionsSql } WHERE p.proname = ${ literal ( name ) } AND n.nspname = ${ literal (
53
+ schema
54
+ ) } ;`
45
55
const { data, error } = await this . query ( sql )
46
56
if ( error ) {
47
57
return { data, error }
48
58
} else if ( data . length === 0 ) {
49
59
return {
50
60
data : null ,
51
- error : { message : `Cannot find a function named ${ name } ` } ,
61
+ error : { message : `Cannot find a function named ${ name } in schema ${ schema } ` } ,
52
62
}
53
63
} else {
54
64
return { data : data [ 0 ] , error }
@@ -57,4 +67,92 @@ export default class PostgresMetaFunctions {
57
67
return { data : null , error : { message : 'Invalid parameters on function retrieve' } }
58
68
}
59
69
}
70
+
71
+ async create ( {
72
+ name,
73
+ schema = 'public' ,
74
+ params,
75
+ definition,
76
+ rettype = 'void' ,
77
+ language = 'sql' ,
78
+ } : {
79
+ name : string
80
+ schema ?: string
81
+ params ?: string [ ]
82
+ definition : string
83
+ rettype ?: string
84
+ language ?: string
85
+ } ) : Promise < PostgresMetaResult < PostgresFunction > > {
86
+ const sql = `
87
+ CREATE FUNCTION ${ ident ( schema ) } .${ ident ( name ) }
88
+ ${ params && params . length ? `(${ params . join ( ',' ) } )` : '()' }
89
+ RETURNS ${ rettype }
90
+ AS ${ literal ( definition ) }
91
+ LANGUAGE ${ language }
92
+ RETURNS NULL ON NULL INPUT;
93
+ `
94
+ const { error } = await this . query ( sql )
95
+ if ( error ) {
96
+ return { data : null , error }
97
+ }
98
+ return await this . retrieve ( { name, schema } )
99
+ }
100
+
101
+ async update (
102
+ id : number ,
103
+ {
104
+ name,
105
+ schema,
106
+ } : {
107
+ name ?: string
108
+ schema ?: string
109
+ }
110
+ ) : Promise < PostgresMetaResult < PostgresFunction > > {
111
+ const { data : old , error : retrieveError } = await this . retrieve ( { id } )
112
+ if ( retrieveError ) {
113
+ return { data : null , error : retrieveError }
114
+ }
115
+
116
+ const updateNameSql =
117
+ name && name !== old ! . name
118
+ ? `ALTER FUNCTION ${ ident ( old ! . schema ) } .${ ident ( old ! . name ) } (${
119
+ old ! . argument_types
120
+ } ) RENAME TO ${ ident ( name ) } ;`
121
+ : ''
122
+
123
+ const updateSchemaSql =
124
+ schema && schema !== old ! . schema
125
+ ? `ALTER FUNCTION ${ ident ( old ! . schema ) } .${ ident ( name || old ! . name ) } (${
126
+ old ! . argument_types
127
+ } ) SET SCHEMA ${ ident ( schema ) } ;`
128
+ : ''
129
+
130
+ const sql = `BEGIN;${ updateNameSql } ${ updateSchemaSql } COMMIT;`
131
+
132
+ const { error } = await this . query ( sql )
133
+ if ( error ) {
134
+ return { data : null , error }
135
+ }
136
+ return await this . retrieve ( { id } )
137
+ }
138
+
139
+ async remove (
140
+ id : number ,
141
+ { cascade = false } = { }
142
+ ) : Promise < PostgresMetaResult < PostgresFunction > > {
143
+ const { data : func , error } = await this . retrieve ( { id } )
144
+ if ( error ) {
145
+ return { data : null , error }
146
+ }
147
+ const sql = `DROP FUNCTION ${ ident ( func ! . schema ) } .${ ident ( func ! . name ) }
148
+ ${ func ! . argument_types ? `(${ func ! . argument_types } )` : '()' }
149
+ ${ cascade ? 'CASCADE' : 'RESTRICT' } ;`
150
+ {
151
+ const { error } = await this . query ( sql )
152
+ if ( error ) {
153
+ return { data : null , error }
154
+ }
155
+ }
156
+ return { data : func ! , error : null }
157
+ }
60
158
}
0 commit comments