@benjosivo/mysql 1.0.4 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,6 +51,34 @@ executeMySQLQuery(query, values?, returnFieldTypes?, connKey?)
51
51
 
52
52
  Returns the rows directly on success. On failure it returns `{ error, values, connKey }` instead of throwing (matches `mysql2`'s row-result shape so existing call sites don't need try/catch).
53
53
 
54
+ ### Statements prepared statements can't run
55
+
56
+ `executeMySQLQuery` uses `execute()` (MySQL's prepared-statement protocol), and MySQL rejects a
57
+ number of statements there with *"This command is not supported in the prepared statement protocol
58
+ yet"* — `SET GLOBAL ...`, `USE ...`, `LOCK TABLES`, several `SHOW` variants, and so on. For those,
59
+ use `runMySQLQuery`, which goes through `query()` (text protocol) instead:
60
+
61
+ ```ts
62
+ import { runMySQLQuery } from '@benjosivo/mysql';
63
+
64
+ await runMySQLQuery("SET GLOBAL general_log = 'OFF'");
65
+
66
+ // placeholders still work — mysql2 escapes and interpolates them client-side
67
+ await runMySQLQuery('SET GLOBAL general_log = ?', ['OFF']);
68
+
69
+ // optionally run inside an existing transaction
70
+ await runMySQLQuery('SELECT * FROM users WHERE id = ?', [userId], connKey);
71
+ ```
72
+
73
+ ```ts
74
+ runMySQLQuery(query, values?, connKey?)
75
+ ```
76
+
77
+ Same result shape as `executeMySQLQuery`: rows on success, `{ error, values, connKey }` on failure.
78
+ It's deliberately simple — no deadlock/lock-timeout retry — so prefer `executeMySQLQuery` for
79
+ regular application queries and keep this one for statements the prepared-statement protocol
80
+ refuses.
81
+
54
82
  ### Transactions
55
83
 
56
84
  ```ts
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import mysql from 'mysql2/promise';
1
2
  export interface MySQLClientConfig {
2
3
  host: string;
3
4
  user: string;
@@ -24,6 +25,27 @@ export declare function executeMySQLQuery2(opt: {
24
25
  returnFieldTypes?: boolean;
25
26
  returnListTables?: boolean | string;
26
27
  }): Promise<any>;
28
+ /**
29
+ * Runs a statement through mysql2's `query()` (text protocol) instead of `execute()`
30
+ * (prepared-statement protocol).
31
+ *
32
+ * MySQL refuses a number of statements in the prepared-statement protocol
33
+ * ("This command is not supported in the prepared statement protocol yet") —
34
+ * `SET GLOBAL ...`, `USE ...`, `LOCK TABLES`, several `SHOW` variants, etc.
35
+ * Use this for those; keep using `executeMySQLQuery` for everything else, since
36
+ * that one adds deadlock/lock-timeout retries and prepared statements.
37
+ *
38
+ * Values are escaped and interpolated client-side by mysql2 (`?` placeholders),
39
+ * so parameters are still safe to pass.
40
+ *
41
+ * Returns the rows on success, or `{ error, values, connKey }` on failure —
42
+ * same shape as `executeMySQLQuery`.
43
+ */
44
+ export declare function runMySQLQuery(query: string, values?: any[], connKey?: string): Promise<mysql.RowDataPacket[][] | mysql.OkPacket[] | mysql.ResultSetHeader[] | mysql.RowDataPacket[] | mysql.OkPacket | mysql.ResultSetHeader | {
45
+ error: any;
46
+ values: any[];
47
+ connKey: string | null;
48
+ } | [mysql.RowDataPacket[], mysql.ResultSetHeader]>;
27
49
  export declare function connectionCommit(keyConn: string): Promise<{
28
50
  error?: unknown;
29
51
  }>;
package/dist/index.js CHANGED
@@ -42,6 +42,7 @@ exports.loopKillOpenTRX = loopKillOpenTRX;
42
42
  exports.stopLoopKillOpenTRX = stopLoopKillOpenTRX;
43
43
  exports.executeMySQLQuery = executeMySQLQuery;
44
44
  exports.executeMySQLQuery2 = executeMySQLQuery2;
45
+ exports.runMySQLQuery = runMySQLQuery;
45
46
  exports.connectionCommit = connectionCommit;
46
47
  exports.connectionRollback = connectionRollback;
47
48
  const crypto_1 = require("crypto");
@@ -369,6 +370,49 @@ async function executeMySQLQuery2(opt) {
369
370
  return { error: error?.message ?? error, values, connKey: connKey ?? null };
370
371
  }
371
372
  }
373
+ /**
374
+ * Runs a statement through mysql2's `query()` (text protocol) instead of `execute()`
375
+ * (prepared-statement protocol).
376
+ *
377
+ * MySQL refuses a number of statements in the prepared-statement protocol
378
+ * ("This command is not supported in the prepared statement protocol yet") —
379
+ * `SET GLOBAL ...`, `USE ...`, `LOCK TABLES`, several `SHOW` variants, etc.
380
+ * Use this for those; keep using `executeMySQLQuery` for everything else, since
381
+ * that one adds deadlock/lock-timeout retries and prepared statements.
382
+ *
383
+ * Values are escaped and interpolated client-side by mysql2 (`?` placeholders),
384
+ * so parameters are still safe to pass.
385
+ *
386
+ * Returns the rows on success, or `{ error, values, connKey }` on failure —
387
+ * same shape as `executeMySQLQuery`.
388
+ */
389
+ async function runMySQLQuery(query, values = [], connKey) {
390
+ requireConfig();
391
+ let conn;
392
+ try {
393
+ if (connKey) {
394
+ const tr = listTransaction.get(connKey);
395
+ if (!tr) {
396
+ const msg = `Transaction key not found: ${connKey}`;
397
+ handleError(msg, 'MySQL: runMySQLQuery');
398
+ return { error: msg, values, connKey };
399
+ }
400
+ tr.lastUpdate = Date.now();
401
+ conn = tr.conn;
402
+ }
403
+ else if (lastConnectionCheck + 5 * 60000 <= Date.now()) {
404
+ await ensurePool();
405
+ }
406
+ const [rows] = await (conn ?? requirePool()).query(query, values);
407
+ return rows;
408
+ }
409
+ catch (error) {
410
+ const errorMsg = String(error?.message ?? error);
411
+ const queryStr = query.length > 200 ? `${query.substring(0, 200)}...` : query;
412
+ handleError(error, `MySQL${error?.code ? ` [${error.code}]` : ''}${connKey ? ' (using connection)' : ''}\n${errorMsg}\n\nparams: ${values}\n\nquery: ${queryStr}`);
413
+ return { error: error?.message ?? error, values, connKey: connKey ?? null };
414
+ }
415
+ }
372
416
  async function createTransaction() {
373
417
  const keyConn = (0, crypto_1.randomUUID)();
374
418
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@benjosivo/mysql",
3
- "version": "1.0.4",
3
+ "version": "1.2.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -18,5 +18,9 @@
18
18
  "@types/node": "^26.1.2",
19
19
  "typescript": "^7.0.2"
20
20
  },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/benjosivo/mysql.git"
24
+ },
21
25
  "license": "MIT"
22
26
  }