Skip to content

Commit f9baaaf

Browse files
authored
fix(policy): run pg/sqlite tests, misc dual db compatibility fixes (#260)
* fix(policy): run pg/sqlite tests, misc dual db compatibility fixes * addressing review comments, cleaning up text search casing * addressing pr comments * try fixing CI * update * fix tests * update
1 parent dcfa6c3 commit f9baaaf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+4094
-4001
lines changed

.github/workflows/build-test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ jobs:
3434
strategy:
3535
matrix:
3636
node-version: [20.x]
37+
provider: [sqlite, postgresql]
3738

3839
steps:
3940
- name: Checkout
@@ -76,4 +77,4 @@ jobs:
7677
run: pnpm run lint
7778

7879
- name: Test
79-
run: pnpm run test
80+
run: TEST_DB_PROVIDER=${{ matrix.provider }} pnpm run test

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"build": "turbo run build",
88
"watch": "turbo run watch build",
99
"lint": "turbo run lint",
10-
"test": "turbo run test",
10+
"test": "vitest run",
1111
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
1212
"pr": "gh pr create --fill-first --base dev",
1313
"merge-main": "gh pr create --title \"merge dev to main\" --body \"\" --base main --head dev",

packages/language/res/stdlib.zmodel

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,10 @@ function future(): Any {
123123
} @@@expressionContext([AccessPolicy])
124124

125125
/**
126-
* If the field value contains the search string. By default, the search is case-sensitive,
127-
* but you can override the behavior with the "caseInSensitive" argument.
126+
* Checks if the field value contains the search string. By default, the search is case-sensitive, and
127+
* "LIKE" operator is used to match. If `caseInSensitive` is true, "ILIKE" operator is used if
128+
* supported, otherwise it still falls back to "LIKE" and delivers whatever the database's
129+
* behavior is.
128130
*/
129131
function contains(field: String, search: String, caseInSensitive: Boolean?): Boolean {
130132
} @@@expressionContext([AccessPolicy, ValidationRule])
@@ -136,15 +138,21 @@ function search(field: String, search: String): Boolean {
136138
} @@@expressionContext([AccessPolicy])
137139

138140
/**
139-
* If the field value starts with the search string
141+
* Checks the field value starts with the search string. By default, the search is case-sensitive, and
142+
* "LIKE" operator is used to match. If `caseInSensitive` is true, "ILIKE" operator is used if
143+
* supported, otherwise it still falls back to "LIKE" and delivers whatever the database's
144+
* behavior is.
140145
*/
141-
function startsWith(field: String, search: String): Boolean {
146+
function startsWith(field: String, search: String, caseInSensitive: Boolean?): Boolean {
142147
} @@@expressionContext([AccessPolicy, ValidationRule])
143148

144149
/**
145-
* If the field value ends with the search string
150+
* Checks if the field value ends with the search string. By default, the search is case-sensitive, and
151+
* "LIKE" operator is used to match. If `caseInSensitive` is true, "ILIKE" operator is used if
152+
* supported, otherwise it still falls back to "LIKE" and delivers whatever the database's
153+
* behavior is.
146154
*/
147-
function endsWith(field: String, search: String): Boolean {
155+
function endsWith(field: String, search: String, caseInSensitive: Boolean?): Boolean {
148156
} @@@expressionContext([AccessPolicy, ValidationRule])
149157

150158
/**

packages/language/test/delegate.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ import { loadSchema, loadSchemaWithError } from './utils';
55
describe('Delegate Tests', () => {
66
it('supports inheriting from delegate', async () => {
77
const model = await loadSchema(`
8+
datasource db {
9+
provider = 'sqlite'
10+
url = 'file:./dev.db'
11+
}
12+
813
model A {
914
id Int @id @default(autoincrement())
1015
x String
@@ -24,6 +29,11 @@ describe('Delegate Tests', () => {
2429
it('rejects inheriting from non-delegate models', async () => {
2530
await loadSchemaWithError(
2631
`
32+
datasource db {
33+
provider = 'sqlite'
34+
url = 'file:./dev.db'
35+
}
36+
2737
model A {
2838
id Int @id @default(autoincrement())
2939
x String
@@ -40,6 +50,11 @@ describe('Delegate Tests', () => {
4050
it('can detect cyclic inherits', async () => {
4151
await loadSchemaWithError(
4252
`
53+
datasource db {
54+
provider = 'sqlite'
55+
url = 'file:./dev.db'
56+
}
57+
4358
model A extends B {
4459
x String
4560
@@delegate(x)
@@ -57,6 +72,11 @@ describe('Delegate Tests', () => {
5772
it('can detect duplicated fields from base model', async () => {
5873
await loadSchemaWithError(
5974
`
75+
datasource db {
76+
provider = 'sqlite'
77+
url = 'file:./dev.db'
78+
}
79+
6080
model A {
6181
id String @id
6282
x String
@@ -74,6 +94,11 @@ describe('Delegate Tests', () => {
7494
it('can detect duplicated attributes from base model', async () => {
7595
await loadSchemaWithError(
7696
`
97+
datasource db {
98+
provider = 'sqlite'
99+
url = 'file:./dev.db'
100+
}
101+
77102
model A {
78103
id String @id
79104
x String

packages/language/test/import.test.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ describe('Import tests', () => {
1212
fs.writeFileSync(
1313
path.join(name, 'a.zmodel'),
1414
`
15+
datasource db {
16+
provider = 'sqlite'
17+
url = 'file:./dev.db'
18+
}
19+
1520
model A {
1621
id Int @id
1722
name String
@@ -48,6 +53,12 @@ enum Role {
4853
path.join(name, 'b.zmodel'),
4954
`
5055
import './a'
56+
57+
datasource db {
58+
provider = 'sqlite'
59+
url = 'file:./dev.db'
60+
}
61+
5162
model User {
5263
id Int @id
5364
role Role
@@ -56,7 +67,7 @@ model User {
5667
);
5768

5869
const model = await expectLoaded(path.join(name, 'b.zmodel'));
59-
expect((model.declarations[0] as DataModel).fields[1].type.reference?.ref?.name).toBe('Role');
70+
expect((model.declarations[1] as DataModel).fields[1].type.reference?.ref?.name).toBe('Role');
6071
});
6172

6273
it('supports cyclic imports', async () => {
@@ -65,6 +76,12 @@ model User {
6576
path.join(name, 'a.zmodel'),
6677
`
6778
import './b'
79+
80+
datasource db {
81+
provider = 'sqlite'
82+
url = 'file:./dev.db'
83+
}
84+
6885
model A {
6986
id Int @id
7087
b B?
@@ -86,7 +103,7 @@ model B {
86103
const modelB = await expectLoaded(path.join(name, 'b.zmodel'));
87104
expect((modelB.declarations[0] as DataModel).fields[1].type.reference?.ref?.name).toBe('A');
88105
const modelA = await expectLoaded(path.join(name, 'a.zmodel'));
89-
expect((modelA.declarations[0] as DataModel).fields[1].type.reference?.ref?.name).toBe('B');
106+
expect((modelA.declarations[1] as DataModel).fields[1].type.reference?.ref?.name).toBe('B');
90107
});
91108

92109
async function expectLoaded(file: string) {

packages/language/test/mixin.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ import { DataModel, TypeDef } from '../src/ast';
55
describe('Mixin Tests', () => {
66
it('supports model mixing types to Model', async () => {
77
const model = await loadSchema(`
8+
datasource db {
9+
provider = 'sqlite'
10+
url = 'file:./dev.db'
11+
}
12+
813
type A {
914
x String
1015
}
@@ -25,6 +30,11 @@ describe('Mixin Tests', () => {
2530

2631
it('supports model mixing types to type', async () => {
2732
const model = await loadSchema(`
33+
datasource db {
34+
provider = 'sqlite'
35+
url = 'file:./dev.db'
36+
}
37+
2838
type A {
2939
x String
3040
}
@@ -52,6 +62,11 @@ describe('Mixin Tests', () => {
5262
it('can detect cyclic mixins', async () => {
5363
await loadSchemaWithError(
5464
`
65+
datasource db {
66+
provider = 'sqlite'
67+
url = 'file:./dev.db'
68+
}
69+
5570
type A with B {
5671
x String
5772
}

packages/runtime/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
"watch": "tsup-node --watch",
99
"lint": "eslint src --ext ts",
1010
"test": "vitest run && pnpm test:typecheck",
11+
"test:sqlite": "TEST_DB_PROVIDER=sqlite vitest run",
12+
"test:postgresql": "TEST_DB_PROVIDER=postgresql vitest run",
1113
"test:generate": "tsx test/scripts/generate.ts",
1214
"test:typecheck": "tsc --project tsconfig.test.json",
1315
"pack": "pnpm pack"

packages/runtime/src/client/client-impl.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export class ClientImpl<Schema extends SchemaDef> {
6161
executor?: QueryExecutor,
6262
) {
6363
this.$schema = schema;
64-
this.$options = options ?? ({} as ClientOptions<Schema>);
64+
this.$options = options;
6565

6666
this.$options.functions = {
6767
...BuiltinFunctions,
@@ -326,7 +326,7 @@ export class ClientImpl<Schema extends SchemaDef> {
326326

327327
function createClientProxy<Schema extends SchemaDef>(client: ClientImpl<Schema>): ClientImpl<Schema> {
328328
const inputValidator = new InputValidator(client.$schema);
329-
const resultProcessor = new ResultProcessor(client.$schema);
329+
const resultProcessor = new ResultProcessor(client.$schema, client.$options);
330330

331331
return new Proxy(client, {
332332
get: (target, prop, receiver) => {

packages/runtime/src/client/crud/dialects/base-dialect.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ export abstract class BaseCrudDialect<Schema extends SchemaDef> {
4545
return value;
4646
}
4747

48+
transformOutput(value: unknown, _type: BuiltinType) {
49+
return value;
50+
}
51+
4852
// #region common query builders
4953

5054
buildSelectModel(eb: ExpressionBuilder<any, any>, model: string, modelAlias: string) {
@@ -1255,5 +1259,15 @@ export abstract class BaseCrudDialect<Schema extends SchemaDef> {
12551259
*/
12561260
abstract get supportInsertWithDefault(): boolean;
12571261

1262+
/**
1263+
* Gets the SQL column type for the given field definition.
1264+
*/
1265+
abstract getFieldSqlType(fieldDef: FieldDef): string;
1266+
1267+
/*
1268+
* Gets the string casing behavior for the dialect.
1269+
*/
1270+
abstract getStringCasingBehavior(): { supportsILike: boolean; likeCaseSensitive: boolean };
1271+
12581272
// #endregion
12591273
}

0 commit comments

Comments
 (0)