Skip to content

Commit beae0a4

Browse files
committed
Fix: Add getAvailableValues to Postgres parser;
1 parent b82a013 commit beae0a4

File tree

1 file changed

+84
-64
lines changed

1 file changed

+84
-64
lines changed

src/dialects/postgres.parser.ts

+84-64
Original file line numberDiff line numberDiff line change
@@ -9,66 +9,58 @@ const pgArrayAggToArray = (agg: string) => agg.replace(/{/g, '').replace(/}/g, '
99

1010
const 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-
7264
export 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

Comments
 (0)