@naturalcycles/mysql-lib 3.15.0 → 3.16.0

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.
@@ -1,4 +1,4 @@
1
- import { DBPatch, BaseCommonDB, CommonDB, CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, DBQuery, RunQueryResult, CommonDBSupport, CommonDBType } from '@naturalcycles/db-lib';
1
+ import { BaseCommonDB, CommonDB, CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBSupport, CommonDBType, DBQuery, RunQueryResult } from '@naturalcycles/db-lib';
2
2
  import { CommonLogger, JsonSchemaObject, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib';
3
3
  import { ReadableTyped } from '@naturalcycles/nodejs-lib';
4
4
  import { Connection, Pool, PoolConfig, PoolConnection, QueryOptions } from 'mysql';
@@ -68,5 +68,5 @@ export declare class MysqlDB extends BaseCommonDB implements CommonDB {
68
68
  createTable<ROW extends ObjectWithId>(table: string, schema: JsonSchemaObject<ROW>, opt?: CommonDBCreateOptions): Promise<void>;
69
69
  getTables(): Promise<string[]>;
70
70
  getTableSchema<ROW extends ObjectWithId>(table: string): Promise<JsonSchemaRootObject<ROW>>;
71
- updateByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, patch: DBPatch<ROW>): Promise<number>;
71
+ patchByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, patch: Partial<ROW>): Promise<number>;
72
72
  }
