effect-qb 0.17.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 +11 -1
- package/dist/index.js +9376 -0
- package/dist/mysql.js +4092 -2671
- package/dist/postgres/metadata.js +2589 -1402
- package/dist/postgres.js +3953 -3583
- package/dist/sqlite.js +5527 -4088
- package/dist/standard.js +9330 -0
- package/package.json +9 -4
- package/src/casing.ts +71 -0
- package/src/index.ts +2 -0
- package/src/internal/casing.ts +89 -0
- package/src/internal/coercion/rules.ts +13 -1
- package/src/internal/column-state.d.ts +3 -3
- package/src/internal/column-state.ts +24 -18
- package/src/internal/column.ts +52 -15
- package/src/internal/datatypes/define.ts +7 -1
- package/src/internal/datatypes/enrich.ts +23 -0
- package/src/internal/datatypes/lookup.ts +81 -25
- package/src/internal/datatypes/matrix.ts +903 -0
- package/src/internal/datatypes/shape.ts +2 -0
- package/src/internal/derived-table.ts +4 -36
- package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/mysql.ts} +552 -361
- package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +657 -400
- package/src/{sqlite/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +505 -347
- package/src/internal/dialect.ts +36 -1
- package/src/internal/dsl-mutation-runtime.ts +12 -162
- package/src/internal/dsl-plan-runtime.ts +10 -138
- package/src/internal/dsl-query-runtime.ts +5 -79
- package/src/internal/dsl-transaction-ddl-runtime.ts +41 -65
- package/src/internal/executor.ts +66 -49
- package/src/internal/grouping-key.ts +87 -20
- package/src/internal/implication-runtime.ts +1 -1
- package/src/internal/json/path-access.ts +351 -0
- package/src/internal/predicate/runtime.ts +3 -0
- package/src/internal/query.d.ts +39 -12
- package/src/internal/query.ts +65 -26
- package/src/internal/renderer.ts +26 -14
- package/src/internal/runtime/driver-value-mapping.ts +3 -3
- package/src/internal/runtime/normalize.ts +12 -5
- 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 +8 -2
- package/src/internal/schema-derivation.d.ts +12 -61
- package/src/internal/schema-derivation.ts +95 -43
- package/src/internal/schema-expression.ts +2 -2
- package/src/internal/sql-expression-renderer.ts +19 -0
- package/src/internal/standard-dsl.ts +6978 -0
- package/src/internal/table-options.ts +126 -66
- package/src/internal/table.ts +819 -237
- package/src/mysql/column-extension.ts +3 -0
- package/src/mysql/column.ts +14 -15
- package/src/mysql/datatypes/index.ts +4 -2
- package/src/mysql/datatypes/spec.ts +6 -176
- package/src/mysql/errors/normalize.ts +0 -1
- package/src/mysql/executor.ts +11 -11
- package/src/mysql/function/temporal.ts +1 -1
- package/src/mysql/internal/dialect.ts +9 -4
- package/src/mysql/internal/dsl.ts +334 -170
- package/src/mysql/internal/renderer.ts +6 -2
- package/src/mysql/json.ts +7 -2
- package/src/mysql/query-extension.ts +16 -0
- package/src/mysql/renderer.ts +37 -3
- package/src/mysql/type.ts +60 -0
- package/src/mysql.ts +7 -13
- package/src/postgres/check.ts +1 -0
- package/src/postgres/column-extension.ts +28 -0
- package/src/postgres/column.ts +13 -19
- package/src/postgres/datatypes/index.d.ts +2 -1
- package/src/postgres/datatypes/index.ts +4 -2
- package/src/postgres/datatypes/spec.ts +6 -260
- package/src/postgres/errors/normalize.ts +0 -1
- package/src/postgres/executor.ts +11 -11
- package/src/postgres/foreign-key.ts +24 -0
- package/src/postgres/function/core.ts +1 -3
- package/src/postgres/function/index.ts +1 -17
- package/src/postgres/function/temporal.ts +1 -1
- package/src/postgres/index.ts +1 -0
- package/src/postgres/internal/dialect.ts +9 -4
- package/src/postgres/internal/dsl.ts +328 -179
- package/src/postgres/internal/renderer.ts +6 -2
- package/src/postgres/internal/schema-ddl.ts +22 -10
- package/src/postgres/internal/schema-model.ts +238 -7
- package/src/postgres/json-extension.ts +7 -0
- package/src/postgres/json.ts +762 -173
- package/src/postgres/jsonb.ts +37 -0
- package/src/postgres/primary-key.ts +24 -0
- package/src/postgres/query-extension.ts +2 -0
- package/src/postgres/renderer.ts +37 -3
- package/src/postgres/schema-management.ts +13 -13
- package/src/postgres/schema.ts +106 -15
- package/src/postgres/table.ts +205 -538
- package/src/postgres/type.ts +93 -10
- package/src/postgres/unique.ts +32 -0
- package/src/postgres.ts +20 -16
- package/src/sqlite/column-extension.ts +3 -0
- package/src/sqlite/column.ts +14 -15
- package/src/sqlite/datatypes/index.ts +4 -2
- package/src/sqlite/datatypes/spec.ts +6 -94
- package/src/sqlite/errors/normalize.ts +0 -1
- package/src/sqlite/executor.ts +11 -11
- package/src/sqlite/function/temporal.ts +1 -1
- package/src/sqlite/internal/dialect.ts +9 -4
- package/src/sqlite/internal/dsl.ts +307 -159
- package/src/sqlite/internal/renderer.ts +6 -2
- package/src/sqlite/json.ts +8 -2
- package/src/sqlite/query-extension.ts +2 -0
- package/src/sqlite/renderer.ts +37 -3
- package/src/sqlite/type.ts +40 -0
- package/src/sqlite.ts +7 -13
- package/src/standard/cast.ts +113 -0
- package/src/standard/check.ts +17 -0
- package/src/standard/column.ts +163 -0
- package/src/standard/datatypes/index.ts +83 -0
- package/src/standard/datatypes/spec.ts +12 -0
- package/src/standard/dialect.ts +40 -0
- package/src/standard/foreign-key.ts +37 -0
- package/src/standard/function/aggregate.ts +2 -0
- package/src/standard/function/core.ts +2 -0
- package/src/standard/function/index.ts +18 -0
- package/src/standard/function/string.ts +2 -0
- package/src/standard/function/temporal.ts +78 -0
- package/src/standard/function/window.ts +2 -0
- package/src/standard/index.ts +17 -0
- package/src/standard/internal/renderer.ts +45 -0
- package/src/standard/json.ts +883 -0
- package/src/standard/primary-key.ts +17 -0
- package/src/standard/query.ts +152 -0
- package/src/standard/renderer.ts +49 -0
- package/src/standard/table.ts +151 -0
- package/src/standard/unique.ts +17 -0
- package/src/standard.ts +32 -0
- package/src/internal/aggregation-validation.ts +0 -57
- package/src/internal/table.d.ts +0 -173
- package/src/mysql/table.ts +0 -183
- package/src/postgres/cast.ts +0 -45
- package/src/sqlite/table.ts +0 -183
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as Query from "../../internal/query.js"
|
|
2
2
|
import type * as Expression from "../../internal/scalar.js"
|
|
3
|
+
import type * as Casing from "../../internal/casing.js"
|
|
3
4
|
import { type RenderState } from "../../internal/dialect.js"
|
|
4
5
|
import { sqliteDialect } from "./dialect.js"
|
|
5
6
|
import { type Projection } from "../../internal/projections.js"
|
|
6
|
-
import { renderQueryAst } from "
|
|
7
|
+
import { renderQueryAst } from "../../internal/sql-expression-renderer.js"
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Internal rendered-query payload produced by the built-in SQLite renderer.
|
|
@@ -17,6 +18,7 @@ export interface SqliteRenderResult {
|
|
|
17
18
|
|
|
18
19
|
export interface SqliteRenderOptions {
|
|
19
20
|
readonly valueMappings?: Expression.DriverValueMappings
|
|
21
|
+
readonly casing?: Casing.Options
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
/**
|
|
@@ -29,9 +31,11 @@ export const renderSqlitePlan = <PlanValue extends Query.Plan.Any>(
|
|
|
29
31
|
const state: RenderState = {
|
|
30
32
|
params: [],
|
|
31
33
|
valueMappings: options.valueMappings,
|
|
34
|
+
casing: options.casing,
|
|
32
35
|
ctes: [],
|
|
33
36
|
cteNames: new Set<string>(),
|
|
34
|
-
cteSources: new Map<string, unknown>()
|
|
37
|
+
cteSources: new Map<string, unknown>(),
|
|
38
|
+
sourceNames: new Map()
|
|
35
39
|
}
|
|
36
40
|
const rendered = renderQueryAst(
|
|
37
41
|
Query.getAst(plan as Query.Plan.Any) as any,
|
package/src/sqlite/json.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
/** SQLite JSON expression helpers. */
|
|
2
|
-
|
|
1
|
+
/** SQLite-specific JSON expression helpers. Portable JSON helpers are exported from `effect-qb`. */
|
|
2
|
+
import { json } from "./internal/dsl.js"
|
|
3
|
+
|
|
4
|
+
export const insert = json.insert
|
|
5
|
+
export const typeOf = json.typeOf
|
|
6
|
+
export const length = json.length
|
|
7
|
+
export const stripNulls = json.stripNulls
|
|
8
|
+
export const pathMatch = json.pathMatch
|
package/src/sqlite/renderer.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { pipeArguments, type Pipeable } from "effect/Pipeable"
|
|
2
|
+
|
|
1
3
|
import * as CoreRenderer from "../internal/renderer.js"
|
|
4
|
+
import * as Casing from "../internal/casing.js"
|
|
2
5
|
import type * as Expression from "../internal/scalar.js"
|
|
6
|
+
import type { SqliteDatatypeFamily, SqliteDatatypeKind } from "./datatypes/spec.js"
|
|
3
7
|
import { renderSqlitePlan } from "./internal/renderer.js"
|
|
4
8
|
|
|
5
9
|
/** SQLite-specialized rendered query shape. */
|
|
@@ -7,18 +11,48 @@ export type RenderedQuery<Row> = CoreRenderer.RenderedQuery<Row, "sqlite">
|
|
|
7
11
|
/** Extracts the row type carried by a SQLite rendered query. */
|
|
8
12
|
export type RowOf<Value extends RenderedQuery<any>> = CoreRenderer.RowOf<Value>
|
|
9
13
|
/** SQLite-specialized renderer contract. */
|
|
10
|
-
export type Renderer = CoreRenderer.Renderer<"sqlite">
|
|
14
|
+
export type Renderer = CoreRenderer.Renderer<"sqlite"> & Pipeable & {
|
|
15
|
+
readonly [Casing.TypeId]: Casing.State
|
|
16
|
+
readonly withCasing: (options: Casing.Options) => Renderer
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type ValueMappings = Expression.DriverValueMappingsFor<SqliteDatatypeKind | "uuid", SqliteDatatypeFamily | "uuid">
|
|
11
20
|
|
|
12
21
|
export interface MakeOptions {
|
|
13
|
-
readonly valueMappings?:
|
|
22
|
+
readonly valueMappings?: ValueMappings
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface RendererState extends MakeOptions {
|
|
26
|
+
readonly casing?: Casing.Options
|
|
14
27
|
}
|
|
15
28
|
|
|
16
29
|
export { TypeId } from "../internal/renderer.js"
|
|
17
30
|
export type { Projection } from "../internal/renderer.js"
|
|
18
31
|
|
|
32
|
+
const RendererProto = {
|
|
33
|
+
pipe(this: Pipeable) {
|
|
34
|
+
return pipeArguments(this, arguments)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Creates the built-in SQLite renderer. */
|
|
39
|
+
const makeWithState = (state: RendererState = {}): Renderer => {
|
|
40
|
+
const renderer = CoreRenderer.makeTrusted("sqlite", (plan) => renderSqlitePlan(plan, state))
|
|
41
|
+
return Object.assign(Object.create(RendererProto), renderer, {
|
|
42
|
+
[Casing.TypeId]: {
|
|
43
|
+
casing: state.casing
|
|
44
|
+
},
|
|
45
|
+
withCasing: (override: Casing.Options) =>
|
|
46
|
+
makeWithState({
|
|
47
|
+
...state,
|
|
48
|
+
casing: Casing.merge(state.casing, override)
|
|
49
|
+
})
|
|
50
|
+
}) as Renderer
|
|
51
|
+
}
|
|
52
|
+
|
|
19
53
|
/** Creates the built-in SQLite renderer. */
|
|
20
54
|
export const make = (options: MakeOptions = {}): Renderer =>
|
|
21
|
-
|
|
55
|
+
makeWithState({ valueMappings: options.valueMappings })
|
|
22
56
|
|
|
23
57
|
/** Shared built-in SQLite renderer instance. */
|
|
24
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
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
/** SQLite-
|
|
2
|
-
export * as Column from "./sqlite/column.js"
|
|
1
|
+
/** SQLite-specific column extensions. Portable columns are exported from `effect-qb`. */
|
|
2
|
+
export * as Column from "./sqlite/column-extension.js"
|
|
3
3
|
/** SQLite datatype witnesses and coercion families. */
|
|
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
|
-
/**
|
|
8
|
-
export * as Scalar from "./internal/scalar.js"
|
|
9
|
-
/** SQLite-specialized SQL function expressions. */
|
|
10
|
-
export * as Function from "./sqlite/function/index.js"
|
|
11
|
-
/** SQLite-specialized JSON expression helpers. */
|
|
7
|
+
/** SQLite-specific JSON expression helpers. Portable JSON helpers are exported from the root package. */
|
|
12
8
|
export * as Json from "./sqlite/json.js"
|
|
13
9
|
/** SQLite-specialized typed query execution contracts. */
|
|
14
10
|
export * as Executor from "./sqlite/executor.js"
|
|
15
|
-
/**
|
|
16
|
-
export * as
|
|
17
|
-
/** SQLite-
|
|
18
|
-
export
|
|
19
|
-
/** SQLite-specialized table-definition DSL. */
|
|
20
|
-
export * as Table from "./sqlite/table.js"
|
|
11
|
+
/** SQLite-specific query helpers. Portable queries are exported from the root package. */
|
|
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"
|
|
21
15
|
/** SQLite-specialized built-in renderer entrypoint. */
|
|
22
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 }))
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema"
|
|
2
|
+
|
|
3
|
+
import * as BaseColumn from "../internal/column.js"
|
|
4
|
+
import { makeColumnDefinition, type AnyColumnDefinition, type ColumnDefinition } from "../internal/column-state.js"
|
|
5
|
+
import type * as Expression from "../internal/scalar.js"
|
|
6
|
+
import type { NonEmptyStringInput } from "../internal/table-options.js"
|
|
7
|
+
import { enrichDbType } from "../internal/datatypes/enrich.js"
|
|
8
|
+
import {
|
|
9
|
+
BigIntStringSchema,
|
|
10
|
+
DecimalStringSchema,
|
|
11
|
+
LocalDateStringSchema,
|
|
12
|
+
LocalDateTimeStringSchema,
|
|
13
|
+
LocalTimeStringSchema,
|
|
14
|
+
type BigIntString,
|
|
15
|
+
type DecimalString,
|
|
16
|
+
type LocalDateString,
|
|
17
|
+
type LocalDateTimeString,
|
|
18
|
+
type LocalTimeString
|
|
19
|
+
} from "../internal/runtime/value.js"
|
|
20
|
+
import { standardDatatypes } from "./datatypes/index.js"
|
|
21
|
+
|
|
22
|
+
const primitive = <Type, Db extends Expression.DbType.Any>(
|
|
23
|
+
schema: Schema.Schema<Type>,
|
|
24
|
+
dbType: Db
|
|
25
|
+
): ColumnDefinition<Type, Type, Type, Db, false, false, false, false, false, undefined> =>
|
|
26
|
+
makeColumnDefinition(schema as Schema.Schema<NonNullable<Type>>, {
|
|
27
|
+
dbType,
|
|
28
|
+
nullable: false,
|
|
29
|
+
hasDefault: false,
|
|
30
|
+
generated: false,
|
|
31
|
+
primaryKey: false,
|
|
32
|
+
unique: false,
|
|
33
|
+
references: undefined
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const renderNumericDdlType = (
|
|
37
|
+
kind: string,
|
|
38
|
+
options?: BaseColumn.NumericOptions
|
|
39
|
+
): string | undefined => {
|
|
40
|
+
if (options === undefined || options.precision === undefined) {
|
|
41
|
+
return undefined
|
|
42
|
+
}
|
|
43
|
+
return options.scale === undefined
|
|
44
|
+
? `${kind}(${options.precision})`
|
|
45
|
+
: `${kind}(${options.precision},${options.scale})`
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const boundedString = (length?: number): Schema.Schema<string> =>
|
|
49
|
+
length === undefined
|
|
50
|
+
? Schema.String
|
|
51
|
+
: Schema.String.check(Schema.isMaxLength(length))
|
|
52
|
+
|
|
53
|
+
const finiteNumber = Schema.Number.check(Schema.isFinite())
|
|
54
|
+
|
|
55
|
+
export const custom = <SchemaType extends Schema.Top, Db extends Expression.DbType.Any>(
|
|
56
|
+
schema: SchemaType,
|
|
57
|
+
dbType: Db
|
|
58
|
+
) =>
|
|
59
|
+
makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>>, {
|
|
60
|
+
dbType: enrichDbType(standardDatatypes, dbType),
|
|
61
|
+
nullable: false,
|
|
62
|
+
hasDefault: false,
|
|
63
|
+
generated: false,
|
|
64
|
+
primaryKey: false,
|
|
65
|
+
unique: false,
|
|
66
|
+
references: undefined,
|
|
67
|
+
ddlType: undefined,
|
|
68
|
+
identity: undefined
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
export const uuid = () => primitive(Schema.String.check(Schema.isUUID()), standardDatatypes.uuid())
|
|
72
|
+
export const text = () => primitive(Schema.String, standardDatatypes.text())
|
|
73
|
+
export const varchar = (length?: number) =>
|
|
74
|
+
makeColumnDefinition(boundedString(length), {
|
|
75
|
+
dbType: standardDatatypes.varchar(),
|
|
76
|
+
nullable: false,
|
|
77
|
+
hasDefault: false,
|
|
78
|
+
generated: false,
|
|
79
|
+
primaryKey: false,
|
|
80
|
+
unique: false,
|
|
81
|
+
references: undefined,
|
|
82
|
+
ddlType: length === undefined ? undefined : `varchar(${length})`,
|
|
83
|
+
identity: undefined
|
|
84
|
+
})
|
|
85
|
+
export const char = (length = 1) =>
|
|
86
|
+
makeColumnDefinition(boundedString(length), {
|
|
87
|
+
dbType: standardDatatypes.char(),
|
|
88
|
+
nullable: false,
|
|
89
|
+
hasDefault: false,
|
|
90
|
+
generated: false,
|
|
91
|
+
primaryKey: false,
|
|
92
|
+
unique: false,
|
|
93
|
+
references: undefined,
|
|
94
|
+
ddlType: `char(${length})`,
|
|
95
|
+
identity: undefined
|
|
96
|
+
})
|
|
97
|
+
export const int = () => primitive(Schema.Int, standardDatatypes.int())
|
|
98
|
+
export const bigint = () => primitive(BigIntStringSchema, standardDatatypes.bigint())
|
|
99
|
+
export const number = (options?: BaseColumn.NumericOptions) =>
|
|
100
|
+
makeColumnDefinition(DecimalStringSchema, {
|
|
101
|
+
dbType: standardDatatypes.decimal(),
|
|
102
|
+
nullable: false,
|
|
103
|
+
hasDefault: false,
|
|
104
|
+
generated: false,
|
|
105
|
+
primaryKey: false,
|
|
106
|
+
unique: false,
|
|
107
|
+
references: undefined,
|
|
108
|
+
ddlType: renderNumericDdlType("decimal", options),
|
|
109
|
+
identity: undefined
|
|
110
|
+
})
|
|
111
|
+
export const real = () => primitive(finiteNumber, standardDatatypes.real())
|
|
112
|
+
export const boolean = () => primitive(Schema.Boolean, standardDatatypes.boolean())
|
|
113
|
+
export const date = () => primitive(LocalDateStringSchema, standardDatatypes.date())
|
|
114
|
+
export const time = () => primitive(LocalTimeStringSchema, standardDatatypes.time())
|
|
115
|
+
export const datetime = () => primitive(LocalDateTimeStringSchema, standardDatatypes.datetime())
|
|
116
|
+
export const timestamp = () => primitive(LocalDateTimeStringSchema, standardDatatypes.timestamp())
|
|
117
|
+
export const blob = () => primitive(Schema.Uint8Array, standardDatatypes.blob())
|
|
118
|
+
export const json = <SchemaType extends Schema.Top>(schema: SchemaType) =>
|
|
119
|
+
makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>>, {
|
|
120
|
+
dbType: { ...standardDatatypes.json(), variant: "json" } as Expression.DbType.Json<"standard", "json">,
|
|
121
|
+
nullable: false,
|
|
122
|
+
hasDefault: false,
|
|
123
|
+
generated: false,
|
|
124
|
+
primaryKey: false,
|
|
125
|
+
unique: false,
|
|
126
|
+
references: undefined,
|
|
127
|
+
ddlType: undefined,
|
|
128
|
+
identity: undefined
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
export const nullable = BaseColumn.nullable
|
|
132
|
+
export const brand = BaseColumn.brand
|
|
133
|
+
export const primaryKey = BaseColumn.primaryKey
|
|
134
|
+
type UniqueColumn<Column extends AnyColumnDefinition> = ReturnType<typeof BaseColumn.unique<Column>>
|
|
135
|
+
|
|
136
|
+
type StandardUniqueOptions = {
|
|
137
|
+
readonly name?: string
|
|
138
|
+
readonly nullsNotDistinct?: never
|
|
139
|
+
readonly deferrable?: never
|
|
140
|
+
readonly initiallyDeferred?: never
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
type NonEmptyOptionNameInput<Options> = Options extends { readonly name: infer Name extends string }
|
|
144
|
+
? NonEmptyStringInput<Name> extends never ? never : unknown
|
|
145
|
+
: unknown
|
|
146
|
+
|
|
147
|
+
type UniqueModifier = {
|
|
148
|
+
<Column extends AnyColumnDefinition>(column: Column): UniqueColumn<Column>
|
|
149
|
+
readonly options: <const Options extends StandardUniqueOptions>(
|
|
150
|
+
options: Options & NonEmptyOptionNameInput<Options>
|
|
151
|
+
) => <Column extends AnyColumnDefinition>(column: Column) => UniqueColumn<Column>
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export const unique = BaseColumn.unique as UniqueModifier
|
|
155
|
+
const default_ = BaseColumn.default_
|
|
156
|
+
export const generated = BaseColumn.generated
|
|
157
|
+
export const driverValueMapping = BaseColumn.driverValueMapping
|
|
158
|
+
export const references = BaseColumn.references
|
|
159
|
+
export const schema = BaseColumn.schema
|
|
160
|
+
export { default_ as default }
|
|
161
|
+
|
|
162
|
+
export type Any = BaseColumn.Any
|
|
163
|
+
export type AnyBound = BaseColumn.AnyBound
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { DatatypeModule } from "../../internal/datatypes/define.js"
|
|
2
|
+
import type * as Expression from "../../internal/scalar.js"
|
|
3
|
+
import type { NonEmptyStringInput } from "../../internal/table-options.js"
|
|
4
|
+
import { standardDatatypeFamilies, standardDatatypeKinds } from "./spec.js"
|
|
5
|
+
|
|
6
|
+
const withMetadata = <Kind extends keyof typeof standardDatatypeKinds & string>(
|
|
7
|
+
kind: Kind
|
|
8
|
+
): Expression.DbType.Base<"standard", Kind> => {
|
|
9
|
+
const kindSpec = standardDatatypeKinds[kind]
|
|
10
|
+
const familySpec = standardDatatypeFamilies[kindSpec.family as keyof typeof standardDatatypeFamilies]
|
|
11
|
+
return {
|
|
12
|
+
dialect: "standard",
|
|
13
|
+
kind,
|
|
14
|
+
family: kindSpec.family,
|
|
15
|
+
runtime: kindSpec.runtime,
|
|
16
|
+
compareGroup: familySpec?.compareGroup,
|
|
17
|
+
castTargets: familySpec?.castTargets,
|
|
18
|
+
implicitTargets: (familySpec as { readonly implicitTargets?: readonly string[] }).implicitTargets,
|
|
19
|
+
traits: familySpec?.traits
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const standardDatatypeModule = {
|
|
24
|
+
custom: <Kind extends string>(kind: NonEmptyStringInput<Kind>) => ({
|
|
25
|
+
dialect: "standard",
|
|
26
|
+
kind: kind as Kind
|
|
27
|
+
}),
|
|
28
|
+
uuid: () => ({
|
|
29
|
+
dialect: "standard",
|
|
30
|
+
kind: "uuid",
|
|
31
|
+
family: "uuid",
|
|
32
|
+
runtime: "string",
|
|
33
|
+
compareGroup: "uuid",
|
|
34
|
+
castTargets: ["uuid", "char", "varchar", "text"],
|
|
35
|
+
traits: {
|
|
36
|
+
textual: true
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
} as Record<string, (...args: readonly any[]) => Expression.DbType.Base<"standard", string>>
|
|
40
|
+
|
|
41
|
+
for (const kind of Object.keys(standardDatatypeKinds)) {
|
|
42
|
+
standardDatatypeModule[kind] = () => withMetadata(kind as keyof typeof standardDatatypeKinds & string)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type StandardUuidWitness = Expression.DbType.Base<"standard", "uuid"> & {
|
|
46
|
+
readonly family: "uuid"
|
|
47
|
+
readonly runtime: "string"
|
|
48
|
+
readonly compareGroup: "uuid"
|
|
49
|
+
readonly castTargets: readonly ["uuid", "char", "varchar", "text"]
|
|
50
|
+
readonly traits: {
|
|
51
|
+
readonly textual: true
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
type StandardJsonWitness = Expression.DbType.Base<"standard", "json"> & {
|
|
56
|
+
readonly family: "json"
|
|
57
|
+
readonly runtime: "json"
|
|
58
|
+
readonly compareGroup: "json"
|
|
59
|
+
readonly castTargets: readonly ["json", "text"]
|
|
60
|
+
readonly driverValueMapping: {
|
|
61
|
+
readonly toDriver: (value: unknown) => unknown
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
standardDatatypeModule.json = () => ({
|
|
66
|
+
...withMetadata("json"),
|
|
67
|
+
driverValueMapping: {
|
|
68
|
+
toDriver: (value: unknown) => JSON.stringify(value)
|
|
69
|
+
}
|
|
70
|
+
}) as StandardJsonWitness
|
|
71
|
+
|
|
72
|
+
export const standardDatatypes = {
|
|
73
|
+
...(standardDatatypeModule as DatatypeModule<
|
|
74
|
+
"standard",
|
|
75
|
+
typeof standardDatatypeKinds,
|
|
76
|
+
typeof standardDatatypeFamilies
|
|
77
|
+
> & {
|
|
78
|
+
readonly uuid: () => StandardUuidWitness
|
|
79
|
+
readonly json: () => StandardJsonWitness
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export type StandardDatatypeModule = typeof standardDatatypes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
portableDatatypeFamilies,
|
|
3
|
+
portableDatatypeKinds,
|
|
4
|
+
type PortableDatatypeFamily,
|
|
5
|
+
type PortableDatatypeKind
|
|
6
|
+
} from "../../internal/datatypes/matrix.js"
|
|
7
|
+
|
|
8
|
+
export const standardDatatypeFamilies = portableDatatypeFamilies
|
|
9
|
+
export const standardDatatypeKinds = portableDatatypeKinds
|
|
10
|
+
|
|
11
|
+
export type StandardDatatypeFamily = PortableDatatypeFamily
|
|
12
|
+
export type StandardDatatypeKind = PortableDatatypeKind
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { quoteDoubleQuotedIdentifier, type RenderState, type RenderValueContext, type SqlDialect } from "../internal/dialect.js"
|
|
2
|
+
import { renderExpression, renderQueryAst } from "../internal/dialect-renderers/postgres.js"
|
|
3
|
+
import { toDriverValue } from "../internal/runtime/driver-value-mapping.js"
|
|
4
|
+
|
|
5
|
+
const quoteIdentifier = quoteDoubleQuotedIdentifier
|
|
6
|
+
|
|
7
|
+
const renderLiteral = (value: unknown, state: RenderState, context: RenderValueContext = {}): string => {
|
|
8
|
+
const driverValue = toDriverValue(value, {
|
|
9
|
+
dialect: "standard",
|
|
10
|
+
valueMappings: state.valueMappings,
|
|
11
|
+
...context
|
|
12
|
+
})
|
|
13
|
+
if (driverValue === null) {
|
|
14
|
+
return "null"
|
|
15
|
+
}
|
|
16
|
+
if (typeof driverValue === "boolean") {
|
|
17
|
+
return driverValue ? "true" : "false"
|
|
18
|
+
}
|
|
19
|
+
state.params.push(driverValue)
|
|
20
|
+
return "?"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const standardDialect: SqlDialect<"standard"> = {
|
|
24
|
+
name: "standard",
|
|
25
|
+
quoteIdentifier,
|
|
26
|
+
renderLiteral,
|
|
27
|
+
renderTableReference(tableName, baseTableName, schemaName) {
|
|
28
|
+
const renderedBase = schemaName && schemaName !== "public"
|
|
29
|
+
? `${quoteIdentifier(schemaName)}.${quoteIdentifier(baseTableName)}`
|
|
30
|
+
: quoteIdentifier(baseTableName)
|
|
31
|
+
return tableName === baseTableName
|
|
32
|
+
? renderedBase
|
|
33
|
+
: `${renderedBase} as ${quoteIdentifier(tableName)}`
|
|
34
|
+
},
|
|
35
|
+
renderConcat(values) {
|
|
36
|
+
return `(${values.join(" || ")})`
|
|
37
|
+
},
|
|
38
|
+
renderQueryAst,
|
|
39
|
+
renderExpression
|
|
40
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as BaseTable from "../internal/table.js"
|
|
2
|
+
import type { TableOptionSpec } from "../internal/table-options.js"
|
|
3
|
+
|
|
4
|
+
type ForeignKeySpec = Extract<TableOptionSpec, { readonly kind: "foreignKey" }>
|
|
5
|
+
|
|
6
|
+
export type ReferentialAction = BaseTable.ReferentialAction
|
|
7
|
+
|
|
8
|
+
export const make = BaseTable.foreignKey
|
|
9
|
+
|
|
10
|
+
export const named = <const Name extends string>(
|
|
11
|
+
name: BaseTable.NonEmptyStringInput<Name>
|
|
12
|
+
) =>
|
|
13
|
+
<Spec extends ForeignKeySpec, TableContext extends BaseTable.TableDefinition<any, any, any, "schema", any>>(
|
|
14
|
+
option: BaseTable.TableOption<Spec, TableContext>
|
|
15
|
+
): BaseTable.TableOption<Spec & { readonly name: Name }, TableContext> =>
|
|
16
|
+
BaseTable.mapOption(option, (spec) => ({
|
|
17
|
+
...spec,
|
|
18
|
+
name
|
|
19
|
+
} as Spec & { readonly name: Name }))
|
|
20
|
+
|
|
21
|
+
export const onDelete = (action: BaseTable.ReferentialAction) =>
|
|
22
|
+
<Spec extends ForeignKeySpec, TableContext extends BaseTable.TableDefinition<any, any, any, "schema", any>>(
|
|
23
|
+
option: BaseTable.TableOption<Spec, TableContext>
|
|
24
|
+
): BaseTable.TableOption<Spec & { readonly onDelete: BaseTable.ReferentialAction }, TableContext> =>
|
|
25
|
+
BaseTable.mapOption(option, (spec) => ({
|
|
26
|
+
...spec,
|
|
27
|
+
onDelete: action
|
|
28
|
+
} as Spec & { readonly onDelete: BaseTable.ReferentialAction }))
|
|
29
|
+
|
|
30
|
+
export const onUpdate = (action: BaseTable.ReferentialAction) =>
|
|
31
|
+
<Spec extends ForeignKeySpec, TableContext extends BaseTable.TableDefinition<any, any, any, "schema", any>>(
|
|
32
|
+
option: BaseTable.TableOption<Spec, TableContext>
|
|
33
|
+
): BaseTable.TableOption<Spec & { readonly onUpdate: BaseTable.ReferentialAction }, TableContext> =>
|
|
34
|
+
BaseTable.mapOption(option, (spec) => ({
|
|
35
|
+
...spec,
|
|
36
|
+
onUpdate: action
|
|
37
|
+
} as Spec & { readonly onUpdate: BaseTable.ReferentialAction }))
|