@egi/smart-db 2.0.4 → 2.1.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.
Files changed (76) hide show
  1. package/.eslintrc.json +212 -0
  2. package/README.md +2 -0
  3. package/assets/mysql/{database-init.sql → smart-db-core-init.sql} +0 -0
  4. package/assets/sqlite3/{database-init.sql → smart-db-core-init.sql} +0 -0
  5. package/bin/copy-assets +6 -0
  6. package/bin/extract-db-api +19 -0
  7. package/package.json +54 -26
  8. package/src/drivers/smart-db-better-sqlite3.ts +284 -0
  9. package/src/drivers/smart-db-mysql.ts +159 -0
  10. package/src/drivers/smart-db-mysql2.ts +159 -0
  11. package/src/drivers/smart-db-sqlite3.ts +198 -0
  12. package/src/helpers/extract-db-api.ts +465 -0
  13. package/src/helpers/terser-tree.ts +39 -0
  14. package/src/models/abstract-model.ts +209 -0
  15. package/src/models/smart-db-core-table-model.ts +161 -0
  16. package/src/models/smart-db-dictionary.ts +28 -0
  17. package/src/models/smart-db-log-model.ts +316 -0
  18. package/src/models/smart-db-version-model.ts +316 -0
  19. package/src/models/smart-db-version-view-model.ts +347 -0
  20. package/src/models/sqlite-master-model.ts +140 -0
  21. package/src/models/sqlite-sequence-model.ts +91 -0
  22. package/src/smart-db-api.ts +15 -0
  23. package/src/smart-db-globals.ts +136 -0
  24. package/src/smart-db-interfaces.ts +218 -0
  25. package/src/smart-db-log.ts +262 -0
  26. package/src/smart-db-sql-build-data.ts +28 -0
  27. package/src/smart-db-upgrade-manager.ts +171 -0
  28. package/src/smart-db.ts +854 -0
  29. package/test/data/sql-engine-tests.json +232 -0
  30. package/test/db/mysql/database-init.sql +11 -0
  31. package/test/db/sqlite3/database-init.sql +11 -0
  32. package/test/exer.js +28 -0
  33. package/test/model/smart-db-dictionary.ts +19 -0
  34. package/test/model/test-table-model.ts +214 -0
  35. package/test/test.js +273 -0
  36. package/test/test2.js +252 -0
  37. package/tsconfig.json +32 -0
  38. package/tsconfig.pro.json +32 -0
  39. package/tsconfig.test-model.json +23 -0
  40. package/bin/extract-db-interface +0 -18
  41. package/drivers/smart-db-better-sqlite3.d.ts +0 -34
  42. package/drivers/smart-db-better-sqlite3.js +0 -1
  43. package/drivers/smart-db-mysql.d.ts +0 -24
  44. package/drivers/smart-db-mysql.js +0 -1
  45. package/drivers/smart-db-mysql2.d.ts +0 -24
  46. package/drivers/smart-db-mysql2.js +0 -1
  47. package/drivers/smart-db-sqlite3.d.ts +0 -28
  48. package/drivers/smart-db-sqlite3.js +0 -1
  49. package/helpers/extract-db-interface.d.ts +0 -1
  50. package/helpers/extract-db-interface.js +0 -1
  51. package/index.d.ts +0 -10
  52. package/index.js +0 -1
  53. package/model/abstract-model.d.ts +0 -44
  54. package/model/abstract-model.js +0 -1
  55. package/model/smart-db-core-table-model.d.ts +0 -33
  56. package/model/smart-db-core-table-model.js +0 -1
  57. package/model/smart-db-dictionary.d.ts +0 -15
  58. package/model/smart-db-dictionary.js +0 -1
  59. package/model/smart-db-log-model.d.ts +0 -63
  60. package/model/smart-db-log-model.js +0 -1
  61. package/model/smart-db-version-model.d.ts +0 -63
  62. package/model/smart-db-version-model.js +0 -1
  63. package/model/smart-db-version-view-model.d.ts +0 -70
  64. package/model/smart-db-version-view-model.js +0 -1
  65. package/model/sqlite-master-model.d.ts +0 -29
  66. package/model/sqlite-master-model.js +0 -1
  67. package/model/sqlite-sequence-model.d.ts +0 -24
  68. package/model/sqlite-sequence-model.js +0 -1
  69. package/smart-db-interface.d.ts +0 -173
  70. package/smart-db-interface.js +0 -1
  71. package/smart-db-log.d.ts +0 -32
  72. package/smart-db-log.js +0 -1
  73. package/smart-db-upgrade-manager.d.ts +0 -13
  74. package/smart-db-upgrade-manager.js +0 -1
  75. package/smart-db.d.ts +0 -74
  76. package/smart-db.js +0 -1
