effect-qb 0.16.0 → 0.19.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.
Files changed (128) hide show
  1. package/README.md +4 -0
  2. package/dist/index.js +8065 -0
  3. package/dist/mysql.js +4036 -2418
  4. package/dist/postgres/metadata.js +2536 -625
  5. package/dist/postgres.js +8248 -7857
  6. package/dist/sqlite.js +8854 -0
  7. package/dist/standard.js +8019 -0
  8. package/package.json +15 -3
  9. package/src/casing.ts +71 -0
  10. package/src/index.ts +2 -0
  11. package/src/internal/casing.ts +89 -0
  12. package/src/internal/column-state.ts +11 -6
  13. package/src/internal/column.ts +44 -7
  14. package/src/internal/datatypes/define.ts +2 -1
  15. package/src/internal/datatypes/enrich.ts +23 -0
  16. package/src/internal/datatypes/lookup.ts +14 -7
  17. package/src/internal/derived-table.ts +7 -13
  18. package/src/internal/dialect-renderers/mysql.ts +2046 -0
  19. package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +867 -283
  20. package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +834 -358
  21. package/src/internal/dialect.ts +37 -0
  22. package/src/internal/dsl-mutation-runtime.ts +29 -10
  23. package/src/internal/dsl-plan-runtime.ts +41 -24
  24. package/src/internal/dsl-query-runtime.ts +11 -31
  25. package/src/internal/dsl-transaction-ddl-runtime.ts +61 -15
  26. package/src/internal/executor.ts +57 -15
  27. package/src/internal/expression-ast.ts +3 -2
  28. package/src/internal/grouping-key.ts +216 -9
  29. package/src/internal/implication-runtime.ts +3 -2
  30. package/src/internal/json/types.ts +155 -40
  31. package/src/internal/predicate/context.ts +14 -1
  32. package/src/internal/predicate/key.ts +19 -2
  33. package/src/internal/predicate/runtime.ts +30 -3
  34. package/src/internal/query.d.ts +38 -11
  35. package/src/internal/query.ts +315 -54
  36. package/src/internal/renderer.ts +51 -6
  37. package/src/internal/runtime/driver-value-mapping.ts +58 -0
  38. package/src/internal/runtime/normalize.ts +74 -43
  39. package/src/internal/runtime/schema.ts +5 -3
  40. package/src/internal/runtime/value.ts +153 -30
  41. package/src/internal/scalar.ts +6 -1
  42. package/src/internal/schema-derivation.d.ts +12 -61
  43. package/src/internal/schema-derivation.ts +90 -38
  44. package/src/internal/schema-expression.ts +2 -2
  45. package/src/internal/sql-expression-renderer.ts +19 -0
  46. package/src/internal/standard-dsl.ts +6885 -0
  47. package/src/internal/table-options.ts +229 -62
  48. package/src/internal/table.d.ts +33 -32
  49. package/src/internal/table.ts +469 -160
  50. package/src/mysql/column-extension.ts +3 -0
  51. package/src/mysql/column.ts +27 -12
  52. package/src/mysql/datatypes/index.ts +24 -2
  53. package/src/mysql/errors/catalog.ts +5 -5
  54. package/src/mysql/errors/normalize.ts +2 -2
  55. package/src/mysql/executor.ts +7 -5
  56. package/src/mysql/internal/dialect.ts +9 -4
  57. package/src/mysql/internal/dsl.ts +906 -324
  58. package/src/mysql/internal/renderer.ts +7 -2
  59. package/src/mysql/json.ts +37 -0
  60. package/src/mysql/query-extension.ts +16 -0
  61. package/src/mysql/query.ts +9 -2
  62. package/src/mysql/renderer.ts +31 -4
  63. package/src/mysql.ts +4 -12
  64. package/src/postgres/column-extension.ts +28 -0
  65. package/src/postgres/column.ts +9 -13
  66. package/src/postgres/datatypes/index.d.ts +2 -1
  67. package/src/postgres/datatypes/index.ts +3 -2
  68. package/src/postgres/errors/normalize.ts +2 -2
  69. package/src/postgres/executor.ts +55 -10
  70. package/src/postgres/function/core.ts +20 -4
  71. package/src/postgres/function/index.ts +1 -17
  72. package/src/postgres/internal/dialect.ts +9 -4
  73. package/src/postgres/internal/dsl.ts +850 -359
  74. package/src/postgres/internal/renderer.ts +7 -2
  75. package/src/postgres/internal/schema-ddl.ts +22 -9
  76. package/src/postgres/internal/schema-model.ts +244 -10
  77. package/src/postgres/json.ts +100 -24
  78. package/src/postgres/jsonb.ts +38 -0
  79. package/src/postgres/query-extension.ts +2 -0
  80. package/src/postgres/query.ts +9 -2
  81. package/src/postgres/renderer.ts +31 -4
  82. package/src/postgres/schema-management.ts +108 -16
  83. package/src/postgres/schema.ts +98 -15
  84. package/src/postgres/table.ts +203 -398
  85. package/src/postgres/type.ts +8 -7
  86. package/src/postgres.ts +9 -11
  87. package/src/sqlite/column-extension.ts +3 -0
  88. package/src/sqlite/column.ts +127 -0
  89. package/src/sqlite/datatypes/index.ts +80 -0
  90. package/src/sqlite/datatypes/spec.ts +98 -0
  91. package/src/sqlite/errors/catalog.ts +103 -0
  92. package/src/sqlite/errors/fields.ts +19 -0
  93. package/src/sqlite/errors/index.ts +19 -0
  94. package/src/sqlite/errors/normalize.ts +229 -0
  95. package/src/sqlite/errors/requirements.ts +71 -0
  96. package/src/sqlite/errors/types.ts +29 -0
  97. package/src/sqlite/executor.ts +229 -0
  98. package/src/sqlite/function/aggregate.ts +2 -0
  99. package/src/sqlite/function/core.ts +2 -0
  100. package/src/sqlite/function/index.ts +19 -0
  101. package/src/sqlite/function/string.ts +2 -0
  102. package/src/sqlite/function/temporal.ts +100 -0
  103. package/src/sqlite/function/window.ts +2 -0
  104. package/src/sqlite/internal/dialect.ts +42 -0
  105. package/src/sqlite/internal/dsl.ts +6979 -0
  106. package/src/sqlite/internal/renderer.ts +51 -0
  107. package/src/sqlite/json.ts +39 -0
  108. package/src/sqlite/query-extension.ts +2 -0
  109. package/src/sqlite/query.ts +196 -0
  110. package/src/sqlite/renderer.ts +51 -0
  111. package/src/sqlite.ts +14 -0
  112. package/src/standard/column.ts +163 -0
  113. package/src/standard/datatypes/index.ts +83 -0
  114. package/src/standard/datatypes/spec.ts +98 -0
  115. package/src/standard/dialect.ts +40 -0
  116. package/src/standard/function/aggregate.ts +2 -0
  117. package/src/standard/function/core.ts +2 -0
  118. package/src/standard/function/index.ts +18 -0
  119. package/src/standard/function/string.ts +2 -0
  120. package/src/standard/function/temporal.ts +78 -0
  121. package/src/standard/function/window.ts +2 -0
  122. package/src/standard/internal/renderer.ts +45 -0
  123. package/src/standard/query.ts +152 -0
  124. package/src/standard/renderer.ts +21 -0
  125. package/src/standard/table.ts +147 -0
  126. package/src/standard.ts +18 -0
  127. package/src/internal/aggregation-validation.ts +0 -57
  128. package/src/mysql/table.ts +0 -157
