@prisma/orm-target-mysql 0.0.0-stage → 8.0.0-rc.21
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/LICENSE +201 -0
- package/README.md +20 -2
- package/dist/adapter-_WBomuTw.d.mts +27 -0
- package/dist/adapter-_WBomuTw.d.mts.map +1 -0
- package/dist/adapter.d.mts +6 -0
- package/dist/adapter.mjs +3 -0
- package/dist/adapter__adapter.d.mts +2 -0
- package/dist/adapter__adapter.mjs +2 -0
- package/dist/adapter__codec-types.d.mts +3 -0
- package/dist/adapter__codec-types.mjs +1 -0
- package/dist/adapter__control.d.mts +2 -0
- package/dist/adapter__control.mjs +2 -0
- package/dist/adapter__runtime.d.mts +2 -0
- package/dist/adapter__runtime.mjs +417 -0
- package/dist/adapter__runtime.mjs.map +1 -0
- package/dist/codec-descriptor-DXyubAS6-siA0R8Ow.d.mts +43 -0
- package/dist/codec-descriptor-DXyubAS6-siA0R8Ow.d.mts.map +1 -0
- package/dist/codec-descriptor-Du6DSz-3-ytBCu_mq.mjs +93 -0
- package/dist/codec-descriptor-Du6DSz-3-ytBCu_mq.mjs.map +1 -0
- package/dist/codec-descriptor-J3TP08l8-ekLvUVxW.d.mts +1 -0
- package/dist/codec-descriptor-oLRh9E29.d.mts +2 -0
- package/dist/codec-ids-BHUwoNOM.d.mts +2 -0
- package/dist/codec-ids-C00hAFkc.mjs +2 -0
- package/dist/codec-ids-cjxtOcLM-vFeQhgPm.mjs +10 -0
- package/dist/codec-ids-cjxtOcLM-vFeQhgPm.mjs.map +1 -0
- package/dist/codec-ids-sMOU8F-B-BQbCq2dr.d.mts +10 -0
- package/dist/codec-ids-sMOU8F-B-BQbCq2dr.d.mts.map +1 -0
- package/dist/codec-types-Bd7DL1Mr-CZWNfnp9.d.mts +21 -0
- package/dist/codec-types-Bd7DL1Mr-CZWNfnp9.d.mts.map +1 -0
- package/dist/codec-types-Bo3Jfilx.d.mts +1 -0
- package/dist/codec-types-Ja2kLzLS.d.mts +1 -0
- package/dist/codecs-C00kjHgh.mjs +282 -0
- package/dist/codecs-C00kjHgh.mjs.map +1 -0
- package/dist/codecs-CO_VNEYU-CwAnKzRs.d.mts +102 -0
- package/dist/codecs-CO_VNEYU-CwAnKzRs.d.mts.map +1 -0
- package/dist/codecs-DM61agRr.d.mts +21 -0
- package/dist/codecs-DM61agRr.d.mts.map +1 -0
- package/dist/contract-contributions-B9njRJbt-ClEtrK2L.mjs +14 -0
- package/dist/contract-contributions-B9njRJbt-ClEtrK2L.mjs.map +1 -0
- package/dist/contract-free-BvCdx_Ee.mjs +71 -0
- package/dist/contract-free-BvCdx_Ee.mjs.map +1 -0
- package/dist/contract-free-Cw9Mjcro.d.mts +22 -0
- package/dist/contract-free-Cw9Mjcro.d.mts.map +1 -0
- package/dist/control-C9zxRXNN.mjs +74 -0
- package/dist/control-C9zxRXNN.mjs.map +1 -0
- package/dist/control-DHkZbo58.d.mts +25 -0
- package/dist/control-DHkZbo58.d.mts.map +1 -0
- package/dist/control-Ez_PtlFI.d.mts +121 -0
- package/dist/control-Ez_PtlFI.d.mts.map +1 -0
- package/dist/control-WTY7Jpxk.mjs +577 -0
- package/dist/control-WTY7Jpxk.mjs.map +1 -0
- package/dist/control-_4epnrIW.d.mts +27 -0
- package/dist/control-_4epnrIW.d.mts.map +1 -0
- package/dist/control-tables-CHw2F-rg.d.mts +9 -0
- package/dist/control-tables-CHw2F-rg.d.mts.map +1 -0
- package/dist/control-tables-CcQ77JE7-CxTQYoQJ.mjs +9 -0
- package/dist/control-tables-CcQ77JE7-CxTQYoQJ.mjs.map +1 -0
- package/dist/data-type-entries-B0AoBozh-f9AEUIUQ.mjs +42 -0
- package/dist/data-type-entries-B0AoBozh-f9AEUIUQ.mjs.map +1 -0
- package/dist/data-types-BpihGKoK-BMW-m4EN.d.mts +52 -0
- package/dist/data-types-BpihGKoK-BMW-m4EN.d.mts.map +1 -0
- package/dist/data-types-Dv9gwVRV-BZPzCWZk.mjs +181 -0
- package/dist/data-types-Dv9gwVRV-BZPzCWZk.mjs.map +1 -0
- package/dist/data-types-SXrh0Lou.d.mts +8 -0
- package/dist/data-types-SXrh0Lou.d.mts.map +1 -0
- package/dist/ddl-CT6DPEqg.d.mts +1 -0
- package/dist/ddl-DDmMHyA_-Bb8sXoS0.mjs +12 -0
- package/dist/ddl-DDmMHyA_-Bb8sXoS0.mjs.map +1 -0
- package/dist/default-normalizer-BBhGpw7r.d.mts +27 -0
- package/dist/default-normalizer-BBhGpw7r.d.mts.map +1 -0
- package/dist/default-normalizer-BDUgHXUn-Xk7HQJuI.mjs +90 -0
- package/dist/default-normalizer-BDUgHXUn-Xk7HQJuI.mjs.map +1 -0
- package/dist/descriptor-meta-BurjcSiU-Cbk2L1jf.mjs +82 -0
- package/dist/descriptor-meta-BurjcSiU-Cbk2L1jf.mjs.map +1 -0
- package/dist/descriptor-meta-runtime-Bk_00UrX-BLN4Ahpj.mjs +17 -0
- package/dist/descriptor-meta-runtime-Bk_00UrX-BLN4Ahpj.mjs.map +1 -0
- package/dist/driver.d.mts +3 -0
- package/dist/driver.mjs +2 -0
- package/dist/driver__control.d.mts +2 -0
- package/dist/driver__control.mjs +2 -0
- package/dist/driver__runtime.d.mts +2 -0
- package/dist/driver__runtime.mjs +325 -0
- package/dist/driver__runtime.mjs.map +1 -0
- package/dist/errors-BYhjQT7y.d.mts +10 -0
- package/dist/errors-BYhjQT7y.d.mts.map +1 -0
- package/dist/errors-rvH_F2Yj-BQrO_--u.mjs +20 -0
- package/dist/errors-rvH_F2Yj-BQrO_--u.mjs.map +1 -0
- package/dist/marker-lock-CmGvN4hw-Com29AtQ.mjs +51 -0
- package/dist/marker-lock-CmGvN4hw-Com29AtQ.mjs.map +1 -0
- package/dist/marker-lock-su6IxinO.d.mts +18 -0
- package/dist/marker-lock-su6IxinO.d.mts.map +1 -0
- package/dist/marker-read-aEaHihYj-Cyg16yn1.mjs +78 -0
- package/dist/marker-read-aEaHihYj-Cyg16yn1.mjs.map +1 -0
- package/dist/migration-DmlblTTw.d.mts +284 -0
- package/dist/migration-DmlblTTw.d.mts.map +1 -0
- package/dist/migration-tFuoN9GB.mjs +5 -0
- package/dist/mysql-contract-serializer-DLv0uW_f-Cg4A43Ry.mjs +160 -0
- package/dist/mysql-contract-serializer-DLv0uW_f-Cg4A43Ry.mjs.map +1 -0
- package/dist/nodes-CvcX47ot-B-ZaUYRj.mjs +25 -0
- package/dist/nodes-CvcX47ot-B-ZaUYRj.mjs.map +1 -0
- package/dist/nodes-xc0cR0_c-2YbhgEjb.d.mts +27 -0
- package/dist/nodes-xc0cR0_c-2YbhgEjb.d.mts.map +1 -0
- package/dist/pack-YVG-iBMQ.d.mts +1073 -0
- package/dist/pack-YVG-iBMQ.d.mts.map +1 -0
- package/dist/planner-target-details-D6g2uSp--C5NKHmCc.d.mts +12 -0
- package/dist/planner-target-details-D6g2uSp--C5NKHmCc.d.mts.map +1 -0
- package/dist/runner-C4r6yEd1-BWQrxW9q.mjs +1644 -0
- package/dist/runner-C4r6yEd1-BWQrxW9q.mjs.map +1 -0
- package/dist/runtime-BGyTXcQH.d.mts +36 -0
- package/dist/runtime-BGyTXcQH.d.mts.map +1 -0
- package/dist/runtime-CeuRr9nE.d.mts +29 -0
- package/dist/runtime-CeuRr9nE.d.mts.map +1 -0
- package/dist/runtime-Cl0BbTZq.d.mts +22 -0
- package/dist/runtime-Cl0BbTZq.d.mts.map +1 -0
- package/dist/sql-utils-BOS1c2QT.d.mts +30 -0
- package/dist/sql-utils-BOS1c2QT.d.mts.map +1 -0
- package/dist/sql-utils-Db0IQO_B-PaULnfrE.mjs +30 -0
- package/dist/sql-utils-Db0IQO_B-PaULnfrE.mjs.map +1 -0
- package/dist/sql-utils-RW0vJvDl.mjs +94 -0
- package/dist/sql-utils-RW0vJvDl.mjs.map +1 -0
- package/dist/statement-A6bbPBf1-q61iHQLb.mjs +483 -0
- package/dist/statement-A6bbPBf1-q61iHQLb.mjs.map +1 -0
- package/dist/target.d.mts +24 -0
- package/dist/target.mjs +19 -0
- package/dist/target__codec-descriptor.d.mts +3 -0
- package/dist/target__codec-descriptor.mjs +2 -0
- package/dist/target__codec-ids.d.mts +3 -0
- package/dist/target__codec-ids.mjs +3 -0
- package/dist/target__codec-types.d.mts +3 -0
- package/dist/target__codec-types.mjs +1 -0
- package/dist/target__codecs.d.mts +3 -0
- package/dist/target__codecs.mjs +2 -0
- package/dist/target__contract-free.d.mts +2 -0
- package/dist/target__contract-free.mjs +3 -0
- package/dist/target__control-tables.d.mts +2 -0
- package/dist/target__control-tables.mjs +2 -0
- package/dist/target__control.d.mts +3 -0
- package/dist/target__control.mjs +58 -0
- package/dist/target__control.mjs.map +1 -0
- package/dist/target__data-types.d.mts +3 -0
- package/dist/target__data-types.mjs +3 -0
- package/dist/target__ddl.d.mts +3 -0
- package/dist/target__ddl.mjs +2 -0
- package/dist/target__default-normalizer.d.mts +2 -0
- package/dist/target__default-normalizer.mjs +2 -0
- package/dist/target__errors.d.mts +2 -0
- package/dist/target__errors.mjs +2 -0
- package/dist/target__marker-lock.d.mts +2 -0
- package/dist/target__marker-lock.mjs +2 -0
- package/dist/target__migration.d.mts +2 -0
- package/dist/target__migration.mjs +3 -0
- package/dist/target__pack.d.mts +2 -0
- package/dist/target__pack.mjs +2 -0
- package/dist/target__runtime.d.mts +2 -0
- package/dist/target__runtime.mjs +17 -0
- package/dist/target__runtime.mjs.map +1 -0
- package/dist/target__sql-utils.d.mts +2 -0
- package/dist/target__sql-utils.mjs +3 -0
- package/package.json +71 -3
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
import { t as mysqlError } from "./errors-rvH_F2Yj-BQrO_--u.mjs";
|
|
2
|
+
import { n as quoteIdentifier } from "./sql-utils-Db0IQO_B-PaULnfrE.mjs";
|
|
3
|
+
import { t as tokenizeMysqlSql } from "./sql-utils-RW0vJvDl.mjs";
|
|
4
|
+
import { structuredError } from "@prisma/orm-framework/utils/structured-error";
|
|
5
|
+
import { type } from "arktype";
|
|
6
|
+
import { ifDefined } from "@prisma/orm-framework/utils/defined";
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
8
|
+
import { SqlConnectionError, SqlQueryError } from "@prisma/orm-family-sql/errors";
|
|
9
|
+
import { assertDefined } from "@prisma/orm-framework/utils/assertions";
|
|
10
|
+
//#region ../../../3-targets/mysql/3-driver/dist/statement-A6bbPBf1.mjs
|
|
11
|
+
var AsyncMutex = class {
|
|
12
|
+
#queue = Promise.resolve();
|
|
13
|
+
async lock() {
|
|
14
|
+
const previous = this.#queue;
|
|
15
|
+
let releaseLock;
|
|
16
|
+
this.#queue = new Promise((resolve) => {
|
|
17
|
+
releaseLock = resolve;
|
|
18
|
+
});
|
|
19
|
+
await previous;
|
|
20
|
+
return () => {
|
|
21
|
+
releaseLock?.();
|
|
22
|
+
releaseLock = void 0;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* One statement at a time on each client, in the order sent, as the Postgres driver's per-client lock runs them, on the runtime and the control driver alike. The lock is held until the statement settles, or for a stream's whole life, so a statement sent while a stream is open waits for it.
|
|
28
|
+
*/
|
|
29
|
+
const clientQueryLocks = /* @__PURE__ */ new WeakMap();
|
|
30
|
+
function acquireClientQueryLock(client) {
|
|
31
|
+
let mutex = clientQueryLocks.get(client);
|
|
32
|
+
if (mutex === void 0) {
|
|
33
|
+
mutex = new AsyncMutex();
|
|
34
|
+
clientQueryLocks.set(client, mutex);
|
|
35
|
+
}
|
|
36
|
+
return mutex.lock();
|
|
37
|
+
}
|
|
38
|
+
/** Removes the `sql_mode` entries the MySQL target does not support, `NO_BACKSLASH_ESCAPES` and `ANSI_QUOTES`, leaving no empty entry between two commas. */
|
|
39
|
+
const CLEAR_UNSUPPORTED_SQL_MODES = "SET SESSION sql_mode = TRIM(BOTH ',' FROM REPLACE(REPLACE(CONCAT(',', @@SESSION.sql_mode, ','), ',NO_BACKSLASH_ESCAPES,', ','), ',ANSI_QUOTES,', ','))";
|
|
40
|
+
/** Makes MySQL read each statement, and the package write it, as utf8mb4. */
|
|
41
|
+
const SET_UTF8MB4 = "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci";
|
|
42
|
+
/**
|
|
43
|
+
* The statements every new connection runs once, before any other. The lexer that finds placeholders reads a backslash as an escape and `"…"` as a string, so the session clears NO_BACKSLASH_ESCAPES and ANSI_QUOTES and MySQL reads quoted text the same way; and it reads each statement as utf8mb4. These hold no value, so they run through the package's `initSql`; the target's session settings, which do, are set afterwards.
|
|
44
|
+
*/
|
|
45
|
+
const SESSION_SETUP = [CLEAR_UNSUPPORTED_SQL_MODES, SET_UTF8MB4];
|
|
46
|
+
/** MySQL's `binary` collation, which marks a string or blob column that holds bytes. */
|
|
47
|
+
const BINARY_COLLATION = 63;
|
|
48
|
+
/** The column types whose value is text, or bytes when the column's collation is binary. */
|
|
49
|
+
const CHARACTER_OR_BLOB_TYPES = /* @__PURE__ */ new Set([
|
|
50
|
+
"VARCHAR",
|
|
51
|
+
"VAR_STRING",
|
|
52
|
+
"STRING",
|
|
53
|
+
"TINY_BLOB",
|
|
54
|
+
"MEDIUM_BLOB",
|
|
55
|
+
"LONG_BLOB",
|
|
56
|
+
"BLOB"
|
|
57
|
+
]);
|
|
58
|
+
/** The column types whose value MySQL sends as text. A type outside this list, such as BIT, GEOMETRY or one the package has no name for, is read as bytes. */
|
|
59
|
+
const TEXT_TYPES = /* @__PURE__ */ new Set([
|
|
60
|
+
...CHARACTER_OR_BLOB_TYPES,
|
|
61
|
+
"DECIMAL",
|
|
62
|
+
"NEWDECIMAL",
|
|
63
|
+
"FLOAT",
|
|
64
|
+
"DOUBLE",
|
|
65
|
+
"TINY",
|
|
66
|
+
"SHORT",
|
|
67
|
+
"INT",
|
|
68
|
+
"INT24",
|
|
69
|
+
"BIGINT",
|
|
70
|
+
"YEAR",
|
|
71
|
+
"DATE",
|
|
72
|
+
"NEWDATE",
|
|
73
|
+
"TIME",
|
|
74
|
+
"TIME2",
|
|
75
|
+
"DATETIME",
|
|
76
|
+
"DATETIME2",
|
|
77
|
+
"TIMESTAMP",
|
|
78
|
+
"TIMESTAMP2",
|
|
79
|
+
"JSON",
|
|
80
|
+
"ENUM",
|
|
81
|
+
"SET",
|
|
82
|
+
"NULL"
|
|
83
|
+
]);
|
|
84
|
+
/**
|
|
85
|
+
* Reads each column as the row value ADR 155 sets at the driver boundary: a binary string or blob, BIT, GEOMETRY and a column of a type the package does not know as its bytes, every other column as text, and NULL as `null`. Bytes are a plain `Uint8Array`, not the package's `Buffer`.
|
|
86
|
+
*/
|
|
87
|
+
const readTextOrBytes = (field) => {
|
|
88
|
+
if (!TEXT_TYPES.has(field.type) || CHARACTER_OR_BLOB_TYPES.has(field.type) && field.collation.index === BINARY_COLLATION) {
|
|
89
|
+
const bytes = field.buffer();
|
|
90
|
+
return bytes === null ? null : new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
91
|
+
}
|
|
92
|
+
return field.string();
|
|
93
|
+
};
|
|
94
|
+
const DEFAULT_CONNECT_TIMEOUT_MILLIS = 2e4;
|
|
95
|
+
const DEFAULT_IDLE_TIMEOUT_MILLIS = 3e4;
|
|
96
|
+
const urlParameters = type({
|
|
97
|
+
"ssl?": type("'true' | '1' | 'false' | '0'").pipe((text) => text === "true" || text === "1"),
|
|
98
|
+
"sslmode?": "'disable' | 'prefer' | 'require' | 'verify-ca' | 'verify-full' | 'no-verify'",
|
|
99
|
+
"sslcert?": "string > 0",
|
|
100
|
+
"sslkey?": "string > 0",
|
|
101
|
+
"sslrootcert?": "string > 0",
|
|
102
|
+
"allowPublicKeyRetrieval?": type("'true' | 'false'").pipe((text) => text === "true")
|
|
103
|
+
});
|
|
104
|
+
/** The form each URL parameter's value must take, for the refusal of a value. */
|
|
105
|
+
const PARAMETER_FORMS = {
|
|
106
|
+
ssl: "true, 1, false or 0",
|
|
107
|
+
sslmode: "disable, prefer, require, verify-ca, verify-full or no-verify",
|
|
108
|
+
sslcert: "the path of a PEM file",
|
|
109
|
+
sslkey: "the path of a PEM file",
|
|
110
|
+
sslrootcert: "the path of a PEM file",
|
|
111
|
+
allowPublicKeyRetrieval: "true or false"
|
|
112
|
+
};
|
|
113
|
+
function isParameterName(name) {
|
|
114
|
+
return Object.hasOwn(PARAMETER_FORMS, name);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Options the URL cannot change. The package writes each value into its statement at a bare `?`; every option that would change where or how it writes one (named placeholders, an object written as `SET` entries, several statements in one) stays off, and `logParam` keeps values out of error messages. `permitRedirect` stays off, so a server cannot send the client, with its credentials, to another host, which `pg` never does. `typeCast` reads every column as text or bytes, so no column reaches a codec as a value the package parsed. `foundRows` makes an UPDATE count the rows it matched, as Postgres's row count does. The connection is utf8mb4: the driver reads each statement as utf8mb4 to find its placeholders, and MySQL must read it the same way.
|
|
118
|
+
*/
|
|
119
|
+
const FIXED_OPTIONS = {
|
|
120
|
+
collation: "UTF8MB4_UNICODE_CI",
|
|
121
|
+
multipleStatements: false,
|
|
122
|
+
namedPlaceholders: false,
|
|
123
|
+
permitSetMultiParamEntries: false,
|
|
124
|
+
permitLocalInfile: false,
|
|
125
|
+
logParam: false,
|
|
126
|
+
permitRedirect: false,
|
|
127
|
+
foundRows: true,
|
|
128
|
+
typeCast: readTextOrBytes
|
|
129
|
+
};
|
|
130
|
+
/** Refuses the URL. `parameters` names the parameters at fault; no value from the URL goes into the error, because a URL carries the password. */
|
|
131
|
+
function invalidBinding(reason, parameters) {
|
|
132
|
+
return structuredError("RUNTIME.BINDING_INVALID", `MySQL connection URL: ${reason}`, { meta: {
|
|
133
|
+
received: parameters.join(", "),
|
|
134
|
+
reason
|
|
135
|
+
} });
|
|
136
|
+
}
|
|
137
|
+
/** Parses `url` as the Postgres facade does, refusing it without the parser's error, which carries the whole URL. */
|
|
138
|
+
function parseUrl(url) {
|
|
139
|
+
try {
|
|
140
|
+
return new URL(url);
|
|
141
|
+
} catch {
|
|
142
|
+
throw invalidBinding("the URL cannot be parsed", []);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function readUrl(url) {
|
|
146
|
+
const parsed = parseUrl(url);
|
|
147
|
+
if (parsed.searchParams.has("charset")) throw invalidBinding("the driver always uses utf8mb4, because it reads each statement as utf8mb4 to find its placeholders; remove the charset parameter", ["charset"]);
|
|
148
|
+
const names = [...new Set(parsed.searchParams.keys())].filter(isParameterName);
|
|
149
|
+
const parameters = urlParameters(Object.fromEntries([...parsed.searchParams].filter(([name]) => isParameterName(name))));
|
|
150
|
+
if (parameters instanceof type.errors) {
|
|
151
|
+
const invalid = names.filter((name) => parameters.some((error) => error.path[0] === name));
|
|
152
|
+
throw invalidBinding(invalid.map((name) => `${name} must be ${PARAMETER_FORMS[name]}`).join("; "), invalid);
|
|
153
|
+
}
|
|
154
|
+
if (parameters.sslcert !== void 0 && parameters.sslkey === void 0) throw invalidBinding("sslcert names the client's certificate and needs sslkey; to check the server's certificate against a CA file, as sslcert did in Prisma 7, use sslrootcert", ["sslcert"]);
|
|
155
|
+
return {
|
|
156
|
+
parsed,
|
|
157
|
+
parameters
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function readPem(parameter, path) {
|
|
161
|
+
try {
|
|
162
|
+
return readFileSync(path, "utf8");
|
|
163
|
+
} catch {
|
|
164
|
+
throw invalidBinding(`the file ${parameter} names cannot be read`, [parameter]);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* The TLS settings the URL gives, read as `pg-connection-string` reads them for the Postgres driver: `ssl=true` turns TLS on and `ssl=false` off; `sslcert`, `sslkey`, `sslrootcert` or `sslmode` turn it on, with the certificate, key and CA read from the files they name. `sslmode=disable` turns it off; `no-verify` accepts any server certificate; every other mode verifies the certificate and the host name, as `verify-full` does.
|
|
169
|
+
*/
|
|
170
|
+
function tlsOptions(parameters) {
|
|
171
|
+
const { sslcert, sslkey, sslrootcert, sslmode } = parameters;
|
|
172
|
+
if ([
|
|
173
|
+
sslcert,
|
|
174
|
+
sslkey,
|
|
175
|
+
sslrootcert,
|
|
176
|
+
sslmode
|
|
177
|
+
].every((value) => value === void 0)) return parameters.ssl;
|
|
178
|
+
if (sslmode === "disable") return false;
|
|
179
|
+
return {
|
|
180
|
+
...ifDefined("cert", sslcert === void 0 ? void 0 : readPem("sslcert", sslcert)),
|
|
181
|
+
...ifDefined("key", sslkey === void 0 ? void 0 : readPem("sslkey", sslkey)),
|
|
182
|
+
...ifDefined("ca", sslrootcert === void 0 ? void 0 : readPem("sslrootcert", sslrootcert)),
|
|
183
|
+
...sslmode === "no-verify" ? { rejectUnauthorized: false } : {}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function connectionOptions(parsed, parameters, connectTimeoutMs) {
|
|
187
|
+
return {
|
|
188
|
+
host: decodeURIComponent(parsed.hostname).replace(/^\[(.*)\]$/, "$1"),
|
|
189
|
+
...ifDefined("port", parsed.port === "" ? void 0 : Number(parsed.port)),
|
|
190
|
+
user: decodeURIComponent(parsed.username),
|
|
191
|
+
password: decodeURIComponent(parsed.password),
|
|
192
|
+
database: decodeURIComponent(parsed.pathname.slice(1)),
|
|
193
|
+
...ifDefined("ssl", tlsOptions(parameters)),
|
|
194
|
+
allowPublicKeyRetrieval: parameters.allowPublicKeyRetrieval ?? false,
|
|
195
|
+
connectTimeout: connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MILLIS,
|
|
196
|
+
initSql: [...SESSION_SETUP],
|
|
197
|
+
...FIXED_OPTIONS
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/** The `mariadb` options for one connection to the server a `mysql://` URL names. Ignores a URL parameter the driver does not read, as `pg` does, and refuses a charset. */
|
|
201
|
+
function mysqlConnectionOptions(url, settings) {
|
|
202
|
+
const { parsed, parameters } = readUrl(url);
|
|
203
|
+
return connectionOptions(parsed, parameters, settings?.connectTimeoutMs);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* The `mariadb` pool options for a `mysql://` URL, sized and timed as the Postgres driver's `pg.Pool`: it opens a connection only when one is needed (`minimumIdle: 0`), closes one idle for `idleTimeoutMillis`, and waits `connectionTimeoutMillis` both to open a connection and for a pooled one to come free.
|
|
207
|
+
*/
|
|
208
|
+
function mysqlPoolOptions(url, poolOptions) {
|
|
209
|
+
const { parsed, parameters } = readUrl(url);
|
|
210
|
+
const timeoutMs = poolOptions?.connectionTimeoutMillis ?? DEFAULT_CONNECT_TIMEOUT_MILLIS;
|
|
211
|
+
return {
|
|
212
|
+
...connectionOptions(parsed, parameters, timeoutMs),
|
|
213
|
+
acquireTimeout: timeoutMs,
|
|
214
|
+
minimumIdle: 0,
|
|
215
|
+
idleTimeout: Math.ceil((poolOptions?.idleTimeoutMillis ?? DEFAULT_IDLE_TIMEOUT_MILLIS) / 1e3),
|
|
216
|
+
...ifDefined("connectionLimit", poolOptions?.max)
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
const mysqlDriverDescriptorMeta = {
|
|
220
|
+
kind: "driver",
|
|
221
|
+
familyId: "sql",
|
|
222
|
+
targetId: "mysql",
|
|
223
|
+
id: "mysql",
|
|
224
|
+
version: "0.0.1",
|
|
225
|
+
capabilities: {}
|
|
226
|
+
};
|
|
227
|
+
function isMariadbError(error) {
|
|
228
|
+
return error instanceof Error && "errno" in error && typeof error.errno === "number";
|
|
229
|
+
}
|
|
230
|
+
/** Whether `error` left its connection unusable: the package marks a lost socket, and a server error of SQLSTATE class 08, as fatal. */
|
|
231
|
+
function isFatal(error) {
|
|
232
|
+
return error instanceof Error && "fatal" in error && error.fatal === true;
|
|
233
|
+
}
|
|
234
|
+
function serverMessage(error) {
|
|
235
|
+
return isMariadbError(error) ? error.sqlMessage ?? error.message : error.message;
|
|
236
|
+
}
|
|
237
|
+
/** The error a statement ends with when its connection is lost or closed under it: a `SqlConnectionError` a retry on a new connection can get past, as on Postgres. */
|
|
238
|
+
function connectionLost(cause) {
|
|
239
|
+
return new SqlConnectionError(serverMessage(cause), {
|
|
240
|
+
cause,
|
|
241
|
+
transient: true,
|
|
242
|
+
...ifDefined("sqlState", isMariadbError(cause) ? cause.sqlState ?? void 0 : void 0)
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/** Node's socket and DNS error codes, and whether a retry can succeed after each, as the Postgres driver classifies them. */
|
|
246
|
+
const NODE_CONNECTION_CODES = /* @__PURE__ */ new Map([
|
|
247
|
+
["ECONNRESET", true],
|
|
248
|
+
["ETIMEDOUT", true],
|
|
249
|
+
["EPIPE", true],
|
|
250
|
+
["EAI_AGAIN", true],
|
|
251
|
+
["ECONNREFUSED", false],
|
|
252
|
+
["ENOTFOUND", false],
|
|
253
|
+
["EHOSTUNREACH", false]
|
|
254
|
+
]);
|
|
255
|
+
/** Whether a retry can succeed after `error`, for a Node socket or DNS error; undefined for any other. */
|
|
256
|
+
function nodeConnectionTransience(error) {
|
|
257
|
+
return error instanceof Error && "code" in error && typeof error.code === "string" ? NODE_CONNECTION_CODES.get(error.code) : void 0;
|
|
258
|
+
}
|
|
259
|
+
const ER_GET_CONNECTION_TIMEOUT = 45028;
|
|
260
|
+
const ER_INITIAL_SQL_ERROR = 45030;
|
|
261
|
+
const ER_CANNOT_RETRIEVE_RSA_KEY = 45044;
|
|
262
|
+
/** The errors MySQL refuses a sign-in with: access denied, access denied for a socket-authenticated account, and an authentication plugin the server has not loaded. Another attempt with the same URL fails the same way. */
|
|
263
|
+
const SIGN_IN_REFUSED = /* @__PURE__ */ new Set([
|
|
264
|
+
1045,
|
|
265
|
+
1698,
|
|
266
|
+
1524
|
|
267
|
+
]);
|
|
268
|
+
/** Whether `error` is one another attempt to connect with the same settings cannot get past: a refused connection, an unknown or unreachable host, a refused sign-in, a sign-in that needs the server's public key, or session setup MySQL refuses. */
|
|
269
|
+
function connectingCannotSucceed(error) {
|
|
270
|
+
if (nodeConnectionTransience(error) === false) return true;
|
|
271
|
+
return isMariadbError(error) && (SIGN_IN_REFUSED.has(error.errno) || error.errno === ER_CANNOT_RETRIEVE_RSA_KEY || error.errno === ER_INITIAL_SQL_ERROR);
|
|
272
|
+
}
|
|
273
|
+
const UNIQUE_VIOLATION = "23505";
|
|
274
|
+
const FOREIGN_KEY_VIOLATION = "23503";
|
|
275
|
+
/** The SQLSTATE Postgres sends for each constraint MySQL reports under a shared SQLSTATE, as the SQLite driver maps its own codes, so a consumer such as `isUniqueConstraintViolation` reads them alike. */
|
|
276
|
+
const CONSTRAINT_SQLSTATES = /* @__PURE__ */ new Map([
|
|
277
|
+
[1062, UNIQUE_VIOLATION],
|
|
278
|
+
[1586, UNIQUE_VIOLATION],
|
|
279
|
+
[1216, FOREIGN_KEY_VIOLATION],
|
|
280
|
+
[1217, FOREIGN_KEY_VIOLATION],
|
|
281
|
+
[1451, FOREIGN_KEY_VIOLATION],
|
|
282
|
+
[1452, FOREIGN_KEY_VIOLATION],
|
|
283
|
+
[1048, "23502"],
|
|
284
|
+
[3819, "23514"]
|
|
285
|
+
]);
|
|
286
|
+
const PUBLIC_KEY_FIX = "Add allowPublicKeyRetrieval=true to the URL, or connect over TLS with sslmode or ssl=true in the URL. Fetching the key over plain TCP lets a machine between the client and the server pose as the server and read the password; TLS does not.";
|
|
287
|
+
/** The fix for a failed connection when the package's error names its cause, such as a sign-in that needs the server's public key. */
|
|
288
|
+
function connectionFix(error) {
|
|
289
|
+
return isMariadbError(error) && error.errno === ER_CANNOT_RETRIEVE_RSA_KEY ? PUBLIC_KEY_FIX : void 0;
|
|
290
|
+
}
|
|
291
|
+
function publicKeyNeeded(error) {
|
|
292
|
+
return new SqlConnectionError(`MySQL sign-in needs the server's public key: the account signs in with caching_sha2_password or sha256_password over a connection without TLS. ${PUBLIC_KEY_FIX}`, {
|
|
293
|
+
cause: error,
|
|
294
|
+
transient: false
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
function poolTimedOut(error) {
|
|
298
|
+
const cause = error.cause;
|
|
299
|
+
if (connectingCannotSucceed(cause)) return normalizeMysqlError(cause);
|
|
300
|
+
return new SqlConnectionError(cause instanceof Error ? `Timed out waiting for a pooled MySQL connection; the pool could not open one: ${serverMessage(cause)}` : "Timed out waiting for a pooled MySQL connection; every connection in the pool was in use.", {
|
|
301
|
+
cause: error,
|
|
302
|
+
transient: true
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* An error from the `mariadb` package as the driver reports it, in the family's types as the Postgres driver reports its own: a Node socket or DNS error as a `SqlConnectionError`, transient as the Postgres driver's table says; a lost connection and a pool that gave no connection in time as a transient `SqlConnectionError`; a sign-in that needs the server's public key, and session setup that fails, as a `SqlConnectionError` that is not transient; a sign-in MySQL refuses, as Postgres's 28P01, and an error MySQL reported about a statement as `SqlQueryError` with its SQLSTATE, a constraint violation with the SQLSTATE Postgres sends; and any other error unchanged. A pool that timed out because it could not connect in a way no retry can get past reports that error.
|
|
307
|
+
*/
|
|
308
|
+
function normalizeMysqlError(error) {
|
|
309
|
+
const transient = nodeConnectionTransience(error);
|
|
310
|
+
if (transient !== void 0 && error instanceof Error) return new SqlConnectionError(error.message, {
|
|
311
|
+
cause: error,
|
|
312
|
+
transient
|
|
313
|
+
});
|
|
314
|
+
if (!isMariadbError(error)) return error;
|
|
315
|
+
if (error.errno === ER_CANNOT_RETRIEVE_RSA_KEY) return publicKeyNeeded(error);
|
|
316
|
+
if (error.errno === ER_INITIAL_SQL_ERROR) return new SqlConnectionError(serverMessage(error), {
|
|
317
|
+
cause: error,
|
|
318
|
+
transient: false
|
|
319
|
+
});
|
|
320
|
+
if (isFatal(error) && !SIGN_IN_REFUSED.has(error.errno)) return connectionLost(error);
|
|
321
|
+
if (error.errno === ER_GET_CONNECTION_TIMEOUT) return poolTimedOut(error);
|
|
322
|
+
if (typeof error.sqlState !== "string") return error;
|
|
323
|
+
return new SqlQueryError(error.sqlMessage ?? error.message, {
|
|
324
|
+
cause: error,
|
|
325
|
+
sqlState: CONSTRAINT_SQLSTATES.get(error.errno) ?? error.sqlState
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
const DECIMAL_INTEGER = /^-?\d+$/;
|
|
329
|
+
/** A setting's value as MySQL takes it: decimal integer text as a whole number, because MySQL refuses text for an integer variable, and any other text as it is. */
|
|
330
|
+
function settingValue(value) {
|
|
331
|
+
return DECIMAL_INTEGER.test(value) ? BigInt(value) : value;
|
|
332
|
+
}
|
|
333
|
+
/** The one statement that sets `sessionSettings`: each name a quoted identifier, each value a parameter. Undefined when there is nothing to set. */
|
|
334
|
+
function sessionSettingsStatement(sessionSettings) {
|
|
335
|
+
const entries = Object.entries(sessionSettings);
|
|
336
|
+
if (entries.length === 0) return void 0;
|
|
337
|
+
return {
|
|
338
|
+
sql: `SET SESSION ${entries.map(([name]) => `${quoteIdentifier(name)} = ?`).join(", ")}`,
|
|
339
|
+
values: entries.map(([, value]) => settingValue(value))
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
/** Sets the session settings on `connection`, the package writing each value into the statement. Throws the package's error as it is. */
|
|
343
|
+
async function applySessionSettings(connection, statement) {
|
|
344
|
+
await connection.query(statement.sql, [...statement.values]);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Ensures the session settings a target declares on each physical connection the runtime driver gets from its pool, once, as the Postgres driver's `SessionSettingsGuard` does for a pool it did not start the sessions of. The package hands out a new wrapper for each `getConnection`, so a connection is known by its `info`, which belongs to the physical connection.
|
|
348
|
+
*/
|
|
349
|
+
var SessionSettingsGuard = class {
|
|
350
|
+
#statement;
|
|
351
|
+
#ensured = /* @__PURE__ */ new WeakSet();
|
|
352
|
+
constructor(sessionSettings) {
|
|
353
|
+
this.#statement = sessionSettingsStatement(sessionSettings);
|
|
354
|
+
}
|
|
355
|
+
async ensure(connection) {
|
|
356
|
+
const key = connection.info;
|
|
357
|
+
assertDefined(key, "the package gives every connection its info when it creates it");
|
|
358
|
+
if (this.#statement === void 0 || this.#ensured.has(key)) return;
|
|
359
|
+
await applySessionSettings(connection, this.#statement);
|
|
360
|
+
this.#ensured.add(key);
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
function unsendable(message, paramIndex, received) {
|
|
364
|
+
return mysqlError("RUNTIME.ENCODE_FAILED", message, { meta: {
|
|
365
|
+
target: "mysql",
|
|
366
|
+
paramIndex,
|
|
367
|
+
received
|
|
368
|
+
} });
|
|
369
|
+
}
|
|
370
|
+
const BIGINT_MIN = -(2n ** 63n);
|
|
371
|
+
const BIGINT_MAX = 2n ** 63n - 1n;
|
|
372
|
+
const LONE_SURROGATE = /\p{Surrogate}/u;
|
|
373
|
+
function withinBigint(value) {
|
|
374
|
+
return value >= BIGINT_MIN && value <= BIGINT_MAX;
|
|
375
|
+
}
|
|
376
|
+
function receivedKind(value) {
|
|
377
|
+
if (value instanceof Date) return "Date";
|
|
378
|
+
if (Array.isArray(value)) return "array";
|
|
379
|
+
return typeof value;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* The value the `mariadb` package writes into the statement for a parameter. A finite number or a bigint goes as it is, and the package writes its digits. A non-finite number is refused, because the package would write `NaN` or `Infinity` into the SQL. A bigint must fit a signed BIGINT, so a parameter's type never depends on its value. A `Uint8Array` goes as a Buffer over the same bytes, because the package writes any other `Uint8Array` as JSON text. A `Date` is refused: the package writes it in the process's local time zone, and the MySQL codecs send dates as text. So is text with a lone UTF-16 surrogate, which the package writes as `?` or U+FFFD depending on the text's length.
|
|
383
|
+
*/
|
|
384
|
+
function bindValue(value, index) {
|
|
385
|
+
if (value === null || value === void 0) return null;
|
|
386
|
+
if (typeof value === "number") {
|
|
387
|
+
if (!Number.isFinite(value)) throw unsendable(`Parameter ${index + 1} is ${value}, which MySQL cannot store`, index, String(value));
|
|
388
|
+
return value;
|
|
389
|
+
}
|
|
390
|
+
if (typeof value === "bigint") {
|
|
391
|
+
if (withinBigint(value)) return value;
|
|
392
|
+
throw unsendable(`Parameter ${index + 1} is an integer outside MySQL's signed 64-bit BIGINT`, index, "bigint");
|
|
393
|
+
}
|
|
394
|
+
if (Buffer.isBuffer(value)) return value;
|
|
395
|
+
if (value instanceof Uint8Array) return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
396
|
+
if (typeof value === "string") {
|
|
397
|
+
if (!LONE_SURROGATE.test(value)) return value;
|
|
398
|
+
throw unsendable(`Parameter ${index + 1} is text with a lone UTF-16 surrogate, which is not a character and has no utf8mb4 form; the mariadb package would store it as ? or as U+FFFD, depending on the length of the text`, index, "string");
|
|
399
|
+
}
|
|
400
|
+
if (typeof value === "boolean") return value;
|
|
401
|
+
const received = receivedKind(value);
|
|
402
|
+
throw unsendable(`Parameter ${index + 1} is of type ${received}; a MySQL parameter must be text, a number, a bigint, a boolean, bytes or null, and a Date is sent as text by its codec`, index, received);
|
|
403
|
+
}
|
|
404
|
+
function placeholderMismatch(placeholders, values) {
|
|
405
|
+
return structuredError("RUNTIME.PARAM_PLACEHOLDER_MISMATCH", `The MySQL statement writes placeholders ${JSON.stringify(placeholders)} for ${values} parameter value(s); write each value as a numbered ?N, or every value as a bare ? in order, and no other placeholder.`, {
|
|
406
|
+
why: "A placeholder that does not match a value binds a value to the wrong place in the statement, or leaves a value unbound.",
|
|
407
|
+
fix: "Pass values into raw SQL through interpolation rather than writing a `?` in the SQL text.",
|
|
408
|
+
meta: {
|
|
409
|
+
placeholders,
|
|
410
|
+
params: values
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
/** The index into `values` each placeholder takes: `?N` takes value N, and bare `?`s take the values in order. */
|
|
415
|
+
function valueIndexes(placeholders, values) {
|
|
416
|
+
const texts = placeholders.map((placeholder) => placeholder.text);
|
|
417
|
+
if (texts.every((text) => text === "?")) {
|
|
418
|
+
if (placeholders.length !== values) throw placeholderMismatch(texts, values);
|
|
419
|
+
return placeholders.map((_, index) => index);
|
|
420
|
+
}
|
|
421
|
+
const indexes = placeholders.map((placeholder) => (placeholder.number ?? 0) - 1);
|
|
422
|
+
if (!(indexes.every((index) => index >= 0 && index < values) && new Set(indexes).size === values)) throw placeholderMismatch(texts, values);
|
|
423
|
+
return indexes;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* The statement with each placeholder written as MySQL's positional `?`, and its values in that order. The adapter writes numbered `?N` placeholders, a value written as often as its `?N` appears; the control plane writes bare `?`s, which take the values in order. `tokenizeMysqlSql` reads the statement as MySQL's lexer does, so a `?` inside a quoted string, a backtick identifier or a comment stays text. Refuses a statement that mixes the two forms, or whose placeholders and values do not match.
|
|
427
|
+
*/
|
|
428
|
+
function positionalParams(sql, values) {
|
|
429
|
+
const tokens = tokenizeMysqlSql(sql);
|
|
430
|
+
const indexes = valueIndexes(tokens.filter((token) => token.kind === "placeholder"), values.length);
|
|
431
|
+
return {
|
|
432
|
+
sql: tokens.map((token) => token.kind === "placeholder" ? "?" : token.text).join(""),
|
|
433
|
+
values: indexes.map((index) => bindValue(values[index], index))
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
/** The server status flag MySQL sets in every reply while it reports `NO_BACKSLASH_ESCAPES` in the session's `sql_mode`. */
|
|
437
|
+
const NO_BACKSLASH_ESCAPES = 512;
|
|
438
|
+
function noBackslashEscapesRefusal(params) {
|
|
439
|
+
return mysqlError("RUNTIME.SQL_MODE_UNSUPPORTED", "MySQL reports NO_BACKSLASH_ESCAPES in this connection's sql_mode, which the MySQL target does not support, so the driver does not send a statement with values", {
|
|
440
|
+
why: "In this mode MySQL ends a string at a backslash and a quote, while the mariadb package, which writes the values into the statement, finds its placeholders as if the backslash escaped the quote, so a value could land outside its string literal and run as SQL. The driver removes the mode on every connection it opens, so a statement on this connection made MySQL report it: a raw SET sql_mode that set it, which stays until the connection closes or a statement clears it, or a stored procedure that set it inside itself, after which MySQL restores the mode the connection had, which may be off, but keeps reporting this one until a statement sets sql_mode again.",
|
|
441
|
+
fix: `Do not set NO_BACKSLASH_ESCAPES on a connection Prisma uses, in raw SQL, a stored procedure or a trigger. A raw SET run outside a transaction stays on whichever pooled connection ran it; restart the client to close that connection. A statement that needs the mode must run in a transaction or on a connection you hold, which must set the mode back before it is released, with ${CLEAR_UNSUPPORTED_SQL_MODES}. A statement without values still runs.`,
|
|
442
|
+
meta: {
|
|
443
|
+
sqlMode: "NO_BACKSLASH_ESCAPES",
|
|
444
|
+
params
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
/** The character set MySQL last reported for the statements the connection sends, as the package records it: utf8mb3 and utf8mb4 both as `utf8`, told apart by their longest character. */
|
|
449
|
+
function reportedCharacterSet(collation) {
|
|
450
|
+
if (typeof collation === "object" && collation !== null && "charset" in collation && "maxLength" in collation) return collation.charset === "utf8" ? `utf8mb${String(collation.maxLength)}` : String(collation.charset);
|
|
451
|
+
return "unknown";
|
|
452
|
+
}
|
|
453
|
+
function characterSetRefusal(characterSet, params) {
|
|
454
|
+
return mysqlError("RUNTIME.CHARACTER_SET_UNSUPPORTED", `The driver could not confirm that MySQL reads this connection's statements as utf8mb4: the character set the mariadb package last recorded for it is ${characterSet}. The MySQL target supports only utf8mb4, so the driver does not send a statement with values`, {
|
|
455
|
+
why: "The mariadb package, which writes the values into the statement, encodes the statement in the character set it last recorded and finds its placeholders byte by byte. In a character set such as sjis, cp932, big5 or gbk, the second byte of some characters is a backslash, so the package can read the end of a string literal in the SQL differently from MySQL, and a value could run as SQL. The package records the character set from the server greeting and from MySQL's report of changed session variables. Two causes are known: a statement on this connection changed character_set_client, such as a raw SET NAMES; or the server does not report character_set_client in session_track_system_variables, so the package never saw the driver set utf8mb4 and still holds the default character set from the greeting.",
|
|
456
|
+
fix: `If a statement changed the character set: do not change it on a connection Prisma uses. A raw SET run outside a transaction stays on whichever pooled connection ran it; restart the client to close that connection. A statement that needs another character set must run in a transaction or on a connection you hold, which must set it back before it is released, with ${SET_UTF8MB4}. If no statement changed it: add character_set_client back to the server's session_track_system_variables, as in MySQL's default, and restart the client. A statement without values still runs.`,
|
|
457
|
+
meta: {
|
|
458
|
+
characterSet,
|
|
459
|
+
params
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* The statement to hand to `connection`: `sql` with its placeholders written as `?` and the values in their order, for the package to write in. A statement without values comes back as written with no values, so the package sends it without searching it for placeholders. Refuses a statement with values while the server last reported `NO_BACKSLASH_ESCAPES` on, or while the package's record of the character set is not utf8mb4, which a statement the application sends or a server that does not report `character_set_client` can cause. A statement without values still runs, so the setting can be put back; the driver's lexer still reads a backslash as an escape then, so at worst it refuses such a statement for a `?` it reads outside a string.
|
|
465
|
+
*/
|
|
466
|
+
function statementFor(connection, sql, params) {
|
|
467
|
+
const { info } = connection;
|
|
468
|
+
assertDefined(info, "the package gives every connection its info when it creates it");
|
|
469
|
+
if (params.length > 0) {
|
|
470
|
+
if ((info.status & NO_BACKSLASH_ESCAPES) !== 0) throw noBackslashEscapesRefusal(params.length);
|
|
471
|
+
const characterSet = reportedCharacterSet(info.collation);
|
|
472
|
+
if (characterSet !== "utf8mb4") throw characterSetRefusal(characterSet, params.length);
|
|
473
|
+
}
|
|
474
|
+
const statement = positionalParams(sql, params);
|
|
475
|
+
return params.length > 0 ? statement : {
|
|
476
|
+
sql,
|
|
477
|
+
values: void 0
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
//#endregion
|
|
481
|
+
export { connectionFix as a, mysqlConnectionOptions as c, normalizeMysqlError as d, sessionSettingsStatement as f, connectingCannotSucceed as i, mysqlDriverDescriptorMeta as l, acquireClientQueryLock as n, connectionLost as o, statementFor as p, applySessionSettings as r, isFatal as s, SessionSettingsGuard as t, mysqlPoolOptions as u };
|
|
482
|
+
|
|
483
|
+
//# sourceMappingURL=statement-A6bbPBf1-q61iHQLb.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statement-A6bbPBf1-q61iHQLb.mjs","names":["#queue","#statement","#ensured"],"sources":["../../../../3-targets/mysql/3-driver/dist/statement-A6bbPBf1.mjs"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { ifDefined } from \"@internal/utils/defined\";\nimport { structuredError } from \"@internal/utils/structured-error\";\nimport { type } from \"arktype\";\nimport { SqlConnectionError, SqlQueryError } from \"@internal/sql-errors\";\nimport { quoteIdentifier, tokenizeMysqlSql } from \"@internal/target-mysql/sql-utils\";\nimport { assertDefined } from \"@internal/utils/assertions\";\nimport { mysqlError } from \"@internal/target-mysql/errors\";\n//#region src/core/client-query-lock.ts\nvar AsyncMutex = class {\n\t#queue = Promise.resolve();\n\tasync lock() {\n\t\tconst previous = this.#queue;\n\t\tlet releaseLock;\n\t\tthis.#queue = new Promise((resolve) => {\n\t\t\treleaseLock = resolve;\n\t\t});\n\t\tawait previous;\n\t\treturn () => {\n\t\t\treleaseLock?.();\n\t\t\treleaseLock = void 0;\n\t\t};\n\t}\n};\n/**\n* One statement at a time on each client, in the order sent, as the Postgres driver's per-client lock runs them, on the runtime and the control driver alike. The lock is held until the statement settles, or for a stream's whole life, so a statement sent while a stream is open waits for it.\n*/\nconst clientQueryLocks = /* @__PURE__ */ new WeakMap();\nfunction acquireClientQueryLock(client) {\n\tlet mutex = clientQueryLocks.get(client);\n\tif (mutex === void 0) {\n\t\tmutex = new AsyncMutex();\n\t\tclientQueryLocks.set(client, mutex);\n\t}\n\treturn mutex.lock();\n}\n//#endregion\n//#region src/core/session-setup.ts\n/** Removes the `sql_mode` entries the MySQL target does not support, `NO_BACKSLASH_ESCAPES` and `ANSI_QUOTES`, leaving no empty entry between two commas. */\nconst CLEAR_UNSUPPORTED_SQL_MODES = \"SET SESSION sql_mode = TRIM(BOTH ',' FROM REPLACE(REPLACE(CONCAT(',', @@SESSION.sql_mode, ','), ',NO_BACKSLASH_ESCAPES,', ','), ',ANSI_QUOTES,', ','))\";\n/** Makes MySQL read each statement, and the package write it, as utf8mb4. */\nconst SET_UTF8MB4 = \"SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci\";\n/**\n* The statements every new connection runs once, before any other. The lexer that finds placeholders reads a backslash as an escape and `\"…\"` as a string, so the session clears NO_BACKSLASH_ESCAPES and ANSI_QUOTES and MySQL reads quoted text the same way; and it reads each statement as utf8mb4. These hold no value, so they run through the package's `initSql`; the target's session settings, which do, are set afterwards.\n*/\nconst SESSION_SETUP = [CLEAR_UNSUPPORTED_SQL_MODES, SET_UTF8MB4];\n//#endregion\n//#region src/core/text-or-bytes.ts\n/** MySQL's `binary` collation, which marks a string or blob column that holds bytes. */\nconst BINARY_COLLATION = 63;\n/** The column types whose value is text, or bytes when the column's collation is binary. */\nconst CHARACTER_OR_BLOB_TYPES = /* @__PURE__ */ new Set([\n\t\"VARCHAR\",\n\t\"VAR_STRING\",\n\t\"STRING\",\n\t\"TINY_BLOB\",\n\t\"MEDIUM_BLOB\",\n\t\"LONG_BLOB\",\n\t\"BLOB\"\n]);\n/** The column types whose value MySQL sends as text. A type outside this list, such as BIT, GEOMETRY or one the package has no name for, is read as bytes. */\nconst TEXT_TYPES = /* @__PURE__ */ new Set([\n\t...CHARACTER_OR_BLOB_TYPES,\n\t\"DECIMAL\",\n\t\"NEWDECIMAL\",\n\t\"FLOAT\",\n\t\"DOUBLE\",\n\t\"TINY\",\n\t\"SHORT\",\n\t\"INT\",\n\t\"INT24\",\n\t\"BIGINT\",\n\t\"YEAR\",\n\t\"DATE\",\n\t\"NEWDATE\",\n\t\"TIME\",\n\t\"TIME2\",\n\t\"DATETIME\",\n\t\"DATETIME2\",\n\t\"TIMESTAMP\",\n\t\"TIMESTAMP2\",\n\t\"JSON\",\n\t\"ENUM\",\n\t\"SET\",\n\t\"NULL\"\n]);\n/**\n* Reads each column as the row value ADR 155 sets at the driver boundary: a binary string or blob, BIT, GEOMETRY and a column of a type the package does not know as its bytes, every other column as text, and NULL as `null`. Bytes are a plain `Uint8Array`, not the package's `Buffer`.\n*/\nconst readTextOrBytes = (field) => {\n\tif (!TEXT_TYPES.has(field.type) || CHARACTER_OR_BLOB_TYPES.has(field.type) && field.collation.index === BINARY_COLLATION) {\n\t\tconst bytes = field.buffer();\n\t\treturn bytes === null ? null : new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n\t}\n\treturn field.string();\n};\n//#endregion\n//#region src/core/connection-options.ts\nconst DEFAULT_CONNECT_TIMEOUT_MILLIS = 2e4;\nconst DEFAULT_IDLE_TIMEOUT_MILLIS = 3e4;\nconst urlParameters = type({\n\t\"ssl?\": type(\"'true' | '1' | 'false' | '0'\").pipe((text) => text === \"true\" || text === \"1\"),\n\t\"sslmode?\": \"'disable' | 'prefer' | 'require' | 'verify-ca' | 'verify-full' | 'no-verify'\",\n\t\"sslcert?\": \"string > 0\",\n\t\"sslkey?\": \"string > 0\",\n\t\"sslrootcert?\": \"string > 0\",\n\t\"allowPublicKeyRetrieval?\": type(\"'true' | 'false'\").pipe((text) => text === \"true\")\n});\n/** The form each URL parameter's value must take, for the refusal of a value. */\nconst PARAMETER_FORMS = {\n\tssl: \"true, 1, false or 0\",\n\tsslmode: \"disable, prefer, require, verify-ca, verify-full or no-verify\",\n\tsslcert: \"the path of a PEM file\",\n\tsslkey: \"the path of a PEM file\",\n\tsslrootcert: \"the path of a PEM file\",\n\tallowPublicKeyRetrieval: \"true or false\"\n};\nfunction isParameterName(name) {\n\treturn Object.hasOwn(PARAMETER_FORMS, name);\n}\n/**\n* Options the URL cannot change. The package writes each value into its statement at a bare `?`; every option that would change where or how it writes one (named placeholders, an object written as `SET` entries, several statements in one) stays off, and `logParam` keeps values out of error messages. `permitRedirect` stays off, so a server cannot send the client, with its credentials, to another host, which `pg` never does. `typeCast` reads every column as text or bytes, so no column reaches a codec as a value the package parsed. `foundRows` makes an UPDATE count the rows it matched, as Postgres's row count does. The connection is utf8mb4: the driver reads each statement as utf8mb4 to find its placeholders, and MySQL must read it the same way.\n*/\nconst FIXED_OPTIONS = {\n\tcollation: \"UTF8MB4_UNICODE_CI\",\n\tmultipleStatements: false,\n\tnamedPlaceholders: false,\n\tpermitSetMultiParamEntries: false,\n\tpermitLocalInfile: false,\n\tlogParam: false,\n\tpermitRedirect: false,\n\tfoundRows: true,\n\ttypeCast: readTextOrBytes\n};\n/** Refuses the URL. `parameters` names the parameters at fault; no value from the URL goes into the error, because a URL carries the password. */\nfunction invalidBinding(reason, parameters) {\n\treturn structuredError(\"RUNTIME.BINDING_INVALID\", `MySQL connection URL: ${reason}`, { meta: {\n\t\treceived: parameters.join(\", \"),\n\t\treason\n\t} });\n}\n/** Parses `url` as the Postgres facade does, refusing it without the parser's error, which carries the whole URL. */\nfunction parseUrl(url) {\n\ttry {\n\t\treturn new URL(url);\n\t} catch {\n\t\tthrow invalidBinding(\"the URL cannot be parsed\", []);\n\t}\n}\nfunction readUrl(url) {\n\tconst parsed = parseUrl(url);\n\tif (parsed.searchParams.has(\"charset\")) throw invalidBinding(\"the driver always uses utf8mb4, because it reads each statement as utf8mb4 to find its placeholders; remove the charset parameter\", [\"charset\"]);\n\tconst names = [...new Set(parsed.searchParams.keys())].filter(isParameterName);\n\tconst parameters = urlParameters(Object.fromEntries([...parsed.searchParams].filter(([name]) => isParameterName(name))));\n\tif (parameters instanceof type.errors) {\n\t\tconst invalid = names.filter((name) => parameters.some((error) => error.path[0] === name));\n\t\tthrow invalidBinding(invalid.map((name) => `${name} must be ${PARAMETER_FORMS[name]}`).join(\"; \"), invalid);\n\t}\n\tif (parameters.sslcert !== void 0 && parameters.sslkey === void 0) throw invalidBinding(\"sslcert names the client's certificate and needs sslkey; to check the server's certificate against a CA file, as sslcert did in Prisma 7, use sslrootcert\", [\"sslcert\"]);\n\treturn {\n\t\tparsed,\n\t\tparameters\n\t};\n}\nfunction readPem(parameter, path) {\n\ttry {\n\t\treturn readFileSync(path, \"utf8\");\n\t} catch {\n\t\tthrow invalidBinding(`the file ${parameter} names cannot be read`, [parameter]);\n\t}\n}\n/**\n* The TLS settings the URL gives, read as `pg-connection-string` reads them for the Postgres driver: `ssl=true` turns TLS on and `ssl=false` off; `sslcert`, `sslkey`, `sslrootcert` or `sslmode` turn it on, with the certificate, key and CA read from the files they name. `sslmode=disable` turns it off; `no-verify` accepts any server certificate; every other mode verifies the certificate and the host name, as `verify-full` does.\n*/\nfunction tlsOptions(parameters) {\n\tconst { sslcert, sslkey, sslrootcert, sslmode } = parameters;\n\tif ([\n\t\tsslcert,\n\t\tsslkey,\n\t\tsslrootcert,\n\t\tsslmode\n\t].every((value) => value === void 0)) return parameters.ssl;\n\tif (sslmode === \"disable\") return false;\n\treturn {\n\t\t...ifDefined(\"cert\", sslcert === void 0 ? void 0 : readPem(\"sslcert\", sslcert)),\n\t\t...ifDefined(\"key\", sslkey === void 0 ? void 0 : readPem(\"sslkey\", sslkey)),\n\t\t...ifDefined(\"ca\", sslrootcert === void 0 ? void 0 : readPem(\"sslrootcert\", sslrootcert)),\n\t\t...sslmode === \"no-verify\" ? { rejectUnauthorized: false } : {}\n\t};\n}\nfunction connectionOptions(parsed, parameters, connectTimeoutMs) {\n\treturn {\n\t\thost: decodeURIComponent(parsed.hostname).replace(/^\\[(.*)\\]$/, \"$1\"),\n\t\t...ifDefined(\"port\", parsed.port === \"\" ? void 0 : Number(parsed.port)),\n\t\tuser: decodeURIComponent(parsed.username),\n\t\tpassword: decodeURIComponent(parsed.password),\n\t\tdatabase: decodeURIComponent(parsed.pathname.slice(1)),\n\t\t...ifDefined(\"ssl\", tlsOptions(parameters)),\n\t\tallowPublicKeyRetrieval: parameters.allowPublicKeyRetrieval ?? false,\n\t\tconnectTimeout: connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MILLIS,\n\t\tinitSql: [...SESSION_SETUP],\n\t\t...FIXED_OPTIONS\n\t};\n}\n/** The `mariadb` options for one connection to the server a `mysql://` URL names. Ignores a URL parameter the driver does not read, as `pg` does, and refuses a charset. */\nfunction mysqlConnectionOptions(url, settings) {\n\tconst { parsed, parameters } = readUrl(url);\n\treturn connectionOptions(parsed, parameters, settings?.connectTimeoutMs);\n}\n/**\n* The `mariadb` pool options for a `mysql://` URL, sized and timed as the Postgres driver's `pg.Pool`: it opens a connection only when one is needed (`minimumIdle: 0`), closes one idle for `idleTimeoutMillis`, and waits `connectionTimeoutMillis` both to open a connection and for a pooled one to come free.\n*/\nfunction mysqlPoolOptions(url, poolOptions) {\n\tconst { parsed, parameters } = readUrl(url);\n\tconst timeoutMs = poolOptions?.connectionTimeoutMillis ?? DEFAULT_CONNECT_TIMEOUT_MILLIS;\n\treturn {\n\t\t...connectionOptions(parsed, parameters, timeoutMs),\n\t\tacquireTimeout: timeoutMs,\n\t\tminimumIdle: 0,\n\t\tidleTimeout: Math.ceil((poolOptions?.idleTimeoutMillis ?? DEFAULT_IDLE_TIMEOUT_MILLIS) / 1e3),\n\t\t...ifDefined(\"connectionLimit\", poolOptions?.max)\n\t};\n}\n//#endregion\n//#region src/core/descriptor-meta.ts\nconst mysqlDriverDescriptorMeta = {\n\tkind: \"driver\",\n\tfamilyId: \"sql\",\n\ttargetId: \"mysql\",\n\tid: \"mysql\",\n\tversion: \"0.0.1\",\n\tcapabilities: {}\n};\n//#endregion\n//#region src/core/normalize-error.ts\nfunction isMariadbError(error) {\n\treturn error instanceof Error && \"errno\" in error && typeof error.errno === \"number\";\n}\n/** Whether `error` left its connection unusable: the package marks a lost socket, and a server error of SQLSTATE class 08, as fatal. */\nfunction isFatal(error) {\n\treturn error instanceof Error && \"fatal\" in error && error.fatal === true;\n}\nfunction serverMessage(error) {\n\treturn isMariadbError(error) ? error.sqlMessage ?? error.message : error.message;\n}\n/** The error a statement ends with when its connection is lost or closed under it: a `SqlConnectionError` a retry on a new connection can get past, as on Postgres. */\nfunction connectionLost(cause) {\n\treturn new SqlConnectionError(serverMessage(cause), {\n\t\tcause,\n\t\ttransient: true,\n\t\t...ifDefined(\"sqlState\", isMariadbError(cause) ? cause.sqlState ?? void 0 : void 0)\n\t});\n}\n/** Node's socket and DNS error codes, and whether a retry can succeed after each, as the Postgres driver classifies them. */\nconst NODE_CONNECTION_CODES = /* @__PURE__ */ new Map([\n\t[\"ECONNRESET\", true],\n\t[\"ETIMEDOUT\", true],\n\t[\"EPIPE\", true],\n\t[\"EAI_AGAIN\", true],\n\t[\"ECONNREFUSED\", false],\n\t[\"ENOTFOUND\", false],\n\t[\"EHOSTUNREACH\", false]\n]);\n/** Whether a retry can succeed after `error`, for a Node socket or DNS error; undefined for any other. */\nfunction nodeConnectionTransience(error) {\n\treturn error instanceof Error && \"code\" in error && typeof error.code === \"string\" ? NODE_CONNECTION_CODES.get(error.code) : void 0;\n}\nconst ER_GET_CONNECTION_TIMEOUT = 45028;\nconst ER_INITIAL_SQL_ERROR = 45030;\nconst ER_CANNOT_RETRIEVE_RSA_KEY = 45044;\n/** The errors MySQL refuses a sign-in with: access denied, access denied for a socket-authenticated account, and an authentication plugin the server has not loaded. Another attempt with the same URL fails the same way. */\nconst SIGN_IN_REFUSED = /* @__PURE__ */ new Set([\n\t1045,\n\t1698,\n\t1524\n]);\n/** Whether `error` is one another attempt to connect with the same settings cannot get past: a refused connection, an unknown or unreachable host, a refused sign-in, a sign-in that needs the server's public key, or session setup MySQL refuses. */\nfunction connectingCannotSucceed(error) {\n\tif (nodeConnectionTransience(error) === false) return true;\n\treturn isMariadbError(error) && (SIGN_IN_REFUSED.has(error.errno) || error.errno === ER_CANNOT_RETRIEVE_RSA_KEY || error.errno === ER_INITIAL_SQL_ERROR);\n}\nconst UNIQUE_VIOLATION = \"23505\";\nconst FOREIGN_KEY_VIOLATION = \"23503\";\n/** The SQLSTATE Postgres sends for each constraint MySQL reports under a shared SQLSTATE, as the SQLite driver maps its own codes, so a consumer such as `isUniqueConstraintViolation` reads them alike. */\nconst CONSTRAINT_SQLSTATES = /* @__PURE__ */ new Map([\n\t[1062, UNIQUE_VIOLATION],\n\t[1586, UNIQUE_VIOLATION],\n\t[1216, FOREIGN_KEY_VIOLATION],\n\t[1217, FOREIGN_KEY_VIOLATION],\n\t[1451, FOREIGN_KEY_VIOLATION],\n\t[1452, FOREIGN_KEY_VIOLATION],\n\t[1048, \"23502\"],\n\t[3819, \"23514\"]\n]);\nconst PUBLIC_KEY_FIX = \"Add allowPublicKeyRetrieval=true to the URL, or connect over TLS with sslmode or ssl=true in the URL. Fetching the key over plain TCP lets a machine between the client and the server pose as the server and read the password; TLS does not.\";\n/** The fix for a failed connection when the package's error names its cause, such as a sign-in that needs the server's public key. */\nfunction connectionFix(error) {\n\treturn isMariadbError(error) && error.errno === ER_CANNOT_RETRIEVE_RSA_KEY ? PUBLIC_KEY_FIX : void 0;\n}\nfunction publicKeyNeeded(error) {\n\treturn new SqlConnectionError(`MySQL sign-in needs the server's public key: the account signs in with caching_sha2_password or sha256_password over a connection without TLS. ${PUBLIC_KEY_FIX}`, {\n\t\tcause: error,\n\t\ttransient: false\n\t});\n}\nfunction poolTimedOut(error) {\n\tconst cause = error.cause;\n\tif (connectingCannotSucceed(cause)) return normalizeMysqlError(cause);\n\treturn new SqlConnectionError(cause instanceof Error ? `Timed out waiting for a pooled MySQL connection; the pool could not open one: ${serverMessage(cause)}` : \"Timed out waiting for a pooled MySQL connection; every connection in the pool was in use.\", {\n\t\tcause: error,\n\t\ttransient: true\n\t});\n}\n/**\n* An error from the `mariadb` package as the driver reports it, in the family's types as the Postgres driver reports its own: a Node socket or DNS error as a `SqlConnectionError`, transient as the Postgres driver's table says; a lost connection and a pool that gave no connection in time as a transient `SqlConnectionError`; a sign-in that needs the server's public key, and session setup that fails, as a `SqlConnectionError` that is not transient; a sign-in MySQL refuses, as Postgres's 28P01, and an error MySQL reported about a statement as `SqlQueryError` with its SQLSTATE, a constraint violation with the SQLSTATE Postgres sends; and any other error unchanged. A pool that timed out because it could not connect in a way no retry can get past reports that error.\n*/\nfunction normalizeMysqlError(error) {\n\tconst transient = nodeConnectionTransience(error);\n\tif (transient !== void 0 && error instanceof Error) return new SqlConnectionError(error.message, {\n\t\tcause: error,\n\t\ttransient\n\t});\n\tif (!isMariadbError(error)) return error;\n\tif (error.errno === ER_CANNOT_RETRIEVE_RSA_KEY) return publicKeyNeeded(error);\n\tif (error.errno === ER_INITIAL_SQL_ERROR) return new SqlConnectionError(serverMessage(error), {\n\t\tcause: error,\n\t\ttransient: false\n\t});\n\tif (isFatal(error) && !SIGN_IN_REFUSED.has(error.errno)) return connectionLost(error);\n\tif (error.errno === ER_GET_CONNECTION_TIMEOUT) return poolTimedOut(error);\n\tif (typeof error.sqlState !== \"string\") return error;\n\treturn new SqlQueryError(error.sqlMessage ?? error.message, {\n\t\tcause: error,\n\t\tsqlState: CONSTRAINT_SQLSTATES.get(error.errno) ?? error.sqlState\n\t});\n}\n//#endregion\n//#region src/core/session-settings.ts\nconst DECIMAL_INTEGER = /^-?\\d+$/;\n/** A setting's value as MySQL takes it: decimal integer text as a whole number, because MySQL refuses text for an integer variable, and any other text as it is. */\nfunction settingValue(value) {\n\treturn DECIMAL_INTEGER.test(value) ? BigInt(value) : value;\n}\n/** The one statement that sets `sessionSettings`: each name a quoted identifier, each value a parameter. Undefined when there is nothing to set. */\nfunction sessionSettingsStatement(sessionSettings) {\n\tconst entries = Object.entries(sessionSettings);\n\tif (entries.length === 0) return void 0;\n\treturn {\n\t\tsql: `SET SESSION ${entries.map(([name]) => `${quoteIdentifier(name)} = ?`).join(\", \")}`,\n\t\tvalues: entries.map(([, value]) => settingValue(value))\n\t};\n}\n/** Sets the session settings on `connection`, the package writing each value into the statement. Throws the package's error as it is. */\nasync function applySessionSettings(connection, statement) {\n\tawait connection.query(statement.sql, [...statement.values]);\n}\n/**\n* Ensures the session settings a target declares on each physical connection the runtime driver gets from its pool, once, as the Postgres driver's `SessionSettingsGuard` does for a pool it did not start the sessions of. The package hands out a new wrapper for each `getConnection`, so a connection is known by its `info`, which belongs to the physical connection.\n*/\nvar SessionSettingsGuard = class {\n\t#statement;\n\t#ensured = /* @__PURE__ */ new WeakSet();\n\tconstructor(sessionSettings) {\n\t\tthis.#statement = sessionSettingsStatement(sessionSettings);\n\t}\n\tasync ensure(connection) {\n\t\tconst key = connection.info;\n\t\tassertDefined(key, \"the package gives every connection its info when it creates it\");\n\t\tif (this.#statement === void 0 || this.#ensured.has(key)) return;\n\t\tawait applySessionSettings(connection, this.#statement);\n\t\tthis.#ensured.add(key);\n\t}\n};\n//#endregion\n//#region src/core/parameter-values.ts\nfunction unsendable(message, paramIndex, received) {\n\treturn mysqlError(\"RUNTIME.ENCODE_FAILED\", message, { meta: {\n\t\ttarget: \"mysql\",\n\t\tparamIndex,\n\t\treceived\n\t} });\n}\nconst BIGINT_MIN = -(2n ** 63n);\nconst BIGINT_MAX = 2n ** 63n - 1n;\nconst LONE_SURROGATE = /\\p{Surrogate}/u;\nfunction withinBigint(value) {\n\treturn value >= BIGINT_MIN && value <= BIGINT_MAX;\n}\nfunction receivedKind(value) {\n\tif (value instanceof Date) return \"Date\";\n\tif (Array.isArray(value)) return \"array\";\n\treturn typeof value;\n}\n/**\n* The value the `mariadb` package writes into the statement for a parameter. A finite number or a bigint goes as it is, and the package writes its digits. A non-finite number is refused, because the package would write `NaN` or `Infinity` into the SQL. A bigint must fit a signed BIGINT, so a parameter's type never depends on its value. A `Uint8Array` goes as a Buffer over the same bytes, because the package writes any other `Uint8Array` as JSON text. A `Date` is refused: the package writes it in the process's local time zone, and the MySQL codecs send dates as text. So is text with a lone UTF-16 surrogate, which the package writes as `?` or U+FFFD depending on the text's length.\n*/\nfunction bindValue(value, index) {\n\tif (value === null || value === void 0) return null;\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) throw unsendable(`Parameter ${index + 1} is ${value}, which MySQL cannot store`, index, String(value));\n\t\treturn value;\n\t}\n\tif (typeof value === \"bigint\") {\n\t\tif (withinBigint(value)) return value;\n\t\tthrow unsendable(`Parameter ${index + 1} is an integer outside MySQL's signed 64-bit BIGINT`, index, \"bigint\");\n\t}\n\tif (Buffer.isBuffer(value)) return value;\n\tif (value instanceof Uint8Array) return Buffer.from(value.buffer, value.byteOffset, value.byteLength);\n\tif (typeof value === \"string\") {\n\t\tif (!LONE_SURROGATE.test(value)) return value;\n\t\tthrow unsendable(`Parameter ${index + 1} is text with a lone UTF-16 surrogate, which is not a character and has no utf8mb4 form; the mariadb package would store it as ? or as U+FFFD, depending on the length of the text`, index, \"string\");\n\t}\n\tif (typeof value === \"boolean\") return value;\n\tconst received = receivedKind(value);\n\tthrow unsendable(`Parameter ${index + 1} is of type ${received}; a MySQL parameter must be text, a number, a bigint, a boolean, bytes or null, and a Date is sent as text by its codec`, index, received);\n}\n//#endregion\n//#region src/core/positional-params.ts\nfunction placeholderMismatch(placeholders, values) {\n\treturn structuredError(\"RUNTIME.PARAM_PLACEHOLDER_MISMATCH\", `The MySQL statement writes placeholders ${JSON.stringify(placeholders)} for ${values} parameter value(s); write each value as a numbered ?N, or every value as a bare ? in order, and no other placeholder.`, {\n\t\twhy: \"A placeholder that does not match a value binds a value to the wrong place in the statement, or leaves a value unbound.\",\n\t\tfix: \"Pass values into raw SQL through interpolation rather than writing a `?` in the SQL text.\",\n\t\tmeta: {\n\t\t\tplaceholders,\n\t\t\tparams: values\n\t\t}\n\t});\n}\n/** The index into `values` each placeholder takes: `?N` takes value N, and bare `?`s take the values in order. */\nfunction valueIndexes(placeholders, values) {\n\tconst texts = placeholders.map((placeholder) => placeholder.text);\n\tif (texts.every((text) => text === \"?\")) {\n\t\tif (placeholders.length !== values) throw placeholderMismatch(texts, values);\n\t\treturn placeholders.map((_, index) => index);\n\t}\n\tconst indexes = placeholders.map((placeholder) => (placeholder.number ?? 0) - 1);\n\tif (!(indexes.every((index) => index >= 0 && index < values) && new Set(indexes).size === values)) throw placeholderMismatch(texts, values);\n\treturn indexes;\n}\n/**\n* The statement with each placeholder written as MySQL's positional `?`, and its values in that order. The adapter writes numbered `?N` placeholders, a value written as often as its `?N` appears; the control plane writes bare `?`s, which take the values in order. `tokenizeMysqlSql` reads the statement as MySQL's lexer does, so a `?` inside a quoted string, a backtick identifier or a comment stays text. Refuses a statement that mixes the two forms, or whose placeholders and values do not match.\n*/\nfunction positionalParams(sql, values) {\n\tconst tokens = tokenizeMysqlSql(sql);\n\tconst indexes = valueIndexes(tokens.filter((token) => token.kind === \"placeholder\"), values.length);\n\treturn {\n\t\tsql: tokens.map((token) => token.kind === \"placeholder\" ? \"?\" : token.text).join(\"\"),\n\t\tvalues: indexes.map((index) => bindValue(values[index], index))\n\t};\n}\n//#endregion\n//#region src/core/statement.ts\n/** The server status flag MySQL sets in every reply while it reports `NO_BACKSLASH_ESCAPES` in the session's `sql_mode`. */\nconst NO_BACKSLASH_ESCAPES = 512;\nfunction noBackslashEscapesRefusal(params) {\n\treturn mysqlError(\"RUNTIME.SQL_MODE_UNSUPPORTED\", \"MySQL reports NO_BACKSLASH_ESCAPES in this connection's sql_mode, which the MySQL target does not support, so the driver does not send a statement with values\", {\n\t\twhy: \"In this mode MySQL ends a string at a backslash and a quote, while the mariadb package, which writes the values into the statement, finds its placeholders as if the backslash escaped the quote, so a value could land outside its string literal and run as SQL. The driver removes the mode on every connection it opens, so a statement on this connection made MySQL report it: a raw SET sql_mode that set it, which stays until the connection closes or a statement clears it, or a stored procedure that set it inside itself, after which MySQL restores the mode the connection had, which may be off, but keeps reporting this one until a statement sets sql_mode again.\",\n\t\tfix: `Do not set NO_BACKSLASH_ESCAPES on a connection Prisma uses, in raw SQL, a stored procedure or a trigger. A raw SET run outside a transaction stays on whichever pooled connection ran it; restart the client to close that connection. A statement that needs the mode must run in a transaction or on a connection you hold, which must set the mode back before it is released, with ${CLEAR_UNSUPPORTED_SQL_MODES}. A statement without values still runs.`,\n\t\tmeta: {\n\t\t\tsqlMode: \"NO_BACKSLASH_ESCAPES\",\n\t\t\tparams\n\t\t}\n\t});\n}\n/** The character set MySQL last reported for the statements the connection sends, as the package records it: utf8mb3 and utf8mb4 both as `utf8`, told apart by their longest character. */\nfunction reportedCharacterSet(collation) {\n\tif (typeof collation === \"object\" && collation !== null && \"charset\" in collation && \"maxLength\" in collation) return collation.charset === \"utf8\" ? `utf8mb${String(collation.maxLength)}` : String(collation.charset);\n\treturn \"unknown\";\n}\nfunction characterSetRefusal(characterSet, params) {\n\treturn mysqlError(\"RUNTIME.CHARACTER_SET_UNSUPPORTED\", `The driver could not confirm that MySQL reads this connection's statements as utf8mb4: the character set the mariadb package last recorded for it is ${characterSet}. The MySQL target supports only utf8mb4, so the driver does not send a statement with values`, {\n\t\twhy: \"The mariadb package, which writes the values into the statement, encodes the statement in the character set it last recorded and finds its placeholders byte by byte. In a character set such as sjis, cp932, big5 or gbk, the second byte of some characters is a backslash, so the package can read the end of a string literal in the SQL differently from MySQL, and a value could run as SQL. The package records the character set from the server greeting and from MySQL's report of changed session variables. Two causes are known: a statement on this connection changed character_set_client, such as a raw SET NAMES; or the server does not report character_set_client in session_track_system_variables, so the package never saw the driver set utf8mb4 and still holds the default character set from the greeting.\",\n\t\tfix: `If a statement changed the character set: do not change it on a connection Prisma uses. A raw SET run outside a transaction stays on whichever pooled connection ran it; restart the client to close that connection. A statement that needs another character set must run in a transaction or on a connection you hold, which must set it back before it is released, with ${SET_UTF8MB4}. If no statement changed it: add character_set_client back to the server's session_track_system_variables, as in MySQL's default, and restart the client. A statement without values still runs.`,\n\t\tmeta: {\n\t\t\tcharacterSet,\n\t\t\tparams\n\t\t}\n\t});\n}\n/**\n* The statement to hand to `connection`: `sql` with its placeholders written as `?` and the values in their order, for the package to write in. A statement without values comes back as written with no values, so the package sends it without searching it for placeholders. Refuses a statement with values while the server last reported `NO_BACKSLASH_ESCAPES` on, or while the package's record of the character set is not utf8mb4, which a statement the application sends or a server that does not report `character_set_client` can cause. A statement without values still runs, so the setting can be put back; the driver's lexer still reads a backslash as an escape then, so at worst it refuses such a statement for a `?` it reads outside a string.\n*/\nfunction statementFor(connection, sql, params) {\n\tconst { info } = connection;\n\tassertDefined(info, \"the package gives every connection its info when it creates it\");\n\tif (params.length > 0) {\n\t\tif ((info.status & NO_BACKSLASH_ESCAPES) !== 0) throw noBackslashEscapesRefusal(params.length);\n\t\tconst characterSet = reportedCharacterSet(info.collation);\n\t\tif (characterSet !== \"utf8mb4\") throw characterSetRefusal(characterSet, params.length);\n\t}\n\tconst statement = positionalParams(sql, params);\n\treturn params.length > 0 ? statement : {\n\t\tsql,\n\t\tvalues: void 0\n\t};\n}\n//#endregion\nexport { connectingCannotSucceed as a, isFatal as c, mysqlConnectionOptions as d, mysqlPoolOptions as f, sessionSettingsStatement as i, normalizeMysqlError as l, SessionSettingsGuard as n, connectionFix as o, acquireClientQueryLock as p, applySessionSettings as r, connectionLost as s, statementFor as t, mysqlDriverDescriptorMeta as u };\n\n//# sourceMappingURL=statement-A6bbPBf1.mjs.map"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { a as MysqlCodecOptions, c as mysqlCodec, i as MysqlCodecDescriptorRegistry, n as AnyMysqlCodecDescriptor, o as buildMysqlCodecDescriptorRegistry, r as MysqlCodecDescriptor, s as isMysqlCodecDescriptor, t as AdaptedMysqlCodecDescriptor } from "./codec-descriptor-DXyubAS6-siA0R8Ow.mjs";
|
|
2
|
+
import { a as MYSQL_TEXT_CODEC_ID, i as MYSQL_INT_CODEC_ID, n as MYSQL_DATETIME_CODEC_ID, r as MYSQL_ENUM_CODEC_ID, t as MYSQL_BIGINT_CODEC_ID } from "./codec-ids-sMOU8F-B-BQbCq2dr.mjs";
|
|
3
|
+
import { a as mysqlDatetime, c as mysqlEnum, d as mysqlText, f as mysqlTextDataTypes, h as renderMysqlEnumType, i as mysqlDataTypes, l as mysqlEnumParams, m as mysqlVarcharParams, n as mysqlChar, o as mysqlDatetimeParams, p as mysqlVarchar, r as mysqlCharParams, s as mysqlDatetimeText, t as mysqlBigint, u as mysqlInt } from "./data-types-BpihGKoK-BMW-m4EN.mjs";
|
|
4
|
+
import { o as decodeMysqlDatetime, s as encodeMysqlDatetime } from "./codecs-CO_VNEYU-CwAnKzRs.mjs";
|
|
5
|
+
import { t as CodecTypes } from "./codec-types-Bd7DL1Mr-CZWNfnp9.mjs";
|
|
6
|
+
import "./codec-types-Ja2kLzLS.mjs";
|
|
7
|
+
import { a as mysqlCodecRegistry, i as mysqlCodecDescriptorRegistry, n as assembleMysqlCodecRegistry, r as createMysqlBuiltinCodecLookup, t as MysqlCodecRegistry } from "./codecs-DM61agRr.mjs";
|
|
8
|
+
import { i as MysqlDdlVisitor, n as MysqlCreateTable, r as MysqlDdlNode, t as AnyMysqlDdlNode } from "./nodes-xc0cR0_c-2YbhgEjb.mjs";
|
|
9
|
+
import "./ddl-CT6DPEqg.mjs";
|
|
10
|
+
import "./codec-descriptor-oLRh9E29.mjs";
|
|
11
|
+
import { n as SQL_RAW_CODEC_ID, r as SQL_VARCHAR_CODEC_ID, t as SQL_CHAR_CODEC_ID } from "./codec-ids-BHUwoNOM.mjs";
|
|
12
|
+
import { n as buildSignMarkerBootstrapQueries, r as createTable, t as buildControlTableBootstrapQueries } from "./contract-free-Cw9Mjcro.mjs";
|
|
13
|
+
import { t as MysqlPlanTargetDetails } from "./planner-target-details-D6g2uSp--C5NKHmCc.mjs";
|
|
14
|
+
import { r as mysqlCreateNamespace, t as MysqlDatabase } from "./control-_4epnrIW.mjs";
|
|
15
|
+
import { n as LEDGER_TABLE_NAME, r as MARKER_TABLE_NAME, t as CONTROL_TABLE_NAMES } from "./control-tables-CHw2F-rg.mjs";
|
|
16
|
+
import { t as mysqlDataTypeEntries } from "./data-types-SXrh0Lou.mjs";
|
|
17
|
+
import { n as mysqlResolveDefault, r as readMysqlDefault, t as MysqlReportedDefault } from "./default-normalizer-BBhGpw7r.mjs";
|
|
18
|
+
import { n as mysqlQueryNotYetSupported, t as mysqlError } from "./errors-BYhjQT7y.mjs";
|
|
19
|
+
import { i as withMarkerLock, n as acquireMarkerLock, r as releaseMarkerLock, t as MARKER_LOCK_TIMEOUT_SECONDS } from "./marker-lock-su6IxinO.mjs";
|
|
20
|
+
import { C as lit, D as sql, E as rawSql, O as unique, S as fn, T as primaryKey, _ as RawSqlCall, a as CreateTableCall, b as createMysqlMigrationPlanner, c as DropIndexCall, d as MigrationCLI, f as MysqlMigration, g as MysqlPlanResult, h as MysqlOpFactoryCall, i as CreateIndexCall, l as DropTableCall, m as MysqlMigrationPlanner, n as AddForeignKeyCall, o as DropColumnCall, p as MysqlMigrationDestinationInfo, r as AddUniqueCall, s as DropForeignKeyCall, t as AddColumnCall, u as DropUniqueCall, v as TypeScriptRenderableMysqlMigration, w as placeholder, x as createMysqlMigrationRunner, y as col } from "./migration-DmlblTTw.mjs";
|
|
21
|
+
import "./pack-YVG-iBMQ.mjs";
|
|
22
|
+
import { n as MysqlRuntimeTargetInstance, t as MysqlContractSerializer } from "./runtime-Cl0BbTZq.mjs";
|
|
23
|
+
import { a as quoteLiteral, i as quoteIdentifier, n as MysqlSqlToken, o as tokenizeMysqlSql, r as escapeLiteral, t as MysqlPlaceholderToken } from "./sql-utils-BOS1c2QT.mjs";
|
|
24
|
+
export { type AdaptedMysqlCodecDescriptor, AddColumnCall, AddForeignKeyCall, AddUniqueCall, type AnyMysqlCodecDescriptor, type AnyMysqlDdlNode, CONTROL_TABLE_NAMES, CodecTypes, CreateIndexCall, CreateTableCall, DropColumnCall, DropForeignKeyCall, DropIndexCall, DropTableCall, DropUniqueCall, LEDGER_TABLE_NAME, MARKER_LOCK_TIMEOUT_SECONDS, MARKER_TABLE_NAME, MYSQL_BIGINT_CODEC_ID, MYSQL_DATETIME_CODEC_ID, MYSQL_ENUM_CODEC_ID, MYSQL_INT_CODEC_ID, MYSQL_TEXT_CODEC_ID, MysqlMigration as Migration, MigrationCLI, MysqlCodecDescriptor, type MysqlCodecDescriptorRegistry, type MysqlCodecOptions, type MysqlCodecRegistry, MysqlContractSerializer, MysqlCreateTable, MysqlDatabase, MysqlDdlNode, type MysqlDdlVisitor, type MysqlMigrationDestinationInfo, MysqlMigrationPlanner, type MysqlOpFactoryCall, type MysqlPlaceholderToken, type MysqlPlanResult, type MysqlPlanTargetDetails, type MysqlReportedDefault, type MysqlRuntimeTargetInstance, type MysqlSqlToken, RawSqlCall, SQL_CHAR_CODEC_ID, SQL_RAW_CODEC_ID, SQL_VARCHAR_CODEC_ID, TypeScriptRenderableMysqlMigration, acquireMarkerLock, assembleMysqlCodecRegistry, buildControlTableBootstrapQueries, buildMysqlCodecDescriptorRegistry, buildSignMarkerBootstrapQueries, col, createMysqlBuiltinCodecLookup, createMysqlMigrationPlanner, createMysqlMigrationRunner, createTable, decodeMysqlDatetime, encodeMysqlDatetime, escapeLiteral, fn, isMysqlCodecDescriptor, lit, mysqlBigint, mysqlChar, mysqlCharParams, mysqlCodec, mysqlCodecDescriptorRegistry, mysqlCodecRegistry, mysqlCreateNamespace, mysqlDataTypeEntries, mysqlDataTypes, mysqlDatetime, mysqlDatetimeParams, mysqlDatetimeText, mysqlEnum, mysqlEnumParams, mysqlError, mysqlInt, mysqlQueryNotYetSupported, mysqlResolveDefault, mysqlText, mysqlTextDataTypes, mysqlVarchar, mysqlVarcharParams, placeholder, primaryKey, quoteIdentifier, quoteLiteral, rawSql, readMysqlDefault, releaseMarkerLock, renderMysqlEnumType, sql, tokenizeMysqlSql, unique, withMarkerLock };
|
package/dist/target.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { i as mysqlCodec, n as buildMysqlCodecDescriptorRegistry, r as isMysqlCodecDescriptor, t as MysqlCodecDescriptor } from "./codec-descriptor-Du6DSz-3-ytBCu_mq.mjs";
|
|
2
|
+
import { a as MYSQL_TEXT_CODEC_ID, i as MYSQL_INT_CODEC_ID, n as MYSQL_DATETIME_CODEC_ID, r as MYSQL_ENUM_CODEC_ID, t as MYSQL_BIGINT_CODEC_ID } from "./codec-ids-cjxtOcLM-vFeQhgPm.mjs";
|
|
3
|
+
import { n as SQL_RAW_CODEC_ID, r as SQL_VARCHAR_CODEC_ID, t as SQL_CHAR_CODEC_ID } from "./codec-ids-C00hAFkc.mjs";
|
|
4
|
+
import { n as mysqlQueryNotYetSupported, t as mysqlError } from "./errors-rvH_F2Yj-BQrO_--u.mjs";
|
|
5
|
+
import { n as quoteIdentifier, r as quoteLiteral, t as escapeLiteral } from "./sql-utils-Db0IQO_B-PaULnfrE.mjs";
|
|
6
|
+
import { a as mysqlDatetime, c as mysqlEnum, d as mysqlText, f as mysqlTextDataTypes, h as renderMysqlEnumType, i as mysqlDataTypes, l as mysqlEnumParams, m as mysqlVarcharParams, n as mysqlChar, o as mysqlDatetimeParams, p as mysqlVarchar, r as mysqlCharParams, s as mysqlDatetimeText, t as mysqlBigint, u as mysqlInt } from "./data-types-Dv9gwVRV-BZPzCWZk.mjs";
|
|
7
|
+
import { a as mysqlCodecDescriptorRegistry, i as encodeMysqlDatetime, n as createMysqlBuiltinCodecLookup, o as mysqlCodecRegistry, r as decodeMysqlDatetime, t as assembleMysqlCodecRegistry } from "./codecs-C00kjHgh.mjs";
|
|
8
|
+
import { n as LEDGER_TABLE_NAME, r as MARKER_TABLE_NAME, t as CONTROL_TABLE_NAMES } from "./control-tables-CcQ77JE7-CxTQYoQJ.mjs";
|
|
9
|
+
import { n as MysqlDdlNode, t as MysqlCreateTable } from "./nodes-CvcX47ot-B-ZaUYRj.mjs";
|
|
10
|
+
import { t as createTable } from "./ddl-DDmMHyA_-Bb8sXoS0.mjs";
|
|
11
|
+
import { n as buildSignMarkerBootstrapQueries, t as buildControlTableBootstrapQueries } from "./contract-free-BvCdx_Ee.mjs";
|
|
12
|
+
import { t as mysqlDataTypeEntries } from "./data-type-entries-B0AoBozh-f9AEUIUQ.mjs";
|
|
13
|
+
import { n as MysqlDatabase, r as mysqlCreateNamespace, t as MysqlContractSerializer } from "./mysql-contract-serializer-DLv0uW_f-Cg4A43Ry.mjs";
|
|
14
|
+
import { n as readMysqlDefault, t as mysqlResolveDefault } from "./default-normalizer-BDUgHXUn-Xk7HQJuI.mjs";
|
|
15
|
+
import { i as withMarkerLock, n as acquireMarkerLock, r as releaseMarkerLock, t as MARKER_LOCK_TIMEOUT_SECONDS } from "./marker-lock-CmGvN4hw-Com29AtQ.mjs";
|
|
16
|
+
import { a as CreateTableCall, c as DropIndexCall, d as MysqlMigration, f as MysqlMigrationPlanner, g as createMysqlMigrationRunner, h as createMysqlMigrationPlanner, i as CreateIndexCall, l as DropTableCall, m as TypeScriptRenderableMysqlMigration, n as AddForeignKeyCall, o as DropColumnCall, p as RawSqlCall, r as AddUniqueCall, s as DropForeignKeyCall, t as AddColumnCall, u as DropUniqueCall, y as rawSql } from "./runner-C4r6yEd1-BWQrxW9q.mjs";
|
|
17
|
+
import { a as placeholder, c as unique, i as lit, n as col, o as primaryKey, r as fn, s as sql, t as MigrationCLI } from "./migration-tFuoN9GB.mjs";
|
|
18
|
+
import { t as tokenizeMysqlSql } from "./sql-utils-RW0vJvDl.mjs";
|
|
19
|
+
export { AddColumnCall, AddForeignKeyCall, AddUniqueCall, CONTROL_TABLE_NAMES, CreateIndexCall, CreateTableCall, DropColumnCall, DropForeignKeyCall, DropIndexCall, DropTableCall, DropUniqueCall, LEDGER_TABLE_NAME, MARKER_LOCK_TIMEOUT_SECONDS, MARKER_TABLE_NAME, MYSQL_BIGINT_CODEC_ID, MYSQL_DATETIME_CODEC_ID, MYSQL_ENUM_CODEC_ID, MYSQL_INT_CODEC_ID, MYSQL_TEXT_CODEC_ID, MysqlMigration as Migration, MigrationCLI, MysqlCodecDescriptor, MysqlContractSerializer, MysqlCreateTable, MysqlDatabase, MysqlDdlNode, MysqlMigrationPlanner, RawSqlCall, SQL_CHAR_CODEC_ID, SQL_RAW_CODEC_ID, SQL_VARCHAR_CODEC_ID, TypeScriptRenderableMysqlMigration, acquireMarkerLock, assembleMysqlCodecRegistry, buildControlTableBootstrapQueries, buildMysqlCodecDescriptorRegistry, buildSignMarkerBootstrapQueries, col, createMysqlBuiltinCodecLookup, createMysqlMigrationPlanner, createMysqlMigrationRunner, createTable, decodeMysqlDatetime, encodeMysqlDatetime, escapeLiteral, fn, isMysqlCodecDescriptor, lit, mysqlBigint, mysqlChar, mysqlCharParams, mysqlCodec, mysqlCodecDescriptorRegistry, mysqlCodecRegistry, mysqlCreateNamespace, mysqlDataTypeEntries, mysqlDataTypes, mysqlDatetime, mysqlDatetimeParams, mysqlDatetimeText, mysqlEnum, mysqlEnumParams, mysqlError, mysqlInt, mysqlQueryNotYetSupported, mysqlResolveDefault, mysqlText, mysqlTextDataTypes, mysqlVarchar, mysqlVarcharParams, placeholder, primaryKey, quoteIdentifier, quoteLiteral, rawSql, readMysqlDefault, releaseMarkerLock, renderMysqlEnumType, sql, tokenizeMysqlSql, unique, withMarkerLock };
|