effect-qb 0.14.0 → 0.16.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/dist/mysql.js +61555 -4252
- package/dist/postgres/metadata.js +728 -104
- package/dist/postgres.js +6906 -4023
- package/package.json +15 -2
- package/src/internal/aggregation-validation.ts +3 -3
- package/src/internal/case-analysis.d.ts +18 -0
- package/src/internal/case-analysis.ts +4 -4
- package/src/internal/coercion/analysis.d.ts +7 -0
- package/src/internal/{coercion-analysis.ts → coercion/analysis.ts} +3 -3
- package/src/internal/coercion/errors.d.ts +17 -0
- package/src/internal/{coercion-errors.ts → coercion/errors.ts} +1 -1
- package/src/internal/coercion/kind.d.ts +4 -0
- package/src/internal/{coercion-kind.ts → coercion/kind.ts} +2 -2
- package/src/internal/{coercion-normalize.ts → coercion/normalize.ts} +1 -1
- package/src/internal/coercion/rules.d.ts +6 -0
- package/src/internal/{coercion-rules.ts → coercion/rules.ts} +2 -2
- package/src/internal/column-state.d.ts +190 -0
- package/src/internal/column-state.ts +43 -47
- package/src/internal/column.ts +43 -305
- package/src/internal/datatypes/define.d.ts +17 -0
- package/src/internal/datatypes/define.ts +18 -4
- package/src/internal/datatypes/lookup.d.ts +44 -0
- package/src/internal/datatypes/lookup.ts +61 -152
- package/src/internal/datatypes/shape.d.ts +16 -0
- package/src/internal/datatypes/shape.ts +1 -1
- package/src/internal/derived-table.d.ts +4 -0
- package/src/internal/derived-table.ts +21 -16
- package/src/internal/dialect.ts +12 -1
- package/src/internal/dsl-mutation-runtime.ts +378 -0
- package/src/internal/dsl-plan-runtime.ts +387 -0
- package/src/internal/dsl-query-runtime.ts +160 -0
- package/src/internal/dsl-transaction-ddl-runtime.ts +263 -0
- package/src/internal/executor.ts +146 -34
- package/src/internal/expression-ast.ts +15 -5
- package/src/internal/grouping-key.d.ts +3 -0
- package/src/internal/grouping-key.ts +1 -1
- package/src/internal/implication-runtime.d.ts +15 -0
- package/src/internal/implication-runtime.ts +4 -4
- package/src/internal/json/ast.d.ts +30 -0
- package/src/internal/json/ast.ts +1 -1
- package/src/internal/json/errors.d.ts +8 -0
- package/src/internal/json/path.d.ts +75 -0
- package/src/internal/json/path.ts +1 -1
- package/src/internal/json/types.d.ts +62 -0
- package/src/internal/predicate/analysis.d.ts +20 -0
- package/src/internal/predicate/analysis.ts +183 -0
- package/src/internal/predicate/atom.d.ts +28 -0
- package/src/internal/{predicate-atom.ts → predicate/atom.ts} +7 -0
- package/src/internal/{predicate-branches.ts → predicate/branches.ts} +2 -2
- package/src/internal/predicate/context.d.ts +67 -0
- package/src/internal/{predicate-context.ts → predicate/context.ts} +163 -20
- package/src/internal/predicate/formula.d.ts +35 -0
- package/src/internal/{predicate-formula.ts → predicate/formula.ts} +1 -1
- package/src/internal/predicate/key.d.ts +11 -0
- package/src/internal/predicate/key.ts +73 -0
- package/src/internal/{predicate-nnf.ts → predicate/nnf.ts} +2 -2
- package/src/internal/predicate/normalize.d.ts +53 -0
- package/src/internal/{predicate-normalize.ts → predicate/normalize.ts} +130 -49
- package/src/internal/predicate/runtime.d.ts +31 -0
- package/src/internal/{predicate-runtime.ts → predicate/runtime.ts} +127 -17
- package/src/internal/projection-alias.d.ts +13 -0
- package/src/internal/projections.d.ts +31 -0
- package/src/internal/projections.ts +1 -1
- package/src/internal/query-ast.d.ts +217 -0
- package/src/internal/query-ast.ts +1 -1
- package/src/internal/query-requirements.d.ts +20 -0
- package/src/internal/query.d.ts +775 -0
- package/src/internal/query.ts +683 -369
- package/src/internal/renderer.ts +11 -21
- package/src/internal/row-set.d.ts +53 -0
- package/src/internal/{plan.ts → row-set.ts} +11 -9
- package/src/internal/runtime/driver-value-mapping.ts +186 -0
- package/src/internal/{runtime-normalize.ts → runtime/normalize.ts} +9 -31
- package/src/internal/{runtime-schema.ts → runtime/schema.ts} +13 -38
- package/src/internal/runtime/value.d.ts +22 -0
- package/src/internal/{runtime-value.ts → runtime/value.ts} +2 -2
- package/src/internal/scalar.d.ts +107 -0
- package/src/internal/scalar.ts +202 -0
- package/src/internal/schema-derivation.d.ts +105 -0
- package/src/internal/schema-expression.d.ts +18 -0
- package/src/internal/schema-expression.ts +38 -7
- package/src/internal/table-options.d.ts +94 -0
- package/src/internal/table-options.ts +8 -2
- package/src/internal/table.d.ts +173 -0
- package/src/internal/table.ts +32 -14
- package/src/mysql/column.ts +95 -18
- package/src/mysql/datatypes/index.ts +47 -7
- package/src/mysql/errors/generated.ts +57336 -0
- package/src/mysql/errors/index.ts +1 -0
- package/src/mysql/errors/normalize.ts +55 -53
- package/src/mysql/errors/types.ts +74 -0
- package/src/mysql/executor.ts +88 -11
- package/src/mysql/function/aggregate.ts +1 -5
- package/src/mysql/function/core.ts +1 -4
- package/src/mysql/function/index.ts +0 -1
- package/src/mysql/function/string.ts +1 -5
- package/src/mysql/function/temporal.ts +12 -15
- package/src/mysql/function/window.ts +1 -6
- package/src/{internal/mysql-dialect.ts → mysql/internal/dialect.ts} +12 -6
- package/src/{internal/mysql-query.ts → mysql/internal/dsl.ts} +1299 -2143
- package/src/mysql/internal/renderer.ts +46 -0
- package/src/mysql/internal/sql-expression-renderer.ts +1501 -0
- package/src/mysql/json.ts +2 -0
- package/src/mysql/query.ts +111 -91
- package/src/mysql/renderer.ts +8 -3
- package/src/mysql/table.ts +1 -1
- package/src/mysql.ts +6 -4
- package/src/postgres/cast.ts +30 -16
- package/src/postgres/column.ts +179 -46
- package/src/postgres/datatypes/index.d.ts +515 -0
- package/src/postgres/datatypes/index.ts +22 -13
- package/src/postgres/datatypes/spec.d.ts +412 -0
- package/src/postgres/errors/generated.ts +2636 -0
- package/src/postgres/errors/index.ts +1 -0
- package/src/postgres/errors/normalize.ts +47 -62
- package/src/postgres/errors/types.ts +92 -34
- package/src/postgres/executor.ts +54 -7
- package/src/postgres/function/aggregate.ts +1 -5
- package/src/postgres/function/core.ts +12 -6
- package/src/postgres/function/index.ts +0 -1
- package/src/postgres/function/string.ts +1 -5
- package/src/postgres/function/temporal.ts +12 -15
- package/src/postgres/function/window.ts +1 -6
- package/src/{internal/postgres-dialect.ts → postgres/internal/dialect.ts} +12 -6
- package/src/{internal/postgres-query.ts → postgres/internal/dsl.ts} +1356 -2133
- package/src/{internal/postgres-renderer.ts → postgres/internal/renderer.ts} +17 -8
- package/src/postgres/internal/schema-ddl.ts +108 -0
- package/src/{internal/postgres-schema-model.ts → postgres/internal/schema-model.ts} +12 -6
- package/src/{internal → postgres/internal}/sql-expression-renderer.ts +79 -25
- package/src/postgres/{function/json.ts → json.ts} +77 -85
- package/src/postgres/metadata.ts +2 -2
- package/src/postgres/query.ts +113 -89
- package/src/postgres/renderer.ts +8 -13
- package/src/postgres/schema-expression.ts +2 -1
- package/src/postgres/schema-management.ts +1 -1
- package/src/postgres/table.ts +12 -4
- package/src/postgres/type.ts +33 -2
- package/src/postgres.ts +6 -4
- package/src/internal/expression.ts +0 -327
- package/src/internal/mysql-renderer.ts +0 -37
- package/src/internal/predicate-analysis.ts +0 -81
- package/src/internal/predicate-key.ts +0 -28
- package/src/internal/schema-ddl.ts +0 -55
- package/src/mysql/function/json.ts +0 -4
- package/src/mysql/private/query.ts +0 -1
- package/src/postgres/private/query.ts +0 -1
package/src/internal/renderer.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as Query from "./query.js"
|
|
2
|
+
import type * as Expression from "./scalar.js"
|
|
2
3
|
import { type Projection, validateProjections } from "./projections.js"
|
|
3
|
-
import { renderPostgresPlan } from "./postgres-renderer.js"
|
|
4
4
|
|
|
5
5
|
/** Symbol used to attach rendered-query phantom row metadata. */
|
|
6
6
|
export const TypeId: unique symbol = Symbol.for("effect-qb/Renderer")
|
|
@@ -22,6 +22,7 @@ export interface RenderedQuery<Row, Dialect extends string = string> {
|
|
|
22
22
|
readonly params: readonly unknown[]
|
|
23
23
|
readonly dialect: Dialect
|
|
24
24
|
readonly projections: readonly Projection[]
|
|
25
|
+
readonly valueMappings?: Expression.DriverValueMappings
|
|
25
26
|
readonly [TypeId]: {
|
|
26
27
|
readonly row: Row
|
|
27
28
|
readonly dialect: Dialect
|
|
@@ -41,53 +42,45 @@ export type RowOf<Value extends RenderedQuery<any, any>> = Value[typeof TypeId][
|
|
|
41
42
|
*/
|
|
42
43
|
export interface Renderer<Dialect extends string = string> {
|
|
43
44
|
readonly dialect: Dialect
|
|
44
|
-
render<PlanValue extends Query.
|
|
45
|
+
render<PlanValue extends Query.Plan.Any>(
|
|
45
46
|
plan: Query.DialectCompatiblePlan<PlanValue, Dialect>
|
|
46
47
|
): RenderedQuery<any, Dialect>
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
type CustomRender<Dialect extends string> = <PlanValue extends Query.
|
|
50
|
+
type CustomRender<Dialect extends string> = <PlanValue extends Query.Plan.Any>(
|
|
50
51
|
plan: Query.DialectCompatiblePlan<PlanValue, Dialect>
|
|
51
52
|
) => {
|
|
52
53
|
readonly sql: string
|
|
53
54
|
readonly params?: readonly unknown[]
|
|
54
55
|
readonly projections?: readonly Projection[]
|
|
56
|
+
readonly valueMappings?: Expression.DriverValueMappings
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
/**
|
|
58
|
-
* Constructs a renderer from a dialect and
|
|
59
|
-
*
|
|
60
|
-
* When no callback is provided, the library supplies a built-in renderer for
|
|
61
|
-
* `"postgres"` that consumes the query AST directly and produces SQL text plus
|
|
62
|
-
* parameter values.
|
|
60
|
+
* Constructs a renderer from a dialect and implementation callback.
|
|
63
61
|
*/
|
|
64
|
-
export function make(dialect: "postgres"): Renderer<"postgres">
|
|
65
62
|
export function make<Dialect extends string>(
|
|
66
63
|
dialect: Dialect,
|
|
67
64
|
render: CustomRender<Dialect>
|
|
68
65
|
): Renderer<Dialect>
|
|
69
66
|
export function make<Dialect extends string>(
|
|
70
67
|
dialect: Dialect,
|
|
71
|
-
render
|
|
68
|
+
render: CustomRender<Dialect>
|
|
72
69
|
): Renderer<Dialect> {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
: undefined) as CustomRender<Dialect> | undefined)
|
|
76
|
-
|
|
77
|
-
if (!implementation) {
|
|
78
|
-
throw new Error(`No built-in renderer for dialect: ${dialect}`)
|
|
70
|
+
if (typeof render !== "function") {
|
|
71
|
+
throw new Error(`Renderer.make requires an explicit render implementation for dialect: ${dialect}`)
|
|
79
72
|
}
|
|
80
|
-
|
|
81
73
|
return {
|
|
82
74
|
dialect,
|
|
83
75
|
render(plan) {
|
|
84
|
-
const rendered =
|
|
76
|
+
const rendered = render(plan)
|
|
85
77
|
const projections = rendered.projections ?? []
|
|
86
78
|
validateProjections(projections)
|
|
87
79
|
return {
|
|
88
80
|
sql: rendered.sql,
|
|
89
81
|
params: rendered.params ?? [],
|
|
90
82
|
projections,
|
|
83
|
+
valueMappings: rendered.valueMappings,
|
|
91
84
|
dialect,
|
|
92
85
|
[TypeId]: {
|
|
93
86
|
row: undefined as any,
|
|
@@ -97,6 +90,3 @@ export function make<Dialect extends string>(
|
|
|
97
90
|
}
|
|
98
91
|
} as Renderer<Dialect>
|
|
99
92
|
}
|
|
100
|
-
|
|
101
|
-
/** Built-in Postgres renderer backed by the current query AST. */
|
|
102
|
-
export const postgres = make("postgres")
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Pipeable } from "effect/Pipeable";
|
|
2
|
+
import type { PredicateFormula } from "./predicate/formula.js";
|
|
3
|
+
/** Symbol used to attach logical-plan metadata to runtime values. */
|
|
4
|
+
export declare const TypeId: unique symbol;
|
|
5
|
+
export type TypeId = typeof TypeId;
|
|
6
|
+
/**
|
|
7
|
+
* Source availability mode within a query scope.
|
|
8
|
+
*
|
|
9
|
+
* `required` means the source is guaranteed to produce a row at this point in
|
|
10
|
+
* the plan. `optional` means the source may be absent, such as the nullable
|
|
11
|
+
* side of a left join.
|
|
12
|
+
*/
|
|
13
|
+
export type SourceMode = "required" | "optional";
|
|
14
|
+
/** Source made available to a plan. */
|
|
15
|
+
export interface Source<Name extends string = string, Mode extends SourceMode = SourceMode, PresentFormula extends PredicateFormula = PredicateFormula, PresenceWitness extends string = never> {
|
|
16
|
+
readonly name: Name;
|
|
17
|
+
readonly mode: Mode;
|
|
18
|
+
readonly baseName?: string;
|
|
19
|
+
readonly _presentFormula?: PresentFormula;
|
|
20
|
+
readonly _presenceWitnesses?: readonly PresenceWitness[];
|
|
21
|
+
}
|
|
22
|
+
export type AnySource = Source<string, SourceMode, PredicateFormula, string>;
|
|
23
|
+
/**
|
|
24
|
+
* Canonical static metadata stored on a plan.
|
|
25
|
+
*
|
|
26
|
+
* `required` tracks sources that the selection references but which are not yet
|
|
27
|
+
* in scope. `available` tracks sources already in scope for subsequent query
|
|
28
|
+
* operations.
|
|
29
|
+
*/
|
|
30
|
+
export interface State<Columns, Required, Available extends Record<string, AnySource>, Dialect extends string> {
|
|
31
|
+
readonly selection: Columns;
|
|
32
|
+
readonly required: Required;
|
|
33
|
+
readonly available: Available;
|
|
34
|
+
readonly dialect: Dialect;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A composable logical row set.
|
|
38
|
+
*
|
|
39
|
+
* Tables implement this interface as already-complete plans. Future query
|
|
40
|
+
* builders such as `select()` and `from()` should produce and transform values
|
|
41
|
+
* with this same structure.
|
|
42
|
+
*/
|
|
43
|
+
export interface RowSet<Columns, Required = never, Available extends Record<string, AnySource> = {}, Dialect extends string = never> extends Pipeable {
|
|
44
|
+
readonly [TypeId]: State<Columns, Required, Available, Dialect>;
|
|
45
|
+
}
|
|
46
|
+
/** Convenience alias for any plan-like value. */
|
|
47
|
+
export type Any = RowSet<any, any, Record<string, AnySource>, string>;
|
|
48
|
+
/** Extracts a row set's columns shape. */
|
|
49
|
+
export type ColumnsOf<Value extends Any> = Value[typeof TypeId]["selection"];
|
|
50
|
+
/** Extracts a plan's selection shape. */
|
|
51
|
+
export type SelectionOf<Value extends Any> = ColumnsOf<Value>;
|
|
52
|
+
/** Extracts a plan's effective dialect. */
|
|
53
|
+
export type DialectOf<Value extends Any> = Value[typeof TypeId]["dialect"];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Pipeable } from "effect/Pipeable"
|
|
2
|
-
import type { PredicateFormula } from "./predicate
|
|
2
|
+
import type { PredicateFormula } from "./predicate/formula.js"
|
|
3
3
|
|
|
4
4
|
/** Symbol used to attach logical-plan metadata to runtime values. */
|
|
5
5
|
export const TypeId: unique symbol = Symbol.for("effect-qb/Plan")
|
|
@@ -39,36 +39,38 @@ export type AnySource = Source<string, SourceMode, PredicateFormula, string>
|
|
|
39
39
|
* operations.
|
|
40
40
|
*/
|
|
41
41
|
export interface State<
|
|
42
|
-
|
|
42
|
+
Columns,
|
|
43
43
|
Required,
|
|
44
44
|
Available extends Record<string, AnySource>,
|
|
45
45
|
Dialect extends string
|
|
46
46
|
> {
|
|
47
|
-
readonly selection:
|
|
47
|
+
readonly selection: Columns
|
|
48
48
|
readonly required: Required
|
|
49
49
|
readonly available: Available
|
|
50
50
|
readonly dialect: Dialect
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
|
-
* A composable logical
|
|
54
|
+
* A composable logical row set.
|
|
55
55
|
*
|
|
56
56
|
* Tables implement this interface as already-complete plans. Future query
|
|
57
57
|
* builders such as `select()` and `from()` should produce and transform values
|
|
58
58
|
* with this same structure.
|
|
59
59
|
*/
|
|
60
|
-
export interface
|
|
61
|
-
|
|
60
|
+
export interface RowSet<
|
|
61
|
+
Columns,
|
|
62
62
|
Required = never,
|
|
63
63
|
Available extends Record<string, AnySource> = {},
|
|
64
64
|
Dialect extends string = never
|
|
65
65
|
> extends Pipeable {
|
|
66
|
-
readonly [TypeId]: State<
|
|
66
|
+
readonly [TypeId]: State<Columns, Required, Available, Dialect>
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/** Convenience alias for any plan-like value. */
|
|
70
|
-
export type Any =
|
|
70
|
+
export type Any = RowSet<any, any, Record<string, AnySource>, string>
|
|
71
|
+
/** Extracts a row set's columns shape. */
|
|
72
|
+
export type ColumnsOf<Value extends Any> = Value[typeof TypeId]["selection"]
|
|
71
73
|
/** Extracts a plan's selection shape. */
|
|
72
|
-
export type SelectionOf<Value extends Any> = Value
|
|
74
|
+
export type SelectionOf<Value extends Any> = ColumnsOf<Value>
|
|
73
75
|
/** Extracts a plan's effective dialect. */
|
|
74
76
|
export type DialectOf<Value extends Any> = Value[typeof TypeId]["dialect"]
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema"
|
|
2
|
+
|
|
3
|
+
import type * as Expression from "../scalar.js"
|
|
4
|
+
import { normalizeDbValue } from "./normalize.js"
|
|
5
|
+
|
|
6
|
+
export type DriverValueMapping = Expression.DriverValueMapping
|
|
7
|
+
export type DriverValueMappings = Expression.DriverValueMappings
|
|
8
|
+
|
|
9
|
+
export interface DriverValueContext {
|
|
10
|
+
readonly dialect?: string
|
|
11
|
+
readonly dbType?: Expression.DbType.Any
|
|
12
|
+
readonly runtimeSchema?: Schema.Schema.Any
|
|
13
|
+
readonly driverValueMapping?: DriverValueMapping
|
|
14
|
+
readonly valueMappings?: DriverValueMappings
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type MappingKey =
|
|
18
|
+
| "fromDriver"
|
|
19
|
+
| "toDriver"
|
|
20
|
+
| "selectSql"
|
|
21
|
+
| "jsonSelectSql"
|
|
22
|
+
|
|
23
|
+
const runtimeTagOfDbType = (
|
|
24
|
+
dbType: Expression.DbType.Any | undefined
|
|
25
|
+
): string | undefined => {
|
|
26
|
+
if (dbType === undefined) {
|
|
27
|
+
return undefined
|
|
28
|
+
}
|
|
29
|
+
if ("base" in dbType) {
|
|
30
|
+
return runtimeTagOfDbType(dbType.base)
|
|
31
|
+
}
|
|
32
|
+
if ("element" in dbType) {
|
|
33
|
+
return "array"
|
|
34
|
+
}
|
|
35
|
+
if ("fields" in dbType) {
|
|
36
|
+
return "record"
|
|
37
|
+
}
|
|
38
|
+
if ("variant" in dbType && dbType.variant === "json") {
|
|
39
|
+
return "json"
|
|
40
|
+
}
|
|
41
|
+
if ("variant" in dbType && (dbType.variant === "enum" || dbType.variant === "set")) {
|
|
42
|
+
return "string"
|
|
43
|
+
}
|
|
44
|
+
return dbType.runtime
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const familyOfDbType = (
|
|
48
|
+
dbType: Expression.DbType.Any | undefined
|
|
49
|
+
): string | undefined => {
|
|
50
|
+
if (dbType === undefined) {
|
|
51
|
+
return undefined
|
|
52
|
+
}
|
|
53
|
+
if ("base" in dbType) {
|
|
54
|
+
return familyOfDbType(dbType.base)
|
|
55
|
+
}
|
|
56
|
+
return dbType.family
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const mappingCandidates = (
|
|
60
|
+
context: DriverValueContext
|
|
61
|
+
): readonly (DriverValueMapping | undefined)[] => {
|
|
62
|
+
const dbType = context.dbType
|
|
63
|
+
const runtimeTag = runtimeTagOfDbType(dbType)
|
|
64
|
+
const family = familyOfDbType(dbType)
|
|
65
|
+
return [
|
|
66
|
+
context.driverValueMapping,
|
|
67
|
+
dbType?.driverValueMapping,
|
|
68
|
+
dbType === undefined ? undefined : context.valueMappings?.[dbType.kind],
|
|
69
|
+
family === undefined ? undefined : context.valueMappings?.[family],
|
|
70
|
+
runtimeTag === undefined ? undefined : context.valueMappings?.[runtimeTag]
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const findMapping = <Key extends MappingKey>(
|
|
75
|
+
context: DriverValueContext,
|
|
76
|
+
key: Key
|
|
77
|
+
): NonNullable<DriverValueMapping[Key]> | undefined => {
|
|
78
|
+
for (const candidate of mappingCandidates(context)) {
|
|
79
|
+
const value = candidate?.[key]
|
|
80
|
+
if (value !== undefined) {
|
|
81
|
+
return value as NonNullable<DriverValueMapping[Key]>
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return undefined
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const encodeWithSchema = (
|
|
88
|
+
schema: Schema.Schema.Any | undefined,
|
|
89
|
+
value: unknown
|
|
90
|
+
): { readonly value: unknown; readonly encoded: boolean } => {
|
|
91
|
+
if (schema === undefined) {
|
|
92
|
+
return { value, encoded: false }
|
|
93
|
+
}
|
|
94
|
+
if (!(Schema.is(schema) as (value: unknown) => boolean)(value)) {
|
|
95
|
+
return { value, encoded: false }
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
value: (Schema.encodeUnknownSync as any)(schema)(value),
|
|
99
|
+
encoded: true
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const toDriverValue = (
|
|
104
|
+
value: unknown,
|
|
105
|
+
context: DriverValueContext
|
|
106
|
+
): unknown => {
|
|
107
|
+
if (value === null) {
|
|
108
|
+
return null
|
|
109
|
+
}
|
|
110
|
+
const dbType = context.dbType
|
|
111
|
+
const encoded = encodeWithSchema(context.runtimeSchema, value)
|
|
112
|
+
let current = encoded.value
|
|
113
|
+
const custom = findMapping(context, "toDriver")
|
|
114
|
+
if (custom !== undefined && dbType !== undefined) {
|
|
115
|
+
return custom(current, dbType)
|
|
116
|
+
}
|
|
117
|
+
return dbType === undefined || !encoded.encoded
|
|
118
|
+
? current
|
|
119
|
+
: normalizeDbValue(dbType, current)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const fromDriverValue = (
|
|
123
|
+
value: unknown,
|
|
124
|
+
context: DriverValueContext
|
|
125
|
+
): unknown => {
|
|
126
|
+
if (value === null) {
|
|
127
|
+
return null
|
|
128
|
+
}
|
|
129
|
+
const dbType = context.dbType
|
|
130
|
+
const custom = findMapping(context, "fromDriver")
|
|
131
|
+
if (custom !== undefined && dbType !== undefined) {
|
|
132
|
+
return custom(value, dbType)
|
|
133
|
+
}
|
|
134
|
+
return dbType === undefined
|
|
135
|
+
? value
|
|
136
|
+
: normalizeDbValue(dbType, value)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const textCast = (sql: string): string => `(${sql})::text`
|
|
140
|
+
|
|
141
|
+
const postgresJsonSql = (
|
|
142
|
+
sql: string,
|
|
143
|
+
dbType: Expression.DbType.Any
|
|
144
|
+
): string => {
|
|
145
|
+
const runtimeTag = runtimeTagOfDbType(dbType)
|
|
146
|
+
switch (runtimeTag) {
|
|
147
|
+
case "bigintString":
|
|
148
|
+
case "decimalString":
|
|
149
|
+
case "localDate":
|
|
150
|
+
case "localTime":
|
|
151
|
+
case "offsetTime":
|
|
152
|
+
case "localDateTime":
|
|
153
|
+
case "instant":
|
|
154
|
+
case "year":
|
|
155
|
+
return textCast(sql)
|
|
156
|
+
case "bytes":
|
|
157
|
+
return `encode(${sql}, 'base64')`
|
|
158
|
+
default:
|
|
159
|
+
return sql
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export const renderSelectSql = (
|
|
164
|
+
sql: string,
|
|
165
|
+
context: DriverValueContext
|
|
166
|
+
): string => {
|
|
167
|
+
const dbType = context.dbType
|
|
168
|
+
const custom = findMapping(context, "selectSql")
|
|
169
|
+
return custom !== undefined && dbType !== undefined
|
|
170
|
+
? custom(sql, dbType)
|
|
171
|
+
: sql
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export const renderJsonSelectSql = (
|
|
175
|
+
sql: string,
|
|
176
|
+
context: DriverValueContext
|
|
177
|
+
): string => {
|
|
178
|
+
const dbType = context.dbType
|
|
179
|
+
const custom = findMapping(context, "jsonSelectSql")
|
|
180
|
+
if (custom !== undefined && dbType !== undefined) {
|
|
181
|
+
return custom(sql, dbType)
|
|
182
|
+
}
|
|
183
|
+
return context.dialect === "postgres" && dbType !== undefined
|
|
184
|
+
? postgresJsonSql(sql, dbType)
|
|
185
|
+
: sql
|
|
186
|
+
}
|
|
@@ -1,22 +1,5 @@
|
|
|
1
|
-
import type * as Expression from "
|
|
2
|
-
import {
|
|
3
|
-
import { postgresDatatypeKinds } from "../postgres/datatypes/spec.js"
|
|
4
|
-
import type { RuntimeTag } from "./datatypes/shape.js"
|
|
5
|
-
|
|
6
|
-
const stripParameterizedKind = (kind: string): string => {
|
|
7
|
-
const openParen = kind.indexOf("(")
|
|
8
|
-
return openParen === -1 ? kind : kind.slice(0, openParen)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const stripArrayKind = (kind: string): string => {
|
|
12
|
-
let current = kind
|
|
13
|
-
while (current.endsWith("[]")) {
|
|
14
|
-
current = current.slice(0, -2)
|
|
15
|
-
}
|
|
16
|
-
return current
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const baseKind = (kind: string): string => stripArrayKind(stripParameterizedKind(kind))
|
|
1
|
+
import type * as Expression from "../scalar.js"
|
|
2
|
+
import type { RuntimeTag } from "../datatypes/shape.js"
|
|
20
3
|
|
|
21
4
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
22
5
|
typeof value === "object" && value !== null && !Array.isArray(value)
|
|
@@ -39,17 +22,9 @@ const formatLocalDateTime = (value: Date): string => {
|
|
|
39
22
|
}
|
|
40
23
|
|
|
41
24
|
const runtimeTagOfBaseDbType = (
|
|
42
|
-
|
|
43
|
-
kind: string
|
|
25
|
+
dbType: Expression.DbType.Base<string, string>
|
|
44
26
|
): RuntimeTag | undefined => {
|
|
45
|
-
|
|
46
|
-
if (dialect === "postgres") {
|
|
47
|
-
return postgresDatatypeKinds[normalizedKind as keyof typeof postgresDatatypeKinds]?.runtime
|
|
48
|
-
}
|
|
49
|
-
if (dialect === "mysql") {
|
|
50
|
-
return mysqlDatatypeKinds[normalizedKind as keyof typeof mysqlDatatypeKinds]?.runtime
|
|
51
|
-
}
|
|
52
|
-
return undefined
|
|
27
|
+
return dbType.runtime
|
|
53
28
|
}
|
|
54
29
|
|
|
55
30
|
const expectString = (value: unknown, label: string): string => {
|
|
@@ -225,7 +200,10 @@ const normalizeBytes = (value: unknown): Uint8Array => {
|
|
|
225
200
|
if (value instanceof Uint8Array) {
|
|
226
201
|
return new Uint8Array(value)
|
|
227
202
|
}
|
|
228
|
-
|
|
203
|
+
const BufferConstructor = (globalThis as {
|
|
204
|
+
readonly Buffer?: abstract new (...args: never[]) => Uint8Array
|
|
205
|
+
}).Buffer
|
|
206
|
+
if (BufferConstructor !== undefined && value instanceof BufferConstructor) {
|
|
229
207
|
return new Uint8Array(value)
|
|
230
208
|
}
|
|
231
209
|
throw new Error("Expected a byte array value")
|
|
@@ -298,7 +276,7 @@ export const normalizeDbValue = (
|
|
|
298
276
|
if ("variant" in dbType && (dbType.variant === "enum" || dbType.variant === "set")) {
|
|
299
277
|
return expectString(value, "text")
|
|
300
278
|
}
|
|
301
|
-
switch (runtimeTagOfBaseDbType(dbType
|
|
279
|
+
switch (runtimeTagOfBaseDbType(dbType)) {
|
|
302
280
|
case "string":
|
|
303
281
|
return expectString(value, "text")
|
|
304
282
|
case "number":
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import * as Schema from "effect/Schema"
|
|
2
2
|
import * as SchemaAST from "effect/SchemaAST"
|
|
3
3
|
|
|
4
|
-
import * as Expression from "
|
|
5
|
-
import * as ExpressionAst from "
|
|
6
|
-
import * as Query from "
|
|
7
|
-
import * as JsonPath from "
|
|
8
|
-
import type { PredicateFormula } from "
|
|
4
|
+
import * as Expression from "../scalar.js"
|
|
5
|
+
import * as ExpressionAst from "../expression-ast.js"
|
|
6
|
+
import * as Query from "../query.js"
|
|
7
|
+
import * as JsonPath from "../json/path.js"
|
|
8
|
+
import type { PredicateFormula } from "../predicate/formula.js"
|
|
9
9
|
import {
|
|
10
10
|
assumeFormulaFalse,
|
|
11
11
|
assumeFormulaTrue,
|
|
12
12
|
contradictsFormula,
|
|
13
13
|
formulaOfExpression as formulaOfExpressionRuntime,
|
|
14
14
|
impliesFormula
|
|
15
|
-
} from "
|
|
16
|
-
import { flattenSelection } from "
|
|
15
|
+
} from "../predicate/runtime.js"
|
|
16
|
+
import { flattenSelection } from "../projections.js"
|
|
17
17
|
import {
|
|
18
18
|
BigIntStringSchema,
|
|
19
19
|
DecimalStringSchema,
|
|
@@ -24,10 +24,8 @@ import {
|
|
|
24
24
|
LocalTimeStringSchema,
|
|
25
25
|
OffsetTimeStringSchema,
|
|
26
26
|
YearStringSchema
|
|
27
|
-
} from "./
|
|
28
|
-
import {
|
|
29
|
-
import { postgresDatatypeKinds } from "../postgres/datatypes/spec.js"
|
|
30
|
-
import type { RuntimeTag } from "./datatypes/shape.js"
|
|
27
|
+
} from "./value.js"
|
|
28
|
+
import type { RuntimeTag } from "../datatypes/shape.js"
|
|
31
29
|
|
|
32
30
|
export type RuntimeSchema = Schema.Schema<any, any, any>
|
|
33
31
|
|
|
@@ -37,21 +35,6 @@ type SchemaContext = {
|
|
|
37
35
|
|
|
38
36
|
const schemaCache = new WeakMap<Expression.Any, RuntimeSchema | undefined>()
|
|
39
37
|
|
|
40
|
-
const stripParameterizedKind = (kind: string): string => {
|
|
41
|
-
const openParen = kind.indexOf("(")
|
|
42
|
-
return openParen === -1 ? kind : kind.slice(0, openParen)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const stripArrayKind = (kind: string): string => {
|
|
46
|
-
let current = kind
|
|
47
|
-
while (current.endsWith("[]")) {
|
|
48
|
-
current = current.slice(0, -2)
|
|
49
|
-
}
|
|
50
|
-
return current
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const baseKind = (kind: string): string => stripArrayKind(stripParameterizedKind(kind))
|
|
54
|
-
|
|
55
38
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
56
39
|
typeof value === "object" && value !== null && !Array.isArray(value)
|
|
57
40
|
|
|
@@ -98,17 +81,9 @@ const runtimeSchemaForTag = (tag: RuntimeTag): RuntimeSchema | undefined => {
|
|
|
98
81
|
}
|
|
99
82
|
|
|
100
83
|
const runtimeTagOfBaseDbType = (
|
|
101
|
-
|
|
102
|
-
kind: string
|
|
84
|
+
dbType: Expression.DbType.Base<string, string>
|
|
103
85
|
): RuntimeTag | undefined => {
|
|
104
|
-
|
|
105
|
-
if (dialect === "postgres") {
|
|
106
|
-
return postgresDatatypeKinds[normalizedKind as keyof typeof postgresDatatypeKinds]?.runtime
|
|
107
|
-
}
|
|
108
|
-
if (dialect === "mysql") {
|
|
109
|
-
return mysqlDatatypeKinds[normalizedKind as keyof typeof mysqlDatatypeKinds]?.runtime
|
|
110
|
-
}
|
|
111
|
-
return undefined
|
|
86
|
+
return dbType.runtime
|
|
112
87
|
}
|
|
113
88
|
|
|
114
89
|
export const runtimeSchemaForDbType = (
|
|
@@ -132,7 +107,7 @@ export const runtimeSchemaForDbType = (
|
|
|
132
107
|
if ("variant" in dbType && (dbType.variant === "enum" || dbType.variant === "set")) {
|
|
133
108
|
return Schema.String
|
|
134
109
|
}
|
|
135
|
-
const runtimeTag = runtimeTagOfBaseDbType(dbType
|
|
110
|
+
const runtimeTag = runtimeTagOfBaseDbType(dbType)
|
|
136
111
|
return runtimeTag === undefined ? undefined : runtimeSchemaForTag(runtimeTag)
|
|
137
112
|
}
|
|
138
113
|
|
|
@@ -257,7 +232,7 @@ const unionSchemas = (schemas: ReadonlyArray<RuntimeSchema | undefined>): Runtim
|
|
|
257
232
|
}
|
|
258
233
|
|
|
259
234
|
const firstSelectedExpression = (
|
|
260
|
-
plan: Query.
|
|
235
|
+
plan: Query.Plan.Any
|
|
261
236
|
): Expression.Any | undefined => {
|
|
262
237
|
const selection = Query.getAst(plan).select
|
|
263
238
|
return flattenSelection(selection as Record<string, unknown>)[0]?.expression
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type * as Brand from "effect/Brand";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import type { JsonPrimitive, JsonValue } from "../json/types.js";
|
|
4
|
+
export type { JsonPrimitive, JsonValue } from "../json/types.js";
|
|
5
|
+
export type LocalDateString = string & Brand.Brand<"LocalDateString">;
|
|
6
|
+
export type LocalTimeString = string & Brand.Brand<"LocalTimeString">;
|
|
7
|
+
export type OffsetTimeString = string & Brand.Brand<"OffsetTimeString">;
|
|
8
|
+
export type LocalDateTimeString = string & Brand.Brand<"LocalDateTimeString">;
|
|
9
|
+
export type InstantString = string & Brand.Brand<"InstantString">;
|
|
10
|
+
export type YearString = string & Brand.Brand<"YearString">;
|
|
11
|
+
export type BigIntString = string & Brand.Brand<"BigIntString">;
|
|
12
|
+
export type DecimalString = string & Brand.Brand<"DecimalString">;
|
|
13
|
+
export declare const LocalDateStringSchema: Schema.Schema<string & Brand.Brand<"LocalDateString">, string & Brand.Brand<"LocalDateString">, never>;
|
|
14
|
+
export declare const LocalTimeStringSchema: Schema.Schema<string & Brand.Brand<"LocalTimeString">, string & Brand.Brand<"LocalTimeString">, never>;
|
|
15
|
+
export declare const OffsetTimeStringSchema: Schema.Schema<string & Brand.Brand<"OffsetTimeString">, string & Brand.Brand<"OffsetTimeString">, never>;
|
|
16
|
+
export declare const LocalDateTimeStringSchema: Schema.Schema<string & Brand.Brand<"LocalDateTimeString">, string & Brand.Brand<"LocalDateTimeString">, never>;
|
|
17
|
+
export declare const InstantStringSchema: Schema.Schema<string & Brand.Brand<"InstantString">, string & Brand.Brand<"InstantString">, never>;
|
|
18
|
+
export declare const YearStringSchema: Schema.Schema<string & Brand.Brand<"YearString">, string & Brand.Brand<"YearString">, never>;
|
|
19
|
+
export declare const BigIntStringSchema: Schema.Schema<string & Brand.Brand<"BigIntString">, string & Brand.Brand<"BigIntString">, never>;
|
|
20
|
+
export declare const DecimalStringSchema: Schema.Schema<string & Brand.Brand<"DecimalString">, string & Brand.Brand<"DecimalString">, never>;
|
|
21
|
+
export declare const JsonValueSchema: Schema.Schema<JsonValue>;
|
|
22
|
+
export declare const JsonPrimitiveSchema: Schema.Schema<JsonPrimitive>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type * as Brand from "effect/Brand"
|
|
2
2
|
import * as Schema from "effect/Schema"
|
|
3
3
|
|
|
4
|
-
import type { JsonPrimitive, JsonValue } from "
|
|
4
|
+
import type { JsonPrimitive, JsonValue } from "../json/types.js"
|
|
5
5
|
|
|
6
|
-
export type { JsonPrimitive, JsonValue } from "
|
|
6
|
+
export type { JsonPrimitive, JsonValue } from "../json/types.js"
|
|
7
7
|
|
|
8
8
|
export type LocalDateString = string & Brand.Brand<"LocalDateString">
|
|
9
9
|
export type LocalTimeString = string & Brand.Brand<"LocalTimeString">
|