@egi/smart-db 2.3.2 → 2.3.4

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.
Files changed (74) hide show
  1. package/drivers/smart-db-better-sqlite3.d.ts +36 -0
  2. package/drivers/smart-db-better-sqlite3.js +1 -0
  3. package/drivers/smart-db-mysql.d.ts +26 -0
  4. package/drivers/smart-db-mysql.js +1 -0
  5. package/drivers/smart-db-mysql2.d.ts +26 -0
  6. package/drivers/smart-db-mysql2.js +1 -0
  7. package/drivers/smart-db-sqlite3.d.ts +30 -0
  8. package/drivers/smart-db-sqlite3.js +1 -0
  9. package/helpers/extract-db-api.d.ts +1 -0
  10. package/helpers/extract-db-api.js +1 -0
  11. package/models/abstract-model.d.ts +22 -0
  12. package/models/abstract-model.js +1 -0
  13. package/models/smart-db-core-table-model.d.ts +35 -0
  14. package/models/smart-db-core-table-model.js +1 -0
  15. package/models/smart-db-dictionary.d.ts +13 -0
  16. package/models/smart-db-dictionary.js +1 -0
  17. package/models/smart-db-log-model.d.ts +65 -0
  18. package/models/smart-db-log-model.js +1 -0
  19. package/models/smart-db-version-model.d.ts +65 -0
  20. package/models/smart-db-version-model.js +1 -0
  21. package/models/smart-db-version-view-model.d.ts +71 -0
  22. package/models/smart-db-version-view-model.js +1 -0
  23. package/models/sqlite-master-model.d.ts +36 -0
  24. package/models/sqlite-master-model.js +1 -0
  25. package/models/sqlite-sequence-model.d.ts +24 -0
  26. package/models/sqlite-sequence-model.js +1 -0
  27. package/package.json +1 -1
  28. package/{src/smart-db-api.ts → smart-db-api.d.ts} +0 -3
  29. package/smart-db-api.js +1 -0
  30. package/smart-db-globals.d.ts +22 -0
  31. package/smart-db-globals.js +1 -0
  32. package/{src/smart-db-interfaces.ts → smart-db-interfaces.d.ts} +34 -82
  33. package/smart-db-interfaces.js +1 -0
  34. package/smart-db-log.d.ts +58 -0
  35. package/smart-db-log.js +1 -0
  36. package/smart-db-sql-build-data.d.ts +9 -0
  37. package/smart-db-sql-build-data.js +1 -0
  38. package/smart-db-upgrade-manager.d.ts +13 -0
  39. package/smart-db-upgrade-manager.js +1 -0
  40. package/smart-db.d.ts +67 -0
  41. package/smart-db.js +1 -0
  42. package/.eslintrc.json +0 -212
  43. package/README.md +0 -2
  44. package/bin/copy-assets +0 -6
  45. package/src/drivers/smart-db-better-sqlite3.ts +0 -284
  46. package/src/drivers/smart-db-mysql.ts +0 -159
  47. package/src/drivers/smart-db-mysql2.ts +0 -159
  48. package/src/drivers/smart-db-sqlite3.ts +0 -198
  49. package/src/helpers/extract-db-api.ts +0 -465
  50. package/src/helpers/terser-tree.ts +0 -39
  51. package/src/models/abstract-model.ts +0 -209
  52. package/src/models/smart-db-core-table-model.ts +0 -161
  53. package/src/models/smart-db-dictionary.ts +0 -28
  54. package/src/models/smart-db-log-model.ts +0 -316
  55. package/src/models/smart-db-version-model.ts +0 -316
  56. package/src/models/smart-db-version-view-model.ts +0 -347
  57. package/src/models/sqlite-master-model.ts +0 -140
  58. package/src/models/sqlite-sequence-model.ts +0 -91
  59. package/src/smart-db-globals.ts +0 -136
  60. package/src/smart-db-log.ts +0 -262
  61. package/src/smart-db-sql-build-data.ts +0 -28
  62. package/src/smart-db-upgrade-manager.ts +0 -171
  63. package/src/smart-db.ts +0 -854
  64. package/test/data/sql-engine-tests.json +0 -232
  65. package/test/db/mysql/database-init.sql +0 -11
  66. package/test/db/sqlite3/database-init.sql +0 -11
  67. package/test/exer.js +0 -28
  68. package/test/model/smart-db-dictionary.ts +0 -19
  69. package/test/model/test-table-model.ts +0 -214
  70. package/test/test.js +0 -273
  71. package/test/test2.js +0 -252
  72. package/tsconfig.json +0 -32
  73. package/tsconfig.pro.json +0 -32
  74. package/tsconfig.test-model.json +0 -23
