@naturalcycles/mysql-lib 4.6.0 → 4.8.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.
- package/dist/mysql.db.d.ts +5 -5
- package/dist/mysql.db.js +3 -11
- package/dist/mysqlKeyValueDB.d.ts +4 -4
- package/dist/mysqlKeyValueDB.js +4 -16
- package/dist/query.util.js +1 -1
- package/dist/schema/mysql.schema.util.d.ts +3 -3
- package/package.json +1 -1
- package/src/mysql.db.ts +9 -20
- package/src/mysqlKeyValueDB.ts +11 -24
- package/src/query.util.ts +1 -1
- package/src/schema/mysql.schema.util.ts +12 -18
package/dist/mysql.db.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { CommonDB, CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBSupport, RunQueryResult } from '@naturalcycles/db-lib';
|
|
2
2
|
import { BaseCommonDB, DBQuery } from '@naturalcycles/db-lib';
|
|
3
|
-
import type { JsonSchemaObject, JsonSchemaRootObject } from '@naturalcycles/js-lib/json-schema';
|
|
4
3
|
import type { CommonLogger } from '@naturalcycles/js-lib/log';
|
|
5
4
|
import type { ObjectWithId } from '@naturalcycles/js-lib/types';
|
|
6
|
-
import type {
|
|
5
|
+
import type { JsonSchema } from '@naturalcycles/nodejs-lib/ajv';
|
|
6
|
+
import { Pipeline } from '@naturalcycles/nodejs-lib/stream';
|
|
7
7
|
import type { Connection, Pool, PoolConfig, PoolConnection, QueryOptions } from 'mysql';
|
|
8
8
|
export interface MysqlDBOptions extends CommonDBOptions {
|
|
9
9
|
}
|
|
@@ -54,7 +54,7 @@ export declare class MysqlDB extends BaseCommonDB implements CommonDB {
|
|
|
54
54
|
*/
|
|
55
55
|
runSQLString(s: string): Promise<void>;
|
|
56
56
|
runQueryCount<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
|
|
57
|
-
streamQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: MysqlDBOptions):
|
|
57
|
+
streamQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: MysqlDBOptions): Pipeline<ROW>;
|
|
58
58
|
saveBatch<ROW extends ObjectWithId>(table: string, rowsInput: ROW[], opt?: MysqlDBSaveOptions<ROW>): Promise<void>;
|
|
59
59
|
/**
|
|
60
60
|
* Limitation: always returns [], regardless of which rows are actually deleted
|
|
@@ -68,8 +68,8 @@ export declare class MysqlDB extends BaseCommonDB implements CommonDB {
|
|
|
68
68
|
/**
|
|
69
69
|
* dropIfExists=true needed as a safety check
|
|
70
70
|
*/
|
|
71
|
-
createTable<ROW extends ObjectWithId>(table: string, schema:
|
|
71
|
+
createTable<ROW extends ObjectWithId>(table: string, schema: JsonSchema<ROW>, opt?: CommonDBCreateOptions): Promise<void>;
|
|
72
72
|
getTables(): Promise<string[]>;
|
|
73
|
-
getTableSchema<ROW extends ObjectWithId>(table: string): Promise<
|
|
73
|
+
getTableSchema<ROW extends ObjectWithId>(table: string): Promise<JsonSchema<ROW>>;
|
|
74
74
|
patchByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, patch: Partial<ROW>): Promise<number>;
|
|
75
75
|
}
|
package/dist/mysql.db.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { Readable, Transform } from 'node:stream';
|
|
3
2
|
import { promisify } from 'node:util';
|
|
4
3
|
import { BaseCommonDB, commonDBFullSupport, CommonDBType, DBQuery } from '@naturalcycles/db-lib';
|
|
5
4
|
import { _Memo } from '@naturalcycles/js-lib/decorators/memo.decorator.js';
|
|
@@ -7,6 +6,7 @@ import { _assert } from '@naturalcycles/js-lib/error/assert.js';
|
|
|
7
6
|
import { commonLoggerPrefix } from '@naturalcycles/js-lib/log';
|
|
8
7
|
import { _filterUndefinedValues, _mapKeys, _mapValues, _omit } from '@naturalcycles/js-lib/object';
|
|
9
8
|
import { white } from '@naturalcycles/nodejs-lib/colors';
|
|
9
|
+
import { Pipeline } from '@naturalcycles/nodejs-lib/stream';
|
|
10
10
|
import * as mysql from 'mysql';
|
|
11
11
|
import { dbQueryToSQLDelete, dbQueryToSQLSelect, dbQueryToSQLUpdate, insertSQL, } from './query.util.js';
|
|
12
12
|
import { jsonSchemaToMySQLDDL, mapNameFromMySQL, mysqlTableStatsToJsonSchemaField, } from './schema/mysql.schema.util.js';
|
|
@@ -170,7 +170,7 @@ export class MysqlDB extends BaseCommonDB {
|
|
|
170
170
|
streamQuery(q, _opt = {}) {
|
|
171
171
|
const sql = dbQueryToSQLSelect(q);
|
|
172
172
|
if (!sql) {
|
|
173
|
-
return
|
|
173
|
+
return Pipeline.fromArray([]);
|
|
174
174
|
}
|
|
175
175
|
if (this.cfg.logSQL)
|
|
176
176
|
this.cfg.logger.log(`stream: ${sql}`);
|
|
@@ -178,15 +178,7 @@ export class MysqlDB extends BaseCommonDB {
|
|
|
178
178
|
// return (this.pool().query(sql).stream() as ReadableTyped<ROW>).map(row =>
|
|
179
179
|
// _filterUndefinedValues(row, true),
|
|
180
180
|
// )
|
|
181
|
-
return this.pool()
|
|
182
|
-
.query(sql)
|
|
183
|
-
.stream()
|
|
184
|
-
.pipe(new Transform({
|
|
185
|
-
objectMode: true,
|
|
186
|
-
transform(row, _encoding, cb) {
|
|
187
|
-
cb(null, _filterUndefinedValues(row, { mutate: true }));
|
|
188
|
-
},
|
|
189
|
-
}));
|
|
181
|
+
return Pipeline.from(this.pool().query(sql).stream()).mapSync(row => _filterUndefinedValues(row, { mutate: true }));
|
|
190
182
|
}
|
|
191
183
|
// SAVE
|
|
192
184
|
async saveBatch(table, rowsInput, opt = {}) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CommonDBCreateOptions } from '@naturalcycles/db-lib';
|
|
2
2
|
import type { CommonKeyValueDB, IncrementTuple, KeyValueDBTuple } from '@naturalcycles/db-lib/kv';
|
|
3
|
-
import
|
|
3
|
+
import { Pipeline } from '@naturalcycles/nodejs-lib/stream';
|
|
4
4
|
import type { MysqlDBCfg } from './mysql.db.js';
|
|
5
5
|
import { MysqlDB } from './mysql.db.js';
|
|
6
6
|
export declare class MySQLKeyValueDB implements CommonKeyValueDB {
|
|
@@ -18,9 +18,9 @@ export declare class MySQLKeyValueDB implements CommonKeyValueDB {
|
|
|
18
18
|
dropTable(table: string): Promise<void>;
|
|
19
19
|
deleteByIds(table: string, ids: string[]): Promise<void>;
|
|
20
20
|
saveBatch(table: string, entries: KeyValueDBTuple[]): Promise<void>;
|
|
21
|
-
streamIds(table: string, limit?: number):
|
|
22
|
-
streamValues(table: string, limit?: number):
|
|
23
|
-
streamEntries(table: string, limit?: number):
|
|
21
|
+
streamIds(table: string, limit?: number): Pipeline<string>;
|
|
22
|
+
streamValues(table: string, limit?: number): Pipeline<Buffer>;
|
|
23
|
+
streamEntries(table: string, limit?: number): Pipeline<KeyValueDBTuple>;
|
|
24
24
|
beginTransaction(): Promise<void>;
|
|
25
25
|
endTransaction(): Promise<void>;
|
|
26
26
|
count(table: string): Promise<number>;
|
package/dist/mysqlKeyValueDB.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Transform } from 'node:stream';
|
|
2
1
|
import { commonKeyValueDBFullSupport } from '@naturalcycles/db-lib/kv';
|
|
3
2
|
import { AppError } from '@naturalcycles/js-lib/error/error.util.js';
|
|
4
3
|
import { pMap } from '@naturalcycles/js-lib/promise/pMap.js';
|
|
4
|
+
import { Pipeline } from '@naturalcycles/nodejs-lib/stream';
|
|
5
5
|
import { MysqlDB } from './mysql.db.js';
|
|
6
6
|
export class MySQLKeyValueDB {
|
|
7
7
|
cfg;
|
|
@@ -70,16 +70,7 @@ export class MySQLKeyValueDB {
|
|
|
70
70
|
this.db.cfg.logger.log(`stream: ${sql}`);
|
|
71
71
|
// todo: this is nice, but `mysql` package uses `readable-stream@2` which is not compatible with `node:stream` iterable helpers
|
|
72
72
|
// return (this.db.pool().query(sql).stream() as ReadableTyped<ObjectWithId>).map(row => row.id)
|
|
73
|
-
return this.db
|
|
74
|
-
.pool()
|
|
75
|
-
.query(sql)
|
|
76
|
-
.stream()
|
|
77
|
-
.pipe(new Transform({
|
|
78
|
-
objectMode: true,
|
|
79
|
-
transform(row, _encoding, cb) {
|
|
80
|
-
cb(null, row.id);
|
|
81
|
-
},
|
|
82
|
-
}));
|
|
73
|
+
return Pipeline.from(this.db.pool().query(sql).stream()).mapSync(r => r.id);
|
|
83
74
|
}
|
|
84
75
|
streamValues(table, limit) {
|
|
85
76
|
let sql = `SELECT v FROM ${table}`;
|
|
@@ -87,7 +78,7 @@ export class MySQLKeyValueDB {
|
|
|
87
78
|
sql += ` LIMIT ${limit}`;
|
|
88
79
|
if (this.cfg.logSQL)
|
|
89
80
|
this.db.cfg.logger.log(`stream: ${sql}`);
|
|
90
|
-
return this.db.pool().query(sql).stream().
|
|
81
|
+
return Pipeline.from(this.db.pool().query(sql).stream()).mapSync(row => row.v);
|
|
91
82
|
}
|
|
92
83
|
streamEntries(table, limit) {
|
|
93
84
|
let sql = `SELECT id,v FROM ${table}`;
|
|
@@ -95,10 +86,7 @@ export class MySQLKeyValueDB {
|
|
|
95
86
|
sql += ` LIMIT ${limit}`;
|
|
96
87
|
if (this.cfg.logSQL)
|
|
97
88
|
this.db.cfg.logger.log(`stream: ${sql}`);
|
|
98
|
-
return this.db.pool().query(sql).stream().
|
|
99
|
-
row.id,
|
|
100
|
-
row.v,
|
|
101
|
-
]);
|
|
89
|
+
return Pipeline.from(this.db.pool().query(sql).stream()).mapSync(row => [row.id, row.v]);
|
|
102
90
|
}
|
|
103
91
|
async beginTransaction() {
|
|
104
92
|
await this.db.runSQL({ sql: `BEGIN TRANSACTION` });
|
package/dist/query.util.js
CHANGED
|
@@ -41,7 +41,7 @@ export function dbQueryToSQLDelete(q) {
|
|
|
41
41
|
export function insertSQL(table, rows, verb = 'INSERT', logger = console) {
|
|
42
42
|
// INSERT INTO table_name (column1, column2, column3, ...)
|
|
43
43
|
// VALUES (value1, value2, value3, ...);
|
|
44
|
-
//
|
|
44
|
+
// oxlint-disable-next-line unicorn/no-array-reduce
|
|
45
45
|
const fieldSet = rows.reduce((set, row) => {
|
|
46
46
|
for (const field of Object.keys(row)) {
|
|
47
47
|
set.add(field);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { JsonSchemaObject, JsonSchemaRootObject } from '@naturalcycles/js-lib/json-schema';
|
|
2
1
|
import type { CommonLogger } from '@naturalcycles/js-lib/log';
|
|
3
2
|
import type { AnyObject } from '@naturalcycles/js-lib/types';
|
|
3
|
+
import type { JsonSchema } from '@naturalcycles/nodejs-lib/ajv';
|
|
4
4
|
export interface MySQLTableStats {
|
|
5
5
|
Field: string;
|
|
6
6
|
Type: string;
|
|
@@ -15,8 +15,8 @@ export interface MySQLSchemaOptions {
|
|
|
15
15
|
/**
|
|
16
16
|
* It currently skips nullability and declares everything as "DEFAULT NULL".
|
|
17
17
|
*/
|
|
18
|
-
export declare function jsonSchemaToMySQLDDL(table: string, schema:
|
|
19
|
-
export declare function mysqlTableStatsToJsonSchemaField<T extends AnyObject = any>(table: string, stats: MySQLTableStats[], logger: CommonLogger):
|
|
18
|
+
export declare function jsonSchemaToMySQLDDL(table: string, schema: JsonSchema<any>, opt?: MySQLSchemaOptions): string;
|
|
19
|
+
export declare function mysqlTableStatsToJsonSchemaField<T extends AnyObject = any>(table: string, stats: MySQLTableStats[], logger: CommonLogger): JsonSchema<T>;
|
|
20
20
|
/**
|
|
21
21
|
* Because MySQL doesn't support `.` in field names and escapes them as tableName + fieldName.
|
|
22
22
|
*
|
package/package.json
CHANGED
package/src/mysql.db.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Readable, Transform } from 'node:stream'
|
|
2
1
|
import { promisify } from 'node:util'
|
|
3
2
|
import type {
|
|
4
3
|
CommonDB,
|
|
@@ -11,13 +10,13 @@ import type {
|
|
|
11
10
|
import { BaseCommonDB, commonDBFullSupport, CommonDBType, DBQuery } from '@naturalcycles/db-lib'
|
|
12
11
|
import { _Memo } from '@naturalcycles/js-lib/decorators/memo.decorator.js'
|
|
13
12
|
import { _assert } from '@naturalcycles/js-lib/error/assert.js'
|
|
14
|
-
import type { JsonSchemaObject, JsonSchemaRootObject } from '@naturalcycles/js-lib/json-schema'
|
|
15
13
|
import type { CommonLogger } from '@naturalcycles/js-lib/log'
|
|
16
14
|
import { commonLoggerPrefix } from '@naturalcycles/js-lib/log'
|
|
17
15
|
import { _filterUndefinedValues, _mapKeys, _mapValues, _omit } from '@naturalcycles/js-lib/object'
|
|
18
16
|
import type { ObjectWithId } from '@naturalcycles/js-lib/types'
|
|
17
|
+
import type { JsonSchema } from '@naturalcycles/nodejs-lib/ajv'
|
|
19
18
|
import { white } from '@naturalcycles/nodejs-lib/colors'
|
|
20
|
-
import
|
|
19
|
+
import { Pipeline } from '@naturalcycles/nodejs-lib/stream'
|
|
21
20
|
import type {
|
|
22
21
|
Connection,
|
|
23
22
|
OkPacket,
|
|
@@ -269,10 +268,10 @@ export class MysqlDB extends BaseCommonDB implements CommonDB {
|
|
|
269
268
|
override streamQuery<ROW extends ObjectWithId>(
|
|
270
269
|
q: DBQuery<ROW>,
|
|
271
270
|
_opt: MysqlDBOptions = {},
|
|
272
|
-
):
|
|
271
|
+
): Pipeline<ROW> {
|
|
273
272
|
const sql = dbQueryToSQLSelect(q)
|
|
274
273
|
if (!sql) {
|
|
275
|
-
return
|
|
274
|
+
return Pipeline.fromArray([])
|
|
276
275
|
}
|
|
277
276
|
|
|
278
277
|
if (this.cfg.logSQL) this.cfg.logger.log(`stream: ${sql}`)
|
|
@@ -281,17 +280,9 @@ export class MysqlDB extends BaseCommonDB implements CommonDB {
|
|
|
281
280
|
// return (this.pool().query(sql).stream() as ReadableTyped<ROW>).map(row =>
|
|
282
281
|
// _filterUndefinedValues(row, true),
|
|
283
282
|
// )
|
|
284
|
-
return this.pool()
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
.pipe(
|
|
288
|
-
new Transform({
|
|
289
|
-
objectMode: true,
|
|
290
|
-
transform(row: ROW, _encoding, cb) {
|
|
291
|
-
cb(null, _filterUndefinedValues(row, { mutate: true }))
|
|
292
|
-
},
|
|
293
|
-
}),
|
|
294
|
-
)
|
|
283
|
+
return Pipeline.from<ROW>(this.pool().query(sql).stream()).mapSync(row =>
|
|
284
|
+
_filterUndefinedValues(row, { mutate: true }),
|
|
285
|
+
)
|
|
295
286
|
}
|
|
296
287
|
|
|
297
288
|
// SAVE
|
|
@@ -395,7 +386,7 @@ export class MysqlDB extends BaseCommonDB implements CommonDB {
|
|
|
395
386
|
*/
|
|
396
387
|
override async createTable<ROW extends ObjectWithId>(
|
|
397
388
|
table: string,
|
|
398
|
-
schema:
|
|
389
|
+
schema: JsonSchema<ROW>,
|
|
399
390
|
opt: CommonDBCreateOptions = {},
|
|
400
391
|
): Promise<void> {
|
|
401
392
|
if (opt.dropIfExists) await this.dropTable(table)
|
|
@@ -410,9 +401,7 @@ export class MysqlDB extends BaseCommonDB implements CommonDB {
|
|
|
410
401
|
.filter(Boolean)
|
|
411
402
|
}
|
|
412
403
|
|
|
413
|
-
override async getTableSchema<ROW extends ObjectWithId>(
|
|
414
|
-
table: string,
|
|
415
|
-
): Promise<JsonSchemaRootObject<ROW>> {
|
|
404
|
+
override async getTableSchema<ROW extends ObjectWithId>(table: string): Promise<JsonSchema<ROW>> {
|
|
416
405
|
const stats = await this.runSQL<MySQLTableStats[]>({
|
|
417
406
|
sql: `describe ${mysql.escapeId(table)}`,
|
|
418
407
|
})
|
package/src/mysqlKeyValueDB.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { Transform } from 'node:stream'
|
|
2
1
|
import type { CommonDBCreateOptions } from '@naturalcycles/db-lib'
|
|
3
2
|
import type { CommonKeyValueDB, IncrementTuple, KeyValueDBTuple } from '@naturalcycles/db-lib/kv'
|
|
4
3
|
import { commonKeyValueDBFullSupport } from '@naturalcycles/db-lib/kv'
|
|
5
4
|
import { AppError } from '@naturalcycles/js-lib/error/error.util.js'
|
|
6
5
|
import { pMap } from '@naturalcycles/js-lib/promise/pMap.js'
|
|
7
6
|
import type { ObjectWithId } from '@naturalcycles/js-lib/types'
|
|
8
|
-
import
|
|
7
|
+
import { Pipeline } from '@naturalcycles/nodejs-lib/stream'
|
|
9
8
|
import type { QueryOptions } from 'mysql'
|
|
10
9
|
import type { MysqlDBCfg } from './mysql.db.js'
|
|
11
10
|
import { MysqlDB } from './mysql.db.js'
|
|
@@ -83,44 +82,32 @@ export class MySQLKeyValueDB implements CommonKeyValueDB {
|
|
|
83
82
|
})
|
|
84
83
|
}
|
|
85
84
|
|
|
86
|
-
streamIds(table: string, limit?: number):
|
|
85
|
+
streamIds(table: string, limit?: number): Pipeline<string> {
|
|
87
86
|
let sql = `SELECT id FROM ${table}`
|
|
88
87
|
if (limit) sql += ` LIMIT ${limit}`
|
|
89
88
|
if (this.cfg.logSQL) this.db.cfg.logger.log(`stream: ${sql}`)
|
|
90
89
|
|
|
91
90
|
// todo: this is nice, but `mysql` package uses `readable-stream@2` which is not compatible with `node:stream` iterable helpers
|
|
92
91
|
// return (this.db.pool().query(sql).stream() as ReadableTyped<ObjectWithId>).map(row => row.id)
|
|
93
|
-
return this.db
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
.pipe(
|
|
98
|
-
new Transform({
|
|
99
|
-
objectMode: true,
|
|
100
|
-
transform(row: ObjectWithId, _encoding, cb) {
|
|
101
|
-
cb(null, row.id)
|
|
102
|
-
},
|
|
103
|
-
}),
|
|
104
|
-
)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
streamValues(table: string, limit?: number): ReadableTyped<Buffer> {
|
|
92
|
+
return Pipeline.from<ObjectWithId>(this.db.pool().query(sql).stream()).mapSync(r => r.id)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
streamValues(table: string, limit?: number): Pipeline<Buffer> {
|
|
108
96
|
let sql = `SELECT v FROM ${table}`
|
|
109
97
|
if (limit) sql += ` LIMIT ${limit}`
|
|
110
98
|
if (this.cfg.logSQL) this.db.cfg.logger.log(`stream: ${sql}`)
|
|
111
99
|
|
|
112
|
-
return (this.db.pool().query(sql).stream()
|
|
100
|
+
return Pipeline.from<{ v: Buffer }>(this.db.pool().query(sql).stream()).mapSync(row => row.v)
|
|
113
101
|
}
|
|
114
102
|
|
|
115
|
-
streamEntries(table: string, limit?: number):
|
|
103
|
+
streamEntries(table: string, limit?: number): Pipeline<KeyValueDBTuple> {
|
|
116
104
|
let sql = `SELECT id,v FROM ${table}`
|
|
117
105
|
if (limit) sql += ` LIMIT ${limit}`
|
|
118
106
|
if (this.cfg.logSQL) this.db.cfg.logger.log(`stream: ${sql}`)
|
|
119
107
|
|
|
120
|
-
return (this.db.pool().query(sql).stream()
|
|
121
|
-
row.id,
|
|
122
|
-
|
|
123
|
-
])
|
|
108
|
+
return Pipeline.from<{ id: string; v: Buffer }>(this.db.pool().query(sql).stream()).mapSync(
|
|
109
|
+
row => [row.id, row.v],
|
|
110
|
+
)
|
|
124
111
|
}
|
|
125
112
|
|
|
126
113
|
async beginTransaction(): Promise<void> {
|
package/src/query.util.ts
CHANGED
|
@@ -60,7 +60,7 @@ export function insertSQL(
|
|
|
60
60
|
// INSERT INTO table_name (column1, column2, column3, ...)
|
|
61
61
|
// VALUES (value1, value2, value3, ...);
|
|
62
62
|
|
|
63
|
-
//
|
|
63
|
+
// oxlint-disable-next-line unicorn/no-array-reduce
|
|
64
64
|
const fieldSet = rows.reduce((set: Set<string>, row) => {
|
|
65
65
|
for (const field of Object.keys(row)) {
|
|
66
66
|
set.add(field)
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
JsonSchemaBoolean,
|
|
3
|
-
JsonSchemaNumber,
|
|
4
|
-
JsonSchemaObject,
|
|
5
|
-
JsonSchemaRootObject,
|
|
6
|
-
JsonSchemaString,
|
|
7
|
-
} from '@naturalcycles/js-lib/json-schema'
|
|
8
1
|
import type { CommonLogger } from '@naturalcycles/js-lib/log'
|
|
9
2
|
import type { AnyObject } from '@naturalcycles/js-lib/types'
|
|
3
|
+
import type { JsonSchema } from '@naturalcycles/nodejs-lib/ajv'
|
|
10
4
|
import * as mysql from 'mysql'
|
|
11
5
|
|
|
12
6
|
export interface MySQLTableStats {
|
|
@@ -27,14 +21,14 @@ export interface MySQLSchemaOptions {
|
|
|
27
21
|
*/
|
|
28
22
|
export function jsonSchemaToMySQLDDL(
|
|
29
23
|
table: string,
|
|
30
|
-
schema:
|
|
24
|
+
schema: JsonSchema<any>,
|
|
31
25
|
opt: MySQLSchemaOptions = {},
|
|
32
26
|
): string {
|
|
33
27
|
const { engine = 'InnoDB' } = opt
|
|
34
28
|
|
|
35
29
|
const lines: string[] = [`CREATE TABLE ${mysql.escapeId(table)} (`]
|
|
36
30
|
|
|
37
|
-
const innerLines = Object.entries(schema.properties).map(([k, s]) => {
|
|
31
|
+
const innerLines = Object.entries(schema.properties!).map(([k, s]) => {
|
|
38
32
|
if (k === 'id') {
|
|
39
33
|
return `id VARCHAR(255) NOT NULL`
|
|
40
34
|
}
|
|
@@ -47,7 +41,7 @@ export function jsonSchemaToMySQLDDL(
|
|
|
47
41
|
} else if (s.type === 'integer') {
|
|
48
42
|
type = 'INT(11)'
|
|
49
43
|
} else if (s.type === 'number') {
|
|
50
|
-
if (['unixTimestamp', 'int32'].includes((s as
|
|
44
|
+
if (['unixTimestamp', 'int32'].includes((s as JsonSchema<number>).format!)) {
|
|
51
45
|
type = 'INT(11)'
|
|
52
46
|
} else {
|
|
53
47
|
type = 'FLOAT(11)'
|
|
@@ -84,8 +78,8 @@ export function mysqlTableStatsToJsonSchemaField<T extends AnyObject = any>(
|
|
|
84
78
|
table: string,
|
|
85
79
|
stats: MySQLTableStats[],
|
|
86
80
|
logger: CommonLogger,
|
|
87
|
-
):
|
|
88
|
-
const s:
|
|
81
|
+
): JsonSchema<T> {
|
|
82
|
+
const s: JsonSchema<T> = {
|
|
89
83
|
$id: `${table}.schema.json`,
|
|
90
84
|
type: 'object',
|
|
91
85
|
properties: {} as any,
|
|
@@ -98,19 +92,19 @@ export function mysqlTableStatsToJsonSchemaField<T extends AnyObject = any>(
|
|
|
98
92
|
const t = stat.Type.toLowerCase()
|
|
99
93
|
const notNull = stat.Null?.toUpperCase() !== 'YES'
|
|
100
94
|
if (notNull) {
|
|
101
|
-
s.required
|
|
95
|
+
s.required!.push(name as any)
|
|
102
96
|
}
|
|
103
97
|
|
|
104
98
|
if (t.includes('text') || t.includes('char')) {
|
|
105
|
-
s.properties[name] = { type: 'string' } as
|
|
99
|
+
s.properties![name] = { type: 'string' } as JsonSchema<T[keyof T]>
|
|
106
100
|
} else if (t.includes('lob')) {
|
|
107
|
-
s.properties[name] = { instanceof: 'Buffer' }
|
|
101
|
+
s.properties![name] = { instanceof: 'Buffer' }
|
|
108
102
|
} else if (t.startsWith('tinyint') || t.includes('(1)')) {
|
|
109
|
-
s.properties[name] = { type: 'boolean' } as
|
|
103
|
+
s.properties![name] = { type: 'boolean' } as JsonSchema<T[keyof T]>
|
|
110
104
|
} else if (t === 'int' || t.startsWith('int(')) {
|
|
111
|
-
s.properties[name] = { type: 'integer' } as
|
|
105
|
+
s.properties![name] = { type: 'integer' } as JsonSchema<T[keyof T]>
|
|
112
106
|
} else if (t.startsWith('float')) {
|
|
113
|
-
s.properties[name] = { type: 'number' } as
|
|
107
|
+
s.properties![name] = { type: 'number' } as JsonSchema<T[keyof T]>
|
|
114
108
|
} else {
|
|
115
109
|
logger.log(s)
|
|
116
110
|
throw new Error(`Unknown mysql field type ${name as string} ${stat.Type}`)
|