@holo-js/db-mysql 0.3.16 → 0.3.17
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/dist/index.d.ts +1 -7
- package/dist/index.mjs +40 -89
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -27,9 +27,7 @@ declare class MySQLAdapter<TConfig extends PoolOptions = PoolOptions> implements
|
|
|
27
27
|
private readonly createPoolInstance?;
|
|
28
28
|
private readonly config;
|
|
29
29
|
private connected;
|
|
30
|
-
private
|
|
31
|
-
private leasedTransactionClient;
|
|
32
|
-
private readonly transactionScope;
|
|
30
|
+
private readonly transactionClients;
|
|
33
31
|
constructor(options?: MySQLAdapterOptions<TConfig>);
|
|
34
32
|
initialize(): Promise<void>;
|
|
35
33
|
isDatabaseMissingError(error: unknown): boolean;
|
|
@@ -47,10 +45,6 @@ declare class MySQLAdapter<TConfig extends PoolOptions = PoolOptions> implements
|
|
|
47
45
|
releaseSavepoint(name: string): Promise<void>;
|
|
48
46
|
private getQueryable;
|
|
49
47
|
ensureDatabaseExists(): Promise<void>;
|
|
50
|
-
private leaseTransactionClient;
|
|
51
|
-
private requireTransactionClient;
|
|
52
|
-
private releaseTransactionClient;
|
|
53
|
-
private releaseScopedTransaction;
|
|
54
48
|
private normalizeSavepointName;
|
|
55
49
|
}
|
|
56
50
|
declare function createMySQLAdapter<TConfig extends PoolOptions = PoolOptions>(options?: MySQLAdapterOptions<TConfig>): MySQLAdapter<TConfig>;
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import {
|
|
2
|
+
import { holoRuntimeInternals } from "@holo-js/db";
|
|
3
3
|
import mysql from "mysql2/promise";
|
|
4
4
|
var TransactionError = class extends Error {
|
|
5
5
|
};
|
|
@@ -63,6 +63,15 @@ function wrapMySQLPool(pool) {
|
|
|
63
63
|
end: rawPool.end.bind(rawPool)
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
+
function createNativeMySQLPool(config) {
|
|
67
|
+
const pool = mysql.createPool({ ...config, timezone: config.timezone ?? "Z" });
|
|
68
|
+
if (!config.timezone || config.timezone === "Z") {
|
|
69
|
+
pool.pool.on("connection", (connection) => {
|
|
70
|
+
connection.query("SET time_zone = '+00:00'");
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return wrapMySQLPool(pool);
|
|
74
|
+
}
|
|
66
75
|
function isMySQLDatabaseMissing(error) {
|
|
67
76
|
return typeof error === "object" && error !== null && ("code" in error && error.code === "ER_BAD_DB_ERROR" || "errno" in error && error.errno === 1049);
|
|
68
77
|
}
|
|
@@ -73,15 +82,27 @@ var MySQLAdapter = class {
|
|
|
73
82
|
createPoolInstance;
|
|
74
83
|
config;
|
|
75
84
|
connected;
|
|
76
|
-
|
|
77
|
-
leasedTransactionClient = false;
|
|
78
|
-
transactionScope = new AsyncLocalStorage();
|
|
85
|
+
transactionClients;
|
|
79
86
|
constructor(options = {}) {
|
|
80
87
|
this.directClient = options.client;
|
|
81
88
|
this.pool = options.pool;
|
|
82
|
-
this.createPoolInstance = options.createPool ?? (options.client || options.pool ? void 0 :
|
|
89
|
+
this.createPoolInstance = options.createPool ?? (options.client || options.pool ? void 0 : createNativeMySQLPool);
|
|
83
90
|
this.config = options.config ?? (options.uri ? { uri: options.uri } : {});
|
|
84
91
|
this.connected = !!(options.client || options.pool);
|
|
92
|
+
this.transactionClients = new holoRuntimeInternals.PooledTransactionClients(
|
|
93
|
+
"MySQL",
|
|
94
|
+
this.directClient,
|
|
95
|
+
async () => {
|
|
96
|
+
await this.initialize();
|
|
97
|
+
if (this.directClient) {
|
|
98
|
+
return this.directClient;
|
|
99
|
+
}
|
|
100
|
+
if (!this.pool) {
|
|
101
|
+
throw new TransactionError("MySQL adapter is not initialized with a pool or client.");
|
|
102
|
+
}
|
|
103
|
+
return this.pool.getConnection();
|
|
104
|
+
}
|
|
105
|
+
);
|
|
85
106
|
}
|
|
86
107
|
async initialize() {
|
|
87
108
|
if (this.connected) {
|
|
@@ -99,11 +120,7 @@ var MySQLAdapter = class {
|
|
|
99
120
|
if (!this.connected) {
|
|
100
121
|
return;
|
|
101
122
|
}
|
|
102
|
-
|
|
103
|
-
this.transactionClient.release?.();
|
|
104
|
-
this.transactionClient = void 0;
|
|
105
|
-
this.leasedTransactionClient = false;
|
|
106
|
-
}
|
|
123
|
+
this.transactionClients.disconnect();
|
|
107
124
|
if (this.pool) {
|
|
108
125
|
await this.pool.end();
|
|
109
126
|
this.pool = void 0;
|
|
@@ -115,30 +132,8 @@ var MySQLAdapter = class {
|
|
|
115
132
|
isConnected() {
|
|
116
133
|
return this.connected;
|
|
117
134
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (active) {
|
|
121
|
-
return callback();
|
|
122
|
-
}
|
|
123
|
-
await this.initialize();
|
|
124
|
-
if (this.directClient) {
|
|
125
|
-
return this.transactionScope.run({
|
|
126
|
-
client: this.directClient
|
|
127
|
-
}, callback);
|
|
128
|
-
}
|
|
129
|
-
if (!this.pool) {
|
|
130
|
-
throw new TransactionError("MySQL adapter is not initialized with a pool or client.");
|
|
131
|
-
}
|
|
132
|
-
const state = {
|
|
133
|
-
client: await this.pool.getConnection()
|
|
134
|
-
};
|
|
135
|
-
return this.transactionScope.run(state, async () => {
|
|
136
|
-
try {
|
|
137
|
-
return await callback();
|
|
138
|
-
} finally {
|
|
139
|
-
this.releaseScopedTransaction(state);
|
|
140
|
-
}
|
|
141
|
-
});
|
|
135
|
+
runWithTransactionScope(callback) {
|
|
136
|
+
return this.transactionClients.run(callback);
|
|
142
137
|
}
|
|
143
138
|
async query(sql, bindings = []) {
|
|
144
139
|
const queryable = await this.getQueryable();
|
|
@@ -162,35 +157,32 @@ var MySQLAdapter = class {
|
|
|
162
157
|
};
|
|
163
158
|
}
|
|
164
159
|
async beginTransaction() {
|
|
165
|
-
const client = await this.
|
|
160
|
+
const client = await this.transactionClients.lease();
|
|
166
161
|
await client.query("START TRANSACTION", []);
|
|
167
162
|
}
|
|
168
163
|
async commit() {
|
|
169
|
-
const client = this.
|
|
164
|
+
const client = this.transactionClients.require();
|
|
170
165
|
await client.query("COMMIT", []);
|
|
171
|
-
this.
|
|
166
|
+
this.transactionClients.release();
|
|
172
167
|
}
|
|
173
168
|
async rollback() {
|
|
174
|
-
const client = this.
|
|
169
|
+
const client = this.transactionClients.require();
|
|
175
170
|
await client.query("ROLLBACK", []);
|
|
176
|
-
this.
|
|
171
|
+
this.transactionClients.release();
|
|
177
172
|
}
|
|
178
173
|
async createSavepoint(name) {
|
|
179
|
-
await this.
|
|
174
|
+
await this.transactionClients.require().query(`SAVEPOINT ${this.normalizeSavepointName(name)}`, []);
|
|
180
175
|
}
|
|
181
176
|
async rollbackToSavepoint(name) {
|
|
182
|
-
await this.
|
|
177
|
+
await this.transactionClients.require().query(`ROLLBACK TO SAVEPOINT ${this.normalizeSavepointName(name)}`, []);
|
|
183
178
|
}
|
|
184
179
|
async releaseSavepoint(name) {
|
|
185
|
-
await this.
|
|
180
|
+
await this.transactionClients.require().query(`RELEASE SAVEPOINT ${this.normalizeSavepointName(name)}`, []);
|
|
186
181
|
}
|
|
187
182
|
async getQueryable() {
|
|
188
|
-
const
|
|
189
|
-
if (
|
|
190
|
-
return
|
|
191
|
-
}
|
|
192
|
-
if (this.transactionClient) {
|
|
193
|
-
return this.transactionClient;
|
|
183
|
+
const active = this.transactionClients.current;
|
|
184
|
+
if (active) {
|
|
185
|
+
return active;
|
|
194
186
|
}
|
|
195
187
|
await this.initialize();
|
|
196
188
|
if (this.directClient) {
|
|
@@ -228,47 +220,6 @@ var MySQLAdapter = class {
|
|
|
228
220
|
await bootstrapPool.end();
|
|
229
221
|
}
|
|
230
222
|
}
|
|
231
|
-
async leaseTransactionClient() {
|
|
232
|
-
const scoped = this.transactionScope.getStore();
|
|
233
|
-
if (scoped) {
|
|
234
|
-
return scoped.client;
|
|
235
|
-
}
|
|
236
|
-
if (this.transactionClient) {
|
|
237
|
-
return this.transactionClient;
|
|
238
|
-
}
|
|
239
|
-
await this.initialize();
|
|
240
|
-
if (this.directClient) {
|
|
241
|
-
this.transactionClient = this.directClient;
|
|
242
|
-
this.leasedTransactionClient = false;
|
|
243
|
-
return this.transactionClient;
|
|
244
|
-
}
|
|
245
|
-
if (!this.pool) {
|
|
246
|
-
throw new TransactionError("MySQL adapter is not initialized with a pool or client.");
|
|
247
|
-
}
|
|
248
|
-
this.transactionClient = await this.pool.getConnection();
|
|
249
|
-
this.leasedTransactionClient = true;
|
|
250
|
-
return this.transactionClient;
|
|
251
|
-
}
|
|
252
|
-
requireTransactionClient() {
|
|
253
|
-
const scoped = this.transactionScope.getStore();
|
|
254
|
-
if (scoped) {
|
|
255
|
-
return scoped.client;
|
|
256
|
-
}
|
|
257
|
-
if (!this.transactionClient) {
|
|
258
|
-
throw new TransactionError("No active MySQL transaction client is available.");
|
|
259
|
-
}
|
|
260
|
-
return this.transactionClient;
|
|
261
|
-
}
|
|
262
|
-
releaseTransactionClient() {
|
|
263
|
-
if (this.transactionClient && this.leasedTransactionClient) {
|
|
264
|
-
this.transactionClient.release?.();
|
|
265
|
-
}
|
|
266
|
-
this.transactionClient = void 0;
|
|
267
|
-
this.leasedTransactionClient = false;
|
|
268
|
-
}
|
|
269
|
-
releaseScopedTransaction(state) {
|
|
270
|
-
state.client.release?.();
|
|
271
|
-
}
|
|
272
223
|
normalizeSavepointName(name) {
|
|
273
224
|
if (!/^[A-Z_]\w*$/i.test(name)) {
|
|
274
225
|
throw new TransactionError(`Invalid savepoint name "${name}".`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holo-js/db-mysql",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.17",
|
|
4
4
|
"description": "Holo-JS Framework - MySQL database adapter",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
"test:integration": "HOLO_MYSQL_INTEGRATION=1 vitest --run tests/mysql.test.ts"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"@holo-js/db": "^0.3.
|
|
27
|
+
"@holo-js/db": "^0.3.17"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"mysql2": "^3.17.1"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@holo-js/db": "^0.3.
|
|
33
|
+
"@holo-js/db": "^0.3.17",
|
|
34
34
|
"tsup": "^8.3.5",
|
|
35
35
|
"typescript": "^5.7.2",
|
|
36
36
|
"vitest": "^4.1.5"
|