package/.eslintrc.json ADDED
@@ -0,0 +1,212 @@
1
+ {
2
+ "env": {
3
+ "browser": true,
4
+ "node": true
5
+ },
6
+ "extends": [
7
+ "plugin:@typescript-eslint/recommended",
8
+ "plugin:@typescript-eslint/recommended-requiring-type-checking",
9
+ "prettier",
10
+ "prettier/@typescript-eslint"
11
+ ],
12
+ "parser": "@typescript-eslint/parser",
13
+ "parserOptions": {
14
+ "project": "tsconfig.json",
15
+ "sourceType": "module"
16
+ },
17
+ "plugins": [
18
+ "@typescript-eslint"
19
+ ],
20
+ "ignorePatterns": ["*spec.ts", "*.min.js", "protractor.conf.js", "xml2abc.js", "zip.js", "app.po.ts", "karma.conf.js", "test.ts"],
21
+ "rules": {
22
+ "@typescript-eslint/adjacent-overload-signatures": "error",
23
+ "@typescript-eslint/array-type": [
24
+ "error",
25
+ {
26
+ "default": "array"
27
+ }
28
+ ],
29
+ "@typescript-eslint/ban-types": [
30
+ "error",
31
+ {
32
+ "types": {
33
+ "Object": {
34
+ "message": "Avoid using the `Object` type. Did you mean `object`?"
35
+ },
36
+ "Function": {
37
+ "message": "Avoid using the `Function` type. Prefer a specific function type, like `() => void`."
38
+ },
39
+ "Boolean": {
40
+ "message": "Avoid using the `Boolean` type. Did you mean `boolean`?"
41
+ },
42
+ "Number": {
43
+ "message": "Avoid using the `Number` type. Did you mean `number`?"
44
+ },
45
+ "String": {
46
+ "message": "Avoid using the `String` type. Did you mean `string`?"
47
+ },
48
+ "Symbol": {
49
+ "message": "Avoid using the `Symbol` type. Did you mean `symbol`?"
50
+ }
51
+ }
52
+ }
53
+ ],
54
+ "@typescript-eslint/consistent-type-assertions": "off",
55
+ "@typescript-eslint/dot-notation": "error",
56
+ "@typescript-eslint/explicit-member-accessibility": [
57
+ "off",
58
+ {
59
+ "accessibility": "explicit"
60
+ }
61
+ ],
62
+ "@typescript-eslint/member-delimiter-style": [
63
+ "error",
64
+ {
65
+ "multiline": {
66
+ "delimiter": "semi",
67
+ "requireLast": true
68
+ },
69
+ "singleline": {
70
+ "delimiter": "semi",
71
+ "requireLast": true
72
+ }
73
+ }
74
+ ],
75
+ "@typescript-eslint/no-empty-interface": "error",
76
+ "@typescript-eslint/no-explicit-any": "off",
77
+ "@typescript-eslint/no-floating-promises": "error",
78
+ "@typescript-eslint/no-misused-new": "error",
79
+ "@typescript-eslint/no-namespace": "error",
80
+ "@typescript-eslint/no-parameter-properties": "off",
81
+ "@typescript-eslint/no-unused-expressions": "error",
82
+ "@typescript-eslint/no-use-before-define": "off",
83
+ "@typescript-eslint/no-var-requires": "error",
84
+ "@typescript-eslint/prefer-for-of": "error",
85
+ "@typescript-eslint/prefer-function-type": "error",
86
+ "@typescript-eslint/prefer-namespace-keyword": "error",
87
+ "@typescript-eslint/prefer-regexp-exec": "off",
88
+ "@typescript-eslint/unbound-method": "off",
89
+ "@typescript-eslint/restrict-plus-operands": "off",
90
+ "@typescript-eslint/member-ordering": [
91
+ "warn",
92
+ {
93
+ "default": [
94
+ "public-static-field",
95
+ "protected-static-field",
96
+ "private-static-field",
97
+ "public-instance-field",
98
+ "protected-instance-field",
99
+ "private-instance-field",
100
+ "constructor",
101
+ "public-static-method",
102
+ "protected-static-method",
103
+ "private-static-method",
104
+ "public-instance-method",
105
+ "protected-instance-method",
106
+ "private-instance-method"
107
+ ]
108
+ }
109
+ ],
110
+ "@typescript-eslint/no-unused-vars": [
111
+ "error",
112
+ {
113
+ "args": "after-used",
114
+ "argsIgnorePattern": "^_"
115
+ }
116
+ ],
117
+ "@typescript-eslint/explicit-module-boundary-types": [
118
+ "warn",
119
+ {
120
+ "allowArgumentsExplicitlyTypedAsAny": true
121
+ }
122
+ ],
123
+ "@typescript-eslint/no-inferrable-types": [
124
+ "warn",
125
+ {
126
+ "ignoreParameters": true,
127
+ "ignoreProperties": true
128
+ }
129
+ ],
130
+ "@typescript-eslint/quotes": [
131
+ "error",
132
+ "double"
133
+ ],
134
+ "@typescript-eslint/semi": [
135
+ "error"
136
+ ],
137
+ "@typescript-eslint/triple-slash-reference": [
138
+ "error",
139
+ {
140
+ "path": "always",
141
+ "types": "prefer-import",
142
+ "lib": "always"
143
+ }
144
+ ],
145
+ "@typescript-eslint/unified-signatures": "error",
146
+ "camelcase": "off",
147
+ "comma-dangle": "off",
148
+ "complexity": "off",
149
+ "constructor-super": "error",
150
+ "eqeqeq": [
151
+ "off",
152
+ "smart"
153
+ ],
154
+ "guard-for-in": "error",
155
+ "id-blacklist": "off",
156
+ "id-match": "off",
157
+ "import/order": "off",
158
+ "max-classes-per-file": [
159
+ "error",
160
+ 1
161
+ ],
162
+ "max-len": [
163
+ "off",
164
+ {
165
+ "code": 210
166
+ }
167
+ ],
168
+ "new-parens": "error",
169
+ "no-bitwise": "error",
170
+ "no-caller": "error",
171
+ "no-cond-assign": "error",
172
+ "no-console": "off",
173
+ "no-debugger": "error",
174
+ "no-empty": "error",
175
+ "no-eval": "error",
176
+ "no-fallthrough": "off",
177
+ "no-invalid-this": "off",
178
+ "no-new-wrappers": "error",
179
+ "no-shadow": [
180
+ "error",
181
+ {
182
+ "hoist": "all"
183
+ }
184
+ ],
185
+ "no-throw-literal": "off",
186
+ "no-trailing-spaces": "error",
187
+ "no-undef-init": "error",
188
+ "no-underscore-dangle": "off",
189
+ "no-unsafe-finally": "error",
190
+ "no-unused-labels": "error",
191
+ "no-var": "error",
192
+ "object-shorthand": "off",
193
+ "one-var": [
194
+ "error",
195
+ "never"
196
+ ],
197
+ "prefer-const": "error",
198
+ "quote-props": "off",
199
+ "radix": "error",
200
+ "spaced-comment": [
201
+ "error",
202
+ "always",
203
+ {
204
+ "markers": [
205
+ "/"
206
+ ]
207
+ }
208
+ ],
209
+ "use-isnan": "error",
210
+ "valid-typeof": "off"
211
+ }
212
+ }
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # smart-db
2
+ Smart DB
@@ -0,0 +1,6 @@
1
+ #! /bin/bash
2
+ #
3
+ mkdir -p dist/bin
4
+ cp bin/extract-db-api dist/bin
5
+ rsync -a --delete --delete-excluded assets/ dist/assets/
6
+ cp -p package*.json dist
@@ -0,0 +1,19 @@
1
+ #! /bin/bash
2
+ if [[ -L "$0" ]]; then
3
+ bin=$(dirname "$0")
4
+ link=$(readlink "$0")
5
+ ROOT=$(cd "$bin" >/dev/null && cd "$(dirname "$link")"/.. >/dev/null && pwd)
6
+ else
7
+ ROOT=$(cd "$(dirname "$0")"/.. >/dev/null && pwd)
8
+ fi
9
+
10
+ if [[ -d $ROOT/dist ]]; then
11
+ ROOT=$ROOT/dist
12
+ fi
13
+
14
+ if [[ -f $ROOT/helpers/extract-db-api.js ]]; then
15
+ # distribution environment
16
+ node --es-module-specifier-resolution=node "$ROOT/helpers/extract-db-api.js" "$@"
17
+ else
18
+ echo "missing smart-db-extract-api script"
19
+ fi
package/package.json CHANGED
@@ -1,9 +1,20 @@
1
1
  {
2
2
  "name": "@egi/smart-db",
3
- "version": "2.0.4",
3
+ "version": "2.1.0",
4
4
  "description": "Unified Smart DB Access",
5
- "main": "dist/index.js",
5
+ "author": "Marcel Egloff",
6
6
  "type": "module",
7
+ "browser": {
8
+ "fs": false,
9
+ "path": false,
10
+ "os": false
11
+ },
12
+ "keywords": [
13
+ "MySql",
14
+ "Sqlite3",
15
+ "Smart",
16
+ "DB"
17
+ ],
7
18
  "scripts": {
8
19
  "test": "echo \"Error: no test specified\" && exit 1",
9
20
  "copy-assets": "bin/copy-assets",
@@ -16,41 +27,58 @@
16
27
  "tsc-pro": "tsc --build tsconfig.pro.json",
17
28
  "tsc-watch": "tsc --build tsconfig.json --watch",
18
29
  "terser": "node dist/helpers/terser-tree 'dist/**/*.js' && rm -f dist/helpers/terser-tree.*",
19
- "extract-db-interface": "bin/extract-db-interface && tsc --build tsconfig.test-model.json"
30
+ "extract-db-api": "bin/extract-db-api && tsc --build tsconfig.test-model.json"
31
+ },
32
+ "exports": {
33
+ ".": "./dist/smart-db-api.js",
34
+ "./drivers/smart-db-sqlite3": "./dist/drivers/smart-db-sqlite3.js",
35
+ "./drivers/smart-db-better-sqlite3": "./dist/drivers/smart-db-better-sqlite3.js",
36
+ "./drivers/smart-db-mysql": "./dist/drivers/smart-db-mysql.js",
37
+ "./drivers/smart-db-mysql2": "./dist/drivers/smart-db-mysql2.js"
38
+ },
39
+ "types": "./dist/smart-db-api.d.ts",
40
+ "typesVersions": {
41
+ "*": {
42
+ "drivers/smart-db-sqlite3": [
43
+ "./dist/drivers/smart-db-sqlite3.d.ts"
44
+ ],
45
+ "drivers/smart-db-better-sqlite3": [
46
+ "./dist/drivers/smart-db-better-sqlite3.d.ts"
47
+ ],
48
+ "drivers/smart-db-better-mysql": [
49
+ "./dist/drivers/smart-db-better-mysql.d.ts"
50
+ ],
51
+ "drivers/smart-db-better-mysql2": [
52
+ "./dist/drivers/smart-db-better-mysql2.d.ts"
53
+ ]
54
+ }
20
55
  },
21
56
  "bin": {
22
- "extract-db-interface": "./bin/extract-db-interface",
23
- "extract-db-interface.js": "./"
57
+ "extract-db-api": "bin/extract-db-api",
58
+ "extract-db-api.js": "./"
24
59
  },
25
- "keywords": [
26
- "MySql",
27
- "Sqlite3",
28
- "Smart",
29
- "DB"
30
- ],
31
- "author": "Marcel Egloff",
32
- "license": "UNLICENSED",
33
60
  "dependencies": {
34
- "lodash": "^4.17.15",
35
- "sqlite3": "^5.0.0",
61
+ "lodash": "^4.17.21",
62
+ "sqlite3": "^5.0.2",
36
63
  "terser": "^4.8.0"
37
64
  },
38
65
  "devDependencies": {
39
- "@types/better-sqlite3": "^5.4.0",
40
- "@types/glob": "^7.1.2",
41
- "@types/lodash": "^4.14.155",
42
- "@types/mysql": "^2.15.14",
43
- "@types/node": "^14.0.13",
44
- "@types/sqlite3": "^3.1.6",
45
- "@types/uglify-js": "^3.9.2",
46
- "glob": "^7.1.6",
47
- "mocha": "^8.0.1",
66
+ "@types/better-sqlite3": "^5.4.2",
67
+ "@types/glob": "^7.1.3",
68
+ "@types/lodash": "^4.14.170",
69
+ "@types/mysql": "^2.15.18",
70
+ "@types/node": "^16.11.19",
71
+ "@types/sqlite3": "^3.1.7",
72
+ "@types/uglify-js": "^3.13.0",
73
+ "glob": "^7.1.7",
74
+ "mocha": "^8.4.0",
48
75
  "npm-run-all": "^4.1.5",
49
- "uglify-js": "^3.10.0"
76
+ "uglify-js": "^3.13.10"
50
77
  },
51
78
  "optionalDependencies": {
52
79
  "better-sqlite3": "^7.1.0",
53
80
  "mysql": "^2.18.1",
54
81
  "mysql2": "^2.1.0"
55
- }
82
+ },
83
+ "license": "UNLICENSED"
56
84
  }
