Skip to content

Commit 382ad8c

Browse files
authored
Type check constraints (#10)
* basic impl for typing check constraints where possible * move to dedicated dump table for all of the type tests * add more test cases and do an actual ast pattern match to decide whether the check constraint is too complex or not * changelog, restructure tests, and remove dependency on ReScript Core * lints and snapshots * ci * ci
1 parent e8d9c64 commit 382ad8c

29 files changed

+1136
-410
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# main
22

3+
- Add automatic parsing of PostgreSQL check constraints to generate ReScript polyvariant types for enumeration-style constraints. Supports both `column IN (value1, value2, ...)` and `column = ANY (ARRAY[value1, value2, ...])` patterns with string and integer values.
4+
- Remove dependency on `@rescript/core` since it's not really used.
5+
36
# 2.6.0
47

58
- Improve `pg` bindings.

RESCRIPT.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,69 @@ In order for this mode to work, you need one more thing - configure the `rescrip
107107

108108
With that, you should be able to write queries directly in your ReScript source, and with the `watch` mode enabled have a seamless experience with types autogenerated and wired up for you.
109109

110+
## Check Constraint Support
111+
112+
`pgtyped-rescript` automatically analyzes PostgreSQL check constraints and generates ReScript polyvariant types for enumeration-style constraints. This provides compile-time safety for constrained database fields.
113+
114+
### Supported Constraint Patterns
115+
116+
The following constraint patterns are automatically detected and converted to polyvariant types:
117+
118+
```sql
119+
-- Pattern 1: IN clause
120+
status TEXT CHECK (status IN ('published', 'draft', 'archived')),
121+
122+
-- Pattern 2: ANY with ARRAY
123+
format TEXT CHECK (format = ANY (ARRAY['hardcover'::text, 'paperback'::text, 'ebook'::text])),
124+
125+
-- Both string and integer values are supported
126+
priority INTEGER CHECK (priority IN (1, 2, 3, 4, 5))
127+
```
128+
129+
### Generated Types
130+
131+
For a table with these constraints:
132+
133+
```sql
134+
CREATE TABLE books (
135+
id SERIAL PRIMARY KEY,
136+
status TEXT CHECK (status IN ('published', 'draft', 'archived')),
137+
priority INTEGER CHECK (priority IN (1, 2, 3, 4, 5))
138+
);
139+
```
140+
141+
The generated ReScript types will include:
142+
143+
```rescript
144+
type result = {
145+
id: int,
146+
status: option<[#"published" | #"draft" | #"archived"]>,
147+
priority: option<[#1 | #2 | #3 | #4 | #5]>,
148+
}
149+
```
150+
151+
### Limitations
152+
153+
- **Float constraints**: Not supported since ReScript polyvariants cannot represent float literals
154+
- **Complex constraints**: Only simple enumeration patterns are supported (no `BETWEEN`, `OR` logic, function calls, etc.)
155+
- **Mixed types**: Constraints mixing different data types in the same clause are not supported
156+
157+
### Example
158+
159+
```sql
160+
/* @name getBooksByStatus */
161+
SELECT * FROM books WHERE status = :status;
162+
```
163+
164+
```rescript
165+
// The generated function will accept a polyvariant for status
166+
let books = await client->GetBooksByStatus.many({
167+
status: #published // Compile-time checked against the database constraint!
168+
})
169+
```
170+
171+
This feature works seamlessly with both separate SQL files and SQL-in-ReScript modes.
172+
110173
## API
111174

112175
### `PgTyped`

package-lock.json

Lines changed: 128 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/cli/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
"@pgtyped/parser": "^2.1.0",
4040
"@pgtyped/wire": "^2.2.0",
4141
"@rescript/tools": "0.6.4",
42-
"@rescript/core": "1.6.0",
4342
"camel-case": "^4.1.1",
4443
"chalk": "^4.0.0",
4544
"chokidar": "^3.3.1",
@@ -66,7 +65,6 @@
6665
"rescript": "11.1.0"
6766
},
6867
"peerDependencies": {
69-
"@rescript/core": ">= 1.3.0",
7068
"rescript": ">= 11.1.0"
7169
}
7270
}

packages/cli/rescript.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,5 @@
77
"module": "commonjs",
88
"in-source": true
99
},
10-
"suffix": ".js",
11-
"bs-dependencies": ["@rescript/core"],
12-
"bsc-flags": ["-open RescriptCore"]
10+
"suffix": ".js"
1311
}

0 commit comments

Comments
 (0)