@@ -9,66 +9,58 @@ const pgArrayAggToArray = (agg: string) => agg.replace(/{/g, '').replace(/}/g, '
99
1010const getColumnType = ( dbType : string ) : PropertyType => {
1111 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' ;
5861 }
5962} ;
6063
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-
7264export class PostgresParser extends BaseDatabaseParser {
7365 public static dialects = [ 'postgresql' as const ] ;
7466
@@ -96,10 +88,10 @@ export class PostgresParser extends BaseDatabaseParser {
9688
9789 public async getTables ( schemaName : string ) {
9890 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 } '
10395 ` ) ;
10496
10597 const result = await query ;
@@ -177,7 +169,7 @@ export class PostgresParser extends BaseDatabaseParser {
177169
178170 const relations = await relQuery ;
179171
180- return columns . map ( ( col ) => {
172+ return Promise . all ( columns . map ( async ( col ) => {
181173 const rel = relations . rows . find ( ( r ) => {
182174 const cols = pgArrayAggToArray ( r . col ) ;
183175 if ( cols . length > 1 ) return null ; // AdminJS doesn't support multiple foreign keys
@@ -189,7 +181,35 @@ export class PostgresParser extends BaseDatabaseParser {
189181 col . referenced_table = rel . referenced_table ;
190182 }
191183
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 )
194214 }
195215}
0 commit comments