effect-qb 0.12.3
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 +1294 -0
- package/dist/mysql.js +57575 -0
- package/dist/postgres.js +6303 -0
- package/package.json +42 -0
- package/src/internal/aggregation-validation.ts +57 -0
- package/src/internal/case-analysis.ts +50 -0
- package/src/internal/coercion-analysis.ts +30 -0
- package/src/internal/coercion-errors.ts +29 -0
- package/src/internal/coercion-kind.ts +32 -0
- package/src/internal/coercion-normalize.ts +7 -0
- package/src/internal/coercion-rules.ts +25 -0
- package/src/internal/column-state.ts +453 -0
- package/src/internal/column.ts +417 -0
- package/src/internal/datatypes/define.ts +44 -0
- package/src/internal/datatypes/lookup.ts +280 -0
- package/src/internal/datatypes/shape.ts +72 -0
- package/src/internal/derived-table.ts +149 -0
- package/src/internal/dialect.ts +30 -0
- package/src/internal/executor.ts +390 -0
- package/src/internal/expression-ast.ts +349 -0
- package/src/internal/expression.ts +325 -0
- package/src/internal/grouping-key.ts +82 -0
- package/src/internal/json/ast.ts +63 -0
- package/src/internal/json/errors.ts +13 -0
- package/src/internal/json/path.ts +227 -0
- package/src/internal/json/shape.ts +1 -0
- package/src/internal/json/types.ts +386 -0
- package/src/internal/mysql-dialect.ts +39 -0
- package/src/internal/mysql-renderer.ts +37 -0
- package/src/internal/plan.ts +64 -0
- package/src/internal/postgres-dialect.ts +34 -0
- package/src/internal/postgres-renderer.ts +40 -0
- package/src/internal/predicate-analysis.ts +71 -0
- package/src/internal/predicate-atom.ts +43 -0
- package/src/internal/predicate-branches.ts +40 -0
- package/src/internal/predicate-context.ts +279 -0
- package/src/internal/predicate-formula.ts +100 -0
- package/src/internal/predicate-key.ts +28 -0
- package/src/internal/predicate-nnf.ts +12 -0
- package/src/internal/predicate-normalize.ts +202 -0
- package/src/internal/projection-alias.ts +15 -0
- package/src/internal/projections.ts +101 -0
- package/src/internal/query-ast.ts +297 -0
- package/src/internal/query-factory.ts +6757 -0
- package/src/internal/query-requirements.ts +40 -0
- package/src/internal/query.ts +1590 -0
- package/src/internal/renderer.ts +102 -0
- package/src/internal/runtime-normalize.ts +344 -0
- package/src/internal/runtime-schema.ts +428 -0
- package/src/internal/runtime-value.ts +85 -0
- package/src/internal/schema-derivation.ts +131 -0
- package/src/internal/sql-expression-renderer.ts +1353 -0
- package/src/internal/table-options.ts +225 -0
- package/src/internal/table.ts +674 -0
- package/src/mysql/column.ts +30 -0
- package/src/mysql/datatypes/index.ts +6 -0
- package/src/mysql/datatypes/spec.ts +180 -0
- package/src/mysql/errors/catalog.ts +51662 -0
- package/src/mysql/errors/fields.ts +21 -0
- package/src/mysql/errors/index.ts +18 -0
- package/src/mysql/errors/normalize.ts +232 -0
- package/src/mysql/errors/requirements.ts +73 -0
- package/src/mysql/executor.ts +134 -0
- package/src/mysql/query.ts +189 -0
- package/src/mysql/renderer.ts +19 -0
- package/src/mysql/table.ts +157 -0
- package/src/mysql.ts +18 -0
- package/src/postgres/column.ts +20 -0
- package/src/postgres/datatypes/index.ts +8 -0
- package/src/postgres/datatypes/spec.ts +264 -0
- package/src/postgres/errors/catalog.ts +452 -0
- package/src/postgres/errors/fields.ts +48 -0
- package/src/postgres/errors/index.ts +4 -0
- package/src/postgres/errors/normalize.ts +209 -0
- package/src/postgres/errors/requirements.ts +65 -0
- package/src/postgres/errors/types.ts +38 -0
- package/src/postgres/executor.ts +131 -0
- package/src/postgres/query.ts +189 -0
- package/src/postgres/renderer.ts +29 -0
- package/src/postgres/table.ts +157 -0
- package/src/postgres.ts +18 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import type * as Renderer from "../../internal/renderer.js"
|
|
2
|
+
import {
|
|
3
|
+
getPostgresErrorDescriptor,
|
|
4
|
+
isPostgresSqlStateCode,
|
|
5
|
+
postgresErrorClasses,
|
|
6
|
+
type PostgresErrorClassCode,
|
|
7
|
+
type PostgresErrorDescriptor,
|
|
8
|
+
type PostgresErrorTag,
|
|
9
|
+
type PostgresSqlStateCode
|
|
10
|
+
} from "./catalog.js"
|
|
11
|
+
import type {
|
|
12
|
+
PostgresErrorFields,
|
|
13
|
+
PostgresQueryContext
|
|
14
|
+
} from "./fields.js"
|
|
15
|
+
|
|
16
|
+
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
17
|
+
typeof value === "object" && value !== null
|
|
18
|
+
|
|
19
|
+
const asString = (value: unknown): string | undefined =>
|
|
20
|
+
typeof value === "string" ? value : undefined
|
|
21
|
+
|
|
22
|
+
const asNumber = (value: unknown): number | undefined => {
|
|
23
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
24
|
+
return value
|
|
25
|
+
}
|
|
26
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
27
|
+
const parsed = Number(value)
|
|
28
|
+
return Number.isFinite(parsed) ? parsed : undefined
|
|
29
|
+
}
|
|
30
|
+
return undefined
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const normalizeFields = (error: Record<string, unknown>): PostgresErrorFields => ({
|
|
34
|
+
severity: asString(error.severity),
|
|
35
|
+
severityNonLocalized: asString(error.severityNonLocalized),
|
|
36
|
+
detail: asString(error.detail),
|
|
37
|
+
hint: asString(error.hint),
|
|
38
|
+
position: asNumber(error.position),
|
|
39
|
+
internalPosition: asNumber(error.internalPosition),
|
|
40
|
+
internalQuery: asString(error.internalQuery),
|
|
41
|
+
where: asString(error.where),
|
|
42
|
+
schemaName: asString(error.schemaName) ?? asString(error.schema),
|
|
43
|
+
tableName: asString(error.tableName) ?? asString(error.table),
|
|
44
|
+
columnName: asString(error.columnName) ?? asString(error.column),
|
|
45
|
+
dataTypeName: asString(error.dataTypeName) ?? asString(error.dataType),
|
|
46
|
+
constraintName: asString(error.constraintName) ?? asString(error.constraint),
|
|
47
|
+
file: asString(error.file),
|
|
48
|
+
line: asNumber(error.line),
|
|
49
|
+
routine: asString(error.routine)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const sqlStatePattern = /^[0-9A-Z]{5}$/
|
|
53
|
+
|
|
54
|
+
/** Raw Postgres-like error object as commonly exposed by client libraries. */
|
|
55
|
+
export interface PostgresErrorLike {
|
|
56
|
+
readonly code?: string
|
|
57
|
+
readonly message?: string
|
|
58
|
+
readonly messagePrimary?: string
|
|
59
|
+
readonly schema?: string
|
|
60
|
+
readonly table?: string
|
|
61
|
+
readonly column?: string
|
|
62
|
+
readonly dataType?: string
|
|
63
|
+
readonly constraint?: string
|
|
64
|
+
readonly severity?: string
|
|
65
|
+
readonly severityNonLocalized?: string
|
|
66
|
+
readonly detail?: string
|
|
67
|
+
readonly hint?: string
|
|
68
|
+
readonly position?: string | number
|
|
69
|
+
readonly internalPosition?: string | number
|
|
70
|
+
readonly internalQuery?: string
|
|
71
|
+
readonly where?: string
|
|
72
|
+
readonly file?: string
|
|
73
|
+
readonly line?: string | number
|
|
74
|
+
readonly routine?: string
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Structured known Postgres SQLSTATE error derived from the catalog. */
|
|
78
|
+
export type KnownPostgresError<Code extends PostgresSqlStateCode = PostgresSqlStateCode> = {
|
|
79
|
+
readonly [Current in Code]: Readonly<{
|
|
80
|
+
readonly _tag: PostgresErrorTag<Current>
|
|
81
|
+
readonly code: Current
|
|
82
|
+
readonly condition: PostgresErrorDescriptor<Current>["condition"]
|
|
83
|
+
readonly classCode: PostgresErrorDescriptor<Current>["classCode"]
|
|
84
|
+
readonly className: PostgresErrorDescriptor<Current>["className"]
|
|
85
|
+
readonly message: string
|
|
86
|
+
readonly primaryFields: PostgresErrorDescriptor<Current>["primaryFields"]
|
|
87
|
+
readonly query?: PostgresQueryContext
|
|
88
|
+
readonly raw: PostgresErrorLike
|
|
89
|
+
} & PostgresErrorFields>
|
|
90
|
+
}[Code]
|
|
91
|
+
|
|
92
|
+
/** Extracts the known Postgres error variant for a specific SQLSTATE code. */
|
|
93
|
+
export type KnownPostgresErrorByCode<Code extends PostgresSqlStateCode> = Extract<
|
|
94
|
+
KnownPostgresError,
|
|
95
|
+
{ readonly code: Code }
|
|
96
|
+
>
|
|
97
|
+
|
|
98
|
+
/** Postgres-like error whose SQLSTATE is well-formed but not in the current catalog. */
|
|
99
|
+
export type UnknownPostgresSqlStateError = Readonly<{
|
|
100
|
+
readonly _tag: "@postgres/unknown/sqlstate"
|
|
101
|
+
readonly code: string
|
|
102
|
+
readonly classCode: string
|
|
103
|
+
readonly className?: string
|
|
104
|
+
readonly message: string
|
|
105
|
+
readonly query?: PostgresQueryContext
|
|
106
|
+
readonly raw: PostgresErrorLike
|
|
107
|
+
} & PostgresErrorFields>
|
|
108
|
+
|
|
109
|
+
/** Fallback for non-Postgres driver failures in the Postgres executor path. */
|
|
110
|
+
export type UnknownPostgresDriverError = Readonly<{
|
|
111
|
+
readonly _tag: "@postgres/unknown/driver"
|
|
112
|
+
readonly message: string
|
|
113
|
+
readonly query?: PostgresQueryContext
|
|
114
|
+
readonly cause: unknown
|
|
115
|
+
}>
|
|
116
|
+
|
|
117
|
+
/** Any Postgres-specific driver failure surfaced by the Postgres executor. */
|
|
118
|
+
export type PostgresDriverError =
|
|
119
|
+
| KnownPostgresError
|
|
120
|
+
| UnknownPostgresSqlStateError
|
|
121
|
+
| UnknownPostgresDriverError
|
|
122
|
+
|
|
123
|
+
/** Runtime guard for objects that look like Postgres driver errors. */
|
|
124
|
+
export const isPostgresErrorLike = (value: unknown): value is PostgresErrorLike =>
|
|
125
|
+
isRecord(value) &&
|
|
126
|
+
(
|
|
127
|
+
(typeof value.code === "string" && sqlStatePattern.test(value.code)) ||
|
|
128
|
+
typeof value.severity === "string" ||
|
|
129
|
+
typeof value.message === "string" ||
|
|
130
|
+
typeof value.messagePrimary === "string"
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
const errorMessageOf = (error: PostgresErrorLike): string =>
|
|
134
|
+
error.message ?? error.messagePrimary ?? "Postgres driver error"
|
|
135
|
+
|
|
136
|
+
const makeKnownPostgresError = <Code extends PostgresSqlStateCode>(
|
|
137
|
+
code: Code,
|
|
138
|
+
raw: PostgresErrorLike,
|
|
139
|
+
query?: PostgresQueryContext
|
|
140
|
+
): KnownPostgresError<Code> => {
|
|
141
|
+
const descriptor = getPostgresErrorDescriptor(code)
|
|
142
|
+
return {
|
|
143
|
+
_tag: descriptor.tag,
|
|
144
|
+
code,
|
|
145
|
+
condition: descriptor.condition,
|
|
146
|
+
classCode: descriptor.classCode,
|
|
147
|
+
className: descriptor.className,
|
|
148
|
+
message: errorMessageOf(raw),
|
|
149
|
+
primaryFields: descriptor.primaryFields,
|
|
150
|
+
query,
|
|
151
|
+
raw,
|
|
152
|
+
...normalizeFields(raw as Record<string, unknown>)
|
|
153
|
+
} as KnownPostgresError<Code>
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Normalizes an unknown failure into a structured Postgres driver error. */
|
|
157
|
+
export const normalizePostgresDriverError = (
|
|
158
|
+
cause: unknown,
|
|
159
|
+
query?: PostgresQueryContext | Renderer.RenderedQuery<any, "postgres">
|
|
160
|
+
): PostgresDriverError => {
|
|
161
|
+
const context = query === undefined
|
|
162
|
+
? undefined
|
|
163
|
+
: "sql" in query
|
|
164
|
+
? { sql: query.sql, params: query.params }
|
|
165
|
+
: query
|
|
166
|
+
|
|
167
|
+
if (!isPostgresErrorLike(cause)) {
|
|
168
|
+
return {
|
|
169
|
+
_tag: "@postgres/unknown/driver",
|
|
170
|
+
message: cause instanceof Error ? cause.message : "Unknown Postgres driver failure",
|
|
171
|
+
query: context,
|
|
172
|
+
cause
|
|
173
|
+
} as UnknownPostgresDriverError
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (cause.code && isPostgresSqlStateCode(cause.code)) {
|
|
177
|
+
return makeKnownPostgresError(cause.code, cause, context)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (typeof cause.code === "string" && sqlStatePattern.test(cause.code)) {
|
|
181
|
+
const classCode = cause.code.slice(0, 2)
|
|
182
|
+
return {
|
|
183
|
+
_tag: "@postgres/unknown/sqlstate",
|
|
184
|
+
code: cause.code,
|
|
185
|
+
classCode,
|
|
186
|
+
className: classCode in postgresErrorClasses
|
|
187
|
+
? postgresErrorClasses[classCode as PostgresErrorClassCode]
|
|
188
|
+
: undefined,
|
|
189
|
+
message: errorMessageOf(cause),
|
|
190
|
+
query: context,
|
|
191
|
+
raw: cause,
|
|
192
|
+
...normalizeFields(cause as Record<string, unknown>)
|
|
193
|
+
} as UnknownPostgresSqlStateError
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
_tag: "@postgres/unknown/driver",
|
|
198
|
+
message: errorMessageOf(cause),
|
|
199
|
+
query: context,
|
|
200
|
+
cause
|
|
201
|
+
} as UnknownPostgresDriverError
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** Type guard for a specific SQLSTATE code. */
|
|
205
|
+
export const hasSqlState = <Code extends PostgresSqlStateCode>(
|
|
206
|
+
error: PostgresDriverError | { readonly code?: string },
|
|
207
|
+
code: Code
|
|
208
|
+
): error is KnownPostgresErrorByCode<Code> =>
|
|
209
|
+
"code" in error && error.code === code
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { read_query_capabilities, type QueryCapability, type QueryRequirement } from "../../internal/query-requirements.js"
|
|
2
|
+
import type { PostgresErrorClassCode } from "./catalog.js"
|
|
3
|
+
import type { PostgresQueryContext } from "./fields.js"
|
|
4
|
+
import type {
|
|
5
|
+
KnownPostgresError,
|
|
6
|
+
PostgresDriverError,
|
|
7
|
+
UnknownPostgresDriverError,
|
|
8
|
+
UnknownPostgresSqlStateError
|
|
9
|
+
} from "./normalize.js"
|
|
10
|
+
|
|
11
|
+
type WriteRequiredPostgresClassCode = "23" | "27" | "44"
|
|
12
|
+
export type PostgresQueryRequirement = Extract<QueryRequirement, "write" | "ddl" | "transaction" | "locking">
|
|
13
|
+
|
|
14
|
+
export const postgres_requirements_by_class_code = {
|
|
15
|
+
"23": ["write"],
|
|
16
|
+
"27": ["write"],
|
|
17
|
+
"44": ["write"]
|
|
18
|
+
} as const satisfies Partial<Record<PostgresErrorClassCode, readonly PostgresQueryRequirement[]>>
|
|
19
|
+
|
|
20
|
+
export type PostgresQueryRequirementsError = Readonly<{
|
|
21
|
+
readonly _tag: "@postgres/unknown/query-requirements"
|
|
22
|
+
readonly message: string
|
|
23
|
+
readonly query?: PostgresQueryContext
|
|
24
|
+
readonly requiredCapabilities: readonly PostgresQueryRequirement[]
|
|
25
|
+
readonly actualCapabilities: readonly QueryCapability[]
|
|
26
|
+
readonly cause: PostgresDriverError
|
|
27
|
+
}>
|
|
28
|
+
|
|
29
|
+
export type PostgresReadQueryError =
|
|
30
|
+
| Exclude<KnownPostgresError, { readonly classCode: keyof typeof postgres_requirements_by_class_code & WriteRequiredPostgresClassCode }>
|
|
31
|
+
| UnknownPostgresSqlStateError
|
|
32
|
+
| UnknownPostgresDriverError
|
|
33
|
+
| PostgresQueryRequirementsError
|
|
34
|
+
|
|
35
|
+
const lookup_postgres_requirements = (
|
|
36
|
+
classCode: string
|
|
37
|
+
): readonly PostgresQueryRequirement[] =>
|
|
38
|
+
classCode in postgres_requirements_by_class_code
|
|
39
|
+
? postgres_requirements_by_class_code[classCode as keyof typeof postgres_requirements_by_class_code]
|
|
40
|
+
: []
|
|
41
|
+
|
|
42
|
+
export const requirements_of_postgres_error = (
|
|
43
|
+
error: PostgresDriverError
|
|
44
|
+
): readonly PostgresQueryRequirement[] =>
|
|
45
|
+
"classCode" in error
|
|
46
|
+
? lookup_postgres_requirements(error.classCode)
|
|
47
|
+
: []
|
|
48
|
+
|
|
49
|
+
export const narrowPostgresDriverErrorForReadQuery = (
|
|
50
|
+
error: PostgresDriverError
|
|
51
|
+
): PostgresReadQueryError => {
|
|
52
|
+
const requiredCapabilities = requirements_of_postgres_error(error)
|
|
53
|
+
if (requiredCapabilities.length === 0) {
|
|
54
|
+
return error as PostgresReadQueryError
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
_tag: "@postgres/unknown/query-requirements",
|
|
59
|
+
message: "Postgres driver error requires query capabilities not provided by this plan",
|
|
60
|
+
query: error.query,
|
|
61
|
+
requiredCapabilities,
|
|
62
|
+
actualCapabilities: read_query_capabilities,
|
|
63
|
+
cause: error
|
|
64
|
+
} satisfies PostgresQueryRequirementsError
|
|
65
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Structured Postgres error-report fields commonly exposed by drivers. */
|
|
2
|
+
export type PostgresErrorSemanticField =
|
|
3
|
+
| "schema"
|
|
4
|
+
| "table"
|
|
5
|
+
| "column"
|
|
6
|
+
| "constraint"
|
|
7
|
+
| "dataType"
|
|
8
|
+
| "position"
|
|
9
|
+
| "internalPosition"
|
|
10
|
+
| "internalQuery"
|
|
11
|
+
| "file"
|
|
12
|
+
| "line"
|
|
13
|
+
| "routine"
|
|
14
|
+
|
|
15
|
+
/** Class-level metadata for a family of SQLSTATE errors. */
|
|
16
|
+
export interface PostgresSqlStateClassMetadata<
|
|
17
|
+
ClassCode extends string = string,
|
|
18
|
+
ClassName extends string = string
|
|
19
|
+
> {
|
|
20
|
+
readonly classCode: ClassCode
|
|
21
|
+
readonly className: ClassName
|
|
22
|
+
readonly tag: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Metadata for a single Postgres SQLSTATE condition. */
|
|
26
|
+
export interface PostgresSqlStateMetadata<
|
|
27
|
+
Code extends string = string,
|
|
28
|
+
Condition extends string = string,
|
|
29
|
+
ClassCode extends string = string,
|
|
30
|
+
ClassName extends string = string
|
|
31
|
+
> {
|
|
32
|
+
readonly code: Code
|
|
33
|
+
readonly condition: Condition
|
|
34
|
+
readonly classCode: ClassCode
|
|
35
|
+
readonly className: ClassName
|
|
36
|
+
readonly tag: string
|
|
37
|
+
readonly semanticFields: readonly PostgresErrorSemanticField[]
|
|
38
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect"
|
|
2
|
+
import * as SqlClient from "@effect/sql/SqlClient"
|
|
3
|
+
|
|
4
|
+
import * as CoreExecutor from "../internal/executor.js"
|
|
5
|
+
import * as Query from "./query.js"
|
|
6
|
+
import * as Renderer from "./renderer.js"
|
|
7
|
+
import {
|
|
8
|
+
narrowPostgresDriverErrorForReadQuery,
|
|
9
|
+
normalizePostgresDriverError,
|
|
10
|
+
type PostgresDriverError,
|
|
11
|
+
type PostgresReadQueryError
|
|
12
|
+
} from "./errors/index.js"
|
|
13
|
+
|
|
14
|
+
/** Postgres-specialized flat row returned by SQL drivers. */
|
|
15
|
+
export type FlatRow = CoreExecutor.FlatRow
|
|
16
|
+
/** Runtime decode failure raised after SQL execution but before row remapping. */
|
|
17
|
+
export type RowDecodeError = CoreExecutor.RowDecodeError
|
|
18
|
+
/** Postgres-specialized rendered-query driver. */
|
|
19
|
+
export type Driver<Error = never, Context = never> = CoreExecutor.Driver<"postgres", Error, Context>
|
|
20
|
+
/** Postgres-specialized executor contract. */
|
|
21
|
+
export type Executor<Error = never, Context = never> = CoreExecutor.Executor<"postgres", Error, Context>
|
|
22
|
+
/** Optional renderer / driver overrides for the standard Postgres executor pipeline. */
|
|
23
|
+
export interface MakeOptions<Error = never, Context = never> {
|
|
24
|
+
readonly renderer?: Renderer.Renderer
|
|
25
|
+
readonly driver?: Driver<Error, Context>
|
|
26
|
+
readonly driverMode?: CoreExecutor.DriverMode
|
|
27
|
+
}
|
|
28
|
+
/** Standard composed error shape for Postgres executors. */
|
|
29
|
+
export type PostgresExecutorError = PostgresDriverError | RowDecodeError
|
|
30
|
+
/** Read-query error surface emitted by built-in Postgres executors. */
|
|
31
|
+
export type PostgresQueryError<PlanValue extends Query.QueryPlan<any, any, any, any, any, any, any, any, any, any>> =
|
|
32
|
+
Exclude<Query.CapabilitiesOfPlan<PlanValue>, "read"> extends never ? PostgresReadQueryError : PostgresExecutorError
|
|
33
|
+
|
|
34
|
+
/** Runs an effect within the ambient Postgres SQL transaction service. */
|
|
35
|
+
export const withTransaction = CoreExecutor.withTransaction
|
|
36
|
+
/** Runs an effect in a nested Postgres SQL transaction scope. */
|
|
37
|
+
export const withSavepoint = CoreExecutor.withSavepoint
|
|
38
|
+
|
|
39
|
+
/** Postgres executor whose error channel narrows based on the query plan. */
|
|
40
|
+
export interface QueryExecutor<Context = never> {
|
|
41
|
+
readonly dialect: "postgres"
|
|
42
|
+
execute<PlanValue extends Query.QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
|
|
43
|
+
plan: Query.DialectCompatiblePlan<PlanValue, "postgres">
|
|
44
|
+
): Effect.Effect<Query.ResultRows<PlanValue>, PostgresQueryError<PlanValue>, Context>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Constructs a Postgres-specialized SQL driver. */
|
|
48
|
+
export function driver(execute: any): Driver<any, any>
|
|
49
|
+
export function driver(dialect: "postgres", execute: any): Driver<any, any>
|
|
50
|
+
export function driver(dialectOrExecute: "postgres" | any, maybeExecute?: any): Driver<any, any> {
|
|
51
|
+
const execute = typeof dialectOrExecute === "string" ? maybeExecute : dialectOrExecute
|
|
52
|
+
return CoreExecutor.driver("postgres", execute as any)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const fromDriver = <
|
|
56
|
+
Error = never,
|
|
57
|
+
Context = never
|
|
58
|
+
>(
|
|
59
|
+
renderer: Renderer.Renderer,
|
|
60
|
+
sqlDriver: Driver<Error, Context>,
|
|
61
|
+
driverMode: CoreExecutor.DriverMode = "raw"
|
|
62
|
+
): QueryExecutor<Context> => ({
|
|
63
|
+
dialect: "postgres",
|
|
64
|
+
execute(plan) {
|
|
65
|
+
const rendered = renderer.render(plan)
|
|
66
|
+
return Effect.mapError(
|
|
67
|
+
Effect.flatMap(
|
|
68
|
+
sqlDriver.execute(rendered),
|
|
69
|
+
(rows) => Effect.try({
|
|
70
|
+
try: () => CoreExecutor.decodeRows(rendered, plan, rows, { driverMode }),
|
|
71
|
+
catch: (error) => error as RowDecodeError
|
|
72
|
+
})
|
|
73
|
+
),
|
|
74
|
+
(error) => {
|
|
75
|
+
if (typeof error === "object" && error !== null && "_tag" in error && error._tag === "RowDecodeError") {
|
|
76
|
+
return error as RowDecodeError
|
|
77
|
+
}
|
|
78
|
+
const normalized = normalizePostgresDriverError(error, rendered)
|
|
79
|
+
return CoreExecutor.hasWriteCapability(plan)
|
|
80
|
+
? normalized
|
|
81
|
+
: narrowPostgresDriverErrorForReadQuery(normalized)
|
|
82
|
+
}
|
|
83
|
+
) as Effect.Effect<any, any, Context>
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
const sqlClientDriver = (): Driver<any, SqlClient.SqlClient> =>
|
|
88
|
+
driver((query: Renderer.RenderedQuery<any>) =>
|
|
89
|
+
Effect.flatMap(SqlClient.SqlClient, (sql) =>
|
|
90
|
+
sql.unsafe<FlatRow>(query.sql, [...query.params])))
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Creates the standard Postgres executor pipeline.
|
|
94
|
+
*
|
|
95
|
+
* By default this uses the built-in Postgres renderer plus the ambient
|
|
96
|
+
* `@effect/sql` `SqlClient`. Advanced callers can override the renderer,
|
|
97
|
+
* driver, or both.
|
|
98
|
+
*/
|
|
99
|
+
export function make(): QueryExecutor<SqlClient.SqlClient>
|
|
100
|
+
export function make(
|
|
101
|
+
options: {
|
|
102
|
+
readonly renderer?: Renderer.Renderer
|
|
103
|
+
readonly driverMode?: CoreExecutor.DriverMode
|
|
104
|
+
}
|
|
105
|
+
): QueryExecutor<SqlClient.SqlClient>
|
|
106
|
+
export function make<Error = never, Context = never>(
|
|
107
|
+
options: {
|
|
108
|
+
readonly renderer?: Renderer.Renderer
|
|
109
|
+
readonly driver: Driver<Error, Context>
|
|
110
|
+
readonly driverMode?: CoreExecutor.DriverMode
|
|
111
|
+
}
|
|
112
|
+
): QueryExecutor<Context>
|
|
113
|
+
export function make<Error = never, Context = never>(
|
|
114
|
+
options: MakeOptions<Error, Context> = {}
|
|
115
|
+
): QueryExecutor<any> {
|
|
116
|
+
if (options.driver) {
|
|
117
|
+
return fromDriver(options.renderer ?? Renderer.make(), options.driver, options.driverMode)
|
|
118
|
+
}
|
|
119
|
+
return fromDriver(options.renderer ?? Renderer.make(), sqlClientDriver(), options.driverMode)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Creates a Postgres-specialized executor from a typed implementation callback. */
|
|
123
|
+
export const custom = <
|
|
124
|
+
Error = never,
|
|
125
|
+
Context = never
|
|
126
|
+
>(
|
|
127
|
+
execute: <PlanValue extends Query.QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
|
|
128
|
+
plan: Query.DialectCompatiblePlan<PlanValue, "postgres">
|
|
129
|
+
) => Effect.Effect<Query.ResultRows<PlanValue>, Error, Context>
|
|
130
|
+
): Executor<Error, Context> =>
|
|
131
|
+
CoreExecutor.make("postgres", execute as any) as Executor<Error, Context>
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import * as Expression from "../internal/expression.js"
|
|
2
|
+
import { postgresDatatypes } from "./datatypes/index.js"
|
|
3
|
+
import {
|
|
4
|
+
type CapabilitiesOfPlan,
|
|
5
|
+
type CompletePlan,
|
|
6
|
+
type DialectCompatiblePlan,
|
|
7
|
+
type DerivedSourceRequiredError,
|
|
8
|
+
type CteSource,
|
|
9
|
+
type EffectiveNullability,
|
|
10
|
+
type ExpressionInput,
|
|
11
|
+
type ExpressionOutput,
|
|
12
|
+
type GroupByInput,
|
|
13
|
+
type MergeCapabilities,
|
|
14
|
+
type MergeCapabilityTuple,
|
|
15
|
+
type HavingPredicateInput,
|
|
16
|
+
type OrderDirection,
|
|
17
|
+
type OutputOfSelection,
|
|
18
|
+
type MutationInputOf,
|
|
19
|
+
type MutationTargetLike,
|
|
20
|
+
type NumericExpressionInput,
|
|
21
|
+
type PredicateInput,
|
|
22
|
+
type QueryCapability,
|
|
23
|
+
type QueryPlan,
|
|
24
|
+
type QueryRequirement,
|
|
25
|
+
type SetCompatiblePlan,
|
|
26
|
+
type SetCompatibleRightPlan,
|
|
27
|
+
type SetOperator,
|
|
28
|
+
type QueryStatement,
|
|
29
|
+
type ResultRow,
|
|
30
|
+
type ResultRows,
|
|
31
|
+
type RuntimeResultRow,
|
|
32
|
+
type RuntimeResultRows,
|
|
33
|
+
type SchemaTableLike,
|
|
34
|
+
type SourceCapabilitiesOf,
|
|
35
|
+
type SourceRequiredOf,
|
|
36
|
+
type SourceRequirementError,
|
|
37
|
+
type StatementOfPlan,
|
|
38
|
+
type StringExpressionInput
|
|
39
|
+
} from "../internal/query.js"
|
|
40
|
+
import { makeDialectQuery } from "../internal/query-factory.js"
|
|
41
|
+
|
|
42
|
+
const postgresQuery = makeDialectQuery({
|
|
43
|
+
dialect: "postgres",
|
|
44
|
+
textDb: { dialect: "postgres", kind: "text" } as Expression.DbType.PgText,
|
|
45
|
+
numericDb: { dialect: "postgres", kind: "float8" } as Expression.DbType.PgFloat8,
|
|
46
|
+
boolDb: { dialect: "postgres", kind: "bool" } as Expression.DbType.PgBool,
|
|
47
|
+
timestampDb: { dialect: "postgres", kind: "timestamp" } as Expression.DbType.PgTimestamp,
|
|
48
|
+
nullDb: { dialect: "postgres", kind: "null" } as Expression.DbType.Base<"postgres", "null">,
|
|
49
|
+
type: postgresDatatypes
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
export const literal = postgresQuery.literal
|
|
53
|
+
export const cast = postgresQuery.cast
|
|
54
|
+
export const type = postgresQuery.type
|
|
55
|
+
export const json = postgresQuery.json
|
|
56
|
+
export const eq = postgresQuery.eq
|
|
57
|
+
export const neq = postgresQuery.neq
|
|
58
|
+
export const lt = postgresQuery.lt
|
|
59
|
+
export const lte = postgresQuery.lte
|
|
60
|
+
export const gt = postgresQuery.gt
|
|
61
|
+
export const gte = postgresQuery.gte
|
|
62
|
+
export const isNull = postgresQuery.isNull
|
|
63
|
+
export const isNotNull = postgresQuery.isNotNull
|
|
64
|
+
export const upper = postgresQuery.upper
|
|
65
|
+
export const lower = postgresQuery.lower
|
|
66
|
+
export const like = postgresQuery.like
|
|
67
|
+
export const ilike = postgresQuery.ilike
|
|
68
|
+
export const and = postgresQuery.and
|
|
69
|
+
export const or = postgresQuery.or
|
|
70
|
+
export const not = postgresQuery.not
|
|
71
|
+
export const all = postgresQuery.all
|
|
72
|
+
export const any = postgresQuery.any
|
|
73
|
+
const case_ = postgresQuery.case
|
|
74
|
+
export const match = postgresQuery.match
|
|
75
|
+
export const coalesce = postgresQuery.coalesce
|
|
76
|
+
export const in_ = postgresQuery.in
|
|
77
|
+
export const notIn = postgresQuery.notIn
|
|
78
|
+
export const between = postgresQuery.between
|
|
79
|
+
export const contains = postgresQuery.contains
|
|
80
|
+
export const containedBy = postgresQuery.containedBy
|
|
81
|
+
export const overlaps = postgresQuery.overlaps
|
|
82
|
+
export const concat = postgresQuery.concat
|
|
83
|
+
export const exists = postgresQuery.exists
|
|
84
|
+
export const over = postgresQuery.over
|
|
85
|
+
export const rowNumber = postgresQuery.rowNumber
|
|
86
|
+
export const rank = postgresQuery.rank
|
|
87
|
+
export const denseRank = postgresQuery.denseRank
|
|
88
|
+
export const count = postgresQuery.count
|
|
89
|
+
export const max = postgresQuery.max
|
|
90
|
+
export const min = postgresQuery.min
|
|
91
|
+
export const isDistinctFrom = postgresQuery.isDistinctFrom
|
|
92
|
+
export const isNotDistinctFrom = postgresQuery.isNotDistinctFrom
|
|
93
|
+
export const excluded = postgresQuery.excluded
|
|
94
|
+
export const as = postgresQuery.as
|
|
95
|
+
export const with_ = postgresQuery.with
|
|
96
|
+
export const withRecursive = postgresQuery.withRecursive
|
|
97
|
+
export const lateral = postgresQuery.lateral
|
|
98
|
+
export const scalar = postgresQuery.scalar
|
|
99
|
+
export const inSubquery = postgresQuery.inSubquery
|
|
100
|
+
export const compareAny = postgresQuery.compareAny
|
|
101
|
+
export const compareAll = postgresQuery.compareAll
|
|
102
|
+
export const values = postgresQuery.values
|
|
103
|
+
export const unnest = postgresQuery.unnest
|
|
104
|
+
export const generateSeries = postgresQuery.generateSeries
|
|
105
|
+
export const returning = postgresQuery.returning
|
|
106
|
+
export const defaultValues = postgresQuery.defaultValues
|
|
107
|
+
export const onConflict = postgresQuery.onConflict
|
|
108
|
+
export const insert = postgresQuery.insert
|
|
109
|
+
export const update = postgresQuery.update
|
|
110
|
+
export const upsert = postgresQuery.upsert
|
|
111
|
+
export const delete_ = postgresQuery.delete
|
|
112
|
+
export const truncate = postgresQuery.truncate
|
|
113
|
+
export const merge = postgresQuery.merge
|
|
114
|
+
export const transaction = postgresQuery.transaction
|
|
115
|
+
export const commit = postgresQuery.commit
|
|
116
|
+
export const rollback = postgresQuery.rollback
|
|
117
|
+
export const savepoint = postgresQuery.savepoint
|
|
118
|
+
export const rollbackTo = postgresQuery.rollbackTo
|
|
119
|
+
export const releaseSavepoint = postgresQuery.releaseSavepoint
|
|
120
|
+
export const createTable = postgresQuery.createTable
|
|
121
|
+
export const dropTable = postgresQuery.dropTable
|
|
122
|
+
export const createIndex = postgresQuery.createIndex
|
|
123
|
+
export const dropIndex = postgresQuery.dropIndex
|
|
124
|
+
export const union = postgresQuery.union
|
|
125
|
+
export const unionAll = postgresQuery.unionAll
|
|
126
|
+
export const intersect = postgresQuery.intersect
|
|
127
|
+
export const intersectAll = postgresQuery.intersectAll
|
|
128
|
+
export const except = postgresQuery.except
|
|
129
|
+
export const exceptAll = postgresQuery.exceptAll
|
|
130
|
+
export const select = postgresQuery.select
|
|
131
|
+
export const where = postgresQuery.where
|
|
132
|
+
export const having = postgresQuery.having
|
|
133
|
+
export const from = postgresQuery.from
|
|
134
|
+
export const innerJoin = postgresQuery.innerJoin
|
|
135
|
+
export const leftJoin = postgresQuery.leftJoin
|
|
136
|
+
export const rightJoin = postgresQuery.rightJoin
|
|
137
|
+
export const fullJoin = postgresQuery.fullJoin
|
|
138
|
+
export const crossJoin = postgresQuery.crossJoin
|
|
139
|
+
export const distinct = postgresQuery.distinct
|
|
140
|
+
export const distinctOn = postgresQuery.distinctOn
|
|
141
|
+
export const limit = postgresQuery.limit
|
|
142
|
+
export const offset = postgresQuery.offset
|
|
143
|
+
export const lock = postgresQuery.lock
|
|
144
|
+
export const orderBy = postgresQuery.orderBy
|
|
145
|
+
export const groupBy = postgresQuery.groupBy
|
|
146
|
+
export { case_ as case }
|
|
147
|
+
export { in_ as in }
|
|
148
|
+
export { with_ as with }
|
|
149
|
+
export { delete_ as delete }
|
|
150
|
+
|
|
151
|
+
export type {
|
|
152
|
+
CapabilitiesOfPlan,
|
|
153
|
+
CompletePlan,
|
|
154
|
+
DialectCompatiblePlan,
|
|
155
|
+
DerivedSourceRequiredError,
|
|
156
|
+
CteSource,
|
|
157
|
+
EffectiveNullability,
|
|
158
|
+
ExpressionInput,
|
|
159
|
+
ExpressionOutput,
|
|
160
|
+
GroupByInput,
|
|
161
|
+
MergeCapabilities,
|
|
162
|
+
MergeCapabilityTuple,
|
|
163
|
+
HavingPredicateInput,
|
|
164
|
+
OrderDirection,
|
|
165
|
+
OutputOfSelection,
|
|
166
|
+
MutationInputOf,
|
|
167
|
+
MutationTargetLike,
|
|
168
|
+
NumericExpressionInput,
|
|
169
|
+
PredicateInput,
|
|
170
|
+
QueryCapability,
|
|
171
|
+
QueryPlan,
|
|
172
|
+
QueryStatement,
|
|
173
|
+
QueryRequirement,
|
|
174
|
+
SetCompatiblePlan,
|
|
175
|
+
SetCompatibleRightPlan,
|
|
176
|
+
SetOperator,
|
|
177
|
+
ResultRow,
|
|
178
|
+
ResultRows,
|
|
179
|
+
RuntimeResultRow,
|
|
180
|
+
RuntimeResultRows,
|
|
181
|
+
SchemaTableLike,
|
|
182
|
+
SourceCapabilitiesOf,
|
|
183
|
+
SourceRequiredOf,
|
|
184
|
+
SourceRequirementError,
|
|
185
|
+
StatementOfPlan,
|
|
186
|
+
StringExpressionInput
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export { union_query_capabilities } from "../internal/query.js"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as CoreRenderer from "../internal/renderer.js"
|
|
2
|
+
|
|
3
|
+
/** Postgres-specialized rendered query shape. */
|
|
4
|
+
export type RenderedQuery<Row> = CoreRenderer.RenderedQuery<Row, "postgres">
|
|
5
|
+
/** Extracts the row type carried by a Postgres rendered query. */
|
|
6
|
+
export type RowOf<Value extends RenderedQuery<any>> = CoreRenderer.RowOf<Value>
|
|
7
|
+
/** Postgres-specialized renderer contract. */
|
|
8
|
+
export type Renderer = CoreRenderer.Renderer<"postgres">
|
|
9
|
+
|
|
10
|
+
export { TypeId } from "../internal/renderer.js"
|
|
11
|
+
export type { Projection } from "../internal/renderer.js"
|
|
12
|
+
|
|
13
|
+
/** Creates the built-in Postgres renderer. */
|
|
14
|
+
export function make(): Renderer
|
|
15
|
+
export function make(dialect: "postgres"): Renderer
|
|
16
|
+
export function make(
|
|
17
|
+
dialect: "postgres",
|
|
18
|
+
render: Parameters<typeof CoreRenderer.make>[1]
|
|
19
|
+
): Renderer
|
|
20
|
+
export function make(
|
|
21
|
+
dialectOrRender?: "postgres" | Parameters<typeof CoreRenderer.make>[1],
|
|
22
|
+
render?: Parameters<typeof CoreRenderer.make>[1]
|
|
23
|
+
): Renderer {
|
|
24
|
+
const customRender = typeof dialectOrRender === "function" ? dialectOrRender : render
|
|
25
|
+
return customRender ? CoreRenderer.make("postgres", customRender as any) : CoreRenderer.make("postgres")
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Shared built-in Postgres renderer instance. */
|
|
29
|
+
export const postgres = make()
|