effect-qb 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/index.js +1990 -679
- package/dist/mysql.js +1490 -617
- package/dist/postgres/metadata.js +1334 -263
- package/dist/postgres.js +3376 -2307
- package/dist/sqlite.js +1573 -628
- package/dist/standard.js +1984 -673
- package/package.json +2 -4
- package/src/internal/coercion/rules.ts +13 -1
- package/src/internal/column-state.d.ts +3 -3
- package/src/internal/column-state.ts +13 -12
- package/src/internal/column.ts +8 -8
- package/src/internal/datatypes/define.ts +5 -0
- package/src/internal/datatypes/lookup.ts +67 -18
- package/src/internal/datatypes/matrix.ts +903 -0
- package/src/internal/datatypes/shape.ts +2 -0
- package/src/internal/dialect-renderers/mysql.ts +6 -4
- package/src/internal/dialect-renderers/postgres.ts +6 -4
- package/src/internal/dialect-renderers/sqlite.ts +6 -4
- package/src/internal/dialect.ts +1 -1
- package/src/internal/executor.ts +56 -43
- package/src/internal/json/path-access.ts +351 -0
- package/src/internal/query.d.ts +1 -1
- package/src/internal/query.ts +1 -1
- package/src/internal/runtime/driver-value-mapping.ts +3 -3
- package/src/internal/runtime/schema.ts +28 -38
- package/src/internal/runtime/value.ts +20 -23
- package/src/internal/scalar.d.ts +1 -1
- package/src/internal/scalar.ts +2 -1
- package/src/internal/schema-derivation.d.ts +7 -7
- package/src/internal/schema-derivation.ts +11 -11
- package/src/internal/standard-dsl.ts +121 -28
- package/src/internal/table.ts +451 -120
- package/src/mysql/column.ts +6 -6
- package/src/mysql/datatypes/index.ts +1 -0
- package/src/mysql/datatypes/spec.ts +6 -176
- package/src/mysql/errors/normalize.ts +0 -1
- package/src/mysql/executor.ts +4 -6
- package/src/mysql/function/temporal.ts +1 -1
- package/src/mysql/internal/dsl.ts +116 -16
- package/src/mysql/json.ts +1 -33
- package/src/mysql/renderer.ts +13 -6
- package/src/mysql/type.ts +60 -0
- package/src/mysql.ts +3 -1
- package/src/postgres/check.ts +1 -0
- package/src/postgres/column.ts +11 -11
- package/src/postgres/datatypes/index.ts +1 -0
- package/src/postgres/datatypes/spec.ts +6 -260
- package/src/postgres/errors/normalize.ts +0 -1
- package/src/postgres/executor.ts +4 -6
- package/src/postgres/foreign-key.ts +24 -0
- package/src/postgres/function/temporal.ts +1 -1
- package/src/postgres/index.ts +1 -0
- package/src/postgres/internal/dsl.ts +122 -21
- package/src/postgres/json-extension.ts +7 -0
- package/src/postgres/json.ts +726 -173
- package/src/postgres/jsonb.ts +0 -1
- package/src/postgres/primary-key.ts +24 -0
- package/src/postgres/renderer.ts +13 -6
- package/src/postgres/schema-management.ts +1 -6
- package/src/postgres/schema.ts +16 -8
- package/src/postgres/table.ts +111 -113
- package/src/postgres/type.ts +86 -4
- package/src/postgres/unique.ts +32 -0
- package/src/postgres.ts +12 -6
- package/src/sqlite/column.ts +6 -6
- package/src/sqlite/datatypes/index.ts +1 -0
- package/src/sqlite/datatypes/spec.ts +6 -94
- package/src/sqlite/errors/normalize.ts +0 -1
- package/src/sqlite/executor.ts +4 -6
- package/src/sqlite/function/temporal.ts +1 -1
- package/src/sqlite/internal/dsl.ts +100 -5
- package/src/sqlite/json.ts +1 -32
- package/src/sqlite/renderer.ts +13 -6
- package/src/sqlite/type.ts +40 -0
- package/src/sqlite.ts +3 -1
- package/src/standard/cast.ts +113 -0
- package/src/standard/check.ts +17 -0
- package/src/standard/column.ts +10 -10
- package/src/standard/datatypes/index.ts +2 -2
- package/src/standard/datatypes/spec.ts +10 -96
- package/src/standard/foreign-key.ts +37 -0
- package/src/standard/function/temporal.ts +1 -1
- package/src/standard/index.ts +17 -0
- package/src/standard/json.ts +883 -0
- package/src/standard/primary-key.ts +17 -0
- package/src/standard/renderer.ts +31 -3
- package/src/standard/table.ts +25 -21
- package/src/standard/unique.ts +17 -0
- package/src/standard.ts +14 -0
- package/src/internal/table.d.ts +0 -174
- package/src/postgres/cast.ts +0 -45
package/src/sqlite/column.ts
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import { sqliteDatatypes } from "./datatypes/index.js"
|
|
19
19
|
|
|
20
20
|
const primitive = <Type, Db extends Expression.DbType.Any>(
|
|
21
|
-
schema: Schema.Schema<Type
|
|
21
|
+
schema: Schema.Schema<Type>,
|
|
22
22
|
dbType: Db
|
|
23
23
|
): ColumnDefinition<Type, Type, Type, Db, false, false, false, false, false, undefined> =>
|
|
24
24
|
makeColumnDefinition(schema as Schema.Schema<NonNullable<Type>>, {
|
|
@@ -43,11 +43,11 @@ const renderNumericDdlType = (
|
|
|
43
43
|
: `${kind}(${options.precision},${options.scale})`
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
export const custom = <SchemaType extends Schema.
|
|
46
|
+
export const custom = <SchemaType extends Schema.Top, Db extends Expression.DbType.Any>(
|
|
47
47
|
schema: SchemaType,
|
|
48
48
|
dbType: Db
|
|
49
49
|
) =>
|
|
50
|
-
makeColumnDefinition(schema as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType
|
|
50
|
+
makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>>, {
|
|
51
51
|
dbType: enrichDbType(sqliteDatatypes, dbType),
|
|
52
52
|
nullable: false,
|
|
53
53
|
hasDefault: false,
|
|
@@ -59,7 +59,7 @@ export const custom = <SchemaType extends Schema.Schema.Any, Db extends Expressi
|
|
|
59
59
|
identity: undefined
|
|
60
60
|
})
|
|
61
61
|
|
|
62
|
-
export const uuid = () => primitive(Schema.
|
|
62
|
+
export const uuid = () => primitive(Schema.String.check(Schema.isUUID()), sqliteDatatypes.uuid())
|
|
63
63
|
export const text = () => primitive(Schema.String, sqliteDatatypes.text())
|
|
64
64
|
export const int = () => primitive(Schema.Int, sqliteDatatypes.int())
|
|
65
65
|
export const number = (options?: BaseColumn.NumericOptions) =>
|
|
@@ -79,8 +79,8 @@ export const date = () => primitive(LocalDateStringSchema, sqliteDatatypes.date(
|
|
|
79
79
|
export const time = () => primitive(LocalTimeStringSchema, sqliteDatatypes.time())
|
|
80
80
|
export const datetime = () => primitive(LocalDateTimeStringSchema, sqliteDatatypes.datetime())
|
|
81
81
|
export const timestamp = () => primitive(LocalDateTimeStringSchema, sqliteDatatypes.timestamp())
|
|
82
|
-
export const json = <SchemaType extends Schema.
|
|
83
|
-
makeColumnDefinition(schema as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType
|
|
82
|
+
export const json = <SchemaType extends Schema.Top>(schema: SchemaType) =>
|
|
83
|
+
makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>>, {
|
|
84
84
|
dbType: { ...sqliteDatatypes.json(), variant: "json" } as Expression.DbType.Json<"sqlite", "json">,
|
|
85
85
|
nullable: false,
|
|
86
86
|
hasDefault: false,
|
|
@@ -15,6 +15,7 @@ const withMetadata = <Kind extends keyof typeof sqliteDatatypeKinds & string>(
|
|
|
15
15
|
runtime: kindSpec.runtime,
|
|
16
16
|
compareGroup: familySpec?.compareGroup,
|
|
17
17
|
castTargets: familySpec?.castTargets,
|
|
18
|
+
implicitTargets: (familySpec as { readonly implicitTargets?: readonly string[] }).implicitTargets,
|
|
18
19
|
traits: familySpec?.traits
|
|
19
20
|
}
|
|
20
21
|
}
|
|
@@ -1,98 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
sqliteDatatypeFamilies as matrixSqliteDatatypeFamilies,
|
|
3
|
+
sqliteDatatypeKinds as matrixSqliteDatatypeKinds
|
|
4
|
+
} from "../../internal/datatypes/matrix.js"
|
|
2
5
|
|
|
3
|
-
export const sqliteDatatypeFamilies =
|
|
4
|
-
|
|
5
|
-
compareGroup: "text",
|
|
6
|
-
castTargets: ["text", "numeric", "integer", "real", "boolean", "date", "time", "datetime", "json", "blob", "null"],
|
|
7
|
-
traits: {
|
|
8
|
-
textual: true,
|
|
9
|
-
ordered: true
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
numeric: {
|
|
13
|
-
compareGroup: "numeric",
|
|
14
|
-
castTargets: ["numeric", "integer", "real", "text", "boolean", "date", "time", "datetime"],
|
|
15
|
-
traits: {
|
|
16
|
-
ordered: true
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
integer: {
|
|
20
|
-
compareGroup: "numeric",
|
|
21
|
-
castTargets: ["integer", "numeric", "real", "text", "boolean", "date", "time", "datetime"],
|
|
22
|
-
traits: {
|
|
23
|
-
ordered: true
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
real: {
|
|
27
|
-
compareGroup: "numeric",
|
|
28
|
-
castTargets: ["real", "numeric", "integer", "text", "boolean"],
|
|
29
|
-
traits: {
|
|
30
|
-
ordered: true
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
boolean: {
|
|
34
|
-
compareGroup: "boolean",
|
|
35
|
-
castTargets: ["boolean", "integer", "numeric", "text"],
|
|
36
|
-
traits: {}
|
|
37
|
-
},
|
|
38
|
-
date: {
|
|
39
|
-
compareGroup: "date",
|
|
40
|
-
castTargets: ["date", "time", "datetime", "text", "numeric", "integer"],
|
|
41
|
-
traits: {
|
|
42
|
-
ordered: true
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
time: {
|
|
46
|
-
compareGroup: "time",
|
|
47
|
-
castTargets: ["time", "date", "datetime", "text", "numeric", "integer"],
|
|
48
|
-
traits: {
|
|
49
|
-
ordered: true
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
datetime: {
|
|
53
|
-
compareGroup: "datetime",
|
|
54
|
-
castTargets: ["datetime", "date", "time", "text", "numeric", "integer"],
|
|
55
|
-
traits: {
|
|
56
|
-
ordered: true
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
json: {
|
|
60
|
-
compareGroup: "json",
|
|
61
|
-
castTargets: ["json", "text"],
|
|
62
|
-
traits: {}
|
|
63
|
-
},
|
|
64
|
-
blob: {
|
|
65
|
-
compareGroup: "blob",
|
|
66
|
-
castTargets: ["blob", "text"],
|
|
67
|
-
traits: {}
|
|
68
|
-
},
|
|
69
|
-
null: {
|
|
70
|
-
compareGroup: "null",
|
|
71
|
-
castTargets: ["text", "numeric", "integer", "real", "boolean", "date", "time", "datetime", "json", "blob", "null"],
|
|
72
|
-
traits: {}
|
|
73
|
-
}
|
|
74
|
-
} as const satisfies Record<string, DatatypeFamilySpec>
|
|
75
|
-
|
|
76
|
-
export const sqliteDatatypeKinds = {
|
|
77
|
-
text: { family: "text", runtime: "string" },
|
|
78
|
-
varchar: { family: "text", runtime: "string" },
|
|
79
|
-
char: { family: "text", runtime: "string" },
|
|
80
|
-
clob: { family: "text", runtime: "string" },
|
|
81
|
-
int: { family: "integer", runtime: "number" },
|
|
82
|
-
integer: { family: "integer", runtime: "number" },
|
|
83
|
-
bigint: { family: "integer", runtime: "bigintString" },
|
|
84
|
-
numeric: { family: "numeric", runtime: "decimalString" },
|
|
85
|
-
decimal: { family: "numeric", runtime: "decimalString" },
|
|
86
|
-
real: { family: "real", runtime: "number" },
|
|
87
|
-
double: { family: "real", runtime: "number" },
|
|
88
|
-
boolean: { family: "boolean", runtime: "boolean" },
|
|
89
|
-
date: { family: "date", runtime: "localDate" },
|
|
90
|
-
time: { family: "time", runtime: "localTime" },
|
|
91
|
-
datetime: { family: "datetime", runtime: "localDateTime" },
|
|
92
|
-
timestamp: { family: "datetime", runtime: "localDateTime" },
|
|
93
|
-
json: { family: "json", runtime: "json" },
|
|
94
|
-
blob: { family: "blob", runtime: "bytes" }
|
|
95
|
-
} as const satisfies Record<string, DatatypeKindSpec>
|
|
6
|
+
export const sqliteDatatypeFamilies = matrixSqliteDatatypeFamilies
|
|
7
|
+
export const sqliteDatatypeKinds = matrixSqliteDatatypeKinds
|
|
96
8
|
|
|
97
9
|
export type SqliteDatatypeFamily = keyof typeof sqliteDatatypeFamilies
|
|
98
10
|
export type SqliteDatatypeKind = keyof typeof sqliteDatatypeKinds
|
package/src/sqlite/executor.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Effect from "effect/Effect"
|
|
2
|
-
import * as SqlClient from "
|
|
2
|
+
import * as SqlClient from "effect/unstable/sql/SqlClient"
|
|
3
3
|
import * as Stream from "effect/Stream"
|
|
4
4
|
|
|
5
5
|
import * as CoreExecutor from "../internal/executor.js"
|
|
@@ -41,8 +41,6 @@ export type SqliteQueryError<PlanValue extends CoreQuery.QueryPlan<any, any, any
|
|
|
41
41
|
|
|
42
42
|
/** Runs an effect within the ambient SQLite SQL transaction service. */
|
|
43
43
|
export const withTransaction = CoreExecutor.withTransaction
|
|
44
|
-
/** Runs an effect in a nested SQLite SQL transaction scope. */
|
|
45
|
-
export const withSavepoint = CoreExecutor.withSavepoint
|
|
46
44
|
|
|
47
45
|
/** SQLite executor whose error channel narrows based on the query plan. */
|
|
48
46
|
export interface QueryExecutor<Context = never> {
|
|
@@ -142,10 +140,10 @@ const fromDriver = <
|
|
|
142
140
|
stream(plan) {
|
|
143
141
|
const rendered = renderer.render(plan)
|
|
144
142
|
return Stream.mapError(
|
|
145
|
-
Stream.
|
|
143
|
+
Stream.mapArrayEffect(
|
|
146
144
|
sqlDriver.stream(rendered),
|
|
147
145
|
(rows) => Effect.try({
|
|
148
|
-
try: () => CoreExecutor.
|
|
146
|
+
try: () => CoreExecutor.decodeRows(rendered, plan, rows, { driverMode, valueMappings }) as never,
|
|
149
147
|
catch: (error) => error as RowDecodeError
|
|
150
148
|
})
|
|
151
149
|
),
|
|
@@ -181,7 +179,7 @@ const sqlClientDriver = (): Driver<any, SqlClient.SqlClient> =>
|
|
|
181
179
|
* Creates the standard SQLite executor pipeline.
|
|
182
180
|
*
|
|
183
181
|
* By default this uses the built-in SQLite renderer plus the ambient
|
|
184
|
-
*
|
|
182
|
+
* `effect/unstable/sql` `SqlClient`. Advanced callers can override the renderer,
|
|
185
183
|
* driver, or both.
|
|
186
184
|
*/
|
|
187
185
|
export function make(): QueryExecutor<SqlClient.SqlClient>
|
|
@@ -35,7 +35,7 @@ const makeTemporal = <
|
|
|
35
35
|
>(
|
|
36
36
|
name: Name,
|
|
37
37
|
dbType: Db,
|
|
38
|
-
runtimeSchema: Schema.Schema<Runtime
|
|
38
|
+
runtimeSchema: Schema.Schema<Runtime>
|
|
39
39
|
): TemporalExpression<Runtime, Db, Name> =>
|
|
40
40
|
makeExpression({
|
|
41
41
|
runtime: undefined as unknown as Runtime,
|
|
@@ -1590,11 +1590,14 @@ const profile: QueryDialectProfile<Dialect, TextDb, NumericDb, BoolDb, Timestamp
|
|
|
1590
1590
|
|
|
1591
1591
|
const literalSchemaOf = <Value extends LiteralValue>(
|
|
1592
1592
|
value: Value
|
|
1593
|
-
): Schema.
|
|
1593
|
+
): Schema.Top | undefined => {
|
|
1594
1594
|
if (value === null || value instanceof Date) {
|
|
1595
1595
|
return undefined
|
|
1596
1596
|
}
|
|
1597
|
-
|
|
1597
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
1598
|
+
return undefined
|
|
1599
|
+
}
|
|
1600
|
+
return Schema.Literal(value) as unknown as Schema.Top
|
|
1598
1601
|
}
|
|
1599
1602
|
|
|
1600
1603
|
const literal = <const Value extends LiteralValue>(
|
|
@@ -4521,6 +4524,83 @@ type ValidateTargetColumnInput<
|
|
|
4521
4524
|
Columns extends DdlColumnInput
|
|
4522
4525
|
> = ValidateTargetColumns<Target, NormalizeDdlColumns<Columns>> extends never ? never : Columns
|
|
4523
4526
|
|
|
4527
|
+
type SameColumnSet<
|
|
4528
|
+
Left extends readonly string[],
|
|
4529
|
+
Right extends readonly string[]
|
|
4530
|
+
> = string extends Left[number] | Right[number]
|
|
4531
|
+
? false
|
|
4532
|
+
: Exclude<Left[number], Right[number]> extends never
|
|
4533
|
+
? Exclude<Right[number], Left[number]> extends never
|
|
4534
|
+
? true
|
|
4535
|
+
: false
|
|
4536
|
+
: false
|
|
4537
|
+
|
|
4538
|
+
type ConflictArbitersOf<Target extends MutationTargetLike> =
|
|
4539
|
+
Target[typeof Table.TypeId]["conflictArbiters"][number]
|
|
4540
|
+
|
|
4541
|
+
type MatchingConflictArbiter<
|
|
4542
|
+
Target extends MutationTargetLike,
|
|
4543
|
+
Columns extends readonly string[],
|
|
4544
|
+
AllowPartial extends boolean
|
|
4545
|
+
> = ConflictArbitersOf<Target> extends infer Arbiter extends Table.ConflictArbiter
|
|
4546
|
+
? Arbiter extends Table.ConflictArbiter
|
|
4547
|
+
? SameColumnSet<Arbiter["columns"], Columns> extends true
|
|
4548
|
+
? Arbiter["scope"] extends "unconditional"
|
|
4549
|
+
? true
|
|
4550
|
+
: AllowPartial extends true ? true : never
|
|
4551
|
+
: never
|
|
4552
|
+
: never
|
|
4553
|
+
: never
|
|
4554
|
+
|
|
4555
|
+
type HasInlineConflictArbiter<
|
|
4556
|
+
Target extends MutationTargetLike,
|
|
4557
|
+
Columns extends readonly string[]
|
|
4558
|
+
> = Columns extends readonly [infer Column extends Extract<keyof Target[typeof Table.TypeId]["fields"], string>]
|
|
4559
|
+
? Target[typeof Table.TypeId]["fields"][Column] extends { readonly metadata: { readonly primaryKey: true } | { readonly unique: true } }
|
|
4560
|
+
? true
|
|
4561
|
+
: false
|
|
4562
|
+
: false
|
|
4563
|
+
|
|
4564
|
+
type HasConflictArbiter<
|
|
4565
|
+
Target extends MutationTargetLike,
|
|
4566
|
+
Columns extends readonly string[],
|
|
4567
|
+
AllowPartial extends boolean
|
|
4568
|
+
> = string extends Extract<keyof Target[typeof Table.TypeId]["fields"], string>
|
|
4569
|
+
? true
|
|
4570
|
+
: HasInlineConflictArbiter<Target, Columns> extends true
|
|
4571
|
+
? true
|
|
4572
|
+
: true extends MatchingConflictArbiter<Target, Columns, AllowPartial> ? true : false
|
|
4573
|
+
|
|
4574
|
+
type ConflictTargetArbiterError<
|
|
4575
|
+
Columns,
|
|
4576
|
+
AllowPartial extends boolean
|
|
4577
|
+
> = {
|
|
4578
|
+
readonly __effect_qb_error__: "effect-qb: conflict target columns must match a primary key, unique constraint, or unique index"
|
|
4579
|
+
readonly __effect_qb_conflict_columns__: Columns
|
|
4580
|
+
readonly __effect_qb_partial_target__: AllowPartial
|
|
4581
|
+
readonly __effect_qb_hint__: "Declare the target columns as primaryKey/unique, add a table-level Unique.make(...), or use a simple Pg.Index.uniqueIndex(...)"
|
|
4582
|
+
}
|
|
4583
|
+
|
|
4584
|
+
type ValidateConflictColumnInput<
|
|
4585
|
+
Target extends MutationTargetLike,
|
|
4586
|
+
Columns extends DdlColumnInput,
|
|
4587
|
+
AllowPartial extends boolean
|
|
4588
|
+
> = ValidateTargetColumnInput<Target, Columns> extends never
|
|
4589
|
+
? never
|
|
4590
|
+
: HasConflictArbiter<Target, NormalizeDdlColumns<Columns>, AllowPartial> extends true
|
|
4591
|
+
? Columns
|
|
4592
|
+
: ConflictTargetArbiterError<NormalizeDdlColumns<Columns>, AllowPartial>
|
|
4593
|
+
|
|
4594
|
+
type ConflictColumnPlanConstraint<
|
|
4595
|
+
Target extends MutationTargetLike,
|
|
4596
|
+
Columns extends DdlColumnInput,
|
|
4597
|
+
AllowPartial extends boolean
|
|
4598
|
+
> = ValidateTargetColumnInput<Target, Columns> extends never
|
|
4599
|
+
? never
|
|
4600
|
+
: HasConflictArbiter<Target, NormalizeDdlColumns<Columns>, AllowPartial> extends true
|
|
4601
|
+
? unknown
|
|
4602
|
+
: ConflictTargetArbiterError<NormalizeDdlColumns<Columns>, AllowPartial>
|
|
4603
|
+
|
|
4524
4604
|
type CreateIndexOptions<Name extends string = string> = {
|
|
4525
4605
|
readonly name?: NonEmptyStringInput<Name>
|
|
4526
4606
|
readonly unique?: boolean
|
|
@@ -5022,6 +5102,21 @@ type ConflictConstraintNameConstraint<Target> =
|
|
|
5022
5102
|
? { readonly constraint: NonEmptyStringInput<Constraint> }
|
|
5023
5103
|
: unknown
|
|
5024
5104
|
|
|
5105
|
+
type ConflictTargetHasPredicate<Target> =
|
|
5106
|
+
Target extends { readonly where: PredicateInput } ? true : false
|
|
5107
|
+
|
|
5108
|
+
type ConflictTargetPlanConstraint<
|
|
5109
|
+
Target extends MutationTargetLike,
|
|
5110
|
+
ConflictTarget
|
|
5111
|
+
> =
|
|
5112
|
+
ConflictTarget extends { readonly constraint: string }
|
|
5113
|
+
? unknown
|
|
5114
|
+
: ConflictTarget extends { readonly columns: infer Columns extends DdlColumnInput }
|
|
5115
|
+
? ConflictColumnPlanConstraint<Target, Columns, ConflictTargetHasPredicate<ConflictTarget>>
|
|
5116
|
+
: ConflictTarget extends DdlColumnInput
|
|
5117
|
+
? ConflictColumnPlanConstraint<Target, ConflictTarget, false>
|
|
5118
|
+
: unknown
|
|
5119
|
+
|
|
5025
5120
|
type ConflictActionInput<
|
|
5026
5121
|
Target extends MutationTargetLike,
|
|
5027
5122
|
Dialect extends string,
|
|
@@ -6315,9 +6410,9 @@ type AsCurriedResult<
|
|
|
6315
6410
|
>(
|
|
6316
6411
|
target: ConflictTarget & ConflictConstraintNameConstraint<ConflictTarget>,
|
|
6317
6412
|
options?: Options & ConflictActionUpdateNonEmptyConstraint<Options>
|
|
6318
|
-
|
|
6413
|
+
) =>
|
|
6319
6414
|
<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
|
|
6320
|
-
plan: PlanValue & RequireInsertStatement<PlanValue>
|
|
6415
|
+
plan: PlanValue & RequireInsertStatement<PlanValue> & ConflictTargetPlanConstraint<MutationTargetOfPlan<PlanValue>, ConflictTarget>
|
|
6321
6416
|
) => QueryPlan<
|
|
6322
6417
|
SelectionOfPlan<PlanValue>,
|
|
6323
6418
|
Exclude<RequiredOfPlan<PlanValue> | ConflictRequired<UpdateValues, Options, ConflictTarget>, AvailableNames<AvailableOfPlan<PlanValue>>>,
|
|
@@ -6381,7 +6476,7 @@ type AsCurriedResult<
|
|
|
6381
6476
|
>(
|
|
6382
6477
|
target: Target,
|
|
6383
6478
|
values: Values & MutationValuesDialectConstraint<Values, Dialect, TextDb, NumericDb, BoolDb, TimestampDb, NullDb>,
|
|
6384
|
-
conflictColumns:
|
|
6479
|
+
conflictColumns: ValidateConflictColumnInput<Target, Columns, false>,
|
|
6385
6480
|
updateValues?: UpdateValues & UpdateValuesNonEmptyConstraint<Exclude<UpdateValues, undefined>> & MutationValuesDialectConstraint<Exclude<UpdateValues, undefined>, Dialect, TextDb, NumericDb, BoolDb, TimestampDb, NullDb>
|
|
6386
6481
|
) => QueryPlan<
|
|
6387
6482
|
{},
|
package/src/sqlite/json.ts
CHANGED
|
@@ -1,39 +1,8 @@
|
|
|
1
|
-
/** SQLite JSON expression helpers. */
|
|
2
|
-
export { json } from "./internal/dsl.js"
|
|
1
|
+
/** SQLite-specific JSON expression helpers. Portable JSON helpers are exported from `effect-qb`. */
|
|
3
2
|
import { json } from "./internal/dsl.js"
|
|
4
3
|
|
|
5
|
-
export const key = json.key
|
|
6
|
-
export const index = json.index
|
|
7
|
-
export const wildcard = json.wildcard
|
|
8
|
-
export const slice = json.slice
|
|
9
|
-
export const descend = json.descend
|
|
10
|
-
export const path = json.path
|
|
11
|
-
export const get = json.get
|
|
12
|
-
export const access = json.access
|
|
13
|
-
export const traverse = json.traverse
|
|
14
|
-
export const text = json.text
|
|
15
|
-
export const accessText = json.accessText
|
|
16
|
-
export const traverseText = json.traverseText
|
|
17
|
-
export const contains = json.contains
|
|
18
|
-
export const containedBy = json.containedBy
|
|
19
|
-
export const hasKey = json.hasKey
|
|
20
|
-
export const keyExists = json.keyExists
|
|
21
|
-
export const hasAnyKeys = json.hasAnyKeys
|
|
22
|
-
export const hasAllKeys = json.hasAllKeys
|
|
23
|
-
export const delete_ = json.delete
|
|
24
|
-
export { delete_ as delete }
|
|
25
|
-
export const remove = json.remove
|
|
26
|
-
export const set = json.set
|
|
27
4
|
export const insert = json.insert
|
|
28
|
-
export const concat = json.concat
|
|
29
|
-
export const merge = json.merge
|
|
30
|
-
export const buildObject = json.buildObject
|
|
31
|
-
export const buildArray = json.buildArray
|
|
32
|
-
export const toJson = json.toJson
|
|
33
|
-
export const toJsonb = json.toJsonb
|
|
34
5
|
export const typeOf = json.typeOf
|
|
35
6
|
export const length = json.length
|
|
36
|
-
export const keys = json.keys
|
|
37
7
|
export const stripNulls = json.stripNulls
|
|
38
|
-
export const pathExists = json.pathExists
|
|
39
8
|
export const pathMatch = json.pathMatch
|
package/src/sqlite/renderer.ts
CHANGED
|
@@ -20,6 +20,9 @@ export type ValueMappings = Expression.DriverValueMappingsFor<SqliteDatatypeKind
|
|
|
20
20
|
|
|
21
21
|
export interface MakeOptions {
|
|
22
22
|
readonly valueMappings?: ValueMappings
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface RendererState extends MakeOptions {
|
|
23
26
|
readonly casing?: Casing.Options
|
|
24
27
|
}
|
|
25
28
|
|
|
@@ -33,19 +36,23 @@ const RendererProto = {
|
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
/** Creates the built-in SQLite renderer. */
|
|
36
|
-
|
|
37
|
-
const renderer = CoreRenderer.makeTrusted("sqlite", (plan) => renderSqlitePlan(plan,
|
|
39
|
+
const makeWithState = (state: RendererState = {}): Renderer => {
|
|
40
|
+
const renderer = CoreRenderer.makeTrusted("sqlite", (plan) => renderSqlitePlan(plan, state))
|
|
38
41
|
return Object.assign(Object.create(RendererProto), renderer, {
|
|
39
42
|
[Casing.TypeId]: {
|
|
40
|
-
casing:
|
|
43
|
+
casing: state.casing
|
|
41
44
|
},
|
|
42
45
|
withCasing: (override: Casing.Options) =>
|
|
43
|
-
|
|
44
|
-
...
|
|
45
|
-
casing: Casing.merge(
|
|
46
|
+
makeWithState({
|
|
47
|
+
...state,
|
|
48
|
+
casing: Casing.merge(state.casing, override)
|
|
46
49
|
})
|
|
47
50
|
}) as Renderer
|
|
48
51
|
}
|
|
49
52
|
|
|
53
|
+
/** Creates the built-in SQLite renderer. */
|
|
54
|
+
export const make = (options: MakeOptions = {}): Renderer =>
|
|
55
|
+
makeWithState({ valueMappings: options.valueMappings })
|
|
56
|
+
|
|
50
57
|
/** Shared built-in SQLite renderer instance. */
|
|
51
58
|
export const sqlite = make()
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type * as Expression from "../internal/scalar.js"
|
|
2
|
+
import type { NonEmptyStringInput } from "../internal/table-options.js"
|
|
3
|
+
import {
|
|
4
|
+
pickDatatypeConstructors,
|
|
5
|
+
sqliteSpecificDatatypeKeys,
|
|
6
|
+
type SqliteSpecificDatatypeKey
|
|
7
|
+
} from "../internal/datatypes/matrix.js"
|
|
8
|
+
import { sqliteDatatypes } from "./datatypes/index.js"
|
|
9
|
+
|
|
10
|
+
type SqliteSpecificDatatypes = Pick<typeof sqliteDatatypes, SqliteSpecificDatatypeKey>
|
|
11
|
+
|
|
12
|
+
type SqliteTypeNamespace = SqliteSpecificDatatypes & {
|
|
13
|
+
readonly custom: <Kind extends string>(kind: NonEmptyStringInput<Kind>) => Expression.DbType.Base<"sqlite", Kind>
|
|
14
|
+
readonly driverValueMapping: <Db extends Expression.DbType.Any>(
|
|
15
|
+
dbType: Db,
|
|
16
|
+
mapping: Expression.DriverValueMapping
|
|
17
|
+
) => Db
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const custom = <Kind extends string>(
|
|
21
|
+
kind: NonEmptyStringInput<Kind>
|
|
22
|
+
): Expression.DbType.Base<"sqlite", Kind> => ({
|
|
23
|
+
dialect: "sqlite",
|
|
24
|
+
kind: kind as Kind
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const driverValueMapping = <Db extends Expression.DbType.Any>(
|
|
28
|
+
dbType: Db,
|
|
29
|
+
mapping: Expression.DriverValueMapping
|
|
30
|
+
): Db => ({
|
|
31
|
+
...dbType,
|
|
32
|
+
driverValueMapping: mapping
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
/** SQLite-only database-type constructors for casts and typed column references. */
|
|
36
|
+
export const type: SqliteTypeNamespace = {
|
|
37
|
+
...pickDatatypeConstructors(sqliteDatatypes, sqliteSpecificDatatypeKeys),
|
|
38
|
+
custom,
|
|
39
|
+
driverValueMapping
|
|
40
|
+
}
|
package/src/sqlite.ts
CHANGED
|
@@ -4,11 +4,13 @@ export * as Column from "./sqlite/column-extension.js"
|
|
|
4
4
|
export * as Datatypes from "./sqlite/datatypes/index.js"
|
|
5
5
|
/** SQLite error catalog and error normalization helpers. */
|
|
6
6
|
export * as Errors from "./sqlite/errors/index.js"
|
|
7
|
-
/** SQLite-
|
|
7
|
+
/** SQLite-specific JSON expression helpers. Portable JSON helpers are exported from the root package. */
|
|
8
8
|
export * as Json from "./sqlite/json.js"
|
|
9
9
|
/** SQLite-specialized typed query execution contracts. */
|
|
10
10
|
export * as Executor from "./sqlite/executor.js"
|
|
11
11
|
/** SQLite-specific query helpers. Portable queries are exported from the root package. */
|
|
12
12
|
export * as Query from "./sqlite/query-extension.js"
|
|
13
|
+
/** SQLite-only database-type constructors for casts and typed references. */
|
|
14
|
+
export { type as Type } from "./sqlite/type.js"
|
|
13
15
|
/** SQLite-specialized built-in renderer entrypoint. */
|
|
14
16
|
export * as Renderer from "./sqlite/renderer.js"
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type * as ExpressionAst from "../internal/expression-ast.js"
|
|
2
|
+
import type { CastTargetError } from "../internal/coercion/errors.js"
|
|
3
|
+
import type { RuntimeOfDbType } from "../internal/coercion/analysis.js"
|
|
4
|
+
import type { CanCastDbType } from "../internal/coercion/rules.js"
|
|
5
|
+
import type { FamilyOfDbType } from "../internal/datatypes/lookup.js"
|
|
6
|
+
import type { ExpressionInput } from "../internal/query.js"
|
|
7
|
+
import type * as Expression from "../internal/scalar.js"
|
|
8
|
+
import { cast as standardCast } from "../internal/standard-dsl.js"
|
|
9
|
+
import type { standardDatatypes } from "./datatypes/index.js"
|
|
10
|
+
import type { standardDatatypeFamilies } from "./datatypes/spec.js"
|
|
11
|
+
|
|
12
|
+
type CastInput = ExpressionInput
|
|
13
|
+
type CastTarget = Expression.DbType.Any
|
|
14
|
+
type IsAny<Value> = 0 extends (1 & Value) ? true : false
|
|
15
|
+
|
|
16
|
+
type StandardNullDb = Expression.DbType.Base<"standard", "null"> & {
|
|
17
|
+
readonly family: "null"
|
|
18
|
+
readonly runtime: "unknown"
|
|
19
|
+
readonly compareGroup: "null"
|
|
20
|
+
readonly castTargets: typeof standardDatatypeFamilies.null.castTargets
|
|
21
|
+
readonly traits: {}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type LiteralDbType<Value> =
|
|
25
|
+
Value extends string ? ReturnType<typeof standardDatatypes.text> :
|
|
26
|
+
Value extends number ? ReturnType<typeof standardDatatypes.real> :
|
|
27
|
+
Value extends boolean ? ReturnType<typeof standardDatatypes.boolean> :
|
|
28
|
+
Value extends Date ? ReturnType<typeof standardDatatypes.timestamp> :
|
|
29
|
+
StandardNullDb
|
|
30
|
+
|
|
31
|
+
type CastSourceDbType<Value extends CastInput> = Value extends Expression.Any
|
|
32
|
+
? Expression.DbTypeOf<Value>
|
|
33
|
+
: LiteralDbType<Value>
|
|
34
|
+
|
|
35
|
+
type CastDialect<Value extends CastInput, Target extends CastTarget> =
|
|
36
|
+
CastSourceDbType<Value>["dialect"] | Target["dialect"]
|
|
37
|
+
|
|
38
|
+
type CastNullability<Value extends CastInput> = Value extends Expression.Any
|
|
39
|
+
? Expression.NullabilityOf<Value>
|
|
40
|
+
: Value extends null ? "always" : "never"
|
|
41
|
+
|
|
42
|
+
type CastKind<Value extends CastInput> = Value extends Expression.Any
|
|
43
|
+
? Expression.KindOf<Value>
|
|
44
|
+
: "scalar"
|
|
45
|
+
|
|
46
|
+
type CastDependencies<Value extends CastInput> = Value extends Expression.Any
|
|
47
|
+
? Expression.DependenciesOf<Value>
|
|
48
|
+
: never
|
|
49
|
+
|
|
50
|
+
type JsonbScalarCastTarget<Value extends CastInput, Target extends CastTarget> =
|
|
51
|
+
Value extends Expression.Any
|
|
52
|
+
? Expression.DbTypeOf<Value> extends Expression.DbType.Json<"postgres", "jsonb">
|
|
53
|
+
? [Expression.RuntimeOf<Value>] extends [number]
|
|
54
|
+
? FamilyOfDbType<Target> extends "numeric" ? Target : never
|
|
55
|
+
: [Expression.RuntimeOf<Value>] extends [boolean]
|
|
56
|
+
? FamilyOfDbType<Target> extends "boolean" ? Target : never
|
|
57
|
+
: never
|
|
58
|
+
: never
|
|
59
|
+
: never
|
|
60
|
+
|
|
61
|
+
type CanCastJsonbScalar<Value extends CastInput, Target extends CastTarget> =
|
|
62
|
+
[JsonbScalarCastTarget<Value, Target>] extends [never]
|
|
63
|
+
? false
|
|
64
|
+
: JsonbScalarCastTarget<Value, Target> extends Target
|
|
65
|
+
? true
|
|
66
|
+
: false
|
|
67
|
+
|
|
68
|
+
type CastTargetInput<Value extends CastInput, Target extends CastTarget> =
|
|
69
|
+
IsAny<Value> extends true
|
|
70
|
+
? Target
|
|
71
|
+
: IsAny<Target> extends true
|
|
72
|
+
? Target
|
|
73
|
+
: CanCastDbType<CastSourceDbType<Value>, Target, CastDialect<Value, Target>> extends true
|
|
74
|
+
? Target
|
|
75
|
+
: CanCastJsonbScalar<Value, Target> extends true
|
|
76
|
+
? Target
|
|
77
|
+
: CastTargetError<CastSourceDbType<Value>, Target, CastDialect<Value, Target>>
|
|
78
|
+
|
|
79
|
+
type CastValueInput<Value extends CastInput, Target extends CastTarget> =
|
|
80
|
+
CastTargetInput<Value, Target> extends Target
|
|
81
|
+
? Value
|
|
82
|
+
: CastTargetInput<Value, Target>
|
|
83
|
+
|
|
84
|
+
type CastExpression<
|
|
85
|
+
Value extends CastInput,
|
|
86
|
+
Target extends CastTarget
|
|
87
|
+
> = Expression.Scalar<
|
|
88
|
+
RuntimeOfDbType<Target>,
|
|
89
|
+
Target,
|
|
90
|
+
CastNullability<Value>,
|
|
91
|
+
CastDialect<Value, Target>,
|
|
92
|
+
CastKind<Value>,
|
|
93
|
+
CastDependencies<Value>
|
|
94
|
+
> & {
|
|
95
|
+
readonly [ExpressionAst.TypeId]: ExpressionAst.CastNode<Value extends Expression.Any ? Value : Expression.Any, Target>
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export const to: {
|
|
99
|
+
<Value extends CastInput, Target extends CastTarget>(
|
|
100
|
+
value: Value,
|
|
101
|
+
target: Target & CastTargetInput<Value, Target>
|
|
102
|
+
): CastExpression<Value, Target>
|
|
103
|
+
// `NoInfer` keeps `Value` out of its own inference constraint: it is inferred
|
|
104
|
+
// from the argument, then validated against the already-fixed `Target`.
|
|
105
|
+
// Without it, the validation forms an inference fixpoint that explodes under
|
|
106
|
+
// higher-order inference (e.g. `.pipe`).
|
|
107
|
+
<Target extends CastTarget>(
|
|
108
|
+
target: Target
|
|
109
|
+
): <Value extends CastInput>(value: Value & CastValueInput<NoInfer<Value>, Target>) => CastExpression<Value, Target>
|
|
110
|
+
} = ((...args: [CastInput, CastTarget] | [CastTarget]) =>
|
|
111
|
+
args.length === 1
|
|
112
|
+
? ((value: CastInput) => standardCast(value as never, args[0] as never))
|
|
113
|
+
: standardCast(args[0] as never, args[1] as never)) as unknown as typeof to
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as BaseTable from "../internal/table.js"
|
|
2
|
+
import type { TableOptionSpec } from "../internal/table-options.js"
|
|
3
|
+
|
|
4
|
+
type CheckSpec = Extract<TableOptionSpec, { readonly kind: "check" }>
|
|
5
|
+
|
|
6
|
+
export const make = BaseTable.check
|
|
7
|
+
|
|
8
|
+
export const named = <const Name extends string>(
|
|
9
|
+
name: BaseTable.NonEmptyStringInput<Name>
|
|
10
|
+
) =>
|
|
11
|
+
<Spec extends CheckSpec, TableContext extends BaseTable.TableDefinition<any, any, any, "schema", any>>(
|
|
12
|
+
option: BaseTable.TableOption<Spec, TableContext>
|
|
13
|
+
): BaseTable.TableOption<Spec & { readonly name: Name }, TableContext> =>
|
|
14
|
+
BaseTable.mapOption(option, (spec) => ({
|
|
15
|
+
...spec,
|
|
16
|
+
name
|
|
17
|
+
} as Spec & { readonly name: Name }))
|