@fluidware-it/mysql2-client 0.6.2 → 0.7.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/build/esm/config.js.map +1 -1
- package/build/esm/dbClient.js +11 -11
- package/build/esm/dbClient.js.map +1 -1
- package/build/esm/upgradeManager.d.ts +3 -2
- package/build/esm/upgradeManager.js +93 -65
- package/build/esm/upgradeManager.js.map +1 -1
- package/build/esnext/config.js.map +1 -1
- package/build/esnext/dbClient.js.map +1 -1
- package/build/esnext/upgradeManager.d.ts +3 -2
- package/build/esnext/upgradeManager.js +44 -30
- package/build/esnext/upgradeManager.js.map +1 -1
- package/build/src/config.js +3 -3
- package/build/src/config.js.map +1 -1
- package/build/src/dbClient.js.map +1 -1
- package/build/src/upgradeManager.d.ts +3 -2
- package/build/src/upgradeManager.js +44 -30
- package/build/src/upgradeManager.js.map +1 -1
- package/build/src/utils.js +1 -2
- package/build/src/utils.js.map +1 -1
- package/package.json +27 -19
package/build/esm/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,MAAM,CAAC,IAAM,4BAA4B,GAAG,QAAQ,CAAC,OAAO,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;AAE1G,SAAS,aAAa,CAAC,gBAAwB,EAAE,WAAmB;IAClE,IAAI,gBAAgB,EAAE;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,MAAM,CAAC,IAAM,4BAA4B,GAAG,QAAQ,CAAC,OAAO,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;AAE1G,SAAS,aAAa,CAAC,gBAAwB,EAAE,WAAmB;IAClE,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,IAAM,eAAe,GAA4C,EAAE,CAAC;AAEpE,MAAM,UAAU,yBAAyB,CAAC,MAAW;IAAX,uBAAA,EAAA,WAAW;IACnD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,IAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,aAAM,MAAM,gBAAa,EAAE,EAAE,CAAC,CAAC;QACtE,IAAM,gBAAgB,GAAG,QAAQ,CAAC,SAAS,CAAC,aAAM,MAAM,qBAAkB,EAAE,EAAE,CAAC,CAAC;QAEhF,IAAI,CAAC,WAAW,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QAED,IAAM,OAAO,GAAG,QAAQ,CAAC,iBAAiB,CAAC,aAAM,MAAM,YAAS,CAAC,CAAC;QAClE,IAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,aAAM,MAAM,YAAS,EAAE,WAAW,CAAC,CAAC;QACvE,IAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAM,MAAM,YAAS,EAAE,IAAI,CAAC,CAAC;QAC7D,IAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,aAAM,MAAM,YAAS,EAAE,OAAO,CAAC,CAAC;QACnE,oJAAoJ;QACpJ,IAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,aAAM,MAAM,oBAAiB,EAAE,EAAE,CAAC,CAAC;QAE5E,IAAM,UAAU,GAAG,aAAa,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;QAChE,IAAM,SAAS,GAAG;YAChB,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,OAAO;SAClB,CAAC;QACF,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QAC5C,CAAC;QACD,eAAe,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACtC,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAc,EAAE,OAA0B;IAClF,eAAe,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;AACpC,CAAC","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ConnectionOptions } from 'mysql2';\nimport { EnvParse } from '@fluidware-it/saddlebag';\nimport * as fs from 'fs';\n\nexport const USE_READ_COMMITTED_ISOLATION = EnvParse.envBool('FW_DB_USE_READ_COMMITTED_ISOLATION', false);\n\nfunction getDbPassword(DB_PASSWORD_FILE: string, DB_PASSWORD: string): string {\n if (DB_PASSWORD_FILE) {\n return fs.readFileSync(DB_PASSWORD_FILE, 'utf8');\n }\n return DB_PASSWORD;\n}\n\nconst memoizedOptions: { [prefix: string]: ConnectionOptions } = {};\n\nexport function getMysqlConnectionOptions(prefix = ''): ConnectionOptions {\n if (!memoizedOptions[prefix]) {\n const DB_PASSWORD = EnvParse.envString(`FW_${prefix}DB_PASSWORD`, '');\n const DB_PASSWORD_FILE = EnvParse.envString(`FW_${prefix}DB_PASSWORD_FILE`, '');\n\n if (!DB_PASSWORD && !DB_PASSWORD_FILE) {\n throw new Error('FW_DB_PASSWORD or FW_DB_PASSWORD_FILE env is required');\n }\n\n const DB_USER = EnvParse.envStringRequired(`FW_${prefix}DB_USER`);\n const DB_HOST = EnvParse.envString(`FW_${prefix}DB_HOST`, 'localhost');\n const DB_PORT = EnvParse.envInt(`FW_${prefix}DB_PORT`, 3306);\n const DB_NAME = EnvParse.envString(`FW_${prefix}DB_NAME`, DB_USER);\n // FW_${prefix}DB_CONN_OPTIONS: JSON string with connection options See https://github.com/mysqljs/mysql#connection-options for all possible options\n const DB_CONN_OPTIONS = EnvParse.envJSON(`FW_${prefix}DB_CONN_OPTIONS`, {});\n\n const dbPassword = getDbPassword(DB_PASSWORD_FILE, DB_PASSWORD);\n const dbOptions = {\n host: DB_HOST,\n port: DB_PORT,\n user: DB_USER,\n password: dbPassword,\n database: DB_NAME\n };\n if (Object.keys(DB_CONN_OPTIONS).length > 0) {\n Object.assign(dbOptions, DB_CONN_OPTIONS);\n }\n memoizedOptions[prefix] = dbOptions;\n }\n return memoizedOptions[prefix];\n}\n\nexport function setMysqlConnectionOptions(prefix: string, options: ConnectionOptions) {\n memoizedOptions[prefix] = options;\n}\n"]}
|
package/build/esm/dbClient.js
CHANGED
|
@@ -23,8 +23,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
25
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
26
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
27
|
-
return g =
|
|
26
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
27
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
28
28
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
29
29
|
function step(op) {
|
|
30
30
|
if (f) throw new TypeError("Generator is already executing.");
|
|
@@ -154,9 +154,9 @@ var DbClient = /** @class */ (function () {
|
|
|
154
154
|
});
|
|
155
155
|
});
|
|
156
156
|
};
|
|
157
|
-
DbClient.prototype.commit = function (
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
DbClient.prototype.commit = function () {
|
|
158
|
+
return __awaiter(this, arguments, void 0, function (closeTransaction) {
|
|
159
|
+
if (closeTransaction === void 0) { closeTransaction = true; }
|
|
160
160
|
return __generator(this, function (_a) {
|
|
161
161
|
switch (_a.label) {
|
|
162
162
|
case 0:
|
|
@@ -176,9 +176,9 @@ var DbClient = /** @class */ (function () {
|
|
|
176
176
|
});
|
|
177
177
|
});
|
|
178
178
|
};
|
|
179
|
-
DbClient.prototype.rollback = function (
|
|
180
|
-
|
|
181
|
-
|
|
179
|
+
DbClient.prototype.rollback = function () {
|
|
180
|
+
return __awaiter(this, arguments, void 0, function (closeTransaction) {
|
|
181
|
+
if (closeTransaction === void 0) { closeTransaction = true; }
|
|
182
182
|
return __generator(this, function (_a) {
|
|
183
183
|
switch (_a.label) {
|
|
184
184
|
case 0:
|
|
@@ -253,10 +253,10 @@ var DbClient = /** @class */ (function () {
|
|
|
253
253
|
});
|
|
254
254
|
});
|
|
255
255
|
};
|
|
256
|
-
DbClient.prototype.update = function (
|
|
257
|
-
|
|
258
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
256
|
+
DbClient.prototype.update = function (sql_1, phs_1) {
|
|
257
|
+
return __awaiter(this, arguments, void 0, function (sql, phs, returnChangedRows) {
|
|
259
258
|
var res;
|
|
259
|
+
if (returnChangedRows === void 0) { returnChangedRows = false; }
|
|
260
260
|
return __generator(this, function (_a) {
|
|
261
261
|
switch (_a.label) {
|
|
262
262
|
case 0:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dbClient.js","sourceRoot":"","sources":["../../src/dbClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGH,OAAO,EACL,gBAAgB,EAMjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,MAAM,UAAU,CAAC;AAYnF;IAIE,kBAAY,yBAAsD;QAChE,IAAI,yBAAyB,EAAE;
|
|
1
|
+
{"version":3,"file":"dbClient.js","sourceRoot":"","sources":["../../src/dbClient.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ConnectionOptions } from 'mysql2';\nimport {\n createConnection,\n Connection,\n RowDataPacket,\n ResultSetHeader,\n ProcedureCallPacket,\n FieldPacket\n} from 'mysql2/promise';\nimport { getMysqlConnectionOptions, USE_READ_COMMITTED_ISOLATION } from './config';\n\ninterface ConnectionWrap extends Connection {\n run<T extends ResultSetHeader | ResultSetHeader[] | RowDataPacket[] | RowDataPacket[][] | ProcedureCallPacket>(\n sql: string,\n phs?: (string | number | boolean | null)[]\n ): Promise<{\n rows: T;\n cols: FieldPacket[];\n }>;\n}\n\nexport class DbClient {\n private connection?: ConnectionWrap;\n private readonly connectionOptions: ConnectionOptions;\n\n constructor(connectionOptionsOrPrefix?: ConnectionOptions | string) {\n if (connectionOptionsOrPrefix) {\n if (typeof connectionOptionsOrPrefix === 'string') {\n this.connectionOptions = getMysqlConnectionOptions(connectionOptionsOrPrefix);\n } else {\n this.connectionOptions = connectionOptionsOrPrefix;\n }\n } else {\n this.connectionOptions = getMysqlConnectionOptions('');\n }\n }\n\n public async open() {\n this.connection = (await createConnection(this.connectionOptions)) as ConnectionWrap;\n this.connection.run = async <\n T extends ResultSetHeader | ResultSetHeader[] | RowDataPacket[] | RowDataPacket[][] | ProcedureCallPacket\n >(\n sql: string,\n phs?: (string | number | boolean | null)[]\n ): Promise<{ rows: T; cols: FieldPacket[] }> => {\n if (!this.connection) {\n throw new Error('run() called but no connection available');\n }\n const [rows, cols] = await this.connection.execute<T>(sql, phs);\n return {\n rows,\n cols\n };\n };\n }\n\n public getConnection(): ConnectionWrap | undefined {\n return this.connection;\n }\n\n public async close() {\n if (this.connection) {\n await this.connection.end();\n }\n }\n\n public async startTransaction() {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n if (USE_READ_COMMITTED_ISOLATION) {\n await this.connection.execute(\"SET SESSION tx_isolation='read-committed'\");\n }\n await this.connection.execute('SET AUTOCOMMIT=0');\n }\n\n public async commit(closeTransaction = true) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n await this.connection.execute('COMMIT');\n if (closeTransaction) {\n await this.connection.execute('SET AUTOCOMMIT=1');\n }\n }\n\n public async rollback(closeTransaction = true) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n\n await this.connection.execute('ROLLBACK');\n if (closeTransaction) {\n await this.connection.execute('SET AUTOCOMMIT=1');\n }\n }\n\n public async all(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<RowDataPacket[]>(sql, phs);\n return res.rows;\n }\n\n public async get(sql: string, phs?: (string | number | boolean | null)[]): Promise<RowDataPacket | null> {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<RowDataPacket[]>(sql, phs);\n if (res.rows.length > 1) throw new Error('get() returned more than one row');\n if (res.rows.length === 1) return res.rows[0];\n return null;\n }\n\n public async insert(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<ResultSetHeader>(sql, phs);\n return res.rows.insertId || res.rows.affectedRows;\n }\n\n public async update(sql: string, phs?: (string | number | boolean | null)[], returnChangedRows = false) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<ResultSetHeader>(sql, phs);\n return returnChangedRows ? res.rows.changedRows : res.rows.affectedRows;\n }\n\n public async delete(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<ResultSetHeader>(sql, phs);\n return res.rows.affectedRows;\n }\n\n public async run(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n return this.connection.execute(sql, phs);\n }\n}\n"]}
|
|
@@ -10,12 +10,13 @@ export declare class UpgradeManager {
|
|
|
10
10
|
constructor(opts?: UpgradeManagerConfig);
|
|
11
11
|
private loadCurrentVersion;
|
|
12
12
|
private createDb;
|
|
13
|
-
private
|
|
13
|
+
private migrate;
|
|
14
14
|
private getCurrentVersion;
|
|
15
15
|
private createVersionTable;
|
|
16
16
|
private updateVersion;
|
|
17
17
|
private initDb;
|
|
18
18
|
private upgradeDb;
|
|
19
|
-
checkDb(targetVersion: number, onSchemaInit: (dbClient: DbClient) => Promise<void>, onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>): Promise<
|
|
19
|
+
checkDb(targetVersion: number, onSchemaInit: (dbClient: DbClient) => Promise<void>, onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>): Promise<void>;
|
|
20
|
+
private _checkDb;
|
|
20
21
|
}
|
|
21
22
|
//# sourceMappingURL=upgradeManager.d.ts.map
|
|
@@ -8,8 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
12
|
-
return g =
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
12
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
13
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
14
|
function step(op) {
|
|
15
15
|
if (f) throw new TypeError("Generator is already executing.");
|
|
@@ -65,30 +65,26 @@ var UpgradeManager = /** @class */ (function () {
|
|
|
65
65
|
return __generator(this, function (_a) {
|
|
66
66
|
switch (_a.label) {
|
|
67
67
|
case 0:
|
|
68
|
-
_a.trys.push([0,
|
|
68
|
+
_a.trys.push([0, 2, , 3]);
|
|
69
69
|
return [4 /*yield*/, this.getCurrentVersion(targetVersion)];
|
|
70
70
|
case 1:
|
|
71
71
|
row = _a.sent();
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return [2 /*return*/, true];
|
|
81
|
-
case 4:
|
|
82
|
-
if (row) {
|
|
72
|
+
if (row === false) {
|
|
73
|
+
return [2 /*return*/, -999];
|
|
74
|
+
}
|
|
75
|
+
else if (row === true) {
|
|
76
|
+
this.logger.info("Check db: same version ".concat(targetVersion));
|
|
77
|
+
return [2 /*return*/, true];
|
|
78
|
+
}
|
|
79
|
+
else if (row) {
|
|
83
80
|
return [2 /*return*/, row.value];
|
|
84
81
|
}
|
|
85
|
-
|
|
86
|
-
case
|
|
87
|
-
case 6:
|
|
82
|
+
return [3 /*break*/, 3];
|
|
83
|
+
case 2:
|
|
88
84
|
e_1 = _a.sent();
|
|
89
85
|
this.logger.error("Failed to read current version: ".concat(e_1.message));
|
|
90
86
|
throw e_1;
|
|
91
|
-
case
|
|
87
|
+
case 3: return [2 /*return*/];
|
|
92
88
|
}
|
|
93
89
|
});
|
|
94
90
|
});
|
|
@@ -99,14 +95,12 @@ var UpgradeManager = /** @class */ (function () {
|
|
|
99
95
|
return __generator(this, function (_a) {
|
|
100
96
|
switch (_a.label) {
|
|
101
97
|
case 0:
|
|
102
|
-
_a.trys.push([0,
|
|
103
|
-
return [
|
|
104
|
-
case 1:
|
|
105
|
-
e_2 = _a.sent();
|
|
106
|
-
if (!(e_2.code === '23505')) return [3 /*break*/, 4];
|
|
107
|
-
return [4 /*yield*/, this.client.close()];
|
|
98
|
+
_a.trys.push([0, 2, , 6]);
|
|
99
|
+
return [4 /*yield*/, this.createVersionTable()];
|
|
100
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
108
101
|
case 2:
|
|
109
|
-
_a.sent();
|
|
102
|
+
e_2 = _a.sent();
|
|
103
|
+
if (!(e_2.code === 'ER_TABLE_EXISTS_ERROR')) return [3 /*break*/, 4];
|
|
110
104
|
return [4 /*yield*/, setTimeout(2000)];
|
|
111
105
|
case 3:
|
|
112
106
|
_a.sent();
|
|
@@ -120,13 +114,13 @@ var UpgradeManager = /** @class */ (function () {
|
|
|
120
114
|
});
|
|
121
115
|
});
|
|
122
116
|
};
|
|
123
|
-
UpgradeManager.prototype.
|
|
117
|
+
UpgradeManager.prototype.migrate = function (currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade) {
|
|
124
118
|
return __awaiter(this, void 0, void 0, function () {
|
|
125
119
|
var e_3;
|
|
126
120
|
return __generator(this, function (_a) {
|
|
127
121
|
switch (_a.label) {
|
|
128
122
|
case 0:
|
|
129
|
-
_a.trys.push([0, 5,
|
|
123
|
+
_a.trys.push([0, 5, , 6]);
|
|
130
124
|
if (!(currentVersion === 0)) return [3 /*break*/, 2];
|
|
131
125
|
return [4 /*yield*/, this.initDb(targetVersion, onSchemaInit)];
|
|
132
126
|
case 1:
|
|
@@ -141,27 +135,23 @@ var UpgradeManager = /** @class */ (function () {
|
|
|
141
135
|
return [4 /*yield*/, this.upgradeDb(currentVersion, targetVersion, onSchemaUpgrade)];
|
|
142
136
|
case 3:
|
|
143
137
|
_a.sent();
|
|
144
|
-
this.logger.info(
|
|
138
|
+
this.logger.info("Db updated to ".concat(targetVersion));
|
|
145
139
|
return [2 /*return*/, true];
|
|
146
|
-
case 4: return [3 /*break*/,
|
|
140
|
+
case 4: return [3 /*break*/, 6];
|
|
147
141
|
case 5:
|
|
148
142
|
e_3 = _a.sent();
|
|
149
143
|
this.logger.error('\n');
|
|
150
144
|
this.logger.error('\n');
|
|
151
145
|
this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');
|
|
152
146
|
this.logger.error('\n');
|
|
153
|
-
this.logger.error(
|
|
147
|
+
this.logger.error("checkDb failed: ".concat(e_3.message));
|
|
154
148
|
this.logger.error('\n');
|
|
155
149
|
this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');
|
|
156
150
|
this.logger.error('\n');
|
|
157
151
|
this.logger.error('\n');
|
|
158
152
|
this.logger.error(e_3.stack);
|
|
159
153
|
throw e_3;
|
|
160
|
-
case 6: return [
|
|
161
|
-
case 7:
|
|
162
|
-
_a.sent();
|
|
163
|
-
return [7 /*endfinally*/];
|
|
164
|
-
case 8: return [2 /*return*/, true];
|
|
154
|
+
case 6: return [2 /*return*/, true];
|
|
165
155
|
}
|
|
166
156
|
});
|
|
167
157
|
});
|
|
@@ -173,37 +163,34 @@ var UpgradeManager = /** @class */ (function () {
|
|
|
173
163
|
switch (_a.label) {
|
|
174
164
|
case 0:
|
|
175
165
|
sqlCheck = "select value from ".concat(this.version_table, " for update");
|
|
176
|
-
|
|
166
|
+
_a.label = 1;
|
|
177
167
|
case 1:
|
|
178
|
-
_a.
|
|
179
|
-
_a.label = 2;
|
|
180
|
-
case 2:
|
|
181
|
-
_a.trys.push([2, 6, , 8]);
|
|
168
|
+
_a.trys.push([1, 5, , 7]);
|
|
182
169
|
return [4 /*yield*/, this.client.get(sqlCheck)];
|
|
183
|
-
case
|
|
170
|
+
case 2:
|
|
184
171
|
row = _a.sent();
|
|
185
172
|
if (!row) {
|
|
186
173
|
return [2 /*return*/, false];
|
|
187
174
|
}
|
|
188
|
-
this.logger.debug(
|
|
189
|
-
if (!(row.value === targetVersion)) return [3 /*break*/,
|
|
175
|
+
this.logger.debug("Versions: ".concat(row.value, " vs ").concat(targetVersion));
|
|
176
|
+
if (!(row.value === targetVersion)) return [3 /*break*/, 4];
|
|
190
177
|
this.logger.debug('versions are equal, rollback');
|
|
191
178
|
return [4 /*yield*/, this.client.rollback()];
|
|
192
|
-
case
|
|
179
|
+
case 3:
|
|
193
180
|
_a.sent();
|
|
194
181
|
return [2 /*return*/, true];
|
|
195
|
-
case
|
|
196
|
-
case
|
|
182
|
+
case 4: return [2 /*return*/, row];
|
|
183
|
+
case 5:
|
|
197
184
|
e_4 = _a.sent();
|
|
198
185
|
return [4 /*yield*/, this.client.rollback()];
|
|
199
|
-
case
|
|
186
|
+
case 6:
|
|
200
187
|
_a.sent();
|
|
201
188
|
if (e_4.code === 'ER_NO_SUCH_TABLE') {
|
|
202
189
|
return [2 /*return*/, false];
|
|
203
190
|
}
|
|
204
|
-
this.logger.error(
|
|
191
|
+
this.logger.error("Failed to get current schema version: [".concat(e_4.code, "] ").concat(e_4.message));
|
|
205
192
|
throw e_4;
|
|
206
|
-
case
|
|
193
|
+
case 7: return [2 /*return*/];
|
|
207
194
|
}
|
|
208
195
|
});
|
|
209
196
|
});
|
|
@@ -240,7 +227,7 @@ var UpgradeManager = /** @class */ (function () {
|
|
|
240
227
|
return [3 /*break*/, 9];
|
|
241
228
|
case 8:
|
|
242
229
|
e_6 = _a.sent();
|
|
243
|
-
this.logger.error(
|
|
230
|
+
this.logger.error("Unable to insert -1 version in \"".concat(this.version_table, " table: [").concat(e_6.code, "] ").concat(e_6.message));
|
|
244
231
|
throw e_6;
|
|
245
232
|
case 9: return [2 /*return*/, 0];
|
|
246
233
|
}
|
|
@@ -313,37 +300,78 @@ var UpgradeManager = /** @class */ (function () {
|
|
|
313
300
|
});
|
|
314
301
|
};
|
|
315
302
|
UpgradeManager.prototype.checkDb = function (targetVersion, onSchemaInit, onSchemaUpgrade) {
|
|
303
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
304
|
+
var retriesCount, done, ret;
|
|
305
|
+
return __generator(this, function (_a) {
|
|
306
|
+
switch (_a.label) {
|
|
307
|
+
case 0:
|
|
308
|
+
retriesCount = 0;
|
|
309
|
+
done = false;
|
|
310
|
+
_a.label = 1;
|
|
311
|
+
case 1: return [4 /*yield*/, this._checkDb(targetVersion, onSchemaInit, onSchemaUpgrade)];
|
|
312
|
+
case 2:
|
|
313
|
+
ret = _a.sent();
|
|
314
|
+
if (ret >= 0) {
|
|
315
|
+
done = true;
|
|
316
|
+
}
|
|
317
|
+
if (ret < 0) {
|
|
318
|
+
retriesCount++;
|
|
319
|
+
}
|
|
320
|
+
_a.label = 3;
|
|
321
|
+
case 3:
|
|
322
|
+
if (!done && retriesCount < 3) return [3 /*break*/, 1];
|
|
323
|
+
_a.label = 4;
|
|
324
|
+
case 4: return [2 /*return*/];
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
};
|
|
329
|
+
UpgradeManager.prototype._checkDb = function (targetVersion, onSchemaInit, onSchemaUpgrade) {
|
|
316
330
|
return __awaiter(this, void 0, void 0, function () {
|
|
317
331
|
var currentVersion;
|
|
318
332
|
return __generator(this, function (_a) {
|
|
319
333
|
switch (_a.label) {
|
|
320
|
-
case 0:
|
|
334
|
+
case 0:
|
|
335
|
+
_a.trys.push([0, , 8, 11]);
|
|
336
|
+
return [4 /*yield*/, this.client.open()];
|
|
321
337
|
case 1:
|
|
322
338
|
_a.sent();
|
|
323
|
-
return [4 /*yield*/, this.
|
|
339
|
+
return [4 /*yield*/, this.client.startTransaction()];
|
|
324
340
|
case 2:
|
|
341
|
+
_a.sent();
|
|
342
|
+
return [4 /*yield*/, this.loadCurrentVersion(targetVersion)];
|
|
343
|
+
case 3:
|
|
325
344
|
currentVersion = _a.sent();
|
|
326
345
|
if (currentVersion === true) {
|
|
327
|
-
return [2 /*return*/,
|
|
346
|
+
return [2 /*return*/, 0];
|
|
328
347
|
}
|
|
329
|
-
this.logger.info(
|
|
330
|
-
if (!(currentVersion === -999)) return [3 /*break*/,
|
|
348
|
+
this.logger.info("Check db: currentVersion ".concat(currentVersion, " targetVersion ").concat(targetVersion));
|
|
349
|
+
if (!(currentVersion === -999)) return [3 /*break*/, 5];
|
|
331
350
|
return [4 /*yield*/, this.createDb()];
|
|
332
|
-
case 3:
|
|
333
|
-
currentVersion = _a.sent();
|
|
334
|
-
if (!(currentVersion < 0)) return [3 /*break*/, 5];
|
|
335
|
-
return [4 /*yield*/, this.checkDb(targetVersion, onSchemaInit, onSchemaUpgrade)];
|
|
336
351
|
case 4:
|
|
337
|
-
_a.sent();
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
352
|
+
currentVersion = _a.sent();
|
|
353
|
+
if (currentVersion < 0) {
|
|
354
|
+
return [2 /*return*/, -1];
|
|
355
|
+
}
|
|
356
|
+
return [3 /*break*/, 6];
|
|
357
|
+
case 5:
|
|
341
358
|
if (currentVersion < 0) {
|
|
342
359
|
this.logger.error('Db in initialization, exiting ');
|
|
343
360
|
throw new Error('Db in initialization, do not proceed');
|
|
344
361
|
}
|
|
345
|
-
_a.label =
|
|
346
|
-
case
|
|
362
|
+
_a.label = 6;
|
|
363
|
+
case 6: return [4 /*yield*/, this.migrate(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade)];
|
|
364
|
+
case 7:
|
|
365
|
+
_a.sent();
|
|
366
|
+
return [2 /*return*/, 1];
|
|
367
|
+
case 8: return [4 /*yield*/, this.client.rollback()];
|
|
368
|
+
case 9:
|
|
369
|
+
_a.sent();
|
|
370
|
+
return [4 /*yield*/, this.client.close()];
|
|
371
|
+
case 10:
|
|
372
|
+
_a.sent();
|
|
373
|
+
return [7 /*endfinally*/];
|
|
374
|
+
case 11: return [2 /*return*/];
|
|
347
375
|
}
|
|
348
376
|
});
|
|
349
377
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgradeManager.js","sourceRoot":"","sources":["../../src/upgradeManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { setTimeout } from 'node:timers/promises';\nimport { getLogger } from '@fluidware-it/saddlebag';\nimport { DbClient } from './dbClient';\nimport { Logger } from 'pino';\n\nexport type UpgradeManagerConfig = {\n version_table_suffix?: string;\n};\n\nexport class UpgradeManager {\n private version_table: string;\n private client: DbClient;\n private logger: Logger;\n private _default_version_table = '_version';\n\n constructor(opts?: UpgradeManagerConfig) {\n this.version_table = this._default_version_table + (opts?.version_table_suffix || '');\n this.logger = getLogger().child({ component: 'mysql-migrator' });\n this.client = new DbClient();\n }\n\n private async loadCurrentVersion(targetVersion: number) {\n try {\n const row = await this.getCurrentVersion(targetVersion);\n if (row === false) {\n return -999;\n } else if (row === true) {\n this.logger.info('Check db: same version %s', targetVersion);\n await this.client.close();\n return true;\n } else if (row) {\n return row.value;\n }\n } catch (e) {\n this.logger.error(`Failed to read current version: ${e.message}`);\n throw e;\n }\n }\n\n private async createDb() {\n try {\n return this.createVersionTable();\n } catch (e) {\n if (e.code === '23505') {\n await this.client.close();\n await setTimeout(2000);\n return -1;\n } else {\n this.logger.error(`Unable to create ${this.version_table} table: [${e.code}] ${e.message}`);\n throw e;\n }\n }\n }\n\n private async _checkDb(\n currentVersion: number,\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n try {\n if (currentVersion === 0) {\n await this.initDb(targetVersion, onSchemaInit);\n this.logger.info('Db created');\n return true;\n }\n if (targetVersion === currentVersion) {\n return true;\n }\n if (targetVersion > currentVersion) {\n await this.upgradeDb(currentVersion, targetVersion, onSchemaUpgrade);\n this.logger.info('Db updated to ', targetVersion);\n return true;\n }\n } catch (e) {\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error('checkDb failed %s', e.message);\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(e.stack);\n throw e;\n } finally {\n await this.client.close();\n }\n return true;\n }\n\n private async getCurrentVersion(targetVersion: number) {\n const sqlCheck = `select value from ${this.version_table} for update`;\n await this.client.startTransaction();\n let row;\n try {\n row = await this.client.get(sqlCheck);\n if (!row) {\n return false;\n }\n this.logger.debug('Versions: %s vs %s', row.value, targetVersion);\n if (row.value === targetVersion) {\n this.logger.debug('versions are equal, rollback');\n await this.client.rollback();\n return true;\n }\n return row;\n } catch (e) {\n await this.client.rollback();\n if (e.code === 'ER_NO_SUCH_TABLE') {\n return false;\n }\n this.logger.error('Ooops: %s', e.message, e.code);\n throw e;\n }\n }\n\n private async createVersionTable() {\n const sqlCreateTable = `create table ${this.version_table} (value INTEGER PRIMARY KEY)`;\n try {\n await this.client.run(sqlCreateTable);\n } catch (e) {\n await this.client.rollback();\n throw e;\n }\n try {\n const sqlInsertVersionZero = `insert into ${this.version_table} values (-1)`;\n await this.client.insert(sqlInsertVersionZero);\n await this.client.get(`select value from ${this.version_table} for update`);\n } catch (e) {\n this.logger.error('Unable to insert -1 version in %s table: [%s] %s', this.version_table, e.code, e.message);\n throw e;\n }\n return 0;\n }\n\n private async updateVersion(targetVersion: number) {\n const sql = `update ${this.version_table} set value = ?`;\n await this.client.update(sql, [targetVersion]);\n await this.client.commit();\n }\n\n private async initDb(targetVersion: number, onInit: (dbClient: DbClient) => Promise<void>) {\n const dbConn = new DbClient();\n try {\n await dbConn.open();\n await onInit(dbConn);\n await this.updateVersion(targetVersion);\n } finally {\n if (dbConn) {\n await dbConn.close();\n }\n }\n }\n\n private async upgradeDb(\n fromVersion: number,\n targetVersion: number,\n onUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n await onUpgrade(this.client, fromVersion);\n await this.updateVersion(targetVersion);\n }\n\n async checkDb(\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n await this.client.open();\n let currentVersion = await this.loadCurrentVersion(targetVersion);\n if (currentVersion === true) {\n return true;\n }\n this.logger.info('Check db: currentVersion %s targetVersion %s', currentVersion, targetVersion);\n\n if (currentVersion === -999) {\n currentVersion = await this.createDb();\n if (currentVersion < 0) {\n await this.checkDb(targetVersion, onSchemaInit, onSchemaUpgrade);\n return;\n }\n } else if (currentVersion < 0) {\n this.logger.error('Db in initialization, exiting ');\n throw new Error('Db in initialization, do not proceed');\n }\n return this._checkDb(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"upgradeManager.js","sourceRoot":"","sources":["../../src/upgradeManager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAOtC;IAME,wBAAY,IAA2B;QAF/B,2BAAsB,GAAG,UAAU,CAAC;QAG1C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,sBAAsB,GAAG,CAAC,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,oBAAoB,KAAI,EAAE,CAAC,CAAC;QACtF,IAAI,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC/B,CAAC;IAEa,2CAAkB,GAAhC,UAAiC,aAAqB;;;;;;;wBAEtC,qBAAM,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAAA;;wBAAjD,GAAG,GAAG,SAA2C;wBACvD,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;4BAClB,sBAAO,CAAC,GAAG,EAAC;wBACd,CAAC;6BAAM,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;4BACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iCAA0B,aAAa,CAAE,CAAC,CAAC;4BAC5D,sBAAO,IAAI,EAAC;wBACd,CAAC;6BAAM,IAAI,GAAG,EAAE,CAAC;4BACf,sBAAO,GAAG,CAAC,KAAK,EAAC;wBACnB,CAAC;;;;wBAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0CAAmC,GAAC,CAAC,OAAO,CAAE,CAAC,CAAC;wBAClE,MAAM,GAAC,CAAC;;;;;KAEX;IAEa,iCAAQ,GAAtB;;;;;;;wBAEW,qBAAM,IAAI,CAAC,kBAAkB,EAAE,EAAA;4BAAtC,sBAAO,SAA+B,EAAC;;;6BAEnC,CAAA,GAAC,CAAC,IAAI,KAAK,uBAAuB,CAAA,EAAlC,wBAAkC;wBACpC,qBAAM,UAAU,CAAC,IAAI,CAAC,EAAA;;wBAAtB,SAAsB,CAAC;wBACvB,sBAAO,CAAC,CAAC,EAAC;;wBAEV,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2BAAoB,IAAI,CAAC,aAAa,sBAAY,GAAC,CAAC,IAAI,eAAK,GAAC,CAAC,OAAO,CAAE,CAAC,CAAC;wBAC5F,MAAM,GAAC,CAAC;;;;;;KAGb;IAEa,gCAAO,GAArB,UACE,cAAsB,EACtB,aAAqB,EACrB,YAAmD,EACnD,eAAoE;;;;;;;6BAG9D,CAAA,cAAc,KAAK,CAAC,CAAA,EAApB,wBAAoB;wBACtB,qBAAM,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,EAAA;;wBAA9C,SAA8C,CAAC;wBAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;wBAC/B,sBAAO,IAAI,EAAC;;wBAEd,IAAI,aAAa,KAAK,cAAc,EAAE,CAAC;4BACrC,sBAAO,IAAI,EAAC;wBACd,CAAC;6BACG,CAAA,aAAa,GAAG,cAAc,CAAA,EAA9B,wBAA8B;wBAChC,qBAAM,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,aAAa,EAAE,eAAe,CAAC,EAAA;;wBAApE,SAAoE,CAAC;wBACrE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAiB,aAAa,CAAE,CAAC,CAAC;wBACnD,sBAAO,IAAI,EAAC;;;;wBAGd,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;wBACpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAAmB,GAAC,CAAC,OAAO,CAAE,CAAC,CAAC;wBAClD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;wBACpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAC,CAAC,KAAK,CAAC,CAAC;wBAC3B,MAAM,GAAC,CAAC;4BAEV,sBAAO,IAAI,EAAC;;;;KACb;IAEa,0CAAiB,GAA/B,UAAgC,aAAqB;;;;;;wBAC7C,QAAQ,GAAG,4BAAqB,IAAI,CAAC,aAAa,gBAAa,CAAC;;;;wBAG9D,qBAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAA;;wBAArC,GAAG,GAAG,SAA+B,CAAC;wBACtC,IAAI,CAAC,GAAG,EAAE,CAAC;4BACT,sBAAO,KAAK,EAAC;wBACf,CAAC;wBACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAa,GAAG,CAAC,KAAK,iBAAO,aAAa,CAAE,CAAC,CAAC;6BAC5D,CAAA,GAAG,CAAC,KAAK,KAAK,aAAa,CAAA,EAA3B,wBAA2B;wBAC7B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;wBAClD,qBAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAA;;wBAA5B,SAA4B,CAAC;wBAC7B,sBAAO,IAAI,EAAC;4BAEd,sBAAO,GAAG,EAAC;;;wBAEX,qBAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAA;;wBAA5B,SAA4B,CAAC;wBAC7B,IAAI,GAAC,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;4BAClC,sBAAO,KAAK,EAAC;wBACf,CAAC;wBACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iDAA0C,GAAC,CAAC,IAAI,eAAK,GAAC,CAAC,OAAO,CAAE,CAAC,CAAC;wBACpF,MAAM,GAAC,CAAC;;;;;KAEX;IAEa,2CAAkB,GAAhC;;;;;;wBACQ,cAAc,GAAG,uBAAgB,IAAI,CAAC,aAAa,iCAA8B,CAAC;;;;wBAEtF,qBAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,EAAA;;wBAArC,SAAqC,CAAC;;;;wBAEtC,qBAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAA;;wBAA5B,SAA4B,CAAC;wBAC7B,MAAM,GAAC,CAAC;;;wBAGF,oBAAoB,GAAG,sBAAe,IAAI,CAAC,aAAa,iBAAc,CAAC;wBAC7E,qBAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,EAAA;;wBAA9C,SAA8C,CAAC;wBAC/C,qBAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4BAAqB,IAAI,CAAC,aAAa,gBAAa,CAAC,EAAA;;wBAA3E,SAA2E,CAAC;;;;wBAE5E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2CAAmC,IAAI,CAAC,aAAa,sBAAY,GAAC,CAAC,IAAI,eAAK,GAAC,CAAC,OAAO,CAAE,CAAC,CAAC;wBAC3G,MAAM,GAAC,CAAC;4BAEV,sBAAO,CAAC,EAAC;;;;KACV;IAEa,sCAAa,GAA3B,UAA4B,aAAqB;;;;;;wBACzC,GAAG,GAAG,iBAAU,IAAI,CAAC,aAAa,mBAAgB,CAAC;wBACzD,qBAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC,EAAA;;wBAA9C,SAA8C,CAAC;wBAC/C,qBAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAA;;wBAA1B,SAA0B,CAAC;;;;;KAC5B;IAEa,+BAAM,GAApB,UAAqB,aAAqB,EAAE,MAA6C;;;;;;wBACjF,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;;;;wBAE5B,qBAAM,MAAM,CAAC,IAAI,EAAE,EAAA;;wBAAnB,SAAmB,CAAC;wBACpB,qBAAM,MAAM,CAAC,MAAM,CAAC,EAAA;;wBAApB,SAAoB,CAAC;wBACrB,qBAAM,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,EAAA;;wBAAvC,SAAuC,CAAC;;;6BAEpC,MAAM,EAAN,wBAAM;wBACR,qBAAM,MAAM,CAAC,KAAK,EAAE,EAAA;;wBAApB,SAAoB,CAAC;;;;;;;KAG1B;IAEa,kCAAS,GAAvB,UACE,WAAmB,EACnB,aAAqB,EACrB,SAA8D;;;;4BAE9D,qBAAM,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAA;;wBAAzC,SAAyC,CAAC;wBAC1C,qBAAM,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,EAAA;;wBAAvC,SAAuC,CAAC;;;;;KACzC;IAEY,gCAAO,GAApB,UACE,aAAqB,EACrB,YAAmD,EACnD,eAAoE;;;;;;wBAEhE,YAAY,GAAG,CAAC,CAAC;wBACjB,IAAI,GAAG,KAAK,CAAC;;4BAEH,qBAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,YAAY,EAAE,eAAe,CAAC,EAAA;;wBAAvE,GAAG,GAAG,SAAiE;wBAC7E,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;4BACb,IAAI,GAAG,IAAI,CAAC;wBACd,CAAC;wBACD,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;4BACZ,YAAY,EAAE,CAAC;wBACjB,CAAC;;;4BACM,CAAC,IAAI,IAAI,YAAY,GAAG,CAAC;;;;;;KACnC;IAEa,iCAAQ,GAAtB,UACE,aAAqB,EACrB,YAAmD,EACnD,eAAoE;;;;;;;wBAGlE,qBAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAA;;wBAAxB,SAAwB,CAAC;wBACzB,qBAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,EAAA;;wBAApC,SAAoC,CAAC;wBAChB,qBAAM,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,EAAA;;wBAA7D,cAAc,GAAG,SAA4C;wBACjE,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;4BAC5B,sBAAO,CAAC,EAAC;wBACX,CAAC;wBACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mCAA4B,cAAc,4BAAkB,aAAa,CAAE,CAAC,CAAC;6BAC1F,CAAA,cAAc,KAAK,CAAC,GAAG,CAAA,EAAvB,wBAAuB;wBACR,qBAAM,IAAI,CAAC,QAAQ,EAAE,EAAA;;wBAAtC,cAAc,GAAG,SAAqB,CAAC;wBACvC,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;4BACvB,sBAAO,CAAC,CAAC,EAAC;wBACZ,CAAC;;;wBACI,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;4BAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;4BACpD,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;wBAC1D,CAAC;;4BACD,qBAAM,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,CAAC,EAAA;;wBAAhF,SAAgF,CAAC;wBACjF,sBAAO,CAAC,EAAC;4BAET,qBAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAA;;wBAA5B,SAA4B,CAAC;wBAC7B,qBAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,EAAA;;wBAAzB,SAAyB,CAAC;;;;;;KAE7B;IACH,qBAAC;AAAD,CAAC,AAtMD,IAsMC","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { setTimeout } from 'node:timers/promises';\nimport { getLogger } from '@fluidware-it/saddlebag';\nimport { DbClient } from './dbClient';\nimport { Logger } from 'pino';\n\nexport type UpgradeManagerConfig = {\n version_table_suffix?: string;\n};\n\nexport class UpgradeManager {\n private version_table: string;\n private client: DbClient;\n private logger: Logger;\n private _default_version_table = '_version';\n\n constructor(opts?: UpgradeManagerConfig) {\n this.version_table = this._default_version_table + (opts?.version_table_suffix || '');\n this.logger = getLogger().child({ component: 'mysql-migrator' });\n this.client = new DbClient();\n }\n\n private async loadCurrentVersion(targetVersion: number) {\n try {\n const row = await this.getCurrentVersion(targetVersion);\n if (row === false) {\n return -999;\n } else if (row === true) {\n this.logger.info(`Check db: same version ${targetVersion}`);\n return true;\n } else if (row) {\n return row.value;\n }\n } catch (e) {\n this.logger.error(`Failed to read current version: ${e.message}`);\n throw e;\n }\n }\n\n private async createDb() {\n try {\n return await this.createVersionTable();\n } catch (e) {\n if (e.code === 'ER_TABLE_EXISTS_ERROR') {\n await setTimeout(2000);\n return -1;\n } else {\n this.logger.error(`Unable to create ${this.version_table} table: [${e.code}] ${e.message}`);\n throw e;\n }\n }\n }\n\n private async migrate(\n currentVersion: number,\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n try {\n if (currentVersion === 0) {\n await this.initDb(targetVersion, onSchemaInit);\n this.logger.info('Db created');\n return true;\n }\n if (targetVersion === currentVersion) {\n return true;\n }\n if (targetVersion > currentVersion) {\n await this.upgradeDb(currentVersion, targetVersion, onSchemaUpgrade);\n this.logger.info(`Db updated to ${targetVersion}`);\n return true;\n }\n } catch (e) {\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error(`checkDb failed: ${e.message}`);\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(e.stack);\n throw e;\n }\n return true;\n }\n\n private async getCurrentVersion(targetVersion: number) {\n const sqlCheck = `select value from ${this.version_table} for update`;\n let row;\n try {\n row = await this.client.get(sqlCheck);\n if (!row) {\n return false;\n }\n this.logger.debug(`Versions: ${row.value} vs ${targetVersion}`);\n if (row.value === targetVersion) {\n this.logger.debug('versions are equal, rollback');\n await this.client.rollback();\n return true;\n }\n return row;\n } catch (e) {\n await this.client.rollback();\n if (e.code === 'ER_NO_SUCH_TABLE') {\n return false;\n }\n this.logger.error(`Failed to get current schema version: [${e.code}] ${e.message}`);\n throw e;\n }\n }\n\n private async createVersionTable() {\n const sqlCreateTable = `create table ${this.version_table} (value INTEGER PRIMARY KEY)`;\n try {\n await this.client.run(sqlCreateTable);\n } catch (e) {\n await this.client.rollback();\n throw e;\n }\n try {\n const sqlInsertVersionZero = `insert into ${this.version_table} values (-1)`;\n await this.client.insert(sqlInsertVersionZero);\n await this.client.get(`select value from ${this.version_table} for update`);\n } catch (e) {\n this.logger.error(`Unable to insert -1 version in \"${this.version_table} table: [${e.code}] ${e.message}`);\n throw e;\n }\n return 0;\n }\n\n private async updateVersion(targetVersion: number) {\n const sql = `update ${this.version_table} set value = ?`;\n await this.client.update(sql, [targetVersion]);\n await this.client.commit();\n }\n\n private async initDb(targetVersion: number, onInit: (dbClient: DbClient) => Promise<void>) {\n const dbConn = new DbClient();\n try {\n await dbConn.open();\n await onInit(dbConn);\n await this.updateVersion(targetVersion);\n } finally {\n if (dbConn) {\n await dbConn.close();\n }\n }\n }\n\n private async upgradeDb(\n fromVersion: number,\n targetVersion: number,\n onUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n await onUpgrade(this.client, fromVersion);\n await this.updateVersion(targetVersion);\n }\n\n public async checkDb(\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n let retriesCount = 0;\n let done = false;\n do {\n const ret = await this._checkDb(targetVersion, onSchemaInit, onSchemaUpgrade);\n if (ret >= 0) {\n done = true;\n }\n if (ret < 0) {\n retriesCount++;\n }\n } while (!done && retriesCount < 3);\n }\n\n private async _checkDb(\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n try {\n await this.client.open();\n await this.client.startTransaction();\n let currentVersion = await this.loadCurrentVersion(targetVersion);\n if (currentVersion === true) {\n return 0;\n }\n this.logger.info(`Check db: currentVersion ${currentVersion} targetVersion ${targetVersion}`);\n if (currentVersion === -999) {\n currentVersion = await this.createDb();\n if (currentVersion < 0) {\n return -1;\n }\n } else if (currentVersion < 0) {\n this.logger.error('Db in initialization, exiting ');\n throw new Error('Db in initialization, do not proceed');\n }\n await this.migrate(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade);\n return 1;\n } finally {\n await this.client.rollback();\n await this.client.close();\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,MAAM,CAAC,MAAM,4BAA4B,GAAG,QAAQ,CAAC,OAAO,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;AAE1G,SAAS,aAAa,CAAC,gBAAwB,EAAE,WAAmB;IAClE,IAAI,gBAAgB,EAAE;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,MAAM,CAAC,MAAM,4BAA4B,GAAG,QAAQ,CAAC,OAAO,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;AAE1G,SAAS,aAAa,CAAC,gBAAwB,EAAE,WAAmB;IAClE,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,eAAe,GAA4C,EAAE,CAAC;AAEpE,MAAM,UAAU,yBAAyB,CAAC,MAAM,GAAG,EAAE;IACnD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,MAAM,aAAa,EAAE,EAAE,CAAC,CAAC;QACtE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,MAAM,kBAAkB,EAAE,EAAE,CAAC,CAAC;QAEhF,IAAI,CAAC,WAAW,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,OAAO,GAAG,QAAQ,CAAC,iBAAiB,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,MAAM,SAAS,EAAE,WAAW,CAAC,CAAC;QACvE,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,MAAM,SAAS,EAAE,IAAI,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,MAAM,SAAS,EAAE,OAAO,CAAC,CAAC;QACnE,oJAAoJ;QACpJ,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,MAAM,iBAAiB,EAAE,EAAE,CAAC,CAAC;QAE5E,MAAM,UAAU,GAAG,aAAa,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG;YAChB,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,OAAO;SAClB,CAAC;QACF,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QAC5C,CAAC;QACD,eAAe,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACtC,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAc,EAAE,OAA0B;IAClF,eAAe,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;AACpC,CAAC","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ConnectionOptions } from 'mysql2';\nimport { EnvParse } from '@fluidware-it/saddlebag';\nimport * as fs from 'fs';\n\nexport const USE_READ_COMMITTED_ISOLATION = EnvParse.envBool('FW_DB_USE_READ_COMMITTED_ISOLATION', false);\n\nfunction getDbPassword(DB_PASSWORD_FILE: string, DB_PASSWORD: string): string {\n if (DB_PASSWORD_FILE) {\n return fs.readFileSync(DB_PASSWORD_FILE, 'utf8');\n }\n return DB_PASSWORD;\n}\n\nconst memoizedOptions: { [prefix: string]: ConnectionOptions } = {};\n\nexport function getMysqlConnectionOptions(prefix = ''): ConnectionOptions {\n if (!memoizedOptions[prefix]) {\n const DB_PASSWORD = EnvParse.envString(`FW_${prefix}DB_PASSWORD`, '');\n const DB_PASSWORD_FILE = EnvParse.envString(`FW_${prefix}DB_PASSWORD_FILE`, '');\n\n if (!DB_PASSWORD && !DB_PASSWORD_FILE) {\n throw new Error('FW_DB_PASSWORD or FW_DB_PASSWORD_FILE env is required');\n }\n\n const DB_USER = EnvParse.envStringRequired(`FW_${prefix}DB_USER`);\n const DB_HOST = EnvParse.envString(`FW_${prefix}DB_HOST`, 'localhost');\n const DB_PORT = EnvParse.envInt(`FW_${prefix}DB_PORT`, 3306);\n const DB_NAME = EnvParse.envString(`FW_${prefix}DB_NAME`, DB_USER);\n // FW_${prefix}DB_CONN_OPTIONS: JSON string with connection options See https://github.com/mysqljs/mysql#connection-options for all possible options\n const DB_CONN_OPTIONS = EnvParse.envJSON(`FW_${prefix}DB_CONN_OPTIONS`, {});\n\n const dbPassword = getDbPassword(DB_PASSWORD_FILE, DB_PASSWORD);\n const dbOptions = {\n host: DB_HOST,\n port: DB_PORT,\n user: DB_USER,\n password: dbPassword,\n database: DB_NAME\n };\n if (Object.keys(DB_CONN_OPTIONS).length > 0) {\n Object.assign(dbOptions, DB_CONN_OPTIONS);\n }\n memoizedOptions[prefix] = dbOptions;\n }\n return memoizedOptions[prefix];\n}\n\nexport function setMysqlConnectionOptions(prefix: string, options: ConnectionOptions) {\n memoizedOptions[prefix] = options;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dbClient.js","sourceRoot":"","sources":["../../src/dbClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EACL,gBAAgB,EAMjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,MAAM,UAAU,CAAC;AAYnF,MAAM,OAAO,QAAQ;IAInB,YAAY,yBAAsD;QAChE,IAAI,yBAAyB,EAAE;
|
|
1
|
+
{"version":3,"file":"dbClient.js","sourceRoot":"","sources":["../../src/dbClient.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ConnectionOptions } from 'mysql2';\nimport {\n createConnection,\n Connection,\n RowDataPacket,\n ResultSetHeader,\n ProcedureCallPacket,\n FieldPacket\n} from 'mysql2/promise';\nimport { getMysqlConnectionOptions, USE_READ_COMMITTED_ISOLATION } from './config';\n\ninterface ConnectionWrap extends Connection {\n run<T extends ResultSetHeader | ResultSetHeader[] | RowDataPacket[] | RowDataPacket[][] | ProcedureCallPacket>(\n sql: string,\n phs?: (string | number | boolean | null)[]\n ): Promise<{\n rows: T;\n cols: FieldPacket[];\n }>;\n}\n\nexport class DbClient {\n private connection?: ConnectionWrap;\n private readonly connectionOptions: ConnectionOptions;\n\n constructor(connectionOptionsOrPrefix?: ConnectionOptions | string) {\n if (connectionOptionsOrPrefix) {\n if (typeof connectionOptionsOrPrefix === 'string') {\n this.connectionOptions = getMysqlConnectionOptions(connectionOptionsOrPrefix);\n } else {\n this.connectionOptions = connectionOptionsOrPrefix;\n }\n } else {\n this.connectionOptions = getMysqlConnectionOptions('');\n }\n }\n\n public async open() {\n this.connection = (await createConnection(this.connectionOptions)) as ConnectionWrap;\n this.connection.run = async <\n T extends ResultSetHeader | ResultSetHeader[] | RowDataPacket[] | RowDataPacket[][] | ProcedureCallPacket\n >(\n sql: string,\n phs?: (string | number | boolean | null)[]\n ): Promise<{ rows: T; cols: FieldPacket[] }> => {\n if (!this.connection) {\n throw new Error('run() called but no connection available');\n }\n const [rows, cols] = await this.connection.execute<T>(sql, phs);\n return {\n rows,\n cols\n };\n };\n }\n\n public getConnection(): ConnectionWrap | undefined {\n return this.connection;\n }\n\n public async close() {\n if (this.connection) {\n await this.connection.end();\n }\n }\n\n public async startTransaction() {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n if (USE_READ_COMMITTED_ISOLATION) {\n await this.connection.execute(\"SET SESSION tx_isolation='read-committed'\");\n }\n await this.connection.execute('SET AUTOCOMMIT=0');\n }\n\n public async commit(closeTransaction = true) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n await this.connection.execute('COMMIT');\n if (closeTransaction) {\n await this.connection.execute('SET AUTOCOMMIT=1');\n }\n }\n\n public async rollback(closeTransaction = true) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n\n await this.connection.execute('ROLLBACK');\n if (closeTransaction) {\n await this.connection.execute('SET AUTOCOMMIT=1');\n }\n }\n\n public async all(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<RowDataPacket[]>(sql, phs);\n return res.rows;\n }\n\n public async get(sql: string, phs?: (string | number | boolean | null)[]): Promise<RowDataPacket | null> {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<RowDataPacket[]>(sql, phs);\n if (res.rows.length > 1) throw new Error('get() returned more than one row');\n if (res.rows.length === 1) return res.rows[0];\n return null;\n }\n\n public async insert(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<ResultSetHeader>(sql, phs);\n return res.rows.insertId || res.rows.affectedRows;\n }\n\n public async update(sql: string, phs?: (string | number | boolean | null)[], returnChangedRows = false) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<ResultSetHeader>(sql, phs);\n return returnChangedRows ? res.rows.changedRows : res.rows.affectedRows;\n }\n\n public async delete(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<ResultSetHeader>(sql, phs);\n return res.rows.affectedRows;\n }\n\n public async run(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n return this.connection.execute(sql, phs);\n }\n}\n"]}
|
|
@@ -10,12 +10,13 @@ export declare class UpgradeManager {
|
|
|
10
10
|
constructor(opts?: UpgradeManagerConfig);
|
|
11
11
|
private loadCurrentVersion;
|
|
12
12
|
private createDb;
|
|
13
|
-
private
|
|
13
|
+
private migrate;
|
|
14
14
|
private getCurrentVersion;
|
|
15
15
|
private createVersionTable;
|
|
16
16
|
private updateVersion;
|
|
17
17
|
private initDb;
|
|
18
18
|
private upgradeDb;
|
|
19
|
-
checkDb(targetVersion: number, onSchemaInit: (dbClient: DbClient) => Promise<void>, onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>): Promise<
|
|
19
|
+
checkDb(targetVersion: number, onSchemaInit: (dbClient: DbClient) => Promise<void>, onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>): Promise<void>;
|
|
20
|
+
private _checkDb;
|
|
20
21
|
}
|
|
21
22
|
//# sourceMappingURL=upgradeManager.d.ts.map
|
|
@@ -30,8 +30,7 @@ export class UpgradeManager {
|
|
|
30
30
|
return -999;
|
|
31
31
|
}
|
|
32
32
|
else if (row === true) {
|
|
33
|
-
this.logger.info(
|
|
34
|
-
await this.client.close();
|
|
33
|
+
this.logger.info(`Check db: same version ${targetVersion}`);
|
|
35
34
|
return true;
|
|
36
35
|
}
|
|
37
36
|
else if (row) {
|
|
@@ -45,11 +44,10 @@ export class UpgradeManager {
|
|
|
45
44
|
}
|
|
46
45
|
async createDb() {
|
|
47
46
|
try {
|
|
48
|
-
return this.createVersionTable();
|
|
47
|
+
return await this.createVersionTable();
|
|
49
48
|
}
|
|
50
49
|
catch (e) {
|
|
51
|
-
if (e.code === '
|
|
52
|
-
await this.client.close();
|
|
50
|
+
if (e.code === 'ER_TABLE_EXISTS_ERROR') {
|
|
53
51
|
await setTimeout(2000);
|
|
54
52
|
return -1;
|
|
55
53
|
}
|
|
@@ -59,7 +57,7 @@ export class UpgradeManager {
|
|
|
59
57
|
}
|
|
60
58
|
}
|
|
61
59
|
}
|
|
62
|
-
async
|
|
60
|
+
async migrate(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade) {
|
|
63
61
|
try {
|
|
64
62
|
if (currentVersion === 0) {
|
|
65
63
|
await this.initDb(targetVersion, onSchemaInit);
|
|
@@ -71,7 +69,7 @@ export class UpgradeManager {
|
|
|
71
69
|
}
|
|
72
70
|
if (targetVersion > currentVersion) {
|
|
73
71
|
await this.upgradeDb(currentVersion, targetVersion, onSchemaUpgrade);
|
|
74
|
-
this.logger.info(
|
|
72
|
+
this.logger.info(`Db updated to ${targetVersion}`);
|
|
75
73
|
return true;
|
|
76
74
|
}
|
|
77
75
|
}
|
|
@@ -80,7 +78,7 @@ export class UpgradeManager {
|
|
|
80
78
|
this.logger.error('\n');
|
|
81
79
|
this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');
|
|
82
80
|
this.logger.error('\n');
|
|
83
|
-
this.logger.error(
|
|
81
|
+
this.logger.error(`checkDb failed: ${e.message}`);
|
|
84
82
|
this.logger.error('\n');
|
|
85
83
|
this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');
|
|
86
84
|
this.logger.error('\n');
|
|
@@ -88,21 +86,17 @@ export class UpgradeManager {
|
|
|
88
86
|
this.logger.error(e.stack);
|
|
89
87
|
throw e;
|
|
90
88
|
}
|
|
91
|
-
finally {
|
|
92
|
-
await this.client.close();
|
|
93
|
-
}
|
|
94
89
|
return true;
|
|
95
90
|
}
|
|
96
91
|
async getCurrentVersion(targetVersion) {
|
|
97
92
|
const sqlCheck = `select value from ${this.version_table} for update`;
|
|
98
|
-
await this.client.startTransaction();
|
|
99
93
|
let row;
|
|
100
94
|
try {
|
|
101
95
|
row = await this.client.get(sqlCheck);
|
|
102
96
|
if (!row) {
|
|
103
97
|
return false;
|
|
104
98
|
}
|
|
105
|
-
this.logger.debug(
|
|
99
|
+
this.logger.debug(`Versions: ${row.value} vs ${targetVersion}`);
|
|
106
100
|
if (row.value === targetVersion) {
|
|
107
101
|
this.logger.debug('versions are equal, rollback');
|
|
108
102
|
await this.client.rollback();
|
|
@@ -115,7 +109,7 @@ export class UpgradeManager {
|
|
|
115
109
|
if (e.code === 'ER_NO_SUCH_TABLE') {
|
|
116
110
|
return false;
|
|
117
111
|
}
|
|
118
|
-
this.logger.error(
|
|
112
|
+
this.logger.error(`Failed to get current schema version: [${e.code}] ${e.message}`);
|
|
119
113
|
throw e;
|
|
120
114
|
}
|
|
121
115
|
}
|
|
@@ -134,7 +128,7 @@ export class UpgradeManager {
|
|
|
134
128
|
await this.client.get(`select value from ${this.version_table} for update`);
|
|
135
129
|
}
|
|
136
130
|
catch (e) {
|
|
137
|
-
this.logger.error(
|
|
131
|
+
this.logger.error(`Unable to insert -1 version in "${this.version_table} table: [${e.code}] ${e.message}`);
|
|
138
132
|
throw e;
|
|
139
133
|
}
|
|
140
134
|
return 0;
|
|
@@ -162,24 +156,44 @@ export class UpgradeManager {
|
|
|
162
156
|
await this.updateVersion(targetVersion);
|
|
163
157
|
}
|
|
164
158
|
async checkDb(targetVersion, onSchemaInit, onSchemaUpgrade) {
|
|
165
|
-
|
|
166
|
-
let
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (currentVersion === -999) {
|
|
172
|
-
currentVersion = await this.createDb();
|
|
173
|
-
if (currentVersion < 0) {
|
|
174
|
-
await this.checkDb(targetVersion, onSchemaInit, onSchemaUpgrade);
|
|
175
|
-
return;
|
|
159
|
+
let retriesCount = 0;
|
|
160
|
+
let done = false;
|
|
161
|
+
do {
|
|
162
|
+
const ret = await this._checkDb(targetVersion, onSchemaInit, onSchemaUpgrade);
|
|
163
|
+
if (ret >= 0) {
|
|
164
|
+
done = true;
|
|
176
165
|
}
|
|
166
|
+
if (ret < 0) {
|
|
167
|
+
retriesCount++;
|
|
168
|
+
}
|
|
169
|
+
} while (!done && retriesCount < 3);
|
|
170
|
+
}
|
|
171
|
+
async _checkDb(targetVersion, onSchemaInit, onSchemaUpgrade) {
|
|
172
|
+
try {
|
|
173
|
+
await this.client.open();
|
|
174
|
+
await this.client.startTransaction();
|
|
175
|
+
let currentVersion = await this.loadCurrentVersion(targetVersion);
|
|
176
|
+
if (currentVersion === true) {
|
|
177
|
+
return 0;
|
|
178
|
+
}
|
|
179
|
+
this.logger.info(`Check db: currentVersion ${currentVersion} targetVersion ${targetVersion}`);
|
|
180
|
+
if (currentVersion === -999) {
|
|
181
|
+
currentVersion = await this.createDb();
|
|
182
|
+
if (currentVersion < 0) {
|
|
183
|
+
return -1;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else if (currentVersion < 0) {
|
|
187
|
+
this.logger.error('Db in initialization, exiting ');
|
|
188
|
+
throw new Error('Db in initialization, do not proceed');
|
|
189
|
+
}
|
|
190
|
+
await this.migrate(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade);
|
|
191
|
+
return 1;
|
|
177
192
|
}
|
|
178
|
-
|
|
179
|
-
this.
|
|
180
|
-
|
|
193
|
+
finally {
|
|
194
|
+
await this.client.rollback();
|
|
195
|
+
await this.client.close();
|
|
181
196
|
}
|
|
182
|
-
return this._checkDb(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade);
|
|
183
197
|
}
|
|
184
198
|
}
|
|
185
199
|
//# sourceMappingURL=upgradeManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgradeManager.js","sourceRoot":"","sources":["../../src/upgradeManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { setTimeout } from 'node:timers/promises';\nimport { getLogger } from '@fluidware-it/saddlebag';\nimport { DbClient } from './dbClient';\nimport { Logger } from 'pino';\n\nexport type UpgradeManagerConfig = {\n version_table_suffix?: string;\n};\n\nexport class UpgradeManager {\n private version_table: string;\n private client: DbClient;\n private logger: Logger;\n private _default_version_table = '_version';\n\n constructor(opts?: UpgradeManagerConfig) {\n this.version_table = this._default_version_table + (opts?.version_table_suffix || '');\n this.logger = getLogger().child({ component: 'mysql-migrator' });\n this.client = new DbClient();\n }\n\n private async loadCurrentVersion(targetVersion: number) {\n try {\n const row = await this.getCurrentVersion(targetVersion);\n if (row === false) {\n return -999;\n } else if (row === true) {\n this.logger.info('Check db: same version %s', targetVersion);\n await this.client.close();\n return true;\n } else if (row) {\n return row.value;\n }\n } catch (e) {\n this.logger.error(`Failed to read current version: ${e.message}`);\n throw e;\n }\n }\n\n private async createDb() {\n try {\n return this.createVersionTable();\n } catch (e) {\n if (e.code === '23505') {\n await this.client.close();\n await setTimeout(2000);\n return -1;\n } else {\n this.logger.error(`Unable to create ${this.version_table} table: [${e.code}] ${e.message}`);\n throw e;\n }\n }\n }\n\n private async _checkDb(\n currentVersion: number,\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n try {\n if (currentVersion === 0) {\n await this.initDb(targetVersion, onSchemaInit);\n this.logger.info('Db created');\n return true;\n }\n if (targetVersion === currentVersion) {\n return true;\n }\n if (targetVersion > currentVersion) {\n await this.upgradeDb(currentVersion, targetVersion, onSchemaUpgrade);\n this.logger.info('Db updated to ', targetVersion);\n return true;\n }\n } catch (e) {\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error('checkDb failed %s', e.message);\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(e.stack);\n throw e;\n } finally {\n await this.client.close();\n }\n return true;\n }\n\n private async getCurrentVersion(targetVersion: number) {\n const sqlCheck = `select value from ${this.version_table} for update`;\n await this.client.startTransaction();\n let row;\n try {\n row = await this.client.get(sqlCheck);\n if (!row) {\n return false;\n }\n this.logger.debug('Versions: %s vs %s', row.value, targetVersion);\n if (row.value === targetVersion) {\n this.logger.debug('versions are equal, rollback');\n await this.client.rollback();\n return true;\n }\n return row;\n } catch (e) {\n await this.client.rollback();\n if (e.code === 'ER_NO_SUCH_TABLE') {\n return false;\n }\n this.logger.error('Ooops: %s', e.message, e.code);\n throw e;\n }\n }\n\n private async createVersionTable() {\n const sqlCreateTable = `create table ${this.version_table} (value INTEGER PRIMARY KEY)`;\n try {\n await this.client.run(sqlCreateTable);\n } catch (e) {\n await this.client.rollback();\n throw e;\n }\n try {\n const sqlInsertVersionZero = `insert into ${this.version_table} values (-1)`;\n await this.client.insert(sqlInsertVersionZero);\n await this.client.get(`select value from ${this.version_table} for update`);\n } catch (e) {\n this.logger.error('Unable to insert -1 version in %s table: [%s] %s', this.version_table, e.code, e.message);\n throw e;\n }\n return 0;\n }\n\n private async updateVersion(targetVersion: number) {\n const sql = `update ${this.version_table} set value = ?`;\n await this.client.update(sql, [targetVersion]);\n await this.client.commit();\n }\n\n private async initDb(targetVersion: number, onInit: (dbClient: DbClient) => Promise<void>) {\n const dbConn = new DbClient();\n try {\n await dbConn.open();\n await onInit(dbConn);\n await this.updateVersion(targetVersion);\n } finally {\n if (dbConn) {\n await dbConn.close();\n }\n }\n }\n\n private async upgradeDb(\n fromVersion: number,\n targetVersion: number,\n onUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n await onUpgrade(this.client, fromVersion);\n await this.updateVersion(targetVersion);\n }\n\n async checkDb(\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n await this.client.open();\n let currentVersion = await this.loadCurrentVersion(targetVersion);\n if (currentVersion === true) {\n return true;\n }\n this.logger.info('Check db: currentVersion %s targetVersion %s', currentVersion, targetVersion);\n\n if (currentVersion === -999) {\n currentVersion = await this.createDb();\n if (currentVersion < 0) {\n await this.checkDb(targetVersion, onSchemaInit, onSchemaUpgrade);\n return;\n }\n } else if (currentVersion < 0) {\n this.logger.error('Db in initialization, exiting ');\n throw new Error('Db in initialization, do not proceed');\n }\n return this._checkDb(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"upgradeManager.js","sourceRoot":"","sources":["../../src/upgradeManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { setTimeout } from 'node:timers/promises';\nimport { getLogger } from '@fluidware-it/saddlebag';\nimport { DbClient } from './dbClient';\nimport { Logger } from 'pino';\n\nexport type UpgradeManagerConfig = {\n version_table_suffix?: string;\n};\n\nexport class UpgradeManager {\n private version_table: string;\n private client: DbClient;\n private logger: Logger;\n private _default_version_table = '_version';\n\n constructor(opts?: UpgradeManagerConfig) {\n this.version_table = this._default_version_table + (opts?.version_table_suffix || '');\n this.logger = getLogger().child({ component: 'mysql-migrator' });\n this.client = new DbClient();\n }\n\n private async loadCurrentVersion(targetVersion: number) {\n try {\n const row = await this.getCurrentVersion(targetVersion);\n if (row === false) {\n return -999;\n } else if (row === true) {\n this.logger.info(`Check db: same version ${targetVersion}`);\n return true;\n } else if (row) {\n return row.value;\n }\n } catch (e) {\n this.logger.error(`Failed to read current version: ${e.message}`);\n throw e;\n }\n }\n\n private async createDb() {\n try {\n return await this.createVersionTable();\n } catch (e) {\n if (e.code === 'ER_TABLE_EXISTS_ERROR') {\n await setTimeout(2000);\n return -1;\n } else {\n this.logger.error(`Unable to create ${this.version_table} table: [${e.code}] ${e.message}`);\n throw e;\n }\n }\n }\n\n private async migrate(\n currentVersion: number,\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n try {\n if (currentVersion === 0) {\n await this.initDb(targetVersion, onSchemaInit);\n this.logger.info('Db created');\n return true;\n }\n if (targetVersion === currentVersion) {\n return true;\n }\n if (targetVersion > currentVersion) {\n await this.upgradeDb(currentVersion, targetVersion, onSchemaUpgrade);\n this.logger.info(`Db updated to ${targetVersion}`);\n return true;\n }\n } catch (e) {\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error(`checkDb failed: ${e.message}`);\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(e.stack);\n throw e;\n }\n return true;\n }\n\n private async getCurrentVersion(targetVersion: number) {\n const sqlCheck = `select value from ${this.version_table} for update`;\n let row;\n try {\n row = await this.client.get(sqlCheck);\n if (!row) {\n return false;\n }\n this.logger.debug(`Versions: ${row.value} vs ${targetVersion}`);\n if (row.value === targetVersion) {\n this.logger.debug('versions are equal, rollback');\n await this.client.rollback();\n return true;\n }\n return row;\n } catch (e) {\n await this.client.rollback();\n if (e.code === 'ER_NO_SUCH_TABLE') {\n return false;\n }\n this.logger.error(`Failed to get current schema version: [${e.code}] ${e.message}`);\n throw e;\n }\n }\n\n private async createVersionTable() {\n const sqlCreateTable = `create table ${this.version_table} (value INTEGER PRIMARY KEY)`;\n try {\n await this.client.run(sqlCreateTable);\n } catch (e) {\n await this.client.rollback();\n throw e;\n }\n try {\n const sqlInsertVersionZero = `insert into ${this.version_table} values (-1)`;\n await this.client.insert(sqlInsertVersionZero);\n await this.client.get(`select value from ${this.version_table} for update`);\n } catch (e) {\n this.logger.error(`Unable to insert -1 version in \"${this.version_table} table: [${e.code}] ${e.message}`);\n throw e;\n }\n return 0;\n }\n\n private async updateVersion(targetVersion: number) {\n const sql = `update ${this.version_table} set value = ?`;\n await this.client.update(sql, [targetVersion]);\n await this.client.commit();\n }\n\n private async initDb(targetVersion: number, onInit: (dbClient: DbClient) => Promise<void>) {\n const dbConn = new DbClient();\n try {\n await dbConn.open();\n await onInit(dbConn);\n await this.updateVersion(targetVersion);\n } finally {\n if (dbConn) {\n await dbConn.close();\n }\n }\n }\n\n private async upgradeDb(\n fromVersion: number,\n targetVersion: number,\n onUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n await onUpgrade(this.client, fromVersion);\n await this.updateVersion(targetVersion);\n }\n\n public async checkDb(\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n let retriesCount = 0;\n let done = false;\n do {\n const ret = await this._checkDb(targetVersion, onSchemaInit, onSchemaUpgrade);\n if (ret >= 0) {\n done = true;\n }\n if (ret < 0) {\n retriesCount++;\n }\n } while (!done && retriesCount < 3);\n }\n\n private async _checkDb(\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n try {\n await this.client.open();\n await this.client.startTransaction();\n let currentVersion = await this.loadCurrentVersion(targetVersion);\n if (currentVersion === true) {\n return 0;\n }\n this.logger.info(`Check db: currentVersion ${currentVersion} targetVersion ${targetVersion}`);\n if (currentVersion === -999) {\n currentVersion = await this.createDb();\n if (currentVersion < 0) {\n return -1;\n }\n } else if (currentVersion < 0) {\n this.logger.error('Db in initialization, exiting ');\n throw new Error('Db in initialization, do not proceed');\n }\n await this.migrate(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade);\n return 1;\n } finally {\n await this.client.rollback();\n await this.client.close();\n }\n }\n}\n"]}
|
package/build/src/config.js
CHANGED
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.
|
|
18
|
+
exports.USE_READ_COMMITTED_ISOLATION = void 0;
|
|
19
|
+
exports.getMysqlConnectionOptions = getMysqlConnectionOptions;
|
|
20
|
+
exports.setMysqlConnectionOptions = setMysqlConnectionOptions;
|
|
19
21
|
const saddlebag_1 = require("@fluidware-it/saddlebag");
|
|
20
22
|
const fs = require("fs");
|
|
21
23
|
exports.USE_READ_COMMITTED_ISOLATION = saddlebag_1.EnvParse.envBool('FW_DB_USE_READ_COMMITTED_ISOLATION', false);
|
|
@@ -54,9 +56,7 @@ function getMysqlConnectionOptions(prefix = '') {
|
|
|
54
56
|
}
|
|
55
57
|
return memoizedOptions[prefix];
|
|
56
58
|
}
|
|
57
|
-
exports.getMysqlConnectionOptions = getMysqlConnectionOptions;
|
|
58
59
|
function setMysqlConnectionOptions(prefix, options) {
|
|
59
60
|
memoizedOptions[prefix] = options;
|
|
60
61
|
}
|
|
61
|
-
exports.setMysqlConnectionOptions = setMysqlConnectionOptions;
|
|
62
62
|
//# sourceMappingURL=config.js.map
|
package/build/src/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAiBH,8DA8BC;AAED,8DAEC;AAhDD,uDAAmD;AACnD,yBAAyB;AAEZ,QAAA,4BAA4B,GAAG,oBAAQ,CAAC,OAAO,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;AAE1G,SAAS,aAAa,CAAC,gBAAwB,EAAE,WAAmB;IAClE,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,eAAe,GAA4C,EAAE,CAAC;AAEpE,SAAgB,yBAAyB,CAAC,MAAM,GAAG,EAAE;IACnD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,oBAAQ,CAAC,SAAS,CAAC,MAAM,MAAM,aAAa,EAAE,EAAE,CAAC,CAAC;QACtE,MAAM,gBAAgB,GAAG,oBAAQ,CAAC,SAAS,CAAC,MAAM,MAAM,kBAAkB,EAAE,EAAE,CAAC,CAAC;QAEhF,IAAI,CAAC,WAAW,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,OAAO,GAAG,oBAAQ,CAAC,iBAAiB,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,oBAAQ,CAAC,SAAS,CAAC,MAAM,MAAM,SAAS,EAAE,WAAW,CAAC,CAAC;QACvE,MAAM,OAAO,GAAG,oBAAQ,CAAC,MAAM,CAAC,MAAM,MAAM,SAAS,EAAE,IAAI,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,oBAAQ,CAAC,SAAS,CAAC,MAAM,MAAM,SAAS,EAAE,OAAO,CAAC,CAAC;QACnE,oJAAoJ;QACpJ,MAAM,eAAe,GAAG,oBAAQ,CAAC,OAAO,CAAC,MAAM,MAAM,iBAAiB,EAAE,EAAE,CAAC,CAAC;QAE5E,MAAM,UAAU,GAAG,aAAa,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG;YAChB,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,OAAO;SAClB,CAAC;QACF,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QAC5C,CAAC;QACD,eAAe,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACtC,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED,SAAgB,yBAAyB,CAAC,MAAc,EAAE,OAA0B;IAClF,eAAe,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;AACpC,CAAC","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ConnectionOptions } from 'mysql2';\nimport { EnvParse } from '@fluidware-it/saddlebag';\nimport * as fs from 'fs';\n\nexport const USE_READ_COMMITTED_ISOLATION = EnvParse.envBool('FW_DB_USE_READ_COMMITTED_ISOLATION', false);\n\nfunction getDbPassword(DB_PASSWORD_FILE: string, DB_PASSWORD: string): string {\n if (DB_PASSWORD_FILE) {\n return fs.readFileSync(DB_PASSWORD_FILE, 'utf8');\n }\n return DB_PASSWORD;\n}\n\nconst memoizedOptions: { [prefix: string]: ConnectionOptions } = {};\n\nexport function getMysqlConnectionOptions(prefix = ''): ConnectionOptions {\n if (!memoizedOptions[prefix]) {\n const DB_PASSWORD = EnvParse.envString(`FW_${prefix}DB_PASSWORD`, '');\n const DB_PASSWORD_FILE = EnvParse.envString(`FW_${prefix}DB_PASSWORD_FILE`, '');\n\n if (!DB_PASSWORD && !DB_PASSWORD_FILE) {\n throw new Error('FW_DB_PASSWORD or FW_DB_PASSWORD_FILE env is required');\n }\n\n const DB_USER = EnvParse.envStringRequired(`FW_${prefix}DB_USER`);\n const DB_HOST = EnvParse.envString(`FW_${prefix}DB_HOST`, 'localhost');\n const DB_PORT = EnvParse.envInt(`FW_${prefix}DB_PORT`, 3306);\n const DB_NAME = EnvParse.envString(`FW_${prefix}DB_NAME`, DB_USER);\n // FW_${prefix}DB_CONN_OPTIONS: JSON string with connection options See https://github.com/mysqljs/mysql#connection-options for all possible options\n const DB_CONN_OPTIONS = EnvParse.envJSON(`FW_${prefix}DB_CONN_OPTIONS`, {});\n\n const dbPassword = getDbPassword(DB_PASSWORD_FILE, DB_PASSWORD);\n const dbOptions = {\n host: DB_HOST,\n port: DB_PORT,\n user: DB_USER,\n password: dbPassword,\n database: DB_NAME\n };\n if (Object.keys(DB_CONN_OPTIONS).length > 0) {\n Object.assign(dbOptions, DB_CONN_OPTIONS);\n }\n memoizedOptions[prefix] = dbOptions;\n }\n return memoizedOptions[prefix];\n}\n\nexport function setMysqlConnectionOptions(prefix: string, options: ConnectionOptions) {\n memoizedOptions[prefix] = options;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dbClient.js","sourceRoot":"","sources":["../../src/dbClient.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAGH,4CAOwB;AACxB,qCAAmF;AAYnF,MAAa,QAAQ;IAInB,YAAY,yBAAsD;QAChE,IAAI,yBAAyB,EAAE;
|
|
1
|
+
{"version":3,"file":"dbClient.js","sourceRoot":"","sources":["../../src/dbClient.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ConnectionOptions } from 'mysql2';\nimport {\n createConnection,\n Connection,\n RowDataPacket,\n ResultSetHeader,\n ProcedureCallPacket,\n FieldPacket\n} from 'mysql2/promise';\nimport { getMysqlConnectionOptions, USE_READ_COMMITTED_ISOLATION } from './config';\n\ninterface ConnectionWrap extends Connection {\n run<T extends ResultSetHeader | ResultSetHeader[] | RowDataPacket[] | RowDataPacket[][] | ProcedureCallPacket>(\n sql: string,\n phs?: (string | number | boolean | null)[]\n ): Promise<{\n rows: T;\n cols: FieldPacket[];\n }>;\n}\n\nexport class DbClient {\n private connection?: ConnectionWrap;\n private readonly connectionOptions: ConnectionOptions;\n\n constructor(connectionOptionsOrPrefix?: ConnectionOptions | string) {\n if (connectionOptionsOrPrefix) {\n if (typeof connectionOptionsOrPrefix === 'string') {\n this.connectionOptions = getMysqlConnectionOptions(connectionOptionsOrPrefix);\n } else {\n this.connectionOptions = connectionOptionsOrPrefix;\n }\n } else {\n this.connectionOptions = getMysqlConnectionOptions('');\n }\n }\n\n public async open() {\n this.connection = (await createConnection(this.connectionOptions)) as ConnectionWrap;\n this.connection.run = async <\n T extends ResultSetHeader | ResultSetHeader[] | RowDataPacket[] | RowDataPacket[][] | ProcedureCallPacket\n >(\n sql: string,\n phs?: (string | number | boolean | null)[]\n ): Promise<{ rows: T; cols: FieldPacket[] }> => {\n if (!this.connection) {\n throw new Error('run() called but no connection available');\n }\n const [rows, cols] = await this.connection.execute<T>(sql, phs);\n return {\n rows,\n cols\n };\n };\n }\n\n public getConnection(): ConnectionWrap | undefined {\n return this.connection;\n }\n\n public async close() {\n if (this.connection) {\n await this.connection.end();\n }\n }\n\n public async startTransaction() {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n if (USE_READ_COMMITTED_ISOLATION) {\n await this.connection.execute(\"SET SESSION tx_isolation='read-committed'\");\n }\n await this.connection.execute('SET AUTOCOMMIT=0');\n }\n\n public async commit(closeTransaction = true) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n await this.connection.execute('COMMIT');\n if (closeTransaction) {\n await this.connection.execute('SET AUTOCOMMIT=1');\n }\n }\n\n public async rollback(closeTransaction = true) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n\n await this.connection.execute('ROLLBACK');\n if (closeTransaction) {\n await this.connection.execute('SET AUTOCOMMIT=1');\n }\n }\n\n public async all(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<RowDataPacket[]>(sql, phs);\n return res.rows;\n }\n\n public async get(sql: string, phs?: (string | number | boolean | null)[]): Promise<RowDataPacket | null> {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<RowDataPacket[]>(sql, phs);\n if (res.rows.length > 1) throw new Error('get() returned more than one row');\n if (res.rows.length === 1) return res.rows[0];\n return null;\n }\n\n public async insert(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<ResultSetHeader>(sql, phs);\n return res.rows.insertId || res.rows.affectedRows;\n }\n\n public async update(sql: string, phs?: (string | number | boolean | null)[], returnChangedRows = false) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<ResultSetHeader>(sql, phs);\n return returnChangedRows ? res.rows.changedRows : res.rows.affectedRows;\n }\n\n public async delete(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n const res = await this.connection.run<ResultSetHeader>(sql, phs);\n return res.rows.affectedRows;\n }\n\n public async run(sql: string, phs?: (string | number | boolean | null)[]) {\n if (!this.connection) {\n throw new Error('no connection available');\n }\n return this.connection.execute(sql, phs);\n }\n}\n"]}
|
|
@@ -10,12 +10,13 @@ export declare class UpgradeManager {
|
|
|
10
10
|
constructor(opts?: UpgradeManagerConfig);
|
|
11
11
|
private loadCurrentVersion;
|
|
12
12
|
private createDb;
|
|
13
|
-
private
|
|
13
|
+
private migrate;
|
|
14
14
|
private getCurrentVersion;
|
|
15
15
|
private createVersionTable;
|
|
16
16
|
private updateVersion;
|
|
17
17
|
private initDb;
|
|
18
18
|
private upgradeDb;
|
|
19
|
-
checkDb(targetVersion: number, onSchemaInit: (dbClient: DbClient) => Promise<void>, onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>): Promise<
|
|
19
|
+
checkDb(targetVersion: number, onSchemaInit: (dbClient: DbClient) => Promise<void>, onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>): Promise<void>;
|
|
20
|
+
private _checkDb;
|
|
20
21
|
}
|
|
21
22
|
//# sourceMappingURL=upgradeManager.d.ts.map
|
|
@@ -33,8 +33,7 @@ class UpgradeManager {
|
|
|
33
33
|
return -999;
|
|
34
34
|
}
|
|
35
35
|
else if (row === true) {
|
|
36
|
-
this.logger.info(
|
|
37
|
-
await this.client.close();
|
|
36
|
+
this.logger.info(`Check db: same version ${targetVersion}`);
|
|
38
37
|
return true;
|
|
39
38
|
}
|
|
40
39
|
else if (row) {
|
|
@@ -48,11 +47,10 @@ class UpgradeManager {
|
|
|
48
47
|
}
|
|
49
48
|
async createDb() {
|
|
50
49
|
try {
|
|
51
|
-
return this.createVersionTable();
|
|
50
|
+
return await this.createVersionTable();
|
|
52
51
|
}
|
|
53
52
|
catch (e) {
|
|
54
|
-
if (e.code === '
|
|
55
|
-
await this.client.close();
|
|
53
|
+
if (e.code === 'ER_TABLE_EXISTS_ERROR') {
|
|
56
54
|
await (0, promises_1.setTimeout)(2000);
|
|
57
55
|
return -1;
|
|
58
56
|
}
|
|
@@ -62,7 +60,7 @@ class UpgradeManager {
|
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
|
-
async
|
|
63
|
+
async migrate(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade) {
|
|
66
64
|
try {
|
|
67
65
|
if (currentVersion === 0) {
|
|
68
66
|
await this.initDb(targetVersion, onSchemaInit);
|
|
@@ -74,7 +72,7 @@ class UpgradeManager {
|
|
|
74
72
|
}
|
|
75
73
|
if (targetVersion > currentVersion) {
|
|
76
74
|
await this.upgradeDb(currentVersion, targetVersion, onSchemaUpgrade);
|
|
77
|
-
this.logger.info(
|
|
75
|
+
this.logger.info(`Db updated to ${targetVersion}`);
|
|
78
76
|
return true;
|
|
79
77
|
}
|
|
80
78
|
}
|
|
@@ -83,7 +81,7 @@ class UpgradeManager {
|
|
|
83
81
|
this.logger.error('\n');
|
|
84
82
|
this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');
|
|
85
83
|
this.logger.error('\n');
|
|
86
|
-
this.logger.error(
|
|
84
|
+
this.logger.error(`checkDb failed: ${e.message}`);
|
|
87
85
|
this.logger.error('\n');
|
|
88
86
|
this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');
|
|
89
87
|
this.logger.error('\n');
|
|
@@ -91,21 +89,17 @@ class UpgradeManager {
|
|
|
91
89
|
this.logger.error(e.stack);
|
|
92
90
|
throw e;
|
|
93
91
|
}
|
|
94
|
-
finally {
|
|
95
|
-
await this.client.close();
|
|
96
|
-
}
|
|
97
92
|
return true;
|
|
98
93
|
}
|
|
99
94
|
async getCurrentVersion(targetVersion) {
|
|
100
95
|
const sqlCheck = `select value from ${this.version_table} for update`;
|
|
101
|
-
await this.client.startTransaction();
|
|
102
96
|
let row;
|
|
103
97
|
try {
|
|
104
98
|
row = await this.client.get(sqlCheck);
|
|
105
99
|
if (!row) {
|
|
106
100
|
return false;
|
|
107
101
|
}
|
|
108
|
-
this.logger.debug(
|
|
102
|
+
this.logger.debug(`Versions: ${row.value} vs ${targetVersion}`);
|
|
109
103
|
if (row.value === targetVersion) {
|
|
110
104
|
this.logger.debug('versions are equal, rollback');
|
|
111
105
|
await this.client.rollback();
|
|
@@ -118,7 +112,7 @@ class UpgradeManager {
|
|
|
118
112
|
if (e.code === 'ER_NO_SUCH_TABLE') {
|
|
119
113
|
return false;
|
|
120
114
|
}
|
|
121
|
-
this.logger.error(
|
|
115
|
+
this.logger.error(`Failed to get current schema version: [${e.code}] ${e.message}`);
|
|
122
116
|
throw e;
|
|
123
117
|
}
|
|
124
118
|
}
|
|
@@ -137,7 +131,7 @@ class UpgradeManager {
|
|
|
137
131
|
await this.client.get(`select value from ${this.version_table} for update`);
|
|
138
132
|
}
|
|
139
133
|
catch (e) {
|
|
140
|
-
this.logger.error(
|
|
134
|
+
this.logger.error(`Unable to insert -1 version in "${this.version_table} table: [${e.code}] ${e.message}`);
|
|
141
135
|
throw e;
|
|
142
136
|
}
|
|
143
137
|
return 0;
|
|
@@ -165,24 +159,44 @@ class UpgradeManager {
|
|
|
165
159
|
await this.updateVersion(targetVersion);
|
|
166
160
|
}
|
|
167
161
|
async checkDb(targetVersion, onSchemaInit, onSchemaUpgrade) {
|
|
168
|
-
|
|
169
|
-
let
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
if (currentVersion === -999) {
|
|
175
|
-
currentVersion = await this.createDb();
|
|
176
|
-
if (currentVersion < 0) {
|
|
177
|
-
await this.checkDb(targetVersion, onSchemaInit, onSchemaUpgrade);
|
|
178
|
-
return;
|
|
162
|
+
let retriesCount = 0;
|
|
163
|
+
let done = false;
|
|
164
|
+
do {
|
|
165
|
+
const ret = await this._checkDb(targetVersion, onSchemaInit, onSchemaUpgrade);
|
|
166
|
+
if (ret >= 0) {
|
|
167
|
+
done = true;
|
|
179
168
|
}
|
|
169
|
+
if (ret < 0) {
|
|
170
|
+
retriesCount++;
|
|
171
|
+
}
|
|
172
|
+
} while (!done && retriesCount < 3);
|
|
173
|
+
}
|
|
174
|
+
async _checkDb(targetVersion, onSchemaInit, onSchemaUpgrade) {
|
|
175
|
+
try {
|
|
176
|
+
await this.client.open();
|
|
177
|
+
await this.client.startTransaction();
|
|
178
|
+
let currentVersion = await this.loadCurrentVersion(targetVersion);
|
|
179
|
+
if (currentVersion === true) {
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
this.logger.info(`Check db: currentVersion ${currentVersion} targetVersion ${targetVersion}`);
|
|
183
|
+
if (currentVersion === -999) {
|
|
184
|
+
currentVersion = await this.createDb();
|
|
185
|
+
if (currentVersion < 0) {
|
|
186
|
+
return -1;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else if (currentVersion < 0) {
|
|
190
|
+
this.logger.error('Db in initialization, exiting ');
|
|
191
|
+
throw new Error('Db in initialization, do not proceed');
|
|
192
|
+
}
|
|
193
|
+
await this.migrate(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade);
|
|
194
|
+
return 1;
|
|
180
195
|
}
|
|
181
|
-
|
|
182
|
-
this.
|
|
183
|
-
|
|
196
|
+
finally {
|
|
197
|
+
await this.client.rollback();
|
|
198
|
+
await this.client.close();
|
|
184
199
|
}
|
|
185
|
-
return this._checkDb(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade);
|
|
186
200
|
}
|
|
187
201
|
}
|
|
188
202
|
exports.UpgradeManager = UpgradeManager;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgradeManager.js","sourceRoot":"","sources":["../../src/upgradeManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { setTimeout } from 'node:timers/promises';\nimport { getLogger } from '@fluidware-it/saddlebag';\nimport { DbClient } from './dbClient';\nimport { Logger } from 'pino';\n\nexport type UpgradeManagerConfig = {\n version_table_suffix?: string;\n};\n\nexport class UpgradeManager {\n private version_table: string;\n private client: DbClient;\n private logger: Logger;\n private _default_version_table = '_version';\n\n constructor(opts?: UpgradeManagerConfig) {\n this.version_table = this._default_version_table + (opts?.version_table_suffix || '');\n this.logger = getLogger().child({ component: 'mysql-migrator' });\n this.client = new DbClient();\n }\n\n private async loadCurrentVersion(targetVersion: number) {\n try {\n const row = await this.getCurrentVersion(targetVersion);\n if (row === false) {\n return -999;\n } else if (row === true) {\n this.logger.info('Check db: same version %s', targetVersion);\n await this.client.close();\n return true;\n } else if (row) {\n return row.value;\n }\n } catch (e) {\n this.logger.error(`Failed to read current version: ${e.message}`);\n throw e;\n }\n }\n\n private async createDb() {\n try {\n return this.createVersionTable();\n } catch (e) {\n if (e.code === '23505') {\n await this.client.close();\n await setTimeout(2000);\n return -1;\n } else {\n this.logger.error(`Unable to create ${this.version_table} table: [${e.code}] ${e.message}`);\n throw e;\n }\n }\n }\n\n private async _checkDb(\n currentVersion: number,\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n try {\n if (currentVersion === 0) {\n await this.initDb(targetVersion, onSchemaInit);\n this.logger.info('Db created');\n return true;\n }\n if (targetVersion === currentVersion) {\n return true;\n }\n if (targetVersion > currentVersion) {\n await this.upgradeDb(currentVersion, targetVersion, onSchemaUpgrade);\n this.logger.info('Db updated to ', targetVersion);\n return true;\n }\n } catch (e) {\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error('checkDb failed %s', e.message);\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(e.stack);\n throw e;\n } finally {\n await this.client.close();\n }\n return true;\n }\n\n private async getCurrentVersion(targetVersion: number) {\n const sqlCheck = `select value from ${this.version_table} for update`;\n await this.client.startTransaction();\n let row;\n try {\n row = await this.client.get(sqlCheck);\n if (!row) {\n return false;\n }\n this.logger.debug('Versions: %s vs %s', row.value, targetVersion);\n if (row.value === targetVersion) {\n this.logger.debug('versions are equal, rollback');\n await this.client.rollback();\n return true;\n }\n return row;\n } catch (e) {\n await this.client.rollback();\n if (e.code === 'ER_NO_SUCH_TABLE') {\n return false;\n }\n this.logger.error('Ooops: %s', e.message, e.code);\n throw e;\n }\n }\n\n private async createVersionTable() {\n const sqlCreateTable = `create table ${this.version_table} (value INTEGER PRIMARY KEY)`;\n try {\n await this.client.run(sqlCreateTable);\n } catch (e) {\n await this.client.rollback();\n throw e;\n }\n try {\n const sqlInsertVersionZero = `insert into ${this.version_table} values (-1)`;\n await this.client.insert(sqlInsertVersionZero);\n await this.client.get(`select value from ${this.version_table} for update`);\n } catch (e) {\n this.logger.error('Unable to insert -1 version in %s table: [%s] %s', this.version_table, e.code, e.message);\n throw e;\n }\n return 0;\n }\n\n private async updateVersion(targetVersion: number) {\n const sql = `update ${this.version_table} set value = ?`;\n await this.client.update(sql, [targetVersion]);\n await this.client.commit();\n }\n\n private async initDb(targetVersion: number, onInit: (dbClient: DbClient) => Promise<void>) {\n const dbConn = new DbClient();\n try {\n await dbConn.open();\n await onInit(dbConn);\n await this.updateVersion(targetVersion);\n } finally {\n if (dbConn) {\n await dbConn.close();\n }\n }\n }\n\n private async upgradeDb(\n fromVersion: number,\n targetVersion: number,\n onUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n await onUpgrade(this.client, fromVersion);\n await this.updateVersion(targetVersion);\n }\n\n async checkDb(\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n await this.client.open();\n let currentVersion = await this.loadCurrentVersion(targetVersion);\n if (currentVersion === true) {\n return true;\n }\n this.logger.info('Check db: currentVersion %s targetVersion %s', currentVersion, targetVersion);\n\n if (currentVersion === -999) {\n currentVersion = await this.createDb();\n if (currentVersion < 0) {\n await this.checkDb(targetVersion, onSchemaInit, onSchemaUpgrade);\n return;\n }\n } else if (currentVersion < 0) {\n this.logger.error('Db in initialization, exiting ');\n throw new Error('Db in initialization, do not proceed');\n }\n return this._checkDb(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"upgradeManager.js","sourceRoot":"","sources":["../../src/upgradeManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { setTimeout } from 'node:timers/promises';\nimport { getLogger } from '@fluidware-it/saddlebag';\nimport { DbClient } from './dbClient';\nimport { Logger } from 'pino';\n\nexport type UpgradeManagerConfig = {\n version_table_suffix?: string;\n};\n\nexport class UpgradeManager {\n private version_table: string;\n private client: DbClient;\n private logger: Logger;\n private _default_version_table = '_version';\n\n constructor(opts?: UpgradeManagerConfig) {\n this.version_table = this._default_version_table + (opts?.version_table_suffix || '');\n this.logger = getLogger().child({ component: 'mysql-migrator' });\n this.client = new DbClient();\n }\n\n private async loadCurrentVersion(targetVersion: number) {\n try {\n const row = await this.getCurrentVersion(targetVersion);\n if (row === false) {\n return -999;\n } else if (row === true) {\n this.logger.info(`Check db: same version ${targetVersion}`);\n return true;\n } else if (row) {\n return row.value;\n }\n } catch (e) {\n this.logger.error(`Failed to read current version: ${e.message}`);\n throw e;\n }\n }\n\n private async createDb() {\n try {\n return await this.createVersionTable();\n } catch (e) {\n if (e.code === 'ER_TABLE_EXISTS_ERROR') {\n await setTimeout(2000);\n return -1;\n } else {\n this.logger.error(`Unable to create ${this.version_table} table: [${e.code}] ${e.message}`);\n throw e;\n }\n }\n }\n\n private async migrate(\n currentVersion: number,\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n try {\n if (currentVersion === 0) {\n await this.initDb(targetVersion, onSchemaInit);\n this.logger.info('Db created');\n return true;\n }\n if (targetVersion === currentVersion) {\n return true;\n }\n if (targetVersion > currentVersion) {\n await this.upgradeDb(currentVersion, targetVersion, onSchemaUpgrade);\n this.logger.info(`Db updated to ${targetVersion}`);\n return true;\n }\n } catch (e) {\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error(`checkDb failed: ${e.message}`);\n this.logger.error('\\n');\n this.logger.error(' !!!!!!!! FATAL ERROR !!!!!!!!');\n this.logger.error('\\n');\n this.logger.error('\\n');\n this.logger.error(e.stack);\n throw e;\n }\n return true;\n }\n\n private async getCurrentVersion(targetVersion: number) {\n const sqlCheck = `select value from ${this.version_table} for update`;\n let row;\n try {\n row = await this.client.get(sqlCheck);\n if (!row) {\n return false;\n }\n this.logger.debug(`Versions: ${row.value} vs ${targetVersion}`);\n if (row.value === targetVersion) {\n this.logger.debug('versions are equal, rollback');\n await this.client.rollback();\n return true;\n }\n return row;\n } catch (e) {\n await this.client.rollback();\n if (e.code === 'ER_NO_SUCH_TABLE') {\n return false;\n }\n this.logger.error(`Failed to get current schema version: [${e.code}] ${e.message}`);\n throw e;\n }\n }\n\n private async createVersionTable() {\n const sqlCreateTable = `create table ${this.version_table} (value INTEGER PRIMARY KEY)`;\n try {\n await this.client.run(sqlCreateTable);\n } catch (e) {\n await this.client.rollback();\n throw e;\n }\n try {\n const sqlInsertVersionZero = `insert into ${this.version_table} values (-1)`;\n await this.client.insert(sqlInsertVersionZero);\n await this.client.get(`select value from ${this.version_table} for update`);\n } catch (e) {\n this.logger.error(`Unable to insert -1 version in \"${this.version_table} table: [${e.code}] ${e.message}`);\n throw e;\n }\n return 0;\n }\n\n private async updateVersion(targetVersion: number) {\n const sql = `update ${this.version_table} set value = ?`;\n await this.client.update(sql, [targetVersion]);\n await this.client.commit();\n }\n\n private async initDb(targetVersion: number, onInit: (dbClient: DbClient) => Promise<void>) {\n const dbConn = new DbClient();\n try {\n await dbConn.open();\n await onInit(dbConn);\n await this.updateVersion(targetVersion);\n } finally {\n if (dbConn) {\n await dbConn.close();\n }\n }\n }\n\n private async upgradeDb(\n fromVersion: number,\n targetVersion: number,\n onUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n await onUpgrade(this.client, fromVersion);\n await this.updateVersion(targetVersion);\n }\n\n public async checkDb(\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n let retriesCount = 0;\n let done = false;\n do {\n const ret = await this._checkDb(targetVersion, onSchemaInit, onSchemaUpgrade);\n if (ret >= 0) {\n done = true;\n }\n if (ret < 0) {\n retriesCount++;\n }\n } while (!done && retriesCount < 3);\n }\n\n private async _checkDb(\n targetVersion: number,\n onSchemaInit: (dbClient: DbClient) => Promise<void>,\n onSchemaUpgrade: (dbClient: DbClient, from: number) => Promise<void>\n ) {\n try {\n await this.client.open();\n await this.client.startTransaction();\n let currentVersion = await this.loadCurrentVersion(targetVersion);\n if (currentVersion === true) {\n return 0;\n }\n this.logger.info(`Check db: currentVersion ${currentVersion} targetVersion ${targetVersion}`);\n if (currentVersion === -999) {\n currentVersion = await this.createDb();\n if (currentVersion < 0) {\n return -1;\n }\n } else if (currentVersion < 0) {\n this.logger.error('Db in initialization, exiting ');\n throw new Error('Db in initialization, do not proceed');\n }\n await this.migrate(currentVersion, targetVersion, onSchemaInit, onSchemaUpgrade);\n return 1;\n } finally {\n await this.client.rollback();\n await this.client.close();\n }\n }\n}\n"]}
|
package/build/src/utils.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.getDateAsUTCMysqlString =
|
|
18
|
+
exports.getDateAsUTCMysqlString = getDateAsUTCMysqlString;
|
|
19
19
|
function getDateAsUTCMysqlString(date, mills = false) {
|
|
20
20
|
const year = date.getUTCFullYear();
|
|
21
21
|
const month = `${date.getUTCMonth() + 1}`.padStart(2, '0');
|
|
@@ -26,5 +26,4 @@ function getDateAsUTCMysqlString(date, mills = false) {
|
|
|
26
26
|
const millisecond = mills ? '.' + `${date.getUTCMilliseconds()}`.padStart(3, '0') : '';
|
|
27
27
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}${millisecond}`;
|
|
28
28
|
}
|
|
29
|
-
exports.getDateAsUTCMysqlString = getDateAsUTCMysqlString;
|
|
30
29
|
//# sourceMappingURL=utils.js.map
|
package/build/src/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;AAEH,0DASC;AATD,SAAgB,uBAAuB,CAAC,IAAU,EAAE,KAAK,GAAG,KAAK;IAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,OAAO,IAAI,OAAO,GAAG,WAAW,EAAE,CAAC;AAChF,CAAC","sourcesContent":["/*\n * Copyright Fluidware srl\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function getDateAsUTCMysqlString(date: Date, mills = false) {\n const year = date.getUTCFullYear();\n const month = `${date.getUTCMonth() + 1}`.padStart(2, '0');\n const day = `${date.getUTCDate()}`.padStart(2, '0');\n const hours = `${date.getUTCHours()}`.padStart(2, '0');\n const minutes = `${date.getUTCMinutes()}`.padStart(2, '0');\n const seconds = `${date.getUTCSeconds()}`.padStart(2, '0');\n const millisecond = mills ? '.' + `${date.getUTCMilliseconds()}`.padStart(3, '0') : '';\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}${millisecond}`;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidware-it/mysql2-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"main": "build/src/index.js",
|
|
5
5
|
"module": "build/esm/index.js",
|
|
6
6
|
"esnext": "build/esnext/index.js",
|
|
@@ -13,31 +13,39 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"prepack": "npm run compile",
|
|
15
15
|
"compile": "npm run clean && tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
|
|
16
|
-
"clean": "
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
16
|
+
"clean": "rm -rf build",
|
|
17
|
+
"env2doc:check": "npm run -s clean && npm run -s compile && env2doc -d -p build/src > .env2doc-check.tmp && diff .env2doc-check.tmp ENVIRONMENT.md",
|
|
18
|
+
"env2doc": "npm run -s compile && env2doc -d -p build/src > ENVIRONMENT.md",
|
|
19
|
+
"lint": "eslint",
|
|
20
|
+
"lint:fix": "eslint --fix",
|
|
21
|
+
"test": "FW_LOGGER_LEVEL=silent jest",
|
|
22
|
+
"test:debug": "jest",
|
|
23
|
+
"preversion": "npm run -s env2doc:check && npm run -s lint && npm run -s test"
|
|
21
24
|
},
|
|
22
25
|
"engines": {
|
|
23
26
|
"node": ">=18.4"
|
|
24
27
|
},
|
|
25
28
|
"dependencies": {
|
|
26
|
-
"@fluidware-it/saddlebag": "^0.
|
|
27
|
-
"mysql2": "^3.
|
|
29
|
+
"@fluidware-it/saddlebag": "^0.3.0",
|
|
30
|
+
"mysql2": "^3.15.2"
|
|
28
31
|
},
|
|
29
32
|
"devDependencies": {
|
|
30
|
-
"@
|
|
31
|
-
"@
|
|
32
|
-
"@
|
|
33
|
-
"
|
|
34
|
-
"eslint
|
|
35
|
-
"eslint-
|
|
36
|
-
"eslint-plugin-
|
|
37
|
-
"
|
|
38
|
-
"prettier": "^
|
|
39
|
-
"
|
|
40
|
-
"
|
|
33
|
+
"@eslint/js": "9.39.4",
|
|
34
|
+
"@fluidware-it/env2doc": "^0.3.2",
|
|
35
|
+
"@testcontainers/mariadb": "^11.12.0",
|
|
36
|
+
"@types/jest": "30.0.0",
|
|
37
|
+
"eslint": "9.39.4",
|
|
38
|
+
"eslint-config-prettier": "^10.1.8",
|
|
39
|
+
"eslint-plugin-import": "2.32.0",
|
|
40
|
+
"eslint-plugin-n": "17.21.3",
|
|
41
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
42
|
+
"eslint-plugin-yet-another-license-header": "^0.2.0",
|
|
43
|
+
"jest": "30.3.0",
|
|
44
|
+
"prettier": "3.8.1",
|
|
45
|
+
"testcontainers": "^11.12.0",
|
|
46
|
+
"ts-jest": "29.4.6",
|
|
47
|
+
"typescript": "5.9.3",
|
|
48
|
+
"typescript-eslint": "8.41.0"
|
|
41
49
|
},
|
|
42
50
|
"files": [
|
|
43
51
|
"build/esm/**/*.js",
|