@@ -1,465 +0,0 @@
1
- import fs from "fs";
2
- import _ from "lodash";
3
-
4
- import process from "process";
5
- import {SmartDbBetterSqlite3} from "../drivers/smart-db-better-sqlite3";
6
-
7
- import {SmartDbCoreTableModel} from "../models/smart-db-core-table-model";
8
- import {SqliteMasterModel} from "../models/sqlite-master-model";
9
- import {SmartDb} from "../smart-db";
10
- import {IN, NE} from "../smart-db-globals";
11
- import {AttributeInfo} from "../smart-db-interfaces";
12
-
13
- interface AnalysisAttributeInfo extends AttributeInfo {
14
- name: string;
15
- attribute: string;
16
- }
17
-
18
- interface ExtractOptions {
19
- db: SmartDb;
20
- modelDirectory: string;
21
- smartDbInterfaces: string;
22
- abstractModelModule: string;
23
- includeCoreTables?: boolean;
24
- }
25
-
26
- // noinspection NestedFunctionJS
27
- function getType(rowType: string): string {
28
- let type: string;
29
-
30
- if (rowType) {
31
- if (rowType.match(/varchar/i) || rowType.match(/text/i)) {
32
- type = "string";
33
- } else if (rowType.match(/integer\(1\)/i)) {
34
- type = "boolean";
35
- } else if (rowType.match(/date/i)) {
36
- type = "Date";
37
- } else if (rowType.match(/integer/i) || rowType.match(/number/i)) {
38
- type = "number";
39
- } else if (rowType) {
40
- type = rowType;
41
- } else {
42
- type = "SqlValueType";
43
- }
44
- } else {
45
- type = "SqlValueType";
46
- }
47
-
48
- return type;
49
- }
50
-
51
- function extractDbApi(options: ExtractOptions) {
52
- console.log(`extract interface from '${options.db.getDbConnector()}' to '${options.modelDirectory}'`);
53
-
54
- if (!fs.existsSync(options.modelDirectory)) {
55
- fs.mkdirSync(options.modelDirectory, {
56
- recursive: true
57
- });
58
- }
59
-
60
- const relations: (SqliteMasterModel[] | false) = options.db.getAllSync(SqliteMasterModel, {
61
- type: IN(["table", "view"]),
62
- name: NE("sqlite_sequence")
63
- });
64
-
65
- if (relations === false) {
66
- console.error(options.db.getLastError());
67
- process.abort();
68
- } else {
69
- let coreTables: string[] = [];
70
- if (!options.includeCoreTables && options.db.existsSync(SmartDbCoreTableModel)) {
71
- const coreTableRows = options.db.getAllSync(SmartDbCoreTableModel);
72
- if (coreTableRows === false) {
73
- throw options.db.getLastError();
74
- } else {
75
- coreTableRows.forEach((row) => {
76
- coreTables.push(row.name);
77
- });
78
- }
79
- }
80
-
81
- const dictionaryRelations: string[] = [];
82
- relations.forEach((relation) => {
83
- if (!coreTables.includes(relation.name)) {
84
- const className = relation.name[0].toUpperCase() + _.camelCase(relation.name.substr(1)) + "Model";
85
- dictionaryRelations.push(className);
86
-
87
- const fieldsInfos: AnalysisAttributeInfo[] = [];
88
-
89
- options.db.getTableInfo(relation.name).then((info) => {
90
- const fields = info.fields;
91
-
92
- let hasSqlValueType = false;
93
- let data = "";
94
- let header = "/* eslint-disable @typescript-eslint/member-ordering */\n";
95
- header += "// noinspection JSUnusedGlobalSymbols\n\n";
96
-
97
- if (fields) {
98
- header += `import {AbstractModel, GenericModelData, ModelAttributeMap} from "${options.abstractModelModule}";\n`;
99
-
100
- data += `export interface ${className}Data extends GenericModelData {\n`;
101
-
102
- if (relation.name == "user") {
103
- fields.push({
104
- name: "hash",
105
- type: "string",
106
- virtual: true
107
- }, {
108
- name: "privileges",
109
- type: "string[]",
110
- virtual: true
111
- });
112
- }
113
-
114
- let pkName = "";
115
- let fieldPrefix = "";
116
- let prefixRegex: RegExp;
117
- let hasColumnWithoutPrefix = false;
118
- const prefixes: string[] = [];
119
- fields.forEach((field) => {
120
- const prefixMatch = field.name.match(/([a-z0-9]{1,4})_/i);
121
-
122
- if (field.isPk) {
123
- pkName = field.name as string;
124
- if (prefixMatch) {
125
- fieldPrefix = prefixMatch[1];
126
- }
127
- }
128
-
129
- if (prefixMatch) {
130
- if (!prefixes.includes(prefixMatch[1])) {
131
- prefixes.push(prefixMatch[1]);
132
- }
133
- } else {
134
- hasColumnWithoutPrefix = true;
135
- }
136
-
137
- });
138
-
139
- if (!fieldPrefix && !hasColumnWithoutPrefix && prefixes.length == 1) {
140
- fieldPrefix = prefixes[0];
141
- }
142
-
143
- if (fieldPrefix) {
144
- prefixRegex = new RegExp(`^${fieldPrefix}_(.*)$`);
145
- }
146
-
147
- const attributes: Record<string, string> = {};
148
-
149
- fields.forEach((row) => {
150
- const type = getType(row.type);
151
- if (!hasSqlValueType && type == "SqlValueType") {
152
- header += `import {SqlValueType} from "${options.smartDbInterfaces}";\n`;
153
- hasSqlValueType = true;
154
- }
155
-
156
- let attribute: string;
157
-
158
- const prefixMatch = prefixRegex && row.name.match(prefixRegex);
159
- if (prefixMatch) {
160
- attribute = _.camelCase(prefixMatch[1]);
161
- } else {
162
- attribute = _.camelCase(row.name);
163
- }
164
-
165
- let typeScriptStyle = true;
166
-
167
- if (false && row.name == pkName && _.camelCase(row.name) != row.name) {
168
- fieldsInfos.push({
169
- name: _.camelCase(row.name),
170
- attribute: attribute,
171
- type: type,
172
- typeScriptStyle: typeScriptStyle,
173
- alias: row.name
174
- });
175
-
176
- typeScriptStyle = false;
177
- }
178
-
179
- if (attribute != row.name) {
180
- fieldsInfos.push({
181
- name: attribute,
182
- attribute: attribute,
183
- type: type,
184
- typeScriptStyle: typeScriptStyle,
185
- alias: row.name
186
- });
187
-
188
- typeScriptStyle = false;
189
- }
190
-
191
- fieldsInfos.push({
192
- name: row.name,
193
- attribute: attribute,
194
- type: type,
195
- physical: row.cid !== undefined,
196
- typeScriptStyle: typeScriptStyle
197
- });
198
-
199
- attributes[attribute] = type;
200
-
201
- if (relation.name == "user" && attribute == "name") {
202
- data += " // @ts-ignore";
203
- }
204
- data += ` ${attribute}?: ${type};\n`;
205
- });
206
-
207
- data += "}\n\n";
208
-
209
- data += `export class ${className} extends AbstractModel<${className}, ${className}Data> {\n`;
210
-
211
- _.forEach(attributes, (type, attribute) => {
212
- data += ` private _${attribute}?: ${type};\n`;
213
- });
214
-
215
- data += "\n";
216
-
217
- data += " static readonly attributeMap: ModelAttributeMap = {\n";
218
-
219
- fieldsInfos.forEach((info, idx) => {
220
- if (idx > 0) {
221
- data += ",\n";
222
- }
223
-
224
- data += ` ${info.name}: {\n`;
225
-
226
- if (info.physical) {
227
- data += " physical: true,\n";
228
- }
229
-
230
- if (info.alias) {
231
- data += ` alias: "${info.alias}",\n`;
232
- }
233
-
234
- if (info.virtual) {
235
- data += " virtual: true,\n";
236
- }
237
-
238
- if (info.typeScriptStyle) {
239
- data += " typeScriptStyle: true,\n";
240
- }
241
-
242
- data += ` type: "${info.type}",\n`;
243
- data += ` attribute: "_${info.attribute}"\n`;
244
- data += " }";
245
- });
246
-
247
- data += "\n";
248
- data += " };\n";
249
-
250
- data += "\n";
251
- data += " static getClassName(): string {\n";
252
- data += ` return "${className}";\n`;
253
- data += " }\n";
254
-
255
- data += "\n";
256
- data += " static getTableName(): string {\n";
257
- data += ` return "${relation.name}";\n`;
258
- data += " }\n";
259
-
260
- data += "\n";
261
- data += " static getPrimaryKey(): string {\n";
262
- data += ` return "${pkName}";\n`;
263
- data += " }\n";
264
-
265
- data += "\n";
266
- data += ` static from(other: ${className} | ${className}Data): ${className} {\n`;
267
- data += ` let value: ${className} = null;\n`;
268
- data += " if (other) {\n";
269
- data += ` value = new ${className}();\n`;
270
- data += ` if (other instanceof ${className}) {\n`;
271
- data += " Object.assign(value, other);\n";
272
- data += " } else {\n";
273
- data += " value.assign(other);\n";
274
- data += " }\n";
275
- data += " }\n";
276
- data += " return value;\n";
277
- data += " }\n";
278
-
279
- data += "\n";
280
- data += ` constructor(data?: ${className} | ${className}Data) {\n`;
281
- data += " super();\n";
282
- data += " if (data) {\n";
283
- data += " this.assign(data);\n";
284
- data += " }\n";
285
- data += " }\n";
286
-
287
-
288
- data += "\n";
289
- data += ` public clone(): ${className} {\n`;
290
- data += ` return ${className}.from(this);\n`;
291
- data += " }\n";
292
-
293
- data += "\n";
294
- data += " public getClassName(): string {\n";
295
- data += ` return "${className}";\n`;
296
- data += " }\n";
297
-
298
- data += "\n";
299
- data += " public getTableName(): string {\n";
300
- data += ` return "${relation.name}";\n`;
301
- data += " }\n";
302
-
303
- data += "\n";
304
- data += " public getPrimaryKey(): string {\n";
305
- data += ` return "${pkName}";\n`;
306
- data += " }\n";
307
-
308
- data += "\n";
309
- data += " public getAttributeMap(): ModelAttributeMap {\n";
310
- data += ` return ${className}.attributeMap;\n`;
311
- data += " }\n";
312
-
313
- fieldsInfos.forEach((info) => {
314
- data += "\n";
315
-
316
- let noInspection: string;
317
-
318
- if (info.name.length < 3 || info.name.match(/_/)) {
319
- noInspection = "FunctionNamingConventionJS";
320
- } else {
321
- noInspection = "";
322
- }
323
-
324
- if (noInspection !== "") {
325
- data += ` // noinspection ${noInspection}\n`;
326
- }
327
-
328
- data += ` get ${info.name}(): ${info.type} {\n`;
329
- data += ` return this._${info.attribute};\n`;
330
- data += " }\n\n";
331
-
332
- if (noInspection !== "") {
333
- data += ` // noinspection ${noInspection}\n`;
334
- }
335
-
336
- data += ` set ${info.name}(${info.attribute}: ${info.type}) {\n`;
337
- data += ` this._${info.attribute} = ${info.attribute};\n`;
338
- data += " }\n";
339
- });
340
-
341
- data += "}\n";
342
-
343
- data = header + "\n" + data;
344
- const filename = relation.name.replace(/[^[a-z0-9]/g, "-") + "-model.ts";
345
- fs.writeFileSync(`${options.modelDirectory}/${filename}`, data);
346
- } else {
347
- console.log("error: table has no fields");
348
- }
349
- }).catch((err) => {
350
- console.error(err);
351
- process.abort();
352
- });
353
- }
354
- });
355
-
356
- let smartDbDictionaryFile = `import {AbstractModel} from "${options.abstractModelModule}";\n`;
357
-
358
- _.forEach(dictionaryRelations, (relation) => {
359
- smartDbDictionaryFile += `import {${relation}} from "./${_.kebabCase(relation)}";\n`;
360
- });
361
-
362
- smartDbDictionaryFile += "\n";
363
- smartDbDictionaryFile += "interface SmartDbDictionaryEntry {\n";
364
-
365
- smartDbDictionaryFile += " cls: " + dictionaryRelations.map((relation) => {
366
- return "typeof " + relation;
367
- }).join(" |\n ");
368
-
369
- smartDbDictionaryFile += ";\n";
370
- smartDbDictionaryFile += "}\n\n";
371
-
372
- smartDbDictionaryFile += "export class SmartDbDictionary {\n";
373
- smartDbDictionaryFile += " static models: { [relation: string]: SmartDbDictionaryEntry; } = {\n";
374
-
375
- _.forEach(dictionaryRelations, (relation) => {
376
- smartDbDictionaryFile += ` ${relation}: {\n`;
377
- smartDbDictionaryFile += ` cls: ${relation}\n`;
378
- smartDbDictionaryFile += ` },\n`;
379
- });
380
-
381
- smartDbDictionaryFile = smartDbDictionaryFile.substring(0, smartDbDictionaryFile.length - 2) + "\n";
382
-
383
- smartDbDictionaryFile += " };\n";
384
-
385
- if (false) {
386
- smartDbDictionaryFile += "\n";
387
- smartDbDictionaryFile += " static createModel(relationName: string): AbstractModel {\n";
388
- smartDbDictionaryFile += " const entry = SmartDbDictionary.models[relationName];\n";
389
- smartDbDictionaryFile += " return entry && entry.cls && new (entry.cls)();\n";
390
- smartDbDictionaryFile += " }\n";
391
- }
392
-
393
- smartDbDictionaryFile += "}\n";
394
-
395
- fs.writeFileSync(`${options.modelDirectory}/smart-db-dictionary.ts`, smartDbDictionaryFile);
396
- }
397
-
398
- options.db.closeSync();
399
- }
400
-
401
- (() => {
402
- if (process.argv.length == 4) {
403
- const options: ExtractOptions = {
404
- modelDirectory: process.argv[3],
405
- smartDbInterfaces: "@egi/smart-db/smart-db-api",
406
- abstractModelModule: "@egi/smart-db/smart-db-api",
407
- db: new SmartDbBetterSqlite3(process.argv[2], {
408
- verbose: (message?: any, ...additionalArgs: any[]) => {
409
- console.log("DB LOG", message, ...additionalArgs);
410
- }
411
- })
412
- };
413
-
414
- extractDbApi(options);
415
- } else if (process.argv.length == 2 && fs.existsSync("src/helpers/extract-db-api.ts")) {
416
- const tmpName = `/tmp/smart-db-core.${process.pid}.sqlite3`;
417
-
418
- const smartDbOptions: ExtractOptions = {
419
- includeCoreTables: true,
420
- modelDirectory: "src/models",
421
- smartDbInterfaces: "../smart-db-interfaces",
422
- abstractModelModule: "./abstract-models",
423
- db: new SmartDbBetterSqlite3(tmpName, {
424
- verbose: (message?: any, ...additionalArgs: any[]) => {
425
- console.log("DB LOG", message, ...additionalArgs);
426
- }
427
- })
428
- };
429
-
430
- smartDbOptions.db.initDb({
431
- module: "smart-db-core",
432
- sqlFilesDirectory: "assets/sqlite3"
433
- }).then(() => {
434
- extractDbApi(smartDbOptions);
435
- fs.unlinkSync(tmpName);
436
- smartDbOptions.db.closeSync();
437
- });
438
-
439
- if (false) {
440
- if (fs.existsSync("test/test.sqlite3")) {
441
- fs.unlinkSync("test/test.sqlite3");
442
- }
443
-
444
- const testDbOptions: ExtractOptions = {
445
- modelDirectory: "test/models",
446
- smartDbInterfaces: "../../src/smart-db-interfaces",
447
- abstractModelModule: "../../src/models/abstract-models",
448
- db: new SmartDbBetterSqlite3("test/db/sqlite3.db", {
449
- verbose: (message?: any, ...additionalArgs: any[]) => {
450
- console.log("DB LOG", message, ...additionalArgs);
451
- }
452
- })
453
- };
454
-
455
- testDbOptions.db.initDb({
456
- module: "smart-db-test",
457
- sqlFilesDirectory: "test/db/sqlite3"
458
- }).then(() => {
459
- extractDbApi(testDbOptions);
460
- });
461
- }
462
- } else {
463
- console.log("usage: extract-db-api {db-connector|path-to-db} {target-models-directory}");
464
- }
465
- })();
@@ -1,39 +0,0 @@
1
- /* eslint-disable */
2
- import fs from "fs";
3
- import glob from "glob";
4
- import process from "process";
5
- import Terser from "Terser";
6
-
7
- const globStrings = process.argv.slice(2);
8
-
9
- globStrings.forEach((globString) => {
10
- glob(globString, null, (err, files) => {
11
- if (err) {
12
- console.error(err);
13
- process.exit(1);
14
- } else {
15
- files.forEach((file) => {
16
- if (file.match(/\.js$/)) {
17
- const data: Record<string, string> = {};
18
- data[file] = fs.readFileSync(file, "utf8");
19
-
20
- const result = Terser.minify(data, {
21
- sourceMap: true
22
- });
23
-
24
- if (result.error) {
25
- console.error("error", file, result.error);
26
- } else {
27
- if (result.warnings) {
28
- console.warn("warning", file, result.warnings);
29
- }
30
-
31
- console.log("tersed", file);
32
-
33
- fs.writeFileSync(file, result.code);
34
- }
35
- }
36
- });
37
- }
38
- });
39
- });