@@ -0,0 +1,229 @@
1
+ import type * as Renderer from "../../internal/renderer.js"
2
+ import {
3
+ findSqliteErrorDescriptorsByNumberLoose,
4
+ getSqliteErrorDescriptor,
5
+ isSqliteErrorNumber,
6
+ isSqliteErrorSymbol,
7
+ type SqliteErrorDescriptor,
8
+ type SqliteErrorNumber,
9
+ type SqliteErrorSymbol,
10
+ } from "./catalog.js"
11
+ import type {
12
+ SqliteErrorFields,
13
+ SqliteQueryContext
14
+ } from "./fields.js"
15
+ import type {
16
+ SqliteErrorLike,
17
+ SqliteKnownErrorBase
18
+ } from "./types.js"
19
+
20
+ const isRecord = (value: unknown): value is Record<string, unknown> =>
21
+ typeof value === "object" && value !== null
22
+
23
+ const unwrapSqliteDriverCause = (cause: unknown): unknown => {
24
+ let current = cause
25
+ while (
26
+ isRecord(current) &&
27
+ "_tag" in current &&
28
+ current._tag === "SqlError" &&
29
+ "cause" in current
30
+ ) {
31
+ current = current.cause
32
+ }
33
+ return current
34
+ }
35
+
36
+ const asString = (value: unknown): string | undefined =>
37
+ typeof value === "string" ? value : undefined
38
+
39
+ const asBoolean = (value: unknown): boolean | undefined =>
40
+ typeof value === "boolean" ? value : undefined
41
+
42
+ const asNumber = (value: unknown): number | undefined => {
43
+ if (typeof value === "number" && Number.isFinite(value)) {
44
+ return value
45
+ }
46
+ if (typeof value === "string" && /^[+-]?\d+$/.test(value.trim())) {
47
+ const parsed = Number(value.trim())
48
+ return Number.isFinite(parsed) ? parsed : undefined
49
+ }
50
+ return undefined
51
+ }
52
+
53
+ const normalizeFields = (error: Record<string, unknown>): SqliteErrorFields => ({
54
+ code: asString(error.code),
55
+ errno: asNumber(error.errno),
56
+ sqlState: asString(error.sqlState),
57
+ sqlMessage: asString(error.sqlMessage),
58
+ fatal: asBoolean(error.fatal),
59
+ sql: asString(error.sql),
60
+ syscall: asString(error.syscall),
61
+ address: asString(error.address),
62
+ port: asNumber(error.port),
63
+ hostname: asString(error.hostname)
64
+ })
65
+
66
+ export type { SqliteErrorLike } from "./types.js"
67
+
68
+ /** Structured known SQLite error derived from the SQLite result-code catalog. */
69
+ export type KnownSqliteError<Symbol extends SqliteErrorSymbol = SqliteErrorSymbol> =
70
+ SqliteKnownErrorBase & { readonly symbol: Symbol }
71
+
72
+ /** Extracts the normalized SQLite error variant for a specific symbol. */
73
+ export type KnownSqliteErrorBySymbol<Symbol extends SqliteErrorSymbol> = KnownSqliteError<Symbol>
74
+
75
+ /** SQLite-like error whose symbol or number is not in the current catalog. */
76
+ export type UnknownSqliteCodeError = Readonly<{
77
+ readonly _tag: "@sqlite/unknown/code"
78
+ readonly code?: string
79
+ readonly errno?: string | number
80
+ readonly message: string
81
+ readonly query?: SqliteQueryContext
82
+ readonly raw: SqliteErrorLike
83
+ } & SqliteErrorFields>
84
+
85
+ /** Fallback for non-SQLite driver failures in the SQLite executor path. */
86
+ export type UnknownSqliteDriverError = Readonly<{
87
+ readonly _tag: "@sqlite/unknown/driver"
88
+ readonly message: string
89
+ readonly query?: SqliteQueryContext
90
+ readonly cause: unknown
91
+ }>
92
+
93
+ /** Any SQLite-specific driver failure surfaced by the SQLite executor. */
94
+ export type SqliteDriverError =
95
+ | KnownSqliteError
96
+ | UnknownSqliteCodeError
97
+ | UnknownSqliteDriverError
98
+
99
+ /** Runtime guard for objects that look like SQLite driver errors. */
100
+ export const isSqliteErrorLike = (value: unknown): value is SqliteErrorLike =>
101
+ isRecord(value) &&
102
+ (
103
+ typeof value.code === "string" ||
104
+ typeof value.errno === "string" ||
105
+ typeof value.errno === "number" ||
106
+ typeof value.sqlState === "string" ||
107
+ typeof value.sqlMessage === "string" ||
108
+ typeof value.message === "string" ||
109
+ typeof value.fatal === "boolean"
110
+ )
111
+
112
+ const errorMessageOf = (error: SqliteErrorLike): string =>
113
+ error.sqlMessage ?? error.message ?? "SQLite driver error"
114
+
115
+ const numberOf = (error: SqliteErrorLike): string | undefined => {
116
+ if (typeof error.errno === "number" && Number.isFinite(error.errno)) {
117
+ return String(error.errno)
118
+ }
119
+ if (typeof error.errno === "string" && error.errno.trim() !== "") {
120
+ return error.errno
121
+ }
122
+ return undefined
123
+ }
124
+
125
+ const findDescriptor = (error: SqliteErrorLike): SqliteErrorDescriptor | undefined => {
126
+ if (typeof error.code === "string" && isSqliteErrorSymbol(error.code)) {
127
+ return getSqliteErrorDescriptor(error.code)
128
+ }
129
+ if (typeof error.code === "string" && isSqliteErrorNumber(error.code)) {
130
+ const matches = findSqliteErrorDescriptorsByNumberLoose(error.code)
131
+ if (matches?.length === 1) {
132
+ return matches[0]
133
+ }
134
+ }
135
+ const number = numberOf(error)
136
+ if (number !== undefined) {
137
+ const matches = findSqliteErrorDescriptorsByNumberLoose(number)
138
+ if (!matches || matches.length === 0) {
139
+ return undefined
140
+ }
141
+ if (matches.length === 1) {
142
+ return matches[0]
143
+ }
144
+ if (typeof error.code === "string") {
145
+ return matches.find((descriptor) => descriptor.symbol === error.code)
146
+ }
147
+ }
148
+ return undefined
149
+ }
150
+
151
+ const makeKnownSqliteError = (
152
+ descriptor: SqliteErrorDescriptor,
153
+ raw: SqliteErrorLike,
154
+ query?: SqliteQueryContext
155
+ ): SqliteKnownErrorBase => {
156
+ const fields = normalizeFields(raw as Record<string, unknown>)
157
+ return {
158
+ _tag: descriptor.tag,
159
+ category: descriptor.category,
160
+ number: descriptor.number,
161
+ symbol: descriptor.symbol,
162
+ messageTemplate: descriptor.messageTemplate,
163
+ message: errorMessageOf(raw),
164
+ query,
165
+ raw,
166
+ ...fields
167
+ } as SqliteKnownErrorBase
168
+ }
169
+
170
+ /** Normalizes an unknown failure into a structured SQLite driver error. */
171
+ export const normalizeSqliteDriverError = (
172
+ cause: unknown,
173
+ query?: SqliteQueryContext | Renderer.RenderedQuery<any, "sqlite">
174
+ ): SqliteDriverError => {
175
+ const normalizedCause = unwrapSqliteDriverCause(cause)
176
+ const context = query === undefined
177
+ ? undefined
178
+ : "sql" in query
179
+ ? { sql: query.sql, params: query.params }
180
+ : query
181
+
182
+ if (!isSqliteErrorLike(normalizedCause)) {
183
+ return {
184
+ _tag: "@sqlite/unknown/driver",
185
+ message: normalizedCause instanceof Error ? normalizedCause.message : "Unknown SQLite driver failure",
186
+ query: context,
187
+ cause
188
+ } as UnknownSqliteDriverError
189
+ }
190
+
191
+ const descriptor = findDescriptor(normalizedCause)
192
+ if (descriptor !== undefined) {
193
+ return makeKnownSqliteError(descriptor, normalizedCause, context)
194
+ }
195
+
196
+ if (typeof normalizedCause.code === "string" || numberOf(normalizedCause) !== undefined) {
197
+ return {
198
+ _tag: "@sqlite/unknown/code",
199
+ code: asString(normalizedCause.code),
200
+ errno: normalizedCause.errno,
201
+ message: errorMessageOf(normalizedCause),
202
+ query: context,
203
+ raw: normalizedCause,
204
+ ...normalizeFields(normalizedCause as Record<string, unknown>)
205
+ } as UnknownSqliteCodeError
206
+ }
207
+
208
+ return {
209
+ _tag: "@sqlite/unknown/driver",
210
+ message: errorMessageOf(normalizedCause),
211
+ query: context,
212
+ cause
213
+ } as UnknownSqliteDriverError
214
+ }
215
+
216
+ /** Type guard for a specific SQLite catalog symbol. */
217
+ export const hasSymbol = <Symbol extends SqliteErrorSymbol>(
218
+ error: SqliteDriverError | { readonly symbol?: string },
219
+ symbol: Symbol
220
+ ): error is KnownSqliteErrorBySymbol<Symbol> =>
221
+ "symbol" in error && error.symbol === symbol
222
+
223
+ /** Type guard for a specific documented SQLite error number. */
224
+ export const hasNumber = <Number extends SqliteErrorNumber>(
225
+ error: SqliteDriverError | { readonly number?: string; readonly errno?: string | number },
226
+ number: Number
227
+ ): error is KnownSqliteError & { readonly number: Number } =>
228
+ ("number" in error && error.number === number) ||
229
+ ("errno" in error && String(error.errno) === number)
@@ -0,0 +1,71 @@
1
+ import { read_query_capabilities, type QueryCapability, type QueryRequirement } from "../../internal/query-requirements.js"
2
+ import type { SqliteQueryContext } from "./fields.js"
3
+ import type {
4
+ KnownSqliteError,
5
+ SqliteDriverError,
6
+ UnknownSqliteCodeError,
7
+ UnknownSqliteDriverError
8
+ } from "./normalize.js"
9
+
10
+ export type SqliteQueryRequirement = Extract<QueryRequirement, "write" | "ddl" | "transaction" | "locking">
11
+
12
+ export const sqlite_requirements_by_sqlstate_prefix = {
13
+ "23": ["write"]
14
+ } as const satisfies Partial<Record<string, readonly SqliteQueryRequirement[]>>
15
+
16
+ export type SqliteQueryRequirementsError = Readonly<{
17
+ readonly _tag: "@sqlite/unknown/query-requirements"
18
+ readonly message: string
19
+ readonly query?: SqliteQueryContext
20
+ readonly requiredCapabilities: readonly SqliteQueryRequirement[]
21
+ readonly actualCapabilities: readonly QueryCapability[]
22
+ readonly cause: SqliteDriverError
23
+ }>
24
+
25
+ export type SqliteReadQueryError =
26
+ | KnownSqliteError
27
+ | UnknownSqliteCodeError
28
+ | UnknownSqliteDriverError
29
+ | SqliteQueryRequirementsError
30
+
31
+ const requiresWriteSqliteError = (error: SqliteDriverError): boolean =>
32
+ requirements_of_sqlite_error(error).length > 0
33
+
34
+ const lookup_sqlite_requirements = (
35
+ sqlState: string
36
+ ): readonly SqliteQueryRequirement[] => {
37
+ const prefix = sqlState.slice(0, 2)
38
+ return prefix in sqlite_requirements_by_sqlstate_prefix
39
+ ? sqlite_requirements_by_sqlstate_prefix[prefix as keyof typeof sqlite_requirements_by_sqlstate_prefix]
40
+ : []
41
+ }
42
+
43
+ export const requirements_of_sqlite_error = (
44
+ error: SqliteDriverError
45
+ ): readonly SqliteQueryRequirement[] => {
46
+ if ("sqlState" in error && typeof error.sqlState === "string") {
47
+ return lookup_sqlite_requirements(error.sqlState)
48
+ }
49
+ if ("symbol" in error && (error.symbol === "SQLITE_READONLY" || error.symbol.startsWith("SQLITE_CONSTRAINT"))) {
50
+ return ["write"]
51
+ }
52
+ return []
53
+ }
54
+
55
+ export const narrowSqliteDriverErrorForReadQuery = (
56
+ error: SqliteDriverError
57
+ ): SqliteReadQueryError => {
58
+ const requiredCapabilities = requirements_of_sqlite_error(error)
59
+ if (!requiresWriteSqliteError(error)) {
60
+ return error as SqliteReadQueryError
61
+ }
62
+
63
+ return {
64
+ _tag: "@sqlite/unknown/query-requirements",
65
+ message: "SQLite driver error requires query capabilities not provided by this plan",
66
+ query: error.query,
67
+ requiredCapabilities,
68
+ actualCapabilities: read_query_capabilities,
69
+ cause: error
70
+ } satisfies SqliteQueryRequirementsError
71
+ }
@@ -0,0 +1,29 @@
1
+ import type { SqliteErrorNumber, SqliteErrorSymbol, SqliteErrorTag } from "./catalog.js"
2
+ import type { SqliteErrorFields, SqliteQueryContext } from "./fields.js"
3
+
4
+ /** Raw SQLite-like error shape as commonly exposed by client libraries. */
5
+ export interface SqliteErrorLike {
6
+ readonly code?: string
7
+ readonly errno?: string | number
8
+ readonly sqlState?: string
9
+ readonly sqlMessage?: string
10
+ readonly message?: string
11
+ readonly fatal?: boolean
12
+ readonly sql?: string
13
+ readonly syscall?: string
14
+ readonly address?: string
15
+ readonly port?: string | number
16
+ readonly hostname?: string
17
+ }
18
+
19
+ /** Broad known-SQLite error surface used by the normalizer return type. */
20
+ export interface SqliteKnownErrorBase extends SqliteErrorFields {
21
+ readonly _tag: SqliteErrorTag
22
+ readonly category: "sqlite"
23
+ readonly number: SqliteErrorNumber
24
+ readonly symbol: SqliteErrorSymbol
25
+ readonly messageTemplate: string
26
+ readonly message: string
27
+ readonly query?: SqliteQueryContext
28
+ readonly raw: SqliteErrorLike
29
+ }
@@ -0,0 +1,229 @@
1
+ import * as Effect from "effect/Effect"
2
+ import * as SqlClient from "@effect/sql/SqlClient"
3
+ import * as Stream from "effect/Stream"
4
+
5
+ import * as CoreExecutor from "../internal/executor.js"
6
+ import * as CoreQuery from "../internal/query.js"
7
+ import * as CoreRenderer from "../internal/renderer.js"
8
+ import type * as Expression from "../internal/scalar.js"
9
+ import type { SqliteDatatypeFamily, SqliteDatatypeKind } from "./datatypes/spec.js"
10
+ import { renderSqlitePlan } from "./internal/renderer.js"
11
+ import {
12
+ narrowSqliteDriverErrorForReadQuery,
13
+ normalizeSqliteDriverError,
14
+ type SqliteDriverError,
15
+ type SqliteReadQueryError
16
+ } from "./errors/index.js"
17
+
18
+ /** SQLite-specialized flat row returned by SQL drivers. */
19
+ export type FlatRow = CoreExecutor.FlatRow
20
+ /** Runtime decode failure raised after SQL execution but before row remapping. */
21
+ export type RowDecodeError = CoreExecutor.RowDecodeError
22
+ /** SQLite-specialized rendered-query driver. */
23
+ export type Driver<Error = never, Context = never> = CoreExecutor.Driver<"sqlite", Error, Context>
24
+ /** SQLite-specialized executor contract. */
25
+ export type Executor<Error = never, Context = never> = CoreExecutor.Executor<"sqlite", Error, Context>
26
+ /** SQLite-specialized renderer contract. */
27
+ export type Renderer = CoreRenderer.Renderer<"sqlite">
28
+ export type ValueMappings = Expression.DriverValueMappingsFor<SqliteDatatypeKind | "uuid", SqliteDatatypeFamily | "uuid">
29
+ /** Optional renderer / driver overrides for the standard SQLite executor pipeline. */
30
+ export interface MakeOptions<Error = never, Context = never> {
31
+ readonly renderer?: Renderer
32
+ readonly driver?: Driver<Error, Context>
33
+ readonly driverMode?: CoreExecutor.DriverMode
34
+ readonly valueMappings?: ValueMappings
35
+ }
36
+ /** Standard composed error shape for SQLite executors. */
37
+ export type SqliteExecutorError = SqliteDriverError | RowDecodeError
38
+ /** Read-query error surface emitted by built-in SQLite executors. */
39
+ export type SqliteQueryError<PlanValue extends CoreQuery.QueryPlan<any, any, any, any, any, any, any, any, any, any>> =
40
+ Exclude<CoreQuery.CapabilitiesOfPlan<PlanValue>, "read"> extends never ? SqliteReadQueryError : SqliteExecutorError
41
+
42
+ /** Runs an effect within the ambient SQLite SQL transaction service. */
43
+ export const withTransaction = CoreExecutor.withTransaction
44
+ /** Runs an effect in a nested SQLite SQL transaction scope. */
45
+ export const withSavepoint = CoreExecutor.withSavepoint
46
+
47
+ /** SQLite executor whose error channel narrows based on the query plan. */
48
+ export interface QueryExecutor<Context = never> {
49
+ readonly dialect: "sqlite"
50
+ execute<PlanValue extends CoreQuery.QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
51
+ plan: CoreQuery.DialectCompatiblePlan<PlanValue, "sqlite">
52
+ ): Effect.Effect<CoreQuery.ResultRows<PlanValue>, SqliteQueryError<PlanValue>, Context>
53
+ stream<PlanValue extends CoreQuery.QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
54
+ plan: Exclude<CoreQuery.CapabilitiesOfPlan<PlanValue>, "read" | "locking"> extends never
55
+ ? CoreQuery.DialectCompatiblePlan<PlanValue, "sqlite">
56
+ : never
57
+ ): Stream.Stream<CoreQuery.ResultRow<PlanValue>, SqliteQueryError<PlanValue>, Context>
58
+ }
59
+
60
+ type DriverExecute<Error, Context> = <Row>(
61
+ query: CoreRenderer.RenderedQuery<Row, "sqlite">
62
+ ) => Effect.Effect<ReadonlyArray<FlatRow>, Error, Context>
63
+
64
+ type DriverHandlers<Error, Context> = {
65
+ readonly execute: DriverExecute<Error, Context>
66
+ readonly stream: <Row>(
67
+ query: CoreRenderer.RenderedQuery<Row, "sqlite">
68
+ ) => Stream.Stream<FlatRow, Error, Context>
69
+ }
70
+
71
+ /** Constructs a SQLite-specialized SQL driver. */
72
+ export function driver<
73
+ Error = never,
74
+ Context = never
75
+ >(
76
+ execute: DriverExecute<Error, Context>
77
+ ): Driver<Error, Context>
78
+ export function driver<
79
+ Error = never,
80
+ Context = never
81
+ >(
82
+ handlers: DriverHandlers<Error, Context>
83
+ ): Driver<Error, Context>
84
+ export function driver<
85
+ Error = never,
86
+ Context = never
87
+ >(
88
+ dialect: "sqlite",
89
+ execute: DriverExecute<Error, Context>
90
+ ): Driver<Error, Context>
91
+ export function driver<
92
+ Error = never,
93
+ Context = never
94
+ >(
95
+ dialect: "sqlite",
96
+ handlers: DriverHandlers<Error, Context>
97
+ ): Driver<Error, Context>
98
+ export function driver<
99
+ Error = never,
100
+ Context = never
101
+ >(
102
+ dialectOrExecute: "sqlite" | DriverExecute<Error, Context> | DriverHandlers<Error, Context>,
103
+ maybeExecute?: DriverExecute<Error, Context> | DriverHandlers<Error, Context>
104
+ ): Driver<Error, Context> {
105
+ const executeOrHandlers = typeof dialectOrExecute === "string" ? maybeExecute : dialectOrExecute
106
+ return typeof executeOrHandlers === "function"
107
+ ? CoreExecutor.driver("sqlite", executeOrHandlers)
108
+ : CoreExecutor.driver("sqlite", executeOrHandlers as DriverHandlers<Error, Context>)
109
+ }
110
+
111
+ const fromDriver = <
112
+ Error = never,
113
+ Context = never
114
+ >(
115
+ renderer: Renderer,
116
+ sqlDriver: Driver<Error, Context>,
117
+ driverMode: CoreExecutor.DriverMode = "raw",
118
+ valueMappings?: Expression.DriverValueMappings
119
+ ): QueryExecutor<Context> => ({
120
+ dialect: "sqlite",
121
+ execute(plan) {
122
+ const rendered = renderer.render(plan)
123
+ return Effect.mapError(
124
+ Effect.flatMap(
125
+ sqlDriver.execute(rendered),
126
+ (rows) => Effect.try({
127
+ try: () => CoreExecutor.decodeRows(rendered, plan, rows, { driverMode, valueMappings }),
128
+ catch: (error) => error as RowDecodeError
129
+ })
130
+ ),
131
+ (error) => {
132
+ if (typeof error === "object" && error !== null && "_tag" in error && error._tag === "RowDecodeError") {
133
+ return error as RowDecodeError
134
+ }
135
+ const normalized = normalizeSqliteDriverError(error, rendered)
136
+ return CoreExecutor.hasWriteCapability(plan)
137
+ ? normalized
138
+ : narrowSqliteDriverErrorForReadQuery(normalized)
139
+ }
140
+ ) as Effect.Effect<any, any, Context>
141
+ },
142
+ stream(plan) {
143
+ const rendered = renderer.render(plan)
144
+ return Stream.mapError(
145
+ Stream.mapChunksEffect(
146
+ sqlDriver.stream(rendered),
147
+ (rows) => Effect.try({
148
+ try: () => CoreExecutor.decodeChunk(rendered, plan, rows, { driverMode, valueMappings }),
149
+ catch: (error) => error as RowDecodeError
150
+ })
151
+ ),
152
+ (error) => {
153
+ if (typeof error === "object" && error !== null && "_tag" in error && error._tag === "RowDecodeError") {
154
+ return error as RowDecodeError
155
+ }
156
+ const normalized = normalizeSqliteDriverError(error, rendered)
157
+ return CoreExecutor.hasWriteCapability(plan)
158
+ ? normalized
159
+ : narrowSqliteDriverErrorForReadQuery(normalized)
160
+ }
161
+ ) as Stream.Stream<any, any, Context>
162
+ }
163
+ })
164
+
165
+ const sqlClientDriver = (): Driver<any, SqlClient.SqlClient> =>
166
+ driver({
167
+ execute: (query: CoreRenderer.RenderedQuery<any, "sqlite">) =>
168
+ Effect.flatMap(SqlClient.SqlClient, (sql) =>
169
+ sql.unsafe<FlatRow>(query.sql, [...query.params])),
170
+ stream: (query: CoreRenderer.RenderedQuery<any, "sqlite">) =>
171
+ Stream.unwrap(
172
+ Effect.map(
173
+ Effect.flatMap(SqlClient.SqlClient, (sql) =>
174
+ sql.unsafe<FlatRow>(query.sql, [...query.params])),
175
+ (rows) => Stream.fromIterable(rows)
176
+ )
177
+ )
178
+ })
179
+
180
+ /**
181
+ * Creates the standard SQLite executor pipeline.
182
+ *
183
+ * By default this uses the built-in SQLite renderer plus the ambient
184
+ * `@effect/sql` `SqlClient`. Advanced callers can override the renderer,
185
+ * driver, or both.
186
+ */
187
+ export function make(): QueryExecutor<SqlClient.SqlClient>
188
+ export function make(options: {
189
+ readonly renderer?: Renderer
190
+ readonly driverMode?: CoreExecutor.DriverMode
191
+ readonly valueMappings?: ValueMappings
192
+ }): QueryExecutor<SqlClient.SqlClient>
193
+ export function make<Error = never, Context = never>(
194
+ options: {
195
+ readonly renderer?: Renderer
196
+ readonly driver: Driver<Error, Context>
197
+ readonly driverMode?: CoreExecutor.DriverMode
198
+ readonly valueMappings?: ValueMappings
199
+ }
200
+ ): QueryExecutor<Context>
201
+ export function make<Error = never, Context = never>(
202
+ options: MakeOptions<Error, Context> = {}
203
+ ): QueryExecutor<any> {
204
+ if (options.driver) {
205
+ return fromDriver(
206
+ options.renderer ?? CoreRenderer.makeTrusted("sqlite", (plan) => renderSqlitePlan(plan, { valueMappings: options.valueMappings })),
207
+ options.driver,
208
+ options.driverMode,
209
+ options.valueMappings
210
+ )
211
+ }
212
+ return fromDriver(
213
+ options.renderer ?? CoreRenderer.makeTrusted("sqlite", (plan) => renderSqlitePlan(plan, { valueMappings: options.valueMappings })),
214
+ sqlClientDriver(),
215
+ options.driverMode,
216
+ options.valueMappings
217
+ )
218
+ }
219
+
220
+ /** Creates a SQLite-specialized executor from a typed implementation callback. */
221
+ export const custom = <
222
+ Error = never,
223
+ Context = never
224
+ >(
225
+ execute: <PlanValue extends CoreQuery.QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
226
+ plan: CoreQuery.DialectCompatiblePlan<PlanValue, "sqlite">
227
+ ) => Effect.Effect<CoreQuery.ResultRows<PlanValue>, Error, Context>
228
+ ): Executor<Error, Context> =>
229
+ CoreExecutor.make("sqlite", execute as any) as Executor<Error, Context>
@@ -0,0 +1,2 @@
1
+ /** SQLite aggregate functions. */
2
+ export { count, max, min } from "../internal/dsl.js"
@@ -0,0 +1,2 @@
1
+ /** SQLite scalar core functions. */
2
+ export { coalesce, call } from "../internal/dsl.js"
@@ -0,0 +1,19 @@
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 * as temporal from "./temporal.js"
6
+
7
+ export { coalesce } from "./core.js"
8
+ export { call } from "./core.js"
9
+ export { lower, upper, concat } from "./string.js"
10
+ export { count, max, min } from "./aggregate.js"
11
+ export { over, rowNumber, rank, denseRank } from "./window.js"
12
+ export {
13
+ currentDate,
14
+ currentTime,
15
+ currentTimestamp,
16
+ localTime,
17
+ localTimestamp,
18
+ now
19
+ } from "./temporal.js"
@@ -0,0 +1,2 @@
1
+ /** SQLite string functions. */
2
+ export { lower, upper, concat } from "../internal/dsl.js"
@@ -0,0 +1,100 @@
1
+ import type * as Schema from "effect/Schema"
2
+
3
+ import type * as Expression from "../../internal/scalar.js"
4
+ import type * as ExpressionAst from "../../internal/expression-ast.js"
5
+ import { makeExpression } from "../../internal/query.js"
6
+ import { sqliteDatatypes } from "../datatypes/index.js"
7
+ import {
8
+ LocalDateStringSchema,
9
+ LocalDateTimeStringSchema,
10
+ LocalTimeStringSchema,
11
+ type LocalDateString,
12
+ type LocalDateTimeString,
13
+ type LocalTimeString
14
+ } from "../../internal/runtime/value.js"
15
+
16
+ type TemporalExpression<
17
+ Runtime,
18
+ Db extends Expression.DbType.Any,
19
+ Name extends string
20
+ > = Expression.Scalar<
21
+ Runtime,
22
+ Db,
23
+ "never",
24
+ "sqlite",
25
+ "scalar",
26
+ never
27
+ > & {
28
+ readonly [ExpressionAst.TypeId]: ExpressionAst.FunctionCallNode<Name, readonly []>
29
+ }
30
+
31
+ const makeTemporal = <
32
+ Runtime,
33
+ Db extends Expression.DbType.Any,
34
+ Name extends string
35
+ >(
36
+ name: Name,
37
+ dbType: Db,
38
+ runtimeSchema: Schema.Schema<Runtime, any, any>
39
+ ): TemporalExpression<Runtime, Db, Name> =>
40
+ makeExpression({
41
+ runtime: undefined as unknown as Runtime,
42
+ dbType,
43
+ runtimeSchema,
44
+ nullability: "never",
45
+ dialect: "sqlite",
46
+ kind: "scalar",
47
+ dependencies: {},
48
+ }, {
49
+ kind: "function",
50
+ name,
51
+ args: []
52
+ }) as TemporalExpression<Runtime, Db, Name>
53
+
54
+ /** SQLite current date. */
55
+ export const currentDate = () =>
56
+ makeTemporal(
57
+ "current_date",
58
+ sqliteDatatypes.date(),
59
+ LocalDateStringSchema
60
+ )
61
+
62
+ /** SQLite current time. */
63
+ export const currentTime = () =>
64
+ makeTemporal(
65
+ "current_time",
66
+ sqliteDatatypes.time(),
67
+ LocalTimeStringSchema
68
+ )
69
+
70
+ /** SQLite current timestamp. */
71
+ export const currentTimestamp = () =>
72
+ makeTemporal(
73
+ "current_timestamp",
74
+ sqliteDatatypes.timestamp(),
75
+ LocalDateTimeStringSchema
76
+ )
77
+
78
+ /** SQLite local time. */
79
+ export const localTime = () =>
80
+ makeTemporal(
81
+ "localtime",
82
+ sqliteDatatypes.time(),
83
+ LocalTimeStringSchema
84
+ )
85
+
86
+ /** SQLite local timestamp. */
87
+ export const localTimestamp = () =>
88
+ makeTemporal(
89
+ "localtimestamp",
90
+ sqliteDatatypes.timestamp(),
91
+ LocalDateTimeStringSchema
92
+ )
93
+
94
+ /** SQLite current instant-like timestamp. */
95
+ export const now = () =>
96
+ makeTemporal(
97
+ "now",
98
+ sqliteDatatypes.timestamp(),
99
+ LocalDateTimeStringSchema
100
+ )
@@ -0,0 +1,2 @@
1
+ /** SQLite window functions. */
2
+ export { over, rowNumber, rank, denseRank } from "../internal/dsl.js"