@nextlyhq/adapter-mysql 0.0.2-alpha.7 → 0.0.2-alpha.70
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 +5 -5
- package/dist/index.cjs +991 -597
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +262 -207
- package/dist/index.d.ts +262 -207
- package/dist/index.mjs +967 -590
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -19
package/dist/index.d.cts
CHANGED
|
@@ -1,48 +1,11 @@
|
|
|
1
|
-
import { DrizzleAdapter } from
|
|
2
|
-
import { MySqlAdapterConfig, PoolStats, SqlParam, TransactionContext, TransactionOptions,
|
|
3
|
-
|
|
4
|
-
import { MySql2Database } from
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @nextlyhq/adapter-mysql
|
|
8
|
-
*
|
|
9
|
-
* MySQL database adapter for Nextly.
|
|
10
|
-
* Extends DrizzleAdapter from @nextlyhq/adapter-drizzle to provide MySQL-specific functionality.
|
|
11
|
-
*
|
|
12
|
-
* @remarks
|
|
13
|
-
* This adapter uses the mysql2 package for database connectivity and provides:
|
|
14
|
-
* - Connection pooling via mysql2 Pool
|
|
15
|
-
* - Full transaction support with isolation levels
|
|
16
|
-
* - CRUD operations with workarounds for missing RETURNING clause
|
|
17
|
-
* - MySQL-specific error classification
|
|
18
|
-
* - Automatic retry for deadlocks (error 1213)
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```typescript
|
|
22
|
-
* import { createMySqlAdapter } from '@nextlyhq/adapter-mysql';
|
|
23
|
-
*
|
|
24
|
-
* const adapter = createMySqlAdapter({
|
|
25
|
-
* url: process.env.DATABASE_URL!,
|
|
26
|
-
* });
|
|
27
|
-
*
|
|
28
|
-
* await adapter.connect();
|
|
29
|
-
*
|
|
30
|
-
* // Query data
|
|
31
|
-
* const users = await adapter.select('users', {
|
|
32
|
-
* where: { and: [{ column: 'status', op: '=', value: 'active' }] },
|
|
33
|
-
* limit: 10,
|
|
34
|
-
* });
|
|
35
|
-
*
|
|
36
|
-
* await adapter.disconnect();
|
|
37
|
-
* ```
|
|
38
|
-
*
|
|
39
|
-
* @packageDocumentation
|
|
40
|
-
*/
|
|
41
|
-
|
|
1
|
+
import { DrizzleAdapter } from "@nextlyhq/adapter-drizzle";
|
|
2
|
+
import { AdapterLogger, BaseAdapterConfig, DatabaseCapabilities, DatabaseError, DatabaseErrorKind, DeleteOptions, InsertOptions, JoinSpec, MySqlAdapterConfig, OrderBySpec, PoolConfig, PoolStats, SelectOptions, SqlParam, SslConfig, TransactionContext, TransactionOptions, UpdateOptions, UpsertOptions, WhereClause, WhereCondition, WhereOperator } from "@nextlyhq/adapter-drizzle/types";
|
|
3
|
+
import { AnyRelations } from "drizzle-orm";
|
|
4
|
+
import { MySql2Database } from "drizzle-orm/mysql2";
|
|
42
5
|
/**
|
|
43
6
|
* Package version
|
|
44
7
|
*/
|
|
45
|
-
declare const VERSION = "0.1.0";
|
|
8
|
+
export declare const VERSION = "0.1.0";
|
|
46
9
|
/**
|
|
47
10
|
* MySQL database adapter for Nextly.
|
|
48
11
|
*
|
|
@@ -67,167 +30,259 @@ declare const VERSION = "0.1.0";
|
|
|
67
30
|
* await adapter.connect();
|
|
68
31
|
* ```
|
|
69
32
|
*/
|
|
70
|
-
declare class MySqlAdapter extends DrizzleAdapter {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
33
|
+
export declare class MySqlAdapter extends DrizzleAdapter {
|
|
34
|
+
private drizzleByRelations;
|
|
35
|
+
private drizzleBare;
|
|
36
|
+
/**
|
|
37
|
+
* The database dialect - always 'mysql' for this adapter.
|
|
38
|
+
*/
|
|
39
|
+
readonly dialect: "mysql";
|
|
40
|
+
/**
|
|
41
|
+
* Adapter configuration.
|
|
42
|
+
*/
|
|
43
|
+
protected readonly config: MySqlAdapterConfig;
|
|
44
|
+
/**
|
|
45
|
+
* Connection pool instance.
|
|
46
|
+
*/
|
|
47
|
+
private pool;
|
|
48
|
+
/**
|
|
49
|
+
* Connection state flag.
|
|
50
|
+
*/
|
|
51
|
+
private connected;
|
|
52
|
+
/**
|
|
53
|
+
* Whether the server accepts `SELECT ... FOR SHARE`, read from its version
|
|
54
|
+
* string at connect. Undefined until then, which callers treat as not known.
|
|
55
|
+
*/
|
|
56
|
+
private sharedRowLock;
|
|
57
|
+
/**
|
|
58
|
+
* Creates a new MySQL adapter instance.
|
|
59
|
+
*
|
|
60
|
+
* @param config - Adapter configuration
|
|
61
|
+
*/
|
|
62
|
+
constructor(config: MySqlAdapterConfig);
|
|
63
|
+
/**
|
|
64
|
+
* Connect to the MySQL database.
|
|
65
|
+
* Creates a connection pool using mysql2.
|
|
66
|
+
*
|
|
67
|
+
* @remarks
|
|
68
|
+
* This method initializes the connection pool and verifies connectivity
|
|
69
|
+
* by executing a simple query. It is idempotent - calling it multiple
|
|
70
|
+
* times will not create multiple pools.
|
|
71
|
+
*
|
|
72
|
+
* @throws {DatabaseError} If connection fails
|
|
73
|
+
*/
|
|
74
|
+
connect(): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Disconnect from the MySQL database.
|
|
77
|
+
* Gracefully closes the connection pool.
|
|
78
|
+
*
|
|
79
|
+
* @remarks
|
|
80
|
+
* This method is idempotent - calling it multiple times is safe.
|
|
81
|
+
* It waits for all connections to be released before shutting down.
|
|
82
|
+
*/
|
|
83
|
+
disconnect(): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Check if connected to the database.
|
|
86
|
+
*/
|
|
87
|
+
isConnected(): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Get connection pool statistics.
|
|
90
|
+
* Returns null if not connected.
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* MySQL2 pool exposes different stats than pg:
|
|
94
|
+
* - _allConnections: all connections
|
|
95
|
+
* - _freeConnections: idle connections
|
|
96
|
+
* - _connectionQueue: waiting requests
|
|
97
|
+
*/
|
|
98
|
+
getPoolStats(): PoolStats | null;
|
|
99
|
+
/**
|
|
100
|
+
* Execute a raw SQL query.
|
|
101
|
+
*
|
|
102
|
+
* @param sql - SQL query string with ? placeholders
|
|
103
|
+
* @param params - Query parameters
|
|
104
|
+
* @returns Query results
|
|
105
|
+
*
|
|
106
|
+
* @throws {DatabaseError} If query execution fails
|
|
107
|
+
*/
|
|
108
|
+
executeQuery<T = unknown>(sql: string, params?: SqlParam[]): Promise<T[]>;
|
|
109
|
+
/**
|
|
110
|
+
* Execute work within a transaction.
|
|
111
|
+
*
|
|
112
|
+
* @param work - Function containing transactional operations
|
|
113
|
+
* @param options - Transaction options (isolation level, timeout, retry)
|
|
114
|
+
* @returns Result of the work function
|
|
115
|
+
*
|
|
116
|
+
* @remarks
|
|
117
|
+
* MySQL transactions support isolation levels. Automatic retry is
|
|
118
|
+
* implemented for deadlocks (error 1213) when `retryCount` is specified.
|
|
119
|
+
*
|
|
120
|
+
* Note: Savepoints are disabled in this adapter for safety due to
|
|
121
|
+
* MySQL's quirks with nested transactions.
|
|
122
|
+
*/
|
|
123
|
+
transaction<T>(work: (tx: TransactionContext) => Promise<T>, options?: TransactionOptions): Promise<T>;
|
|
124
|
+
/** The attempts `transaction` makes, each on a connection of its own. */
|
|
125
|
+
private runTransactionAttempts;
|
|
126
|
+
/**
|
|
127
|
+
* Get MySQL database capabilities.
|
|
128
|
+
*
|
|
129
|
+
* @remarks
|
|
130
|
+
* MySQL has some limitations:
|
|
131
|
+
* - No JSONB (uses JSON)
|
|
132
|
+
* - No arrays
|
|
133
|
+
* - No native ILIKE
|
|
134
|
+
* - No RETURNING clause
|
|
135
|
+
* - Savepoints disabled for safety
|
|
136
|
+
*/
|
|
137
|
+
getCapabilities(): DatabaseCapabilities;
|
|
138
|
+
/**
|
|
139
|
+
* Build a placeholder for MySQL (uses ? instead of $1, $2, etc.)
|
|
140
|
+
*
|
|
141
|
+
* @param _index - Parameter index (ignored for MySQL)
|
|
142
|
+
* @returns The ? placeholder
|
|
143
|
+
*/
|
|
144
|
+
protected buildPlaceholder(_index: number): string;
|
|
145
|
+
/**
|
|
146
|
+
* Build multiple placeholders for MySQL.
|
|
147
|
+
*
|
|
148
|
+
* @param count - Number of placeholders needed
|
|
149
|
+
* @param _startIndex - Starting index (ignored for MySQL)
|
|
150
|
+
* @returns Comma-separated ? placeholders
|
|
151
|
+
*/
|
|
152
|
+
protected buildPlaceholders(count: number, _startIndex?: number): string;
|
|
153
|
+
/**
|
|
154
|
+
* Escape an identifier for MySQL (uses backticks instead of double quotes).
|
|
155
|
+
*
|
|
156
|
+
* @param identifier - The identifier to escape
|
|
157
|
+
* @returns Escaped identifier with backticks
|
|
158
|
+
*/
|
|
159
|
+
protected escapeIdentifier(identifier: string): string;
|
|
160
|
+
/**
|
|
161
|
+
* Ensures pool is connected and returns it.
|
|
162
|
+
*
|
|
163
|
+
* @throws {DatabaseError} If not connected
|
|
164
|
+
*/
|
|
165
|
+
private ensurePool;
|
|
166
|
+
/**
|
|
167
|
+
* Return the typed Drizzle instance for MySQL.
|
|
168
|
+
* Guarded for server-only usage and requires an active connection.
|
|
169
|
+
*
|
|
170
|
+
* @param schema - Optional schema for relational queries (db.query.*)
|
|
171
|
+
* @returns Drizzle ORM instance wrapping the mysql2 pool connection
|
|
172
|
+
* @throws {Error} If called in browser or not connected
|
|
173
|
+
*/
|
|
174
|
+
getDrizzle<T = MySql2Database<AnyRelations>>(relations?: AnyRelations): T;
|
|
175
|
+
/**
|
|
176
|
+
* A Drizzle handle on the pool, for `getDrizzle`.
|
|
177
|
+
*
|
|
178
|
+
* Its `transaction` runs on a connection this adapter checks out and
|
|
179
|
+
* returns itself (`pinDrizzleTransactions`): destroyed rather than pooled
|
|
180
|
+
* when no ROLLBACK could be confirmed on it. And it counts for
|
|
181
|
+
* `transactionOpenInFlow`, as the adapter's does.
|
|
182
|
+
*/
|
|
183
|
+
private poolDrizzle;
|
|
184
|
+
/**
|
|
185
|
+
* Builds mysql2 Pool configuration from adapter config.
|
|
186
|
+
*/
|
|
187
|
+
private buildPoolConfig;
|
|
188
|
+
/**
|
|
189
|
+
* Begins a transaction with the specified options, recording in `changed`
|
|
190
|
+
* each session setting it changes, as it changes it, for `restoreSession`
|
|
191
|
+
* to put back.
|
|
192
|
+
*/
|
|
193
|
+
private beginTransaction;
|
|
194
|
+
/**
|
|
195
|
+
* Creates a TransactionContext for the given connection.
|
|
196
|
+
*
|
|
197
|
+
* @remarks
|
|
198
|
+
* Note: Savepoint methods are not implemented (set to undefined)
|
|
199
|
+
* as savepoints are disabled in this adapter per approved approach.
|
|
200
|
+
*/
|
|
201
|
+
/**
|
|
202
|
+
* Upsert with the meaning `INSERT … ON CONFLICT (target)` has on PostgreSQL
|
|
203
|
+
* and SQLite, on the tables where MySQL can keep that promise.
|
|
204
|
+
*
|
|
205
|
+
* MySQL cannot limit a duplicate to one key: `ON DUPLICATE KEY UPDATE`
|
|
206
|
+
* fires on a collision with ANY unique key, and a failed insert does not
|
|
207
|
+
* say reliably which one. So the conflict target must be the table's only
|
|
208
|
+
* unique key apart from its primary key, and any other table is refused
|
|
209
|
+
* before anything is written. On such a table the row is inserted first —
|
|
210
|
+
* its validation and triggers apply, as they do before `ON CONFLICT`
|
|
211
|
+
* elsewhere — and a duplicate is resolved by a locking read of the target
|
|
212
|
+
* key, which sees the latest committed row rather than the transaction's
|
|
213
|
+
* snapshot. The row found is kept as it is when there is nothing to update
|
|
214
|
+
* (a no-op assignment would still run its update triggers), or updated by
|
|
215
|
+
* its key. No row there means the collision was on the primary key, and it
|
|
216
|
+
* is refused as `ON CONFLICT (target)` refuses it.
|
|
217
|
+
*
|
|
218
|
+
* The steps run in the caller's transaction, or in one of their own, since a
|
|
219
|
+
* locking read locks nothing past its statement under autocommit. Rows are
|
|
220
|
+
* read back by their primary key, so a trigger that rewrites the conflict
|
|
221
|
+
* value still returns the row stored. The conflict columns must also be
|
|
222
|
+
* given values: MySQL cannot look a row up by a key the database would only
|
|
223
|
+
* fill in itself. A conflict is resolved on the caller's key value: a
|
|
224
|
+
* BEFORE INSERT trigger that moves the key onto another row's value is
|
|
225
|
+
* refused as a unique violation rather than resolved onto that row. A failed insert rolls back only itself on MySQL, so a
|
|
226
|
+
* caller's transaction stays usable.
|
|
227
|
+
*/
|
|
228
|
+
override upsert<T = unknown>(table: string, data: Record<string, unknown>, options: UpsertOptions, executor?: unknown): Promise<T>;
|
|
229
|
+
/**
|
|
230
|
+
* What an upsert is keyed on: the target's condition, and whether its key
|
|
231
|
+
* holds a NULL. Refuses a target this dialect cannot keep to, and a conflict
|
|
232
|
+
* column left for the database to fill — MySQL cannot look a row up by a key
|
|
233
|
+
* value only the database would supply.
|
|
234
|
+
*/
|
|
235
|
+
private upsertTarget;
|
|
236
|
+
/**
|
|
237
|
+
* The table's columns for a conflict target, refusing a target MySQL cannot
|
|
238
|
+
* keep to: one that is not a primary or unique key, which an update could
|
|
239
|
+
* spread over several rows, and one beside which the table has another
|
|
240
|
+
* unique key, a collision on which MySQL would not tell apart.
|
|
241
|
+
*/
|
|
242
|
+
private conflictKey;
|
|
243
|
+
/** The update an upsert applies to an existing row: never its key. */
|
|
244
|
+
private updateValues;
|
|
245
|
+
/** The row matching `where`, by a locking (current) read. */
|
|
246
|
+
private lockedRow;
|
|
247
|
+
/**
|
|
248
|
+
* Insert the row, or resolve a duplicate on the target key. The insert is
|
|
249
|
+
* read back by the primary key it reports, not by the conflict key: a
|
|
250
|
+
* BEFORE INSERT trigger may have rewritten the conflict value, and the row
|
|
251
|
+
* stored is the one to return.
|
|
252
|
+
*
|
|
253
|
+
* A duplicate is resolved when a row holds the TARGET key, whichever unique
|
|
254
|
+
* key MySQL names in its error. PostgreSQL checks the target's index before
|
|
255
|
+
* any other, so a row colliding on the target and on another key resolves
|
|
256
|
+
* on the target there too; refusing it here because MySQL happened to check
|
|
257
|
+
* the other index first would answer that case differently. A target row
|
|
258
|
+
* committed by another transaction after this insert failed is the order in
|
|
259
|
+
* which that transaction ran first, where PostgreSQL also resolves on it.
|
|
260
|
+
*/
|
|
261
|
+
private insertOrResolve;
|
|
262
|
+
/**
|
|
263
|
+
* Insert a row and read it back by its primary key: the value the caller
|
|
264
|
+
* gave, or the one MySQL or the model generated, which `$returningId()`
|
|
265
|
+
* reports and a given value it does not. Undefined when the table has no
|
|
266
|
+
* primary key to read by.
|
|
267
|
+
*/
|
|
268
|
+
private insertRow;
|
|
269
|
+
/**
|
|
270
|
+
* A row's primary key as a condition, from a record keyed as the model's
|
|
271
|
+
* properties are. Undefined when the table has no primary key or the record
|
|
272
|
+
* lacks part of it.
|
|
273
|
+
*/
|
|
274
|
+
private byIdentity;
|
|
275
|
+
/** A table-level `primaryKey({ columns })`, read through the MySQL table config. */
|
|
276
|
+
protected override compositePrimaryKey(tableObj: Record<string, unknown>): object[];
|
|
277
|
+
private createTransactionContext;
|
|
278
|
+
/**
|
|
279
|
+
* Classifies a MySQL error into a DatabaseError.
|
|
280
|
+
*
|
|
281
|
+
* @param error - Original error from mysql2
|
|
282
|
+
* @param sql - SQL statement that caused the error (optional)
|
|
283
|
+
* @returns DatabaseError with proper classification
|
|
284
|
+
*/
|
|
285
|
+
protected override classifyError(error: unknown, sql?: string): DatabaseError;
|
|
231
286
|
}
|
|
232
287
|
/**
|
|
233
288
|
* Create a MySQL database adapter.
|
|
@@ -259,7 +314,7 @@ declare class MySqlAdapter extends DrizzleAdapter {
|
|
|
259
314
|
* await adapter.connect();
|
|
260
315
|
* ```
|
|
261
316
|
*/
|
|
262
|
-
declare function createMySqlAdapter(config: MySqlAdapterConfig): MySqlAdapter;
|
|
317
|
+
export declare function createMySqlAdapter(config: MySqlAdapterConfig): MySqlAdapter;
|
|
263
318
|
/**
|
|
264
319
|
* Type guard to check if a value is a MySqlAdapter.
|
|
265
320
|
*
|
|
@@ -274,6 +329,6 @@ declare function createMySqlAdapter(config: MySqlAdapterConfig): MySqlAdapter;
|
|
|
274
329
|
* }
|
|
275
330
|
* ```
|
|
276
331
|
*/
|
|
277
|
-
declare function isMySqlAdapter(value: unknown): value is MySqlAdapter;
|
|
278
|
-
|
|
279
|
-
|
|
332
|
+
export declare function isMySqlAdapter(value: unknown): value is MySqlAdapter;
|
|
333
|
+
export type { AdapterLogger, BaseAdapterConfig, DatabaseCapabilities, DatabaseError, DatabaseErrorKind, DeleteOptions, InsertOptions, JoinSpec, MySqlAdapterConfig, OrderBySpec, PoolConfig, PoolStats, SelectOptions, SqlParam, SslConfig, TransactionContext, TransactionOptions, UpdateOptions, UpsertOptions, WhereClause, WhereCondition, WhereOperator };
|
|
334
|
+
//# sourceMappingURL=index.d.cts.map
|