@@ -0,0 +1,284 @@
1
+ import BetterSqlite3 from "better-sqlite3";
2
+
3
+ import _ from "lodash";
4
+ import { SmartDbSqlBuildData } from "../smart-db-sql-build-data";
5
+ import { AbstractModel } from "../models/abstract-model";
6
+ import { SqliteMasterModel } from "../models/sqlite-master-model";
7
+ import {SmartDb} from "../smart-db";
8
+ import {AbstractModelGlobals, GenericModelData, SmartDbConnector, SmartDbFieldDescription, SmartDbRunResult, SmartDbTableInfo} from "../smart-db-interfaces";
9
+
10
+ type VariableArgFunction = (...params: any[]) => any;
11
+
12
+ interface SmartDbSqlite3TableInfo {
13
+ cid: number;
14
+ name: string;
15
+ type: string;
16
+ notnull: 0;
17
+ // noinspection SpellCheckingInspection
18
+ dflt_value: string | number | boolean;
19
+ pk: number;
20
+ }
21
+
22
+ // noinspection JSClassNamingConvention
23
+ export class SmartDbBetterSqlite3 extends SmartDb {
24
+ protected db: BetterSqlite3.Database;
25
+
26
+ constructor(connectorOrDb: string | BetterSqlite3.Database, options?: BetterSqlite3.Options) {
27
+ if (_.isString(connectorOrDb)) {
28
+ super(connectorOrDb);
29
+ this.db = new BetterSqlite3(connectorOrDb, options);
30
+ } else {
31
+ super(null);
32
+ this.db = connectorOrDb;
33
+ this.db.inTransaction;
34
+ }
35
+ }
36
+
37
+ public getDatabaseType(): string {
38
+ return "sqlite3";
39
+ }
40
+
41
+ public getDbQuote(): string {
42
+ return "\"";
43
+ }
44
+
45
+ public getDbConnector(): string | SmartDbConnector {
46
+ return this.dbConnector;
47
+ }
48
+
49
+ public hasConcurrentTransactions(): boolean {
50
+ return false;
51
+ }
52
+
53
+ // noinspection JSUnusedGlobalSymbols
54
+ public exists<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): Promise<boolean> {
55
+ return new Promise<boolean>((resolve, reject) => {
56
+ const tableName = _.isString(modelClass) ? modelClass : (<AbstractModelGlobals<T, D>><unknown>modelClass).getTableName();
57
+
58
+ this.getFirst(SqliteMasterModel, {
59
+ name: tableName,
60
+ type: type,
61
+ tblName: indexTableName
62
+ }).then((rows) => {
63
+ if (rows === null) {
64
+ reject(this.getLastError());
65
+ } else {
66
+ resolve(!!rows);
67
+ }
68
+ }).catch((err) => {
69
+ reject(err);
70
+ });
71
+ });
72
+ }
73
+
74
+ public existsSync<T extends AbstractModel<T, D>, D extends GenericModelData>(modelClass: string | (new () => T), type?: "view" | "table" | "index", indexTableName?: string): boolean {
75
+ let exists = false;
76
+
77
+ const tableName = _.isString(modelClass) ? modelClass : (<AbstractModelGlobals<T, D>><unknown>modelClass).getTableName();
78
+
79
+ const rows = this.getFirstSync(SqliteMasterModel, {
80
+ name: tableName,
81
+ type: type,
82
+ tblName: indexTableName
83
+ });
84
+
85
+ if (rows === false) {
86
+ throw this.getLastError();
87
+ } else {
88
+ exists = !!rows;
89
+ }
90
+
91
+ return exists;
92
+ }
93
+
94
+ public exec(script: string): Promise<any> {
95
+ return new Promise<any>((resolve, reject) => {
96
+ const ret = this.execSync(script);
97
+ if (ret === false) {
98
+ reject("unable to execute script");
99
+ } else {
100
+ resolve(ret);
101
+ }
102
+ });
103
+ }
104
+
105
+ public execSync(script: string): BetterSqlite3.Database | false {
106
+ return this.saveExecute(() => {
107
+ return this.db.exec(script);
108
+ });
109
+ }
110
+
111
+ // noinspection JSUnusedGlobalSymbols
112
+ public transaction<F extends VariableArgFunction>(fn: F): BetterSqlite3.Transaction | false {
113
+ return this.saveExecute(() => {
114
+ return this.db.transaction(fn);
115
+ });
116
+ }
117
+
118
+ // noinspection JSUnusedGlobalSymbols
119
+ public pragma(source: string, options?: BetterSqlite3.PragmaOptions): unknown {
120
+ return this.saveExecute(() => {
121
+ return this.db.pragma(source, options) as unknown;
122
+ });
123
+ }
124
+
125
+ // noinspection JSUnusedGlobalSymbols
126
+ public checkpoint(databaseName?: string): BetterSqlite3.Database | false {
127
+ return this.saveExecute(() => {
128
+ return this.db.checkpoint(databaseName);
129
+ });
130
+ }
131
+
132
+ // noinspection JSUnusedGlobalSymbols
133
+ public func(name: string, options: BetterSqlite3.RegistrationOptions, cb: VariableArgFunction): BetterSqlite3.Database | false {
134
+ return this.saveExecute(() => {
135
+ let ret;
136
+ if (_.isFunction(options)) {
137
+ ret = this.db.function(name, options);
138
+ } else {
139
+ ret = this.db.function(name, options, cb);
140
+ }
141
+ return ret;
142
+ });
143
+ }
144
+
145
+ // noinspection JSUnusedGlobalSymbols
146
+ public aggregate(name: string, options: BetterSqlite3.AggregateOptions): BetterSqlite3.Database | false {
147
+ return this.saveExecute(() => {
148
+ return this.db.aggregate(name, options);
149
+ });
150
+ }
151
+
152
+ // noinspection JSUnusedGlobalSymbols
153
+ public loadExtension(path: string): BetterSqlite3.Database | false {
154
+ return this.saveExecute(() => {
155
+ return this.db.loadExtension(path);
156
+ });
157
+ }
158
+
159
+ // noinspection JSUnusedGlobalSymbols
160
+ public closeSync(): boolean {
161
+ return this.saveExecute(() => {
162
+ this.smartDbLog.setDb(null);
163
+ return !!this.db.close();
164
+ });
165
+ }
166
+
167
+ // noinspection JSUnusedGlobalSymbols
168
+ public defaultSafeIntegers(toggleState?: boolean): BetterSqlite3.Database | false {
169
+ return this.saveExecute(() => {
170
+ return this.db.defaultSafeIntegers(toggleState);
171
+ });
172
+ }
173
+
174
+ // noinspection JSUnusedGlobalSymbols
175
+ public backup(destinationFile: string, options?: BetterSqlite3.BackupOptions): Promise<BetterSqlite3.BackupMetadata> | false {
176
+ return this.saveExecute(() => {
177
+ return this.db.backup(destinationFile, options);
178
+ });
179
+ }
180
+
181
+ public getTableInfo(tableName: string): Promise<SmartDbTableInfo> {
182
+ return new Promise<SmartDbTableInfo>((resolve) => {
183
+
184
+ const infos = this.pragma(`table_info(${tableName})`) as SmartDbSqlite3TableInfo[];
185
+ let fieldInfos: SmartDbFieldDescription[] = [];
186
+ if (infos) {
187
+ fieldInfos = infos.map((info) => {
188
+ return <SmartDbFieldDescription>{
189
+ cid: info.cid,
190
+ name: info.name,
191
+ type: info.type,
192
+ notNull: info.notnull !== 0,
193
+ defaultValue: info.dflt_value,
194
+ isPk: info.pk !== 0
195
+ };
196
+ });
197
+
198
+ resolve({
199
+ name: tableName,
200
+ fields: fieldInfos
201
+ });
202
+ }
203
+ });
204
+ }
205
+
206
+ protected statementRun(buildData: SmartDbSqlBuildData, retry: number = 0): Promise<SmartDbRunResult> {
207
+ return new Promise<SmartDbRunResult>((resolve, reject) => {
208
+ try {
209
+ resolve(this.statementRunSync(buildData));
210
+ } catch (err) {
211
+ if (err.code == "SQLITE_BUSY") {
212
+ if (retry < 10) {
213
+ setTimeout(() => {
214
+ this.statementRun(buildData, retry + 1).then((result) => {
215
+ resolve(result);
216
+ }).catch((err) => {
217
+ reject(err);
218
+ });
219
+ }, 100);
220
+ } else {
221
+ reject(err);
222
+ }
223
+ } else {
224
+ reject(err);
225
+ }
226
+ }
227
+ });
228
+ }
229
+
230
+ protected statementRunSync(buildData: SmartDbSqlBuildData): SmartDbRunResult {
231
+ const stmt = this.db.prepare(buildData.sql);
232
+ const runResult = stmt && stmt.run(buildData.values);
233
+ return runResult && {
234
+ changes: runResult.changes,
235
+ affected: runResult.changes,
236
+ lastId: runResult.lastInsertRowid as number
237
+ };
238
+ }
239
+
240
+ protected statementGet(buildData: SmartDbSqlBuildData): Promise<any> {
241
+ return new Promise<any>((resolve, reject) => {
242
+ try {
243
+ const stmt = this.db.prepare(buildData.sql);
244
+ resolve(stmt.get(buildData.values));
245
+ } catch (err) {
246
+ reject(err);
247
+ }
248
+ });
249
+ }
250
+
251
+ protected statementGetSync(buildData: SmartDbSqlBuildData) {
252
+ const stmt = this.db.prepare(buildData.sql);
253
+ return stmt && stmt.get(buildData.values);
254
+ }
255
+
256
+ protected statementGetAll(buildData: SmartDbSqlBuildData): Promise<any[]> {
257
+ return new Promise<any[]>((resolve, reject) => {
258
+ try {
259
+ const stmt = this.db.prepare(buildData.sql);
260
+ resolve(stmt.all(buildData.values));
261
+ } catch (err) {
262
+ reject(err);
263
+ }
264
+ });
265
+ }
266
+
267
+ protected statementGetAllSync(buildData: SmartDbSqlBuildData): any[] {
268
+ const stmt = this.db.prepare(buildData.sql);
269
+ return stmt && stmt.all(buildData.values);
270
+ }
271
+
272
+ // noinspection JSUnusedGlobalSymbols
273
+ public close(): Promise<void> {
274
+ return new Promise<void>((resolve, reject) => {
275
+ try {
276
+ this.smartDbLog.setDb(null);
277
+ this.db.close();
278
+ resolve();
279
+ } catch (err) {
280
+ reject(err);
281
+ }
282
+ });
283
+ }
284
+ }