Skip to content

Commit 08006cf

Browse files
committed
feat: Handle the database type mapping
1 parent f6f78e0 commit 08006cf

File tree

4 files changed

+68
-5
lines changed

4 files changed

+68
-5
lines changed

packages/cli/src/actions/pull/index.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
import type { ZModelServices } from '@zenstackhq/language';
2-
import { Attribute, isEnum, type DataField, type DataModel, type Enum, type Model } from '@zenstackhq/language/ast';
2+
import {
3+
Attribute,
4+
isEnum,
5+
type DataField,
6+
type DataModel,
7+
type Enum,
8+
type Model,
9+
type BuiltinType,
10+
} from '@zenstackhq/language/ast';
311
import {
412
DataFieldAttributeFactory,
513
DataFieldFactory,
@@ -260,9 +268,16 @@ export function syncTable({
260268
const dbAttr = services.shared.workspace.IndexManager.allElements('Attribute').find(
261269
(d) => d.name.toLowerCase() === `@db.${column.datatype.toLowerCase()}`,
262270
)?.node as Attribute | undefined;
263-
//TODO: exclude default types like text in postgres
264-
//because Zenstack string = text in postgres so unnecessary to map to default types
265-
if (dbAttr && !['text'].includes(column.datatype)) {
271+
272+
const defaultDatabaseType = provider.getDefaultDatabaseType(builtinType.type as BuiltinType);
273+
274+
if (
275+
dbAttr &&
276+
defaultDatabaseType &&
277+
(defaultDatabaseType.type !== column.datatype ||
278+
(defaultDatabaseType.precisition &&
279+
defaultDatabaseType.precisition !== (column.length || column.precision)))
280+
) {
266281
const dbAttrFactory = new DataFieldAttributeFactory().setDecl(dbAttr);
267282
if (column.length || column.precision)
268283
dbAttrFactory.addArg((a) => a.NumberLiteral.setValue(column.length! || column.precision!));

packages/cli/src/actions/pull/provider/postgresql.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { DataFieldAttributeFactory } from '@zenstackhq/language/factory';
22
import { Client } from 'pg';
33
import { getAttributeRef, getDbName, getFunctionRef } from '../utils';
44
import type { IntrospectedEnum, IntrospectedSchema, IntrospectedTable, IntrospectionProvider } from './provider';
5+
import type { BuiltinType } from '@zenstackhq/language/ast';
56

67
export const postgresql: IntrospectionProvider = {
78
getBuiltinType(type) {
@@ -78,6 +79,28 @@ export const postgresql: IntrospectionProvider = {
7879
tables,
7980
};
8081
},
82+
getDefaultDatabaseType(type: BuiltinType) {
83+
switch (type) {
84+
case 'String':
85+
return { type: 'text' };
86+
case 'Boolean':
87+
return { type: 'boolean' };
88+
case 'Int':
89+
return { type: 'integer' };
90+
case 'BigInt':
91+
return { type: 'bigint' };
92+
case 'Float':
93+
return { type: 'double precision' };
94+
case 'Decimal':
95+
return { type: 'decimal' };
96+
case 'DateTime':
97+
return { type: 'timestamp', precisition: 3 };
98+
case 'Json':
99+
return { type: 'jsonb' };
100+
case 'Bytes':
101+
return { type: 'bytea' };
102+
}
103+
},
81104
getDefaultValue({ defaultValue, fieldName, services, enums }) {
82105
const val = defaultValue.trim();
83106
const factories: DataFieldAttributeFactory[] = [];
@@ -276,7 +299,7 @@ SELECT
276299
),
277300
'[]'
278301
) AS "options"
279-
302+
280303
FROM "pg_catalog"."pg_attribute" AS "att"
281304
282305
INNER JOIN "pg_catalog"."pg_type" AS "typ" ON "typ"."oid" = "att"."atttypid"

packages/cli/src/actions/pull/provider/provider.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export interface IntrospectionProvider {
6464
type: BuiltinType | 'Unsupported';
6565
isArray: boolean;
6666
};
67+
getDefaultDatabaseType(type: BuiltinType): { precisition?: number; type: string } | undefined;
6768
getDefaultValue(args: {
6869
fieldName: string;
6970
defaultValue: string;

packages/cli/src/actions/pull/provider/sqlite.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { BuiltinType } from '@zenstackhq/language/ast';
12
import type { IntrospectedEnum, IntrospectedSchema, IntrospectedTable, IntrospectionProvider } from './provider';
23

34
// Note: We dynamically import better-sqlite3 inside the async function to avoid
@@ -71,6 +72,29 @@ export const sqlite: IntrospectionProvider = {
7172
}
7273
},
7374

75+
getDefaultDatabaseType(type: BuiltinType) {
76+
switch (type) {
77+
case 'String':
78+
return { type: 'TEXT' };
79+
case 'Boolean':
80+
return { type: 'INTEGER' };
81+
case 'Int':
82+
return { type: 'INTEGER' };
83+
case 'BigInt':
84+
return { type: 'INTEGER' };
85+
case 'Float':
86+
return { type: 'REAL' };
87+
case 'Decimal':
88+
return { type: 'DECIMAL' };
89+
case 'DateTime':
90+
return { type: 'NUMERIC' };
91+
case 'Json':
92+
return { type: 'JSONB' };
93+
case 'Bytes':
94+
return { type: 'BLOB' };
95+
}
96+
},
97+
7498
async introspect(connectionString: string): Promise<IntrospectedSchema> {
7599
const SQLite = (await import('better-sqlite3')).default;
76100
const db = new SQLite(connectionString, { readonly: true });

0 commit comments

Comments
 (0)