@naturalcycles/mysql-lib 3.7.1 → 3.9.1

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/dbAdapter.js CHANGED
@@ -7,4 +7,3 @@ function getDBAdapter(cfgStr = '{}') {
7
7
  return new mysql_db_1.MysqlDB(cfg);
8
8
  }
9
9
  exports.getDBAdapter = getDBAdapter;
10
- //# sourceMappingURL=dbAdapter.js.map
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { getDBAdapter } from './dbAdapter';
2
2
  import { MysqlDB, MysqlDBCfg, MysqlDBOptions, MysqlDBSaveOptions } from './mysql.db';
3
- import { commonSchemaToMySQLDDL } from './schema/mysql.schema.util';
4
- export { MysqlDB, MysqlDBCfg, MysqlDBOptions, MysqlDBSaveOptions, commonSchemaToMySQLDDL, getDBAdapter, };
3
+ import { jsonSchemaToMySQLDDL } from './schema/mysql.schema.util';
4
+ export type { MysqlDBCfg, MysqlDBOptions, MysqlDBSaveOptions };
5
+ export { MysqlDB, jsonSchemaToMySQLDDL, getDBAdapter };
package/dist/index.js CHANGED
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getDBAdapter = exports.commonSchemaToMySQLDDL = exports.MysqlDB = void 0;
3
+ exports.getDBAdapter = exports.jsonSchemaToMySQLDDL = exports.MysqlDB = void 0;
4
4
  const dbAdapter_1 = require("./dbAdapter");
5
5
  Object.defineProperty(exports, "getDBAdapter", { enumerable: true, get: function () { return dbAdapter_1.getDBAdapter; } });
6
6
  const mysql_db_1 = require("./mysql.db");
7
7
  Object.defineProperty(exports, "MysqlDB", { enumerable: true, get: function () { return mysql_db_1.MysqlDB; } });
8
8
  const mysql_schema_util_1 = require("./schema/mysql.schema.util");
