effect-qb 0.12.3 → 0.14.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 +6 -1283
- package/dist/mysql.js +6376 -4978
- package/dist/postgres/metadata.js +2724 -0
- package/dist/postgres.js +5475 -3636
- package/package.json +13 -8
- package/src/internal/column-state.ts +88 -6
- package/src/internal/column.ts +569 -34
- package/src/internal/datatypes/define.ts +0 -30
- package/src/internal/executor.ts +45 -11
- package/src/internal/expression-ast.ts +15 -0
- package/src/internal/expression.ts +3 -1
- package/src/internal/implication-runtime.ts +171 -0
- package/src/internal/mysql-query.ts +7173 -0
- package/src/internal/mysql-renderer.ts +2 -2
- package/src/internal/plan.ts +14 -4
- package/src/internal/{query-factory.ts → postgres-query.ts} +669 -230
- package/src/internal/postgres-renderer.ts +2 -2
- package/src/internal/postgres-schema-model.ts +144 -0
- package/src/internal/predicate-analysis.ts +10 -0
- package/src/internal/predicate-context.ts +112 -36
- package/src/internal/predicate-formula.ts +31 -19
- package/src/internal/predicate-normalize.ts +177 -106
- package/src/internal/predicate-runtime.ts +676 -0
- package/src/internal/query.ts +471 -41
- package/src/internal/renderer.ts +2 -2
- package/src/internal/runtime-schema.ts +74 -20
- package/src/internal/schema-ddl.ts +55 -0
- package/src/internal/schema-derivation.ts +93 -21
- package/src/internal/schema-expression.ts +44 -0
- package/src/internal/sql-expression-renderer.ts +123 -35
- package/src/internal/table-options.ts +88 -7
- package/src/internal/table.ts +106 -42
- package/src/mysql/column.ts +3 -1
- package/src/mysql/datatypes/index.ts +17 -2
- package/src/mysql/executor.ts +20 -17
- package/src/mysql/function/aggregate.ts +6 -0
- package/src/mysql/function/core.ts +5 -0
- package/src/mysql/function/index.ts +20 -0
- package/src/mysql/function/json.ts +4 -0
- package/src/mysql/function/string.ts +6 -0
- package/src/mysql/function/temporal.ts +103 -0
- package/src/mysql/function/window.ts +7 -0
- package/src/mysql/private/query.ts +1 -0
- package/src/mysql/query.ts +6 -26
- package/src/mysql.ts +2 -0
- package/src/postgres/cast.ts +31 -0
- package/src/postgres/column.ts +27 -1
- package/src/postgres/datatypes/index.ts +40 -5
- package/src/postgres/executor.ts +19 -17
- package/src/postgres/function/aggregate.ts +6 -0
- package/src/postgres/function/core.ts +16 -0
- package/src/postgres/function/index.ts +20 -0
- package/src/postgres/function/json.ts +501 -0
- package/src/postgres/function/string.ts +6 -0
- package/src/postgres/function/temporal.ts +107 -0
- package/src/postgres/function/window.ts +7 -0
- package/src/postgres/metadata.ts +31 -0
- package/src/postgres/private/query.ts +1 -0
- package/src/postgres/query.ts +6 -28
- package/src/postgres/schema-expression.ts +16 -0
- package/src/postgres/schema-management.ts +204 -0
- package/src/postgres/schema.ts +35 -0
- package/src/postgres/table.ts +307 -41
- package/src/postgres/type.ts +4 -0
- package/src/postgres.ts +16 -0
package/src/internal/table.ts
CHANGED
|
@@ -2,14 +2,18 @@ import { pipeArguments, type Pipeable } from "effect/Pipeable"
|
|
|
2
2
|
import * as Schema from "effect/Schema"
|
|
3
3
|
|
|
4
4
|
import * as Plan from "./plan.js"
|
|
5
|
+
import type { Any as AnyExpression } from "./expression.js"
|
|
6
|
+
import type { TrueFormula } from "./predicate-formula.js"
|
|
5
7
|
import type { BoundColumnFrom } from "./column-state.js"
|
|
6
8
|
import { bindColumn, type AnyColumnDefinition } from "./column-state.js"
|
|
7
9
|
import {
|
|
8
10
|
collectInlineOptions,
|
|
9
11
|
normalizeColumnList,
|
|
10
12
|
resolvePrimaryKeyColumns,
|
|
11
|
-
type
|
|
13
|
+
type DdlExpressionLike,
|
|
14
|
+
type IndexKeySpec,
|
|
12
15
|
type NormalizeColumns,
|
|
16
|
+
type ReferentialAction,
|
|
13
17
|
type TableOptionSpec,
|
|
14
18
|
type ValidateKnownColumns,
|
|
15
19
|
type ValidatePrimaryKeyColumns,
|
|
@@ -41,7 +45,16 @@ type TableDialect<Fields extends TableFieldMap> = Fields[keyof Fields][typeof im
|
|
|
41
45
|
type TableKind = "schema" | "alias"
|
|
42
46
|
type DefaultSchemaName = "public"
|
|
43
47
|
type ClassOptionSpec = Exclude<TableOptionSpec, { readonly kind: "primaryKey" }>
|
|
44
|
-
|
|
48
|
+
interface TableOptionBuilderLike<
|
|
49
|
+
Spec extends TableOptionSpec = TableOptionSpec
|
|
50
|
+
> {
|
|
51
|
+
(
|
|
52
|
+
table: TableDefinition<any, any, any, "schema", any>
|
|
53
|
+
): TableDefinition<any, any, any, "schema", any>
|
|
54
|
+
readonly option: Spec
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
type ClassTableOption = TableOptionBuilderLike<ClassOptionSpec>
|
|
45
58
|
type ClassDeclaredTableOptions = readonly ClassTableOption[]
|
|
46
59
|
|
|
47
60
|
type BuildPrimaryKey<
|
|
@@ -82,12 +95,13 @@ export type BoundColumns<
|
|
|
82
95
|
|
|
83
96
|
/** Derived runtime schemas exposed by a table definition. */
|
|
84
97
|
export interface TableSchemas<
|
|
98
|
+
Name extends string,
|
|
85
99
|
Fields extends TableFieldMap,
|
|
86
100
|
PrimaryKeyColumns extends keyof Fields & string
|
|
87
101
|
> {
|
|
88
|
-
readonly select: Schema.Schema<SelectRow<Fields>>
|
|
89
|
-
readonly insert: Schema.Schema<InsertRow<Fields>>
|
|
90
|
-
readonly update: Schema.Schema<UpdateRow<Fields, PrimaryKeyColumns>>
|
|
102
|
+
readonly select: Schema.Schema<SelectRow<Name, Fields>>
|
|
103
|
+
readonly insert: Schema.Schema<InsertRow<Name, Fields>>
|
|
104
|
+
readonly update: Schema.Schema<UpdateRow<Name, Fields, PrimaryKeyColumns>>
|
|
91
105
|
}
|
|
92
106
|
|
|
93
107
|
interface TableState<
|
|
@@ -115,11 +129,12 @@ export interface TableSchemaNamespace<SchemaName extends string> {
|
|
|
115
129
|
>(
|
|
116
130
|
name: Name,
|
|
117
131
|
fields: Fields,
|
|
118
|
-
...options:
|
|
132
|
+
...options: DeclaredTableOptions
|
|
119
133
|
) => TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>
|
|
120
134
|
}
|
|
121
135
|
|
|
122
|
-
export type DeclaredTableOptions =
|
|
136
|
+
export type DeclaredTableOptions = readonly TableOptionBuilderLike[]
|
|
137
|
+
export type { DdlExpressionLike, IndexKeySpec, NormalizeColumns, ReferentialAction } from "./table-options.js"
|
|
123
138
|
|
|
124
139
|
export type TableDefinition<
|
|
125
140
|
Name extends string,
|
|
@@ -130,12 +145,12 @@ export type TableDefinition<
|
|
|
130
145
|
> = Pipeable & {
|
|
131
146
|
readonly name: Name
|
|
132
147
|
readonly columns: BoundColumns<Name, Fields>
|
|
133
|
-
readonly schemas: TableSchemas<Fields, PrimaryKeyColumns>
|
|
148
|
+
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns>
|
|
134
149
|
readonly [TypeId]: TableState<Name, Fields, PrimaryKeyColumns, Kind, SchemaName>
|
|
135
150
|
readonly [Plan.TypeId]: Plan.State<
|
|
136
151
|
BoundColumns<Name, Fields>,
|
|
137
152
|
never,
|
|
138
|
-
Record<Name, Plan.Source<Name>>,
|
|
153
|
+
Record<Name, Plan.Source<Name, "required", TrueFormula>>,
|
|
139
154
|
TableDialect<Fields>
|
|
140
155
|
>
|
|
141
156
|
readonly [OptionsSymbol]: readonly TableOptionSpec[]
|
|
@@ -143,7 +158,7 @@ export type TableDefinition<
|
|
|
143
158
|
} & BoundColumns<Name, Fields> & Plan.Plan<
|
|
144
159
|
BoundColumns<Name, Fields>,
|
|
145
160
|
never,
|
|
146
|
-
Record<Name, Plan.Source<Name>>,
|
|
161
|
+
Record<Name, Plan.Source<Name, "required", TrueFormula>>,
|
|
147
162
|
TableDialect<Fields>
|
|
148
163
|
>
|
|
149
164
|
|
|
@@ -160,12 +175,12 @@ export type TableClassStatic<
|
|
|
160
175
|
SchemaName extends string | undefined = DefaultSchemaName
|
|
161
176
|
> = (abstract new (...args: any[]) => any) & Pipeable & {
|
|
162
177
|
readonly columns: BoundColumns<Name, Fields>
|
|
163
|
-
readonly schemas: TableSchemas<Fields, PrimaryKeyColumns>
|
|
178
|
+
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns>
|
|
164
179
|
readonly [TypeId]: TableState<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>
|
|
165
180
|
readonly [Plan.TypeId]: Plan.State<
|
|
166
181
|
BoundColumns<Name, Fields>,
|
|
167
182
|
never,
|
|
168
|
-
Record<Name, Plan.Source<Name>>,
|
|
183
|
+
Record<Name, Plan.Source<Name, "required", TrueFormula>>,
|
|
169
184
|
TableDialect<Fields>
|
|
170
185
|
>
|
|
171
186
|
readonly [OptionsSymbol]: readonly TableOptionSpec[]
|
|
@@ -175,7 +190,7 @@ export type TableClassStatic<
|
|
|
175
190
|
} & BoundColumns<Name, Fields> & Plan.Plan<
|
|
176
191
|
BoundColumns<Name, Fields>,
|
|
177
192
|
never,
|
|
178
|
-
Record<Name, Plan.Source<Name>>,
|
|
193
|
+
Record<Name, Plan.Source<Name, "required", TrueFormula>>,
|
|
179
194
|
TableDialect<Fields>
|
|
180
195
|
>
|
|
181
196
|
|
|
@@ -208,7 +223,7 @@ type BuildArtifacts<
|
|
|
208
223
|
PrimaryKeyColumns extends keyof Fields & string
|
|
209
224
|
> = {
|
|
210
225
|
readonly columns: BoundColumns<Name, Fields>
|
|
211
|
-
readonly schemas: TableSchemas<Fields, PrimaryKeyColumns>
|
|
226
|
+
readonly schemas: TableSchemas<Name, Fields, PrimaryKeyColumns>
|
|
212
227
|
readonly normalizedOptions: readonly TableOptionSpec[]
|
|
213
228
|
readonly primaryKey: readonly PrimaryKeyColumns[]
|
|
214
229
|
}
|
|
@@ -230,7 +245,7 @@ const buildArtifacts = <
|
|
|
230
245
|
const columns = Object.fromEntries(
|
|
231
246
|
Object.entries(fields).map(([key, column]) => [key, bindColumn(name, key, column, name, schemaName)])
|
|
232
247
|
) as BoundColumns<Name, Fields>
|
|
233
|
-
const schemas = deriveSchemas(fields, primaryKey)
|
|
248
|
+
const schemas = deriveSchemas(name, fields, primaryKey)
|
|
234
249
|
return {
|
|
235
250
|
columns,
|
|
236
251
|
schemas,
|
|
@@ -298,6 +313,21 @@ const extractDeclaredOptions = (
|
|
|
298
313
|
declaredOptions: DeclaredTableOptions | undefined
|
|
299
314
|
): readonly TableOptionSpec[] => declaredOptions?.map((option) => option.option) ?? []
|
|
300
315
|
|
|
316
|
+
const applyDeclaredOptions = <
|
|
317
|
+
Table extends TableDefinition<any, any, any, "schema", any>
|
|
318
|
+
>(
|
|
319
|
+
table: Table,
|
|
320
|
+
declaredOptions: DeclaredTableOptions | undefined
|
|
321
|
+
): Table => {
|
|
322
|
+
if (declaredOptions === undefined || declaredOptions.length === 0) {
|
|
323
|
+
return table
|
|
324
|
+
}
|
|
325
|
+
return declaredOptions.reduce<TableDefinition<any, any, any, "schema", any>>(
|
|
326
|
+
(current, option) => option(current),
|
|
327
|
+
table
|
|
328
|
+
) as unknown as Table
|
|
329
|
+
}
|
|
330
|
+
|
|
301
331
|
const validateClassOptions = (declaredOptions: readonly TableOptionSpec[]): void => {
|
|
302
332
|
for (const option of declaredOptions) {
|
|
303
333
|
if (option.kind === "primaryKey") {
|
|
@@ -339,14 +369,26 @@ const ensureClassArtifacts = <
|
|
|
339
369
|
return cached
|
|
340
370
|
}
|
|
341
371
|
const state = self[TypeId]
|
|
342
|
-
const
|
|
343
|
-
validateClassOptions(
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
372
|
+
const classOptions = self[options]
|
|
373
|
+
validateClassOptions(extractDeclaredOptions(classOptions))
|
|
374
|
+
const table = applyDeclaredOptions(
|
|
375
|
+
makeTable(
|
|
376
|
+
state.name,
|
|
377
|
+
state.fields,
|
|
378
|
+
[],
|
|
379
|
+
state.name,
|
|
380
|
+
"schema",
|
|
381
|
+
state.schemaName,
|
|
382
|
+
state.schemaName === undefined || state.schemaName === "public" ? "default" : "explicit"
|
|
383
|
+
) as TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", typeof state.schemaName>,
|
|
384
|
+
classOptions
|
|
385
|
+
)
|
|
386
|
+
const artifacts = {
|
|
387
|
+
columns: table.columns,
|
|
388
|
+
schemas: table.schemas,
|
|
389
|
+
normalizedOptions: table[OptionsSymbol],
|
|
390
|
+
primaryKey: table[TypeId].primaryKey as readonly PrimaryKeyColumns[]
|
|
391
|
+
} satisfies BuildArtifacts<Name, Fields, PrimaryKeyColumns>
|
|
350
392
|
Object.defineProperty(self, CacheSymbol, {
|
|
351
393
|
configurable: true,
|
|
352
394
|
value: artifacts
|
|
@@ -383,6 +425,25 @@ const makeOption = <Spec extends TableOptionSpec>(option: Spec): TableOption<Spe
|
|
|
383
425
|
return builder
|
|
384
426
|
}
|
|
385
427
|
|
|
428
|
+
const makeResolvedOption = <Spec extends TableOptionSpec>(
|
|
429
|
+
option: Spec,
|
|
430
|
+
resolve: (table: TableDefinition<any, any, any, "schema", any>) => Spec
|
|
431
|
+
): TableOption<Spec> => {
|
|
432
|
+
const builder = ((table: TableDefinition<any, any, any, "schema", any>) =>
|
|
433
|
+
appendOption(table, resolve(table))) as unknown as TableOption<Spec>
|
|
434
|
+
;(builder as { option: Spec }).option = option
|
|
435
|
+
return builder
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
export const option = <Spec extends TableOptionSpec>(spec: Spec): TableOption<Spec> =>
|
|
439
|
+
makeOption(spec)
|
|
440
|
+
|
|
441
|
+
export const optionFromTable = <Spec extends TableOptionSpec>(
|
|
442
|
+
spec: Spec,
|
|
443
|
+
resolve: (table: TableDefinition<any, any, any, "schema", any>) => Spec
|
|
444
|
+
): TableOption<Spec> =>
|
|
445
|
+
makeResolvedOption(spec, resolve)
|
|
446
|
+
|
|
386
447
|
/** Creates a table definition from a name and field map. */
|
|
387
448
|
export function make<
|
|
388
449
|
Name extends string,
|
|
@@ -421,17 +482,20 @@ export const schema = <SchemaName extends string>(
|
|
|
421
482
|
>(
|
|
422
483
|
name: Name,
|
|
423
484
|
fields: Fields,
|
|
424
|
-
...options:
|
|
485
|
+
...options: DeclaredTableOptions
|
|
425
486
|
): TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName> =>
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
487
|
+
applyDeclaredOptions(
|
|
488
|
+
makeTable(
|
|
489
|
+
name,
|
|
490
|
+
fields,
|
|
491
|
+
[],
|
|
492
|
+
name,
|
|
493
|
+
"schema",
|
|
494
|
+
schemaName,
|
|
495
|
+
"explicit"
|
|
496
|
+
) as TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>,
|
|
497
|
+
options
|
|
498
|
+
)
|
|
435
499
|
})
|
|
436
500
|
|
|
437
501
|
/**
|
|
@@ -464,7 +528,7 @@ export const alias = <
|
|
|
464
528
|
const aliased = Object.create(TableProto)
|
|
465
529
|
aliased.name = aliasName
|
|
466
530
|
aliased.columns = columns
|
|
467
|
-
aliased.schemas =
|
|
531
|
+
aliased.schemas = deriveSchemas(aliasName, state.fields, state.primaryKey)
|
|
468
532
|
aliased[TypeId] = {
|
|
469
533
|
name: aliasName,
|
|
470
534
|
baseName: state.baseName,
|
|
@@ -580,7 +644,7 @@ export function Class<
|
|
|
580
644
|
|
|
581
645
|
/** Declares a table-level primary key. */
|
|
582
646
|
export const primaryKey = <
|
|
583
|
-
Columns extends string | readonly string[]
|
|
647
|
+
const Columns extends string | readonly string[]
|
|
584
648
|
>(
|
|
585
649
|
columns: Columns
|
|
586
650
|
): TableOption<{
|
|
@@ -593,7 +657,7 @@ export const primaryKey = <
|
|
|
593
657
|
|
|
594
658
|
/** Declares a table-level unique constraint. */
|
|
595
659
|
export const unique = <
|
|
596
|
-
Columns extends string | readonly string[]
|
|
660
|
+
const Columns extends string | readonly string[]
|
|
597
661
|
>(
|
|
598
662
|
columns: Columns
|
|
599
663
|
): TableOption<{
|
|
@@ -606,7 +670,7 @@ export const unique = <
|
|
|
606
670
|
|
|
607
671
|
/** Declares a table-level index. */
|
|
608
672
|
export const index = <
|
|
609
|
-
Columns extends string | readonly string[]
|
|
673
|
+
const Columns extends string | readonly string[]
|
|
610
674
|
>(
|
|
611
675
|
columns: Columns
|
|
612
676
|
): TableOption<{
|
|
@@ -619,9 +683,9 @@ export const index = <
|
|
|
619
683
|
|
|
620
684
|
/** Declares a table-level foreign key. */
|
|
621
685
|
export const foreignKey = <
|
|
622
|
-
LocalColumns extends string | readonly string[],
|
|
686
|
+
const LocalColumns extends string | readonly string[],
|
|
623
687
|
TargetTable extends AnyTable,
|
|
624
|
-
TargetColumns extends string | readonly string[]
|
|
688
|
+
const TargetColumns extends string | readonly string[]
|
|
625
689
|
>(
|
|
626
690
|
columns: LocalColumns,
|
|
627
691
|
target: () => TargetTable,
|
|
@@ -646,14 +710,14 @@ export const foreignKey = <
|
|
|
646
710
|
})
|
|
647
711
|
})
|
|
648
712
|
|
|
649
|
-
/** Declares a
|
|
713
|
+
/** Declares a check constraint expression. */
|
|
650
714
|
export const check = <Name extends string>(
|
|
651
715
|
name: Name,
|
|
652
|
-
predicate:
|
|
716
|
+
predicate: DdlExpressionLike
|
|
653
717
|
): TableOption<{
|
|
654
718
|
readonly kind: "check"
|
|
655
719
|
readonly name: Name
|
|
656
|
-
readonly predicate:
|
|
720
|
+
readonly predicate: DdlExpressionLike
|
|
657
721
|
}> => makeOption({
|
|
658
722
|
kind: "check",
|
|
659
723
|
name,
|
package/src/mysql/column.ts
CHANGED
|
@@ -19,12 +19,14 @@ export const json = BaseColumn.mysql.json
|
|
|
19
19
|
export const custom = BaseColumn.mysql.custom
|
|
20
20
|
|
|
21
21
|
export const nullable = BaseColumn.nullable
|
|
22
|
+
export const brand = BaseColumn.brand
|
|
22
23
|
export const primaryKey = BaseColumn.primaryKey
|
|
23
24
|
export const unique = BaseColumn.unique
|
|
24
|
-
|
|
25
|
+
const default_ = BaseColumn.default_
|
|
25
26
|
export const generated = BaseColumn.generated
|
|
26
27
|
export const references = BaseColumn.references
|
|
27
28
|
export const schema = BaseColumn.schema
|
|
29
|
+
export { default_ as default }
|
|
28
30
|
|
|
29
31
|
export type Any = BaseColumn.Any
|
|
30
32
|
export type AnyBound = BaseColumn.AnyBound
|
|
@@ -1,6 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { DatatypeModule } from "../../internal/datatypes/define.js"
|
|
2
|
+
import type * as Expression from "../../internal/expression.js"
|
|
2
3
|
import { mysqlDatatypeKinds } from "./spec.js"
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const mysqlDatatypeModule = {
|
|
6
|
+
custom: (kind: string) => ({
|
|
7
|
+
dialect: "mysql",
|
|
8
|
+
kind
|
|
9
|
+
})
|
|
10
|
+
} as Record<string, (...args: readonly any[]) => Expression.DbType.Base<"mysql", string>>
|
|
11
|
+
|
|
12
|
+
for (const kind of Object.keys(mysqlDatatypeKinds)) {
|
|
13
|
+
mysqlDatatypeModule[kind] = () => ({
|
|
14
|
+
dialect: "mysql",
|
|
15
|
+
kind
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const mysqlDatatypes = mysqlDatatypeModule as DatatypeModule<"mysql", typeof mysqlDatatypeKinds>
|
|
5
20
|
|
|
6
21
|
export type MysqlDatatypeModule = typeof mysqlDatatypes
|
package/src/mysql/executor.ts
CHANGED
|
@@ -2,8 +2,9 @@ import * as Effect from "effect/Effect"
|
|
|
2
2
|
import * as SqlClient from "@effect/sql/SqlClient"
|
|
3
3
|
|
|
4
4
|
import * as CoreExecutor from "../internal/executor.js"
|
|
5
|
-
import * as
|
|
6
|
-
import * as
|
|
5
|
+
import * as CoreQuery from "../internal/query.js"
|
|
6
|
+
import * as CoreRenderer from "../internal/renderer.js"
|
|
7
|
+
import { renderMysqlPlan } from "../internal/mysql-renderer.js"
|
|
7
8
|
import {
|
|
8
9
|
narrowMysqlDriverErrorForReadQuery,
|
|
9
10
|
normalizeMysqlDriverError,
|
|
@@ -19,17 +20,19 @@ export type RowDecodeError = CoreExecutor.RowDecodeError
|
|
|
19
20
|
export type Driver<Error = never, Context = never> = CoreExecutor.Driver<"mysql", Error, Context>
|
|
20
21
|
/** MySQL-specialized executor contract. */
|
|
21
22
|
export type Executor<Error = never, Context = never> = CoreExecutor.Executor<"mysql", Error, Context>
|
|
23
|
+
/** MySQL-specialized renderer contract. */
|
|
24
|
+
export type Renderer = CoreRenderer.Renderer<"mysql">
|
|
22
25
|
/** Optional renderer / driver overrides for the standard MySQL executor pipeline. */
|
|
23
26
|
export interface MakeOptions<Error = never, Context = never> {
|
|
24
|
-
readonly renderer?: Renderer
|
|
27
|
+
readonly renderer?: Renderer
|
|
25
28
|
readonly driver?: Driver<Error, Context>
|
|
26
29
|
readonly driverMode?: CoreExecutor.DriverMode
|
|
27
30
|
}
|
|
28
31
|
/** Standard composed error shape for MySQL executors. */
|
|
29
32
|
export type MysqlExecutorError = MysqlDriverError | RowDecodeError
|
|
30
33
|
/** Read-query error surface emitted by built-in MySQL executors. */
|
|
31
|
-
export type MysqlQueryError<PlanValue extends
|
|
32
|
-
Exclude<
|
|
34
|
+
export type MysqlQueryError<PlanValue extends CoreQuery.QueryPlan<any, any, any, any, any, any, any, any, any, any>> =
|
|
35
|
+
Exclude<CoreQuery.CapabilitiesOfPlan<PlanValue>, "read"> extends never ? MysqlReadQueryError : MysqlExecutorError
|
|
33
36
|
|
|
34
37
|
/** Runs an effect within the ambient MySQL SQL transaction service. */
|
|
35
38
|
export const withTransaction = CoreExecutor.withTransaction
|
|
@@ -39,9 +42,9 @@ export const withSavepoint = CoreExecutor.withSavepoint
|
|
|
39
42
|
/** MySQL executor whose error channel narrows based on the query plan. */
|
|
40
43
|
export interface QueryExecutor<Context = never> {
|
|
41
44
|
readonly dialect: "mysql"
|
|
42
|
-
execute<PlanValue extends
|
|
43
|
-
plan:
|
|
44
|
-
): Effect.Effect<
|
|
45
|
+
execute<PlanValue extends CoreQuery.QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
|
|
46
|
+
plan: CoreQuery.DialectCompatiblePlan<PlanValue, "mysql">
|
|
47
|
+
): Effect.Effect<CoreQuery.ResultRows<PlanValue>, MysqlQueryError<PlanValue>, Context>
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
/** Constructs a MySQL-specialized SQL driver. */
|
|
@@ -50,7 +53,7 @@ export const driver = <
|
|
|
50
53
|
Context = never
|
|
51
54
|
>(
|
|
52
55
|
execute: <Row>(
|
|
53
|
-
query:
|
|
56
|
+
query: CoreRenderer.RenderedQuery<Row, "mysql">
|
|
54
57
|
) => Effect.Effect<ReadonlyArray<FlatRow>, Error, Context>
|
|
55
58
|
): Driver<Error, Context> =>
|
|
56
59
|
CoreExecutor.driver("mysql", execute)
|
|
@@ -59,7 +62,7 @@ const fromDriver = <
|
|
|
59
62
|
Error = never,
|
|
60
63
|
Context = never
|
|
61
64
|
>(
|
|
62
|
-
renderer: Renderer
|
|
65
|
+
renderer: Renderer,
|
|
63
66
|
sqlDriver: Driver<Error, Context>,
|
|
64
67
|
driverMode: CoreExecutor.DriverMode = "raw"
|
|
65
68
|
): QueryExecutor<Context> => ({
|
|
@@ -102,13 +105,13 @@ const sqlClientDriver = (): Driver<any, SqlClient.SqlClient> =>
|
|
|
102
105
|
export function make(): QueryExecutor<SqlClient.SqlClient>
|
|
103
106
|
export function make(
|
|
104
107
|
options: {
|
|
105
|
-
readonly renderer?: Renderer
|
|
108
|
+
readonly renderer?: Renderer
|
|
106
109
|
readonly driverMode?: CoreExecutor.DriverMode
|
|
107
110
|
}
|
|
108
111
|
): QueryExecutor<SqlClient.SqlClient>
|
|
109
112
|
export function make<Error = never, Context = never>(
|
|
110
113
|
options: {
|
|
111
|
-
readonly renderer?: Renderer
|
|
114
|
+
readonly renderer?: Renderer
|
|
112
115
|
readonly driver: Driver<Error, Context>
|
|
113
116
|
readonly driverMode?: CoreExecutor.DriverMode
|
|
114
117
|
}
|
|
@@ -117,9 +120,9 @@ export function make<Error = never, Context = never>(
|
|
|
117
120
|
options: MakeOptions<Error, Context> = {}
|
|
118
121
|
): QueryExecutor<any> {
|
|
119
122
|
if (options.driver) {
|
|
120
|
-
return fromDriver(options.renderer ??
|
|
123
|
+
return fromDriver(options.renderer ?? CoreRenderer.make("mysql", renderMysqlPlan), options.driver, options.driverMode)
|
|
121
124
|
}
|
|
122
|
-
return fromDriver(options.renderer ??
|
|
125
|
+
return fromDriver(options.renderer ?? CoreRenderer.make("mysql", renderMysqlPlan), sqlClientDriver(), options.driverMode)
|
|
123
126
|
}
|
|
124
127
|
|
|
125
128
|
/** Creates a MySQL-specialized executor from a typed implementation callback. */
|
|
@@ -127,8 +130,8 @@ export const custom = <
|
|
|
127
130
|
Error = never,
|
|
128
131
|
Context = never
|
|
129
132
|
>(
|
|
130
|
-
execute: <PlanValue extends
|
|
131
|
-
plan:
|
|
132
|
-
) => Effect.Effect<
|
|
133
|
+
execute: <PlanValue extends CoreQuery.QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
|
|
134
|
+
plan: CoreQuery.DialectCompatiblePlan<PlanValue, "mysql">
|
|
135
|
+
) => Effect.Effect<CoreQuery.ResultRows<PlanValue>, Error, Context>
|
|
133
136
|
): Executor<Error, Context> =>
|
|
134
137
|
CoreExecutor.make("mysql", execute as any) as Executor<Error, Context>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * as core from "./core.js"
|
|
2
|
+
export * as string from "./string.js"
|
|
3
|
+
export * as aggregate from "./aggregate.js"
|
|
4
|
+
export * as window from "./window.js"
|
|
5
|
+
export { json } from "./json.js"
|
|
6
|
+
export * as temporal from "./temporal.js"
|
|
7
|
+
|
|
8
|
+
export { coalesce } from "./core.js"
|
|
9
|
+
export { call } from "./core.js"
|
|
10
|
+
export { lower, upper, concat } from "./string.js"
|
|
11
|
+
export { count, max, min } from "./aggregate.js"
|
|
12
|
+
export { over, rowNumber, rank, denseRank } from "./window.js"
|
|
13
|
+
export {
|
|
14
|
+
currentDate,
|
|
15
|
+
currentTime,
|
|
16
|
+
currentTimestamp,
|
|
17
|
+
localTime,
|
|
18
|
+
localTimestamp,
|
|
19
|
+
now
|
|
20
|
+
} from "./temporal.js"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type * as Schema from "effect/Schema"
|
|
2
|
+
|
|
3
|
+
import type * as Expression from "../../internal/expression.js"
|
|
4
|
+
import type * as ExpressionAst from "../../internal/expression-ast.js"
|
|
5
|
+
import { makeExpression } from "../../internal/query.js"
|
|
6
|
+
import {
|
|
7
|
+
LocalDateStringSchema,
|
|
8
|
+
LocalDateTimeStringSchema,
|
|
9
|
+
LocalTimeStringSchema,
|
|
10
|
+
type LocalDateString,
|
|
11
|
+
type LocalDateTimeString,
|
|
12
|
+
type LocalTimeString
|
|
13
|
+
} from "../../internal/runtime-value.js"
|
|
14
|
+
|
|
15
|
+
type TemporalExpression<
|
|
16
|
+
Runtime,
|
|
17
|
+
Db extends Expression.DbType.Any,
|
|
18
|
+
Name extends string
|
|
19
|
+
> = Expression.Expression<
|
|
20
|
+
Runtime,
|
|
21
|
+
Db,
|
|
22
|
+
"never",
|
|
23
|
+
"mysql",
|
|
24
|
+
"scalar",
|
|
25
|
+
never,
|
|
26
|
+
{},
|
|
27
|
+
"resolved"
|
|
28
|
+
> & {
|
|
29
|
+
readonly [ExpressionAst.TypeId]: ExpressionAst.FunctionCallNode<Name, readonly []>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const makeTemporal = <
|
|
33
|
+
Runtime,
|
|
34
|
+
Db extends Expression.DbType.Any,
|
|
35
|
+
Name extends string
|
|
36
|
+
>(
|
|
37
|
+
name: Name,
|
|
38
|
+
dbType: Db,
|
|
39
|
+
runtimeSchema: Schema.Schema<Runtime, any, any>
|
|
40
|
+
): TemporalExpression<Runtime, Db, Name> =>
|
|
41
|
+
makeExpression({
|
|
42
|
+
runtime: undefined as unknown as Runtime,
|
|
43
|
+
dbType,
|
|
44
|
+
runtimeSchema,
|
|
45
|
+
nullability: "never",
|
|
46
|
+
dialect: "mysql",
|
|
47
|
+
aggregation: "scalar",
|
|
48
|
+
source: undefined as never,
|
|
49
|
+
dependencies: {},
|
|
50
|
+
sourceNullability: "resolved"
|
|
51
|
+
}, {
|
|
52
|
+
kind: "function",
|
|
53
|
+
name,
|
|
54
|
+
args: []
|
|
55
|
+
}) as TemporalExpression<Runtime, Db, Name>
|
|
56
|
+
|
|
57
|
+
/** MySQL current date. */
|
|
58
|
+
export const currentDate = () =>
|
|
59
|
+
makeTemporal(
|
|
60
|
+
"current_date",
|
|
61
|
+
{ dialect: "mysql", kind: "date" } as Expression.DbType.MySqlDate,
|
|
62
|
+
LocalDateStringSchema
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
/** MySQL current time. */
|
|
66
|
+
export const currentTime = () =>
|
|
67
|
+
makeTemporal(
|
|
68
|
+
"current_time",
|
|
69
|
+
{ dialect: "mysql", kind: "time" } as Expression.DbType.MySqlTime,
|
|
70
|
+
LocalTimeStringSchema
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
/** MySQL current timestamp. */
|
|
74
|
+
export const currentTimestamp = () =>
|
|
75
|
+
makeTemporal(
|
|
76
|
+
"current_timestamp",
|
|
77
|
+
{ dialect: "mysql", kind: "timestamp" } as Expression.DbType.MySqlTimestamp,
|
|
78
|
+
LocalDateTimeStringSchema
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
/** MySQL local time. */
|
|
82
|
+
export const localTime = () =>
|
|
83
|
+
makeTemporal(
|
|
84
|
+
"localtime",
|
|
85
|
+
{ dialect: "mysql", kind: "time" } as Expression.DbType.MySqlTime,
|
|
86
|
+
LocalTimeStringSchema
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
/** MySQL local timestamp. */
|
|
90
|
+
export const localTimestamp = () =>
|
|
91
|
+
makeTemporal(
|
|
92
|
+
"localtimestamp",
|
|
93
|
+
{ dialect: "mysql", kind: "timestamp" } as Expression.DbType.MySqlTimestamp,
|
|
94
|
+
LocalDateTimeStringSchema
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
/** MySQL current instant-like timestamp. */
|
|
98
|
+
export const now = () =>
|
|
99
|
+
makeTemporal(
|
|
100
|
+
"now",
|
|
101
|
+
{ dialect: "mysql", kind: "timestamp" } as Expression.DbType.MySqlTimestamp,
|
|
102
|
+
LocalDateTimeStringSchema
|
|
103
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { mysqlQuery } from "../../internal/mysql-query.js"
|