package/dist/mysql.db.js CHANGED
@@ -37,8 +37,9 @@ class MysqlDB extends db_lib_1.BaseCommonDB {
37
37
  this.dbType = db_lib_1.CommonDBType.relational;
38
38
  this.support = {
39
39
  ...db_lib_1.commonDBFullSupport,
40
- updateSaveMethod: false,
41
- transactions: false,
40
+ updateSaveMethod: false, // todo: can be implemented
41
+ transactions: false, // todo: can be implemented
42
+ increment: false, // todo: can be implemented
42
43
  };
43
44
  this.cfg = {
44
45
  typeCast,
@@ -157,7 +158,7 @@ class MysqlDB extends db_lib_1.BaseCommonDB {
157
158
  .split(';')
158
159
  .map(s => s.trim())
159
160
  .filter(Boolean);
160
- for await (const sql of queries) {
161
+ for (const sql of queries) {
161
162
  await this.runSQL({ sql });
162
163
  }
163
164
  }
@@ -191,12 +192,12 @@ class MysqlDB extends db_lib_1.BaseCommonDB {
191
192
  if (opt.assignGeneratedIds) {
192
193
  // Insert rows one-by-one, to get their auto-generated id
193
194
  let i = -1;
194
- for await (const row of rows) {
195
+ for (const row of rows) {
195
196
  i++;
196
197
  if (row.id) {
197
198
  // Update already existing
198
199
  const query = new db_lib_1.DBQuery(table).filterEq('id', row.id);
199
- await this.updateByQuery(query, (0, js_lib_1._omit)(row, ['id']));
200
+ await this.patchByQuery(query, (0, js_lib_1._omit)(row, ['id']));
200
201
  }
201
202
  else {
202
203
  // Create new
@@ -210,18 +211,18 @@ class MysqlDB extends db_lib_1.BaseCommonDB {
210
211
  }
211
212
  if (opt.saveMethod === 'update') {
212
213
  // TODO: This fails if a combination of entities with id and without id are parsed
213
- for await (const row of rows) {
214
+ for (const row of rows) {
214
215
  // Update already existing
215
216
  (0, js_lib_1._assert)(row.id, 'id is required for updating');
216
217
  const query = new db_lib_1.DBQuery(table).filterEq('id', row.id);
217
- await this.updateByQuery(query, (0, js_lib_1._omit)(row, ['id']));
218
+ await this.patchByQuery(query, (0, js_lib_1._omit)(row, ['id']));
218
219
  }
219
220
  return;
220
221
  }
221
222
  const verb = opt.saveMethod === 'insert' ? 'INSERT' : 'REPLACE';
222
223
  // inserts are split into multiple sentenses to respect the max_packet_size (1Mb usually)
223
224
  const sqls = (0, query_util_1.insertSQL)(table, rows, verb, this.cfg.logger);
224
- for await (const sql of sqls) {
225
+ for (const sql of sqls) {
225
226
  await this.runSQL({ sql });
226
227
  }
227
228
  }
@@ -271,7 +272,7 @@ class MysqlDB extends db_lib_1.BaseCommonDB {
271
272
  });
272
273
  return (0, mysql_schema_util_1.mysqlTableStatsToJsonSchemaField)(table, stats, this.cfg.logger);
273
274
  }
274
- async updateByQuery(q, patch) {
275
+ async patchByQuery(q, patch) {
275
276
  const sql = (0, query_util_1.dbQueryToSQLUpdate)(q, patch);
276
277
  if (!sql)
277
278
  return 0;
@@ -1,10 +1,15 @@
1
1
  import { CommonDBCreateOptions, CommonKeyValueDB, KeyValueDBTuple } from '@naturalcycles/db-lib';
2
+ import { StringMap } from '@naturalcycles/js-lib';
2
3
  import { ReadableTyped } from '@naturalcycles/nodejs-lib';
3
4
  import { MysqlDB, MysqlDBCfg } from './mysql.db';
4
5
  export declare class MySQLKeyValueDB implements CommonKeyValueDB {
5
6
  cfg: MysqlDBCfg;
6
7
  constructor(cfg: MysqlDBCfg);
7
8
  db: MysqlDB;
9
+ support: {
10
+ increment: boolean;
11
+ count?: boolean;
12
+ };
8
13
  ping(): Promise<void>;
9
14
  close(): Promise<void>;
10
15
  createTable(table: string, opt?: CommonDBCreateOptions): Promise<void>;
@@ -22,4 +27,5 @@ export declare class MySQLKeyValueDB implements CommonKeyValueDB {
22
27
  endTransaction(): Promise<void>;
23
28
  count(table: string): Promise<number>;
24
29
  increment(_table: string, _id: string, _by?: number): Promise<number>;
30
+ incrementBatch(_table: string, _incrementMap: StringMap<number>): Promise<StringMap<number>>;
25
31
  }
@@ -1,11 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MySQLKeyValueDB = void 0;
4
+ const db_lib_1 = require("@naturalcycles/db-lib");
4
5
  const js_lib_1 = require("@naturalcycles/js-lib");
5
6
  const mysql_db_1 = require("./mysql.db");
6
7
  class MySQLKeyValueDB {
7
8
  constructor(cfg) {
8
9
  this.cfg = cfg;
10
+ this.support = {
11
+ ...db_lib_1.commonKeyValueDBFullSupport,
12
+ increment: false,
13
+ };
9
14
  this.db = new mysql_db_1.MysqlDB(this.cfg);
10
15
  }
11
16
  async ping() {
@@ -99,5 +104,8 @@ class MySQLKeyValueDB {
99
104
  async increment(_table, _id, _by) {
100
105
  throw new js_lib_1.AppError('MySQLKeyValueDB.increment() is not implemented');
101
106
  }
107
+ async incrementBatch(_table, _incrementMap) {
108
+ throw new js_lib_1.AppError('MySQLKeyValueDB.incrementBatch() is not implemented');
109
+ }
102
110
  }
103
111
  exports.MySQLKeyValueDB = MySQLKeyValueDB;
@@ -16,4 +16,4 @@ export declare function dbQueryToSQLDelete(q: DBQuery<any>): string | null;
16
16
  export declare function insertSQL(table: string, rows: Record<any, any>[], verb?: 'INSERT' | 'REPLACE', logger?: CommonLogger): string[];
17
17
  export declare function insertSQLSingle(table: string, record: Record<any, any>): string;
18
18
  export declare function insertSQLSetSingle(table: string, record: Record<any, any>): QueryOptions;
19
- export declare function dbQueryToSQLUpdate(q: DBQuery<any>, record: Record<any, any>): string | null;
19
+ export declare function dbQueryToSQLUpdate(q: DBQuery<any>, patch: Record<any, any>): string | null;
@@ -118,7 +118,7 @@ function insertSQLSetSingle(table, record) {
118
118
  values: [record],
119
119
  };
120
120
  }
121
- function dbQueryToSQLUpdate(q, record) {
121
+ function dbQueryToSQLUpdate(q, patch) {
122
122
  // var sql = mysql.format('UPDATE posts SET modified = ? WHERE id = ?', [CURRENT_TIMESTAMP, 42]);
123
123
  const whereTokens = getWhereTokens(q);
124
124
  if (!whereTokens)
@@ -127,12 +127,12 @@ function dbQueryToSQLUpdate(q, record) {
127
127
  `UPDATE`,
128
128
  mysql.escapeId(q.table),
129
129
  `SET`,
130
- Object.keys(record)
130
+ Object.keys(patch)
131
131
  .map(f => mysql.escapeId((0, mysql_schema_util_1.mapNameToMySQL)(f)) + ' = ?')
132
132
  .join(', '),
133
133
  ...whereTokens,
134
134
  ];
135
- return mysql.format(tokens.join(' '), Object.values(record));
135
+ return mysql.format(tokens.join(' '), Object.values(patch));
136
136
  }
137
137
  function selectTokens(q) {
138
138
  let fields = ['*'];
package/package.json CHANGED
@@ -1,7 +1,12 @@
1
1
  {
2
2
  "name": "@naturalcycles/mysql-lib",
3
3
  "scripts": {
4
- "prepare": "husky"
4
+ "prepare": "husky",
5
+ "build": "dev-lib build",
6
+ "test": "dev-lib test",
7
+ "lint": "dev-lib lint",
8
+ "bt": "dev-lib bt",
9
+ "lbt": "dev-lib lbt"
5
10
  },
6
11
  "dependencies": {
7
12
  "@naturalcycles/db-lib": "^9.1.0",
@@ -12,7 +17,7 @@
12
17
  },
13
18
  "devDependencies": {
14
19
  "@naturalcycles/dev-lib": "^15.18.0",
15
- "@types/node": "^20.2.3",
20
+ "@types/node": "^22.7.4",
16
21
  "dotenv": "^16.0.0",
17
22
  "jest": "^29.0.0"
18
23
  },
@@ -34,9 +39,9 @@
34
39
  "url": "https://github.com/NaturalCycles/mysql-lib"
35
40
  },
36
41
  "engines": {
37
- "node": ">=18.12.0"
42
+ "node": ">=20.13.0"
38
43
  },
39
- "version": "3.15.0",
44
+ "version": "3.16.0",
40
45
  "description": "MySQL client implementing CommonDB interface",
41
46
  "keywords": [
42
47
  "mysql",
package/src/mysql.db.ts CHANGED
@@ -1,17 +1,16 @@
1
1
  import { Readable } from 'node:stream'
2
2
  import { promisify } from 'node:util'
3
3
  import {
4
- DBPatch,
5
4
  BaseCommonDB,
6
5
  CommonDB,
7
6
  CommonDBCreateOptions,
7
+ commonDBFullSupport,
8
8
  CommonDBOptions,
9
9
  CommonDBSaveOptions,
10
- DBQuery,
11
- RunQueryResult,
12
10
  CommonDBSupport,
13
- commonDBFullSupport,
14
11
  CommonDBType,
12
+ DBQuery,
13
+ RunQueryResult,
15
14
  } from '@naturalcycles/db-lib'
16
15
  import {
17
16
  _assert,
@@ -96,8 +95,9 @@ export class MysqlDB extends BaseCommonDB implements CommonDB {
96
95
 
97
96
  override support: CommonDBSupport = {
98
97
  ...commonDBFullSupport,
99
- updateSaveMethod: false,
100
- transactions: false,
98
+ updateSaveMethod: false, // todo: can be implemented
99
+ transactions: false, // todo: can be implemented
100
+ increment: false, // todo: can be implemented
101
101
  }
102
102
 
103
103
  constructor(cfg: MysqlDBCfg = {}) {
@@ -253,7 +253,7 @@ export class MysqlDB extends BaseCommonDB implements CommonDB {
253
253
  .map(s => s.trim())
254
254
  .filter(Boolean)
255
255
 
256
- for await (const sql of queries) {
256
+ for (const sql of queries) {
257
257
  await this.runSQL({ sql })
258
258
  }
259
259
  }
@@ -310,12 +310,12 @@ export class MysqlDB extends BaseCommonDB implements CommonDB {
310
310
  // Insert rows one-by-one, to get their auto-generated id
311
311
 
312
312
  let i = -1
313
- for await (const row of rows) {
313
+ for (const row of rows) {
314
314
  i++
315
315
  if (row.id) {
316
316
  // Update already existing
317
317
  const query = new DBQuery(table).filterEq('id', row.id)
318
- await this.updateByQuery(query, _omit(row, ['id']))
318
+ await this.patchByQuery(query, _omit(row, ['id']))
319
319
  } else {
320
320
  // Create new
321
321
  const sql = insertSQL(table, [row], 'INSERT', this.cfg.logger)[0]!
@@ -331,11 +331,11 @@ export class MysqlDB extends BaseCommonDB implements CommonDB {
331
331
 
332
332
  if (opt.saveMethod === 'update') {
333
333
  // TODO: This fails if a combination of entities with id and without id are parsed
334
- for await (const row of rows) {
334
+ for (const row of rows) {
335
335
  // Update already existing
336
336
  _assert(row.id, 'id is required for updating')
337
337
  const query = new DBQuery(table).filterEq('id', row.id)
338
- await this.updateByQuery(query, _omit(row, ['id']))
338
+ await this.patchByQuery(query, _omit(row, ['id']))
339
339
  }
340
340
  return
341
341
  }
@@ -344,7 +344,7 @@ export class MysqlDB extends BaseCommonDB implements CommonDB {
344
344
  // inserts are split into multiple sentenses to respect the max_packet_size (1Mb usually)
345
345
  const sqls = insertSQL(table, rows, verb, this.cfg.logger)
346
346
 
347
- for await (const sql of sqls) {
347
+ for (const sql of sqls) {
348
348
  await this.runSQL({ sql })
349
349
  }
350
350
  }
@@ -409,9 +409,9 @@ export class MysqlDB extends BaseCommonDB implements CommonDB {
409
409
  return mysqlTableStatsToJsonSchemaField<ROW>(table, stats, this.cfg.logger)
410
410
  }
411
411
 
412
- override async updateByQuery<ROW extends ObjectWithId>(
412
+ override async patchByQuery<ROW extends ObjectWithId>(
413
413
  q: DBQuery<ROW>,
414
- patch: DBPatch<ROW>,
414
+ patch: Partial<ROW>,
415
415
  ): Promise<number> {
416
416
  const sql = dbQueryToSQLUpdate(q, patch)
417
417
  if (!sql) return 0
@@ -1,5 +1,10 @@
1
- import { CommonDBCreateOptions, CommonKeyValueDB, KeyValueDBTuple } from '@naturalcycles/db-lib'
2
- import { AppError, ObjectWithId, pMap } from '@naturalcycles/js-lib'
1
+ import {
2
+ CommonDBCreateOptions,
3
+ CommonKeyValueDB,
4
+ commonKeyValueDBFullSupport,
5
+ KeyValueDBTuple,
6
+ } from '@naturalcycles/db-lib'
7
+ import { AppError, ObjectWithId, pMap, StringMap } from '@naturalcycles/js-lib'
3
8
  import { ReadableTyped } from '@naturalcycles/nodejs-lib'
4
9
  import { QueryOptions } from 'mysql'
5
10
  import { MysqlDB, MysqlDBCfg } from './mysql.db'
@@ -16,6 +21,11 @@ export class MySQLKeyValueDB implements CommonKeyValueDB {
16
21
 
17
22
  db: MysqlDB
18
23
 
24
+ support = {
25
+ ...commonKeyValueDBFullSupport,
26
+ increment: false,
27
+ }
28
+
19
29
  async ping(): Promise<void> {
20
30
  await this.db.ping()
21
31
  }
@@ -118,4 +128,11 @@ export class MySQLKeyValueDB implements CommonKeyValueDB {
118
128
  async increment(_table: string, _id: string, _by?: number): Promise<number> {
119
129
  throw new AppError('MySQLKeyValueDB.increment() is not implemented')
120
130
  }
131
+
132
+ async incrementBatch(
133
+ _table: string,
134
+ _incrementMap: StringMap<number>,
135
+ ): Promise<StringMap<number>> {
136
+ throw new AppError('MySQLKeyValueDB.incrementBatch() is not implemented')
137
+ }
121
138
  }
package/src/query.util.ts CHANGED
@@ -142,7 +142,7 @@ export function insertSQLSetSingle(table: string, record: Record<any, any>): Que
142
142
  }
143
143
  }
144
144
 
145
- export function dbQueryToSQLUpdate(q: DBQuery<any>, record: Record<any, any>): string | null {
145
+ export function dbQueryToSQLUpdate(q: DBQuery<any>, patch: Record<any, any>): string | null {
146
146
  // var sql = mysql.format('UPDATE posts SET modified = ? WHERE id = ?', [CURRENT_TIMESTAMP, 42]);
147
147
  const whereTokens = getWhereTokens(q)
148
148
  if (!whereTokens) return null
@@ -151,13 +151,13 @@ export function dbQueryToSQLUpdate(q: DBQuery<any>, record: Record<any, any>): s
151
151
  `UPDATE`,
152
152
  mysql.escapeId(q.table),
153
153
  `SET`,
154
- Object.keys(record)
154
+ Object.keys(patch)
155
155
  .map(f => mysql.escapeId(mapNameToMySQL(f)) + ' = ?')
156
156
  .join(', '),
157
157
  ...whereTokens,
158
158
  ]
159
159
 
160
- return mysql.format(tokens.join(' '), Object.values(record))
160
+ return mysql.format(tokens.join(' '), Object.values(patch))
161
161
  }
162
162
 
163
163
  function selectTokens(q: DBQuery<any>): string[] {
@@ -39,7 +39,7 @@ export function jsonSchemaToMySQLDDL(
39
39
  return `id VARCHAR(255) NOT NULL`
40
40
  }
41
41
 
42
- let type
42
+ let type: string
43
43
 
44
44
  if (s.type === 'string') {
45
45
  // can specify isoDate later