9
- Object.defineProperty(exports, "commonSchemaToMySQLDDL", { enumerable: true, get: function () { return mysql_schema_util_1.commonSchemaToMySQLDDL; } });
10
- //# sourceMappingURL=index.js.map
9
+ Object.defineProperty(exports, "jsonSchemaToMySQLDDL", { enumerable: true, get: function () { return mysql_schema_util_1.jsonSchemaToMySQLDDL; } });
@@ -1,9 +1,10 @@
1
- import { BaseCommonDB, BaseDBEntity, CommonDB, CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, CommonSchema, DBQuery, ObjectWithId, RunQueryResult } from '@naturalcycles/db-lib';
1
+ import { BaseCommonDB, CommonDB, CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, DBQuery, RunQueryResult } from '@naturalcycles/db-lib';
2
+ import { AnyObjectWithId, CommonLogger, JsonSchemaObject, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib';
2
3
  import { ReadableTyped } from '@naturalcycles/nodejs-lib';
3
4
  import { Connection, Pool, PoolConfig, PoolConnection, QueryOptions } from 'mysql';
4
5
  export interface MysqlDBOptions extends CommonDBOptions {
5
6
  }
6
- export interface MysqlDBSaveOptions extends CommonDBSaveOptions {
7
+ export interface MysqlDBSaveOptions<ROW extends ObjectWithId = AnyObjectWithId> extends CommonDBSaveOptions<ROW> {
7
8
  }
8
9
  /**
9
10
  * @default false / undefined
@@ -17,10 +18,16 @@ export interface MysqlDBCfg extends PoolConfig {
17
18
  * If true - will emit logs of connection events.
18
19
  */
19
20
  debugConnections?: boolean;
21
+ /**
22
+ * Default to `console`
23
+ */
24
+ logger?: CommonLogger;
20
25
  }
21
26
  export declare class MysqlDB extends BaseCommonDB implements CommonDB {
22
27
  constructor(cfg?: MysqlDBCfg);
23
- cfg: MysqlDBCfg;
28
+ cfg: MysqlDBCfg & {
29
+ logger: CommonLogger;
30
+ };
24
31
  ping(): Promise<void>;
25
32
  pool(): Pool;
26
33
  close(): Promise<void>;
@@ -34,16 +41,16 @@ export declare class MysqlDB extends BaseCommonDB implements CommonDB {
34
41
  */
35
42
  createSingleConnection(): Promise<Connection>;
36
43
  getByIds<ROW extends ObjectWithId>(table: string, ids: string[], opt?: MysqlDBOptions): Promise<ROW[]>;
37
- runQuery<ROW extends ObjectWithId, OUT = ROW>(q: DBQuery<ROW>, opt?: MysqlDBOptions): Promise<RunQueryResult<OUT>>;
44
+ runQuery<ROW extends ObjectWithId, OUT = ROW>(q: DBQuery<ROW>, _opt?: MysqlDBOptions): Promise<RunQueryResult<OUT>>;
38
45
  runSQL<RESULT>(q: QueryOptions): Promise<RESULT>;
39
- runQueryCount<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions): Promise<number>;
40
- streamQuery<ROW extends ObjectWithId, OUT = ROW>(q: DBQuery<ROW>, opt?: MysqlDBOptions): ReadableTyped<OUT>;
41
- saveBatch<ROW extends BaseDBEntity>(table: string, _rows: ROW[], opt?: MysqlDBSaveOptions): Promise<void>;
46
+ runQueryCount<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
47
+ streamQuery<ROW extends ObjectWithId, OUT = ROW>(q: DBQuery<ROW>, _opt?: MysqlDBOptions): ReadableTyped<OUT>;
48
+ saveBatch<ROW extends ObjectWithId>(table: string, _rows: ROW[], _opt?: MysqlDBSaveOptions<ROW>): Promise<void>;
42
49
  /**
43
50
  * Limitation: always returns [], regardless of which rows are actually deleted
44
51
  */
45
- deleteByIds(table: string, ids: string[], opt?: MysqlDBOptions): Promise<number>;
46
- deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions): Promise<number>;
52
+ deleteByIds(table: string, ids: string[], _opt?: MysqlDBOptions): Promise<number>;
53
+ deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
47
54
  /**
48
55
  * Use with caution!
49
56
  */
@@ -51,7 +58,7 @@ export declare class MysqlDB extends BaseCommonDB implements CommonDB {
51
58
  /**
52
59
  * dropIfExists=true needed as a safety check
53
60
  */
54
- createTable(schema: CommonSchema, opt?: CommonDBCreateOptions): Promise<void>;
61
+ createTable<ROW extends ObjectWithId>(table: string, schema: JsonSchemaObject<ROW>, opt?: CommonDBCreateOptions): Promise<void>;
55
62
  getTables(): Promise<string[]>;
56
- getTableSchema<ROW extends ObjectWithId>(table: string): Promise<CommonSchema<ROW>>;
63
+ getTableSchema<ROW extends ObjectWithId>(table: string): Promise<JsonSchemaRootObject<ROW>>;
57
64
  }
package/dist/mysql.db.js CHANGED
@@ -2,16 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MysqlDB = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const stream_1 = require("stream");
6
+ const util_1 = require("util");
5
7
  const db_lib_1 = require("@naturalcycles/db-lib");
6
8
  const js_lib_1 = require("@naturalcycles/js-lib");
7
- const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
8
9
  const colors_1 = require("@naturalcycles/nodejs-lib/dist/colors");
9
10
  const mysql = require("mysql");
10
- const stream_1 = require("stream");
11
- const util_1 = require("util");
12
11
  const query_util_1 = require("./query.util");
13
12
  const mysql_schema_util_1 = require("./schema/mysql.schema.util");
14
- const log = nodejs_lib_1.Debug('nc:mysql-lib');
15
13
  const BOOLEAN_TYPES = new Set(['TINY', 'TINYINT', 'INT']);
16
14
  const BOOLEAN_BIT_TYPES = new Set(['BIT']);
17
15
  const typeCast = (field, next) => {
@@ -33,188 +31,184 @@ const typeCast = (field, next) => {
33
31
  }
34
32
  return next();
35
33
  };
36
- let MysqlDB = /** @class */ (() => {
37
- class MysqlDB extends db_lib_1.BaseCommonDB {
38
- constructor(cfg = {}) {
39
- super();
40
- this.cfg = {
41
- typeCast,
42
- // charset: 'utf8mb4', // for emoji support
43
- // host: 'localhost',
44
- // user: MYSQL_USER,
45
- // password: MYSQL_PW,
46
- // database: MYSQL_DB,
47
- ...cfg,
48
- };
49
- }
50
- async ping() {
51
- const con = await this.getConnection();
52
- con.release();
53
- }
54
- pool() {
55
- const pool = mysql.createPool(this.cfg);
56
- const { host, database } = this.cfg;
57
- log(`connected to ${colors_1.white(host + '/' + database)}`);
58
- if (this.cfg.debugConnections) {
59
- pool.on('acquire', con => {
60
- log(`acquire(${con.threadId})`);
61
- });
62
- pool.on('connection', con => {
63
- log(`connection(${con.threadId})`);
64
- });
65
- pool.on('enqueue', () => {
66
- log(`enqueue`);
67
- });
68
- pool.on('release', con => {
69
- log(`release(${con.threadId})`);
70
- });
71
- }
72
- pool.on('error', err => {
73
- log.error(`error`, err);
34
+ class MysqlDB extends db_lib_1.BaseCommonDB {
35
+ constructor(cfg = {}) {
36
+ super();
37
+ this.cfg = {
38
+ typeCast,
39
+ // charset: 'utf8mb4', // for emoji support
40
+ // host: 'localhost',
41
+ // user: MYSQL_USER,
42
+ // password: MYSQL_PW,
43
+ // database: MYSQL_DB,
44
+ ...cfg,
45
+ logger: (0, js_lib_1.commonLoggerPrefix)(cfg.logger || console, '[mysql]'),
46
+ };
47
+ }
48
+ async ping() {
49
+ const con = await this.getConnection();
50
+ con.release();
51
+ }
52
+ pool() {
53
+ const pool = mysql.createPool(this.cfg);
54
+ const { host, database, logger } = this.cfg;
55
+ logger.log(`connected to ${(0, colors_1.white)(host + '/' + database)}`);
56
+ if (this.cfg.debugConnections) {
57
+ pool.on('acquire', con => {
58
+ logger.log(`acquire(${con.threadId})`);
74
59
  });
75
- return pool;
76
- }
77
- async close() {
78
- const pool = this.pool();
79
- await util_1.promisify(pool.end.bind(pool));
80
- }
81
- /**
82
- * Be careful to always call `con.release()` when you get connection with this method.
83
- */
84
- async getConnection() {
85
- const pool = this.pool();
86
- return util_1.promisify(pool.getConnection.bind(pool))();
87
- }
88
- /**
89
- * Manually create a single (not pool) connection.
90
- * Be careful to manage this connection yourself (open, release, etc).
91
- */
92
- async createSingleConnection() {
93
- const con = mysql.createConnection(this.cfg);
94
- await util_1.promisify(con.connect.bind(con))();
95
- const { threadId } = con;
96
- if (this.cfg.debugConnections) {
97
- log(`createSingleConnection(${threadId})`);
98
- con.on('connect', () => log(`createSingleConnection(${threadId}).connect`));
99
- con.on('drain', () => log(`createSingleConnection(${threadId}).drain`));
100
- con.on('enqueue', () => log(`createSingleConnection(${threadId}).enqueue`));
101
- con.on('end', () => log(`createSingleConnection(${threadId}).end`));
102
- }
103
- con.on('error', err => {
104
- log.error(`createSingleConnection(${threadId}).error`, err);
60
+ pool.on('connection', con => {
61
+ logger.log(`connection(${con.threadId})`);
105
62
  });
106
- return con;
107
- }
108
- // GET
109
- async getByIds(table, ids, opt = {}) {
110
- if (!ids.length)
111
- return [];
112
- const q = new db_lib_1.DBQuery(table).filterEq('id', ids);
113
- const { rows } = await this.runQuery(q, opt);
114
- return rows.map(r => js_lib_1._mapKeys(r, (_v, k) => mysql_schema_util_1.mapNameFromMySQL(k)));
115
- }
116
- // QUERY
117
- async runQuery(q, opt = {}) {
118
- const sql = query_util_1.dbQueryToSQLSelect(q);
119
- const rows = await this.runSQL({ sql });
120
- return {
121
- rows: rows.map(r => js_lib_1._mapKeys(js_lib_1._filterUndefinedValues(r, true), (_v, k) => mysql_schema_util_1.mapNameFromMySQL(k))),
122
- };
123
- }
124
- async runSQL(q) {
125
- if (this.cfg.logSQL)
126
- log(q.sql, q.values);
127
- return new Promise(async (resolve, reject) => {
128
- this.pool().query(q, (err, res) => {
129
- if (err)
130
- return reject(err);
131
- resolve(res);
132
- });
63
+ pool.on('enqueue', () => {
64
+ logger.log(`enqueue`);
65
+ });
66
+ pool.on('release', con => {
67
+ logger.log(`release(${con.threadId})`);
133
68
  });
134
69
  }
135
- async runQueryCount(q, opt) {
136
- const { rows } = await this.runQuery(q.select(['count(*) as _count']));
137
- return rows[0]._count;
138
- }
139
- streamQuery(q, opt = {}) {
140
- const sql = query_util_1.dbQueryToSQLSelect(q);
141
- if (this.cfg.logSQL)
142
- log(`stream: ${sql}`);
143
- // return this.streamSQL(sql, opt)
144
- return this.pool()
145
- .query(sql)
146
- .stream()
147
- .pipe(new stream_1.Transform({
148
- objectMode: true,
149
- transform(row, _encoding, cb) {
150
- cb(null, js_lib_1._filterUndefinedValues(row, true));
151
- },
152
- }));
153
- }
154
- // SAVE
155
- async saveBatch(table, _rows, opt) {
156
- if (!_rows.length)
157
- return;
158
- // Stringify object values
159
- const rows = _rows.map(row => js_lib_1._mapValues(row, v => {
160
- return v && typeof v === 'object' && !Buffer.isBuffer(v) ? JSON.stringify(v) : v;
161
- }));
162
- // inserts are split into multiple sentenses to respect the max_packet_size (1Mb usually)
163
- const sqls = query_util_1.insertSQL(table, rows);
164
- for await (const sql of sqls) {
165
- await this.runSQL({ sql });
166
- }
167
- }
168
- // DELETE
169
- /**
170
- * Limitation: always returns [], regardless of which rows are actually deleted
171
- */
172
- async deleteByIds(table, ids, opt) {
173
- if (!ids.length)
174
- return 0;
175
- const sql = query_util_1.dbQueryToSQLDelete(new db_lib_1.DBQuery(table).filterEq('id', ids));
176
- const res = await this.runSQL({ sql });
177
- return res.affectedRows;
178
- }
179
- async deleteByQuery(q, opt) {
180
- const sql = query_util_1.dbQueryToSQLDelete(q);
181
- const res = await this.runSQL({ sql });
182
- return res.affectedRows;
183
- }
184
- /**
185
- * Use with caution!
186
- */
187
- async dropTable(table) {
188
- await this.runSQL({ sql: `DROP TABLE IF EXISTS ${table}` });
189
- }
190
- /**
191
- * dropIfExists=true needed as a safety check
192
- */
193
- async createTable(schema, opt = {}) {
194
- if (opt.dropIfExists)
195
- await this.dropTable(schema.table);
196
- const sql = mysql_schema_util_1.commonSchemaToMySQLDDL(schema);
197
- await this.runSQL({ sql });
198
- }
199
- async getTables() {
200
- return (await this.runSQL({ sql: `show tables` }))
201
- .map(r => Object.values(r)[0])
202
- .filter(Boolean);
203
- }
204
- async getTableSchema(table) {
205
- const statsArray = await this.runSQL({
206
- sql: `describe ${mysql.escapeId(table)}`,
70
+ pool.on('error', err => {
71
+ logger.error(err);
72
+ });
73
+ return pool;
74
+ }
75
+ async close() {
76
+ const pool = this.pool();
77
+ // eslint-disable-next-line @typescript-eslint/await-thenable
78
+ await (0, util_1.promisify)(pool.end.bind(pool));
79
+ this.cfg.logger.log('closed');
80
+ }
81
+ /**
82
+ * Be careful to always call `con.release()` when you get connection with this method.
83
+ */
84
+ async getConnection() {
85
+ const pool = this.pool();
86
+ return await (0, util_1.promisify)(pool.getConnection.bind(pool))();
87
+ }
88
+ /**
89
+ * Manually create a single (not pool) connection.
90
+ * Be careful to manage this connection yourself (open, release, etc).
91
+ */
92
+ async createSingleConnection() {
93
+ const con = mysql.createConnection(this.cfg);
94
+ await (0, util_1.promisify)(con.connect.bind(con))();
95
+ const { threadId } = con;
96
+ if (this.cfg.debugConnections) {
97
+ this.cfg.logger.log(`createSingleConnection(${threadId})`);
98
+ con.on('connect', () => this.cfg.logger.log(`createSingleConnection(${threadId}).connect`));
99
+ con.on('drain', () => this.cfg.logger.log(`createSingleConnection(${threadId}).drain`));
100
+ con.on('enqueue', () => this.cfg.logger.log(`createSingleConnection(${threadId}).enqueue`));
101
+ con.on('end', () => this.cfg.logger.log(`createSingleConnection(${threadId}).end`));
102
+ }
103
+ con.on('error', err => {
104
+ this.cfg.logger.error(`createSingleConnection(${threadId}).error`, err);
105
+ });
106
+ return con;
107
+ }
108
+ // GET
109
+ async getByIds(table, ids, opt = {}) {
110
+ if (!ids.length)
111
+ return [];
112
+ const q = new db_lib_1.DBQuery(table).filterEq('id', ids);
113
+ const { rows } = await this.runQuery(q, opt);
114
+ return rows.map(r => (0, js_lib_1._mapKeys)(r, k => (0, mysql_schema_util_1.mapNameFromMySQL)(k)));
115
+ }
116
+ // QUERY
117
+ async runQuery(q, _opt = {}) {
118
+ const sql = (0, query_util_1.dbQueryToSQLSelect)(q);
119
+ const rows = await this.runSQL({ sql });
120
+ return {
121
+ rows: rows.map(r => (0, js_lib_1._mapKeys)((0, js_lib_1._filterNullishValues)(r, true), k => (0, mysql_schema_util_1.mapNameFromMySQL)(k))),
122
+ };
123
+ }
124
+ async runSQL(q) {
125
+ if (this.cfg.logSQL)
126
+ this.cfg.logger.log(q.sql, q.values);
127
+ return await new Promise((resolve, reject) => {
128
+ this.pool().query(q, (err, res) => {
129
+ if (err)
130
+ return reject(err);
131
+ resolve(res);
207
132
  });
208
- return {
209
- table,
210
- fields: statsArray.map(stats => mysql_schema_util_1.mysqlTableStatsToCommonSchemaField(stats)),
211
- };
133
+ });
134
+ }
135
+ async runQueryCount(q, _opt) {
136
+ const { rows } = await this.runQuery(q.select(['count(*) as _count']));
137
+ return rows[0]._count;
138
+ }
139
+ streamQuery(q, _opt = {}) {
140
+ const sql = (0, query_util_1.dbQueryToSQLSelect)(q);
141
+ if (this.cfg.logSQL)
142
+ this.cfg.logger.log(`stream: ${sql}`);
143
+ // return this.streamSQL(sql, opt)
144
+ return this.pool()
145
+ .query(sql)
146
+ .stream()
147
+ .pipe(new stream_1.Transform({
148
+ objectMode: true,
149
+ transform(row, _encoding, cb) {
150
+ cb(null, (0, js_lib_1._filterNullishValues)(row, true));
151
+ },
152
+ }));
153
+ }
154
+ // SAVE
155
+ async saveBatch(table, _rows, _opt) {
156
+ if (!_rows.length)
157
+ return;
158
+ // Stringify object values
159
+ const rows = _rows.map(row => (0, js_lib_1._mapValues)(row, v => {
160
+ return v && typeof v === 'object' && !Buffer.isBuffer(v) ? JSON.stringify(v) : v;
161
+ }));
162
+ // inserts are split into multiple sentenses to respect the max_packet_size (1Mb usually)
163
+ const sqls = (0, query_util_1.insertSQL)(table, rows, 'INSERT', this.cfg.logger);
164
+ for await (const sql of sqls) {
165
+ await this.runSQL({ sql });
212
166
  }
213
167
  }
214
- tslib_1.__decorate([
215
- js_lib_1._Memo()
216
- ], MysqlDB.prototype, "pool", null);
217
- return MysqlDB;
218
- })();
168
+ // DELETE
169
+ /**
170
+ * Limitation: always returns [], regardless of which rows are actually deleted
171
+ */
172
+ async deleteByIds(table, ids, _opt) {
173
+ if (!ids.length)
174
+ return 0;
175
+ const sql = (0, query_util_1.dbQueryToSQLDelete)(new db_lib_1.DBQuery(table).filterEq('id', ids));
176
+ const res = await this.runSQL({ sql });
177
+ return res.affectedRows;
178
+ }
179
+ async deleteByQuery(q, _opt) {
180
+ const sql = (0, query_util_1.dbQueryToSQLDelete)(q);
181
+ const res = await this.runSQL({ sql });
182
+ return res.affectedRows;
183
+ }
184
+ /**
185
+ * Use with caution!
186
+ */
187
+ async dropTable(table) {
188
+ await this.runSQL({ sql: `DROP TABLE IF EXISTS ${table}` });
189
+ }
190
+ /**
191
+ * dropIfExists=true needed as a safety check
192
+ */
193
+ async createTable(table, schema, opt = {}) {
194
+ if (opt.dropIfExists)
195
+ await this.dropTable(table);
196
+ const sql = (0, mysql_schema_util_1.jsonSchemaToMySQLDDL)(table, schema);
197
+ await this.runSQL({ sql });
198
+ }
199
+ async getTables() {
200
+ return (await this.runSQL({ sql: `show tables` }))
201
+ .map(r => Object.values(r)[0])
202
+ .filter(Boolean);
203
+ }
204
+ async getTableSchema(table) {
205
+ const stats = await this.runSQL({
206
+ sql: `describe ${mysql.escapeId(table)}`,
207
+ });
208
+ return (0, mysql_schema_util_1.mysqlTableStatsToJsonSchemaField)(table, stats, this.cfg.logger);
209
+ }
210
+ }
211
+ (0, tslib_1.__decorate)([
212
+ (0, js_lib_1._Memo)()
213
+ ], MysqlDB.prototype, "pool", null);
219
214
  exports.MysqlDB = MysqlDB;
220
- //# sourceMappingURL=mysql.db.js.map
@@ -1,11 +1,12 @@
1
1
  import { DBQuery } from '@naturalcycles/db-lib';
2
+ import { CommonLogger } from '@naturalcycles/js-lib';
2
3
  import { QueryOptions } from 'mysql';
3
- export declare function dbQueryToSQLSelect(q: DBQuery): string;
4
- export declare function dbQueryToSQLDelete(q: DBQuery): string;
4
+ export declare function dbQueryToSQLSelect(q: DBQuery<any>): string;
5
+ export declare function dbQueryToSQLDelete(q: DBQuery<any>): string;
5
6
  /**
6
7
  * Returns array of sql statements to respect the max sql size.
7
8
  */
8
- export declare function insertSQL(table: string, records: object[], verb?: 'INSERT' | 'REPLACE'): string[];
9
- export declare function insertSQLSingle(table: string, record: object): string;
10
- export declare function insertSQLSetSingle(table: string, record: object): QueryOptions;
11
- export declare function dbQueryToSQLUpdate(q: DBQuery, record: object): string;
9
+ export declare function insertSQL(table: string, records: Record<any, any>[], verb?: 'INSERT' | 'REPLACE', logger?: CommonLogger): string[];
10
+ export declare function insertSQLSingle(table: string, record: Record<any, any>): string;
11
+ export declare function insertSQLSetSingle(table: string, record: Record<any, any>): QueryOptions;
12
+ export declare function dbQueryToSQLUpdate(q: DBQuery<any>, record: Record<any, any>): string;
@@ -30,9 +30,10 @@ exports.dbQueryToSQLDelete = dbQueryToSQLDelete;
30
30
  /**
31
31
  * Returns array of sql statements to respect the max sql size.
32
32
  */
33
- function insertSQL(table, records, verb = 'INSERT') {
33
+ function insertSQL(table, records, verb = 'INSERT', logger = console) {
34
34
  // INSERT INTO table_name (column1, column2, column3, ...)
35
35
  // VALUES (value1, value2, value3, ...);
36
+ // eslint-disable-next-line unicorn/no-array-reduce
36
37
  const fieldSet = records.reduce((set, rec) => {
37
38
  Object.keys(rec).forEach(field => set.add(field));
38
39
  return set;
@@ -42,7 +43,7 @@ function insertSQL(table, records, verb = 'INSERT') {
42
43
  verb,
43
44
  `INTO`,
44
45
  mysql.escapeId(table),
45
- `(` + [...fields].map(f => mysql.escapeId(mysql_schema_util_1.mapNameToMySQL(f))).join(',') + `)`,
46
+ `(` + [...fields].map(f => mysql.escapeId((0, mysql_schema_util_1.mapNameToMySQL)(f))).join(',') + `)`,
46
47
  `VALUES\n`,
47
48
  ].join(' ');
48
49
  const valueRows = records.map(rec => {
@@ -70,7 +71,7 @@ function insertSQL(table, records, verb = 'INSERT') {
70
71
  if (sql) {
71
72
  sqls.push(sql); // last one
72
73
  }
73
- console.log(`${colors_1.white(table)} large sql query (${colors_1.yellow(js_lib_1._hb(full.length))}) was split into ${colors_1.yellow(sqls.length)} chunks`);
74
+ logger.log(`${(0, colors_1.white)(table)} large sql query (${(0, colors_1.yellow)((0, js_lib_1._hb)(full.length))}) was split into ${(0, colors_1.yellow)(sqls.length)} chunks`);
74
75
  return sqls;
75
76
  // todo: handle "upsert" later
76
77
  }
@@ -83,7 +84,7 @@ function insertSQLSingle(table, record) {
83
84
  mysql.escapeId(table),
84
85
  `(` +
85
86
  Object.keys(record)
86
- .map(f => mysql.escapeId(mysql_schema_util_1.mapNameToMySQL(f)))
87
+ .map(f => mysql.escapeId((0, mysql_schema_util_1.mapNameToMySQL)(f)))
87
88
  .join(',') +
88
89
  `)`,
89
90
  `\nVALUES`,
@@ -110,7 +111,7 @@ function dbQueryToSQLUpdate(q, record) {
110
111
  mysql.escapeId(q.table),
111
112
  `SET`,
112
113
  Object.keys(record)
113
- .map(f => mysql.escapeId(mysql_schema_util_1.mapNameToMySQL(f)) + ' = ?')
114
+ .map(f => mysql.escapeId((0, mysql_schema_util_1.mapNameToMySQL)(f)) + ' = ?')
114
115
  .join(', '),
115
116
  ...whereTokens(q),
116
117
  ];
@@ -123,7 +124,7 @@ function selectTokens(q) {
123
124
  fields = q._selectedFieldNames.length ? q._selectedFieldNames : ['id'];
124
125
  }
125
126
  // We don't do `escapeId` cause it'll ruin e.g SELECT `count *` FROM ...
126
- return [`SELECT`, fields.map(f => mysql_schema_util_1.mapNameToMySQL(f)).join(', '), `FROM`, mysql.escapeId(q.table)];
127
+ return [`SELECT`, fields.map(f => (0, mysql_schema_util_1.mapNameToMySQL)(f)).join(', '), `FROM`, mysql.escapeId(q.table)];
127
128
  }
128
129
  function offsetLimitTokens(q) {
129
130
  const tokens = [];
@@ -144,6 +145,9 @@ function orderTokens(q) {
144
145
  q._orders.map(o => `\`${o.name}\` ${o.descending ? 'DESC' : 'ASC'}`).join(', '),
145
146
  ];
146
147
  }
148
+ const OP_MAP = {
149
+ '==': '=',
150
+ };
147
151
  function whereTokens(q) {
148
152
  if (!q._filters.length)
149
153
  return [];
@@ -154,17 +158,20 @@ function whereTokens(q) {
154
158
  if (f.val === null || f.val === undefined) {
155
159
  // special treatment
156
160
  return [
157
- mysql.escapeId(mysql_schema_util_1.mapNameToMySQL(f.name)),
158
- f.op === '=' ? 'IS NULL' : 'IS NOT NULL',
161
+ mysql.escapeId((0, mysql_schema_util_1.mapNameToMySQL)(f.name)),
162
+ f.op === '==' ? 'IS NULL' : 'IS NOT NULL',
159
163
  ].join(' ');
160
164
  }
161
165
  if (Array.isArray(f.val)) {
162
166
  // special case for arrays
163
- return `${mysql.escapeId(mysql_schema_util_1.mapNameToMySQL(f.name))} IN (${mysql.escape(f.val)})`;
167
+ return `${mysql.escapeId((0, mysql_schema_util_1.mapNameToMySQL)(f.name))} IN (${mysql.escape(f.val)})`;
164
168
  }
165
- return [mysql.escapeId(mysql_schema_util_1.mapNameToMySQL(f.name)), f.op, mysql.escape(f.val)].join(' ');
169
+ return [
170
+ mysql.escapeId((0, mysql_schema_util_1.mapNameToMySQL)(f.name)),
171
+ OP_MAP[f.op] || f.op,
172
+ mysql.escape(f.val),
173
+ ].join(' ');
166
174
  })
167
175
  .join(' AND '),
168
176
  ];
169
177
  }
170
- //# sourceMappingURL=query.util.js.map
@@ -1,4 +1,4 @@
1
- import { CommonSchema, CommonSchemaField } from '@naturalcycles/db-lib';
1
+ import { CommonLogger, JsonSchemaObject, JsonSchemaRootObject } from '@naturalcycles/js-lib';
2
2
  export interface MySQLTableStats {
3
3
  Field: string;
4
4
  Type: string;
@@ -13,10 +13,11 @@ export interface MySQLSchemaOptions {
13
13
  /**
14
14
  * It currently skips nullability and declares everything as "DEFAULT NULL".
15
15
  */
16
- export declare function commonSchemaToMySQLDDL(schema: CommonSchema, opt?: MySQLSchemaOptions): string;
17
- export declare function mysqlTableStatsToCommonSchemaField(s: MySQLTableStats): CommonSchemaField;
16
+ export declare function jsonSchemaToMySQLDDL(table: string, schema: JsonSchemaObject<any>, opt?: MySQLSchemaOptions): string;
17
+ export declare function mysqlTableStatsToJsonSchemaField<T = any>(table: string, stats: MySQLTableStats[], logger: CommonLogger): JsonSchemaRootObject<T>;
18
18
  /**
19
19
  * Because MySQL doesn't support `.` in field names and escapes them as tableName + fieldName.
20
+ *
20
21
  * @param name
21
22
  */
22
23
  export declare function mapNameToMySQL(name: string): string;