@@ -9,66 +9,58 @@ const pgArrayAggToArray = (agg: string) => agg.replace(/{/g, '').replace(/}/g, '
9
9
10
10
const getColumnType = ( dbType : string ) : PropertyType => {
11
11
switch ( dbType ) {
12
- case 'uuid' : return 'uuid' ;
13
- case 'bigint' :
14
- case 'int8' :
15
- case 'bigserial' :
16
- case 'serial8' :
17
- case 'integer' :
18
- case 'int' :
19
- case 'int4' :
20
- case 'smallint' :
21
- case 'int2' :
22
- case 'serial' :
23
- case 'serial4' :
24
- case 'smallserial' :
25
- case 'serial2' :
26
- return 'number' ;
27
- case 'double precision' :
28
- case 'float8' :
29
- case 'numeric' :
30
- case 'decimal' :
31
- case 'real' :
32
- case 'float4' :
33
- return 'float' ;
34
- case 'money' :
35
- return 'currency' ;
36
- case 'boolean' :
37
- return 'boolean' ;
38
- case 'time' :
39
- case 'time with time zone' :
40
- case 'timetz' :
41
- case 'time without time zone' :
42
- case 'timestamp' :
43
- case 'timestamp with time zone' :
44
- case 'timestamptz' :
45
- case 'timestamp without time zone' :
46
- return 'datetime' ;
47
- case 'date' :
48
- return 'date' ;
49
- case 'json' :
50
- case 'jsonb' :
51
- return 'key-value' ;
52
- case 'text' :
53
- case 'character varying' :
54
- case 'char' :
55
- case 'varchar' :
56
- default :
57
- return 'string' ;
12
+ case 'USER-DEFINED' :
13
+ return 'mixed' ;
14
+ case 'uuid' :
15
+ return 'uuid' ;
16
+ case 'bigint' :
17
+ case 'int8' :
18
+ case 'bigserial' :
19
+ case 'serial8' :
20
+ case 'integer' :
21
+ case 'int' :
22
+ case 'int4' :
23
+ case 'smallint' :
24
+ case 'int2' :
25
+ case 'serial' :
26
+ case 'serial4' :
27
+ case 'smallserial' :
28
+ case 'serial2' :
29
+ return 'number' ;
30
+ case 'double precision' :
31
+ case 'float8' :
32
+ case 'numeric' :
33
+ case 'decimal' :
34
+ case 'real' :
35
+ case 'float4' :
36
+ return 'float' ;
37
+ case 'money' :
38
+ return 'currency' ;
39
+ case 'boolean' :
40
+ return 'boolean' ;
41
+ case 'time' :
42
+ case 'time with time zone' :
43
+ case 'timetz' :
44
+ case 'time without time zone' :
45
+ case 'timestamp' :
46
+ case 'timestamp with time zone' :
47
+ case 'timestamptz' :
48
+ case 'timestamp without time zone' :
49
+ return 'datetime' ;
50
+ case 'date' :
51
+ return 'date' ;
52
+ case 'json' :
53
+ case 'jsonb' :
54
+ return 'key-value' ;
55
+ case 'text' :
56
+ case 'character varying' :
57
+ case 'char' :
58
+ case 'varchar' :
59
+ default :
60
+ return 'string' ;
58
61
}
59
62
} ;
60
63
61
- const getColumnInfo = ( column : Record < string , number | string > ) : ColumnInfo => ( {
62
- name : column . column_name as string ,
63
- isId : column . key_type === 'PRIMARY KEY' ,
64
- position : column . ordinal_position as number ,
65
- defaultValue : column . column_default ,
66
- isNullable : column . is_nullable === 'YES' ,
67
- isEditable : column . is_updatable === 'YES' ,
68
- type : column . referenced_table ? 'reference' : getColumnType ( column . data_type as string ) ,
69
- referencedTable : ( column . referenced_table ?? null ) as string | null ,
70
- } ) ;
71
-
72
64
export class PostgresParser extends BaseDatabaseParser {
73
65
public static dialects = [ 'postgresql' as const ] ;
74
66
@@ -96,10 +88,10 @@ export class PostgresParser extends BaseDatabaseParser {
96
88
97
89
public async getTables ( schemaName : string ) {
98
90
const query = await this . knex . raw ( `
99
- SELECT table_name
100
- FROM information_schema.tables
101
- WHERE table_type='BASE TABLE'
102
- AND table_schema='${ schemaName } '
91
+ SELECT table_name
92
+ FROM information_schema.tables
93
+ WHERE table_type='BASE TABLE'
94
+ AND table_schema='${ schemaName } '
103
95
` ) ;
104
96
105
97
const result = await query ;
@@ -177,7 +169,7 @@ export class PostgresParser extends BaseDatabaseParser {
177
169
178
170
const relations = await relQuery ;
179
171
180
- return columns . map ( ( col ) => {
172
+ return Promise . all ( columns . map ( async ( col ) => {
181
173
const rel = relations . rows . find ( ( r ) => {
182
174
const cols = pgArrayAggToArray ( r . col ) ;
183
175
if ( cols . length > 1 ) return null ; // AdminJS doesn't support multiple foreign keys
@@ -189,7 +181,35 @@ export class PostgresParser extends BaseDatabaseParser {
189
181
col . referenced_table = rel . referenced_table ;
190
182
}
191
183
192
- return new Property ( getColumnInfo ( col ) ) ;
193
- } ) ;
184
+ return new Property ( await this . getColumnInfo ( col ) ) ;
185
+ } ) ) ;
186
+ }
187
+
188
+
189
+ async getColumnInfo ( column : Record < string , number | string > ) : Promise < ColumnInfo > {
190
+ return {
191
+ name : column . column_name as string ,
192
+ isId : column . key_type === 'PRIMARY KEY' ,
193
+ position : column . ordinal_position as number ,
194
+ defaultValue : column . column_default ,
195
+ isNullable : column . is_nullable === 'YES' ,
196
+ isEditable : column . is_updatable === 'YES' ,
197
+ type : column . referenced_table ? ( 'reference' as PropertyType ) : getColumnType ( column . data_type as string ) ,
198
+ referencedTable : ( column . referenced_table ?? null ) as string | null ,
199
+ availableValues : await this . getAvailableValues ( column ) ,
200
+ }
201
+ }
202
+
203
+ async getAvailableValues ( column : Record < string , number | string > ) : Promise < string [ ] | null > {
204
+ if ( column . data_type !== 'USER-DEFINED' || ! column . udt_name ) {
205
+ return null ;
206
+ }
207
+ const query = this . knex
208
+ . from ( 'pg_catalog.pg_enum as e' )
209
+ . select ( 'e.enumlabel' )
210
+ . leftJoin ( 'pg_catalog.pg_type as t' , ( c ) => c . on ( 'e.enumtypid' , 't.oid' ) )
211
+ . where ( 't.typname' , column . udt_name ) ;
212
+ const labels = await query ;
213
+ return labels . map ( ( l ) => l . enumlabel as string )
194
214
}
195
215
}
0 commit comments