clickhouse-migrations 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/lib/migrate.d.ts +1 -1
- package/lib/migrate.js +68 -31
- package/package.json +18 -16
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ For migrations' content should be used correct SQL ClickHouse queries. Multiple
|
|
|
19
19
|
|
|
20
20
|
If the database provided in the `--db` option (or in `CH_MIGRATIONS_DB`) doesn't exist, it will be created automatically.
|
|
21
21
|
|
|
22
|
+
For TLS/HTTPS connections, you can provide a custom CA certificate and optional client certificate/key via the `--ca-cert`, `--cert`, and `--key` options (or the `CH_MIGRATIONS_CA_CERT`, `CH_MIGRATIONS_CERT`, and `CH_MIGRATIONS_KEY` environment variables).
|
|
23
|
+
|
|
22
24
|
```
|
|
23
25
|
Usage
|
|
24
26
|
$ clickhouse-migrations migrate <options>
|
|
@@ -36,6 +38,9 @@ If the database provided in the `--db` option (or in `CH_MIGRATIONS_DB`) doesn't
|
|
|
36
38
|
(default: 'ENGINE=Atomic')
|
|
37
39
|
--timeout=<value> Client request timeout
|
|
38
40
|
(milliseconds, default: 30000)
|
|
41
|
+
--ca-cert=<path> CA certificate file path
|
|
42
|
+
--cert=<path> Client certificate file path
|
|
43
|
+
--key=<path> Client key file path
|
|
39
44
|
|
|
40
45
|
Environment variables
|
|
41
46
|
Instead of options can be used environment variables.
|
|
@@ -48,6 +53,10 @@ If the database provided in the `--db` option (or in `CH_MIGRATIONS_DB`) doesn't
|
|
|
48
53
|
CH_MIGRATIONS_DB_ENGINE (optional) DB engine (--db-engine)
|
|
49
54
|
CH_MIGRATIONS_TIMEOUT (optional) Client request timeout
|
|
50
55
|
(--timeout)
|
|
56
|
+
CH_MIGRATIONS_CA_CERT (optional) CA certificate file path
|
|
57
|
+
CH_MIGRATIONS_CERT (optional) Client certificate file path
|
|
58
|
+
CH_MIGRATIONS_KEY (optional) Client key file path
|
|
59
|
+
|
|
51
60
|
|
|
52
61
|
CLI executions examples
|
|
53
62
|
settings are passed as command-line options
|
|
@@ -66,6 +75,12 @@ If the database provided in the `--db` option (or in `CH_MIGRATIONS_DB`) doesn't
|
|
|
66
75
|
|
|
67
76
|
settings provided partially through options and environment variables
|
|
68
77
|
clickhouse-migrations migrate --timeout=60000
|
|
78
|
+
|
|
79
|
+
settings provided as options with TLS certificates
|
|
80
|
+
clickhouse-migrations migrate --host=https://localhost:8443
|
|
81
|
+
--user=default --password='' --db=analytics
|
|
82
|
+
--migrations-home=/app/clickhouse/migrations
|
|
83
|
+
--ca-cert=/app/certs/ca.pem --cert=/app/certs/client.crt --key=/app/certs/client.key
|
|
69
84
|
```
|
|
70
85
|
|
|
71
86
|
Migration file example:
|
package/lib/migrate.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const migration: (migrations_home: string, host: string, username: string, password: string, db_name: string, db_engine?: string, timeout?: string) => Promise<void>;
|
|
1
|
+
declare const migration: (migrations_home: string, host: string, username: string, password: string, db_name: string, db_engine?: string, timeout?: string, ca_cert?: string | undefined, cert?: string | undefined, key?: string | undefined) => Promise<void>;
|
|
2
2
|
declare const migrate: () => void;
|
|
3
3
|
export { migrate, migration };
|
package/lib/migrate.js
CHANGED
|
@@ -63,7 +63,7 @@ var log = function (type, message, error) {
|
|
|
63
63
|
console.error('\x1b[36m', "clickhouse-migrations :", '\x1b[31m', "Error: ".concat(message), error ? "\n\n ".concat(error) : '');
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
|
-
var connect = function (url, username, password, db_name, timeout) {
|
|
66
|
+
var connect = function (url, username, password, db_name, timeout, ca_cert, cert, key) {
|
|
67
67
|
var db_params = {
|
|
68
68
|
url: url,
|
|
69
69
|
username: username,
|
|
@@ -76,6 +76,26 @@ var connect = function (url, username, password, db_name, timeout) {
|
|
|
76
76
|
if (timeout) {
|
|
77
77
|
db_params.request_timeout = Number(timeout);
|
|
78
78
|
}
|
|
79
|
+
if (ca_cert) {
|
|
80
|
+
try {
|
|
81
|
+
if (cert && key) {
|
|
82
|
+
db_params.tls = {
|
|
83
|
+
ca_cert: fs_1.default.readFileSync(ca_cert),
|
|
84
|
+
cert: fs_1.default.readFileSync(cert),
|
|
85
|
+
key: fs_1.default.readFileSync(key),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
db_params.tls = {
|
|
90
|
+
ca_cert: fs_1.default.readFileSync(ca_cert),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
log('error', 'Failed to read CA certificate file for TLS connection.', e instanceof Error ? e.message : String(e));
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
79
99
|
return (0, client_1.createClient)(db_params);
|
|
80
100
|
};
|
|
81
101
|
var create_db = function (host_1, username_1, password_1, db_name_1) {
|
|
@@ -83,33 +103,46 @@ var create_db = function (host_1, username_1, password_1, db_name_1) {
|
|
|
83
103
|
for (var _i = 4; _i < arguments.length; _i++) {
|
|
84
104
|
args_1[_i - 4] = arguments[_i];
|
|
85
105
|
}
|
|
86
|
-
return __awaiter(void 0, __spreadArray([host_1, username_1, password_1, db_name_1], args_1, true), void 0, function (host, username, password, db_name, db_engine) {
|
|
87
|
-
var client, q,
|
|
106
|
+
return __awaiter(void 0, __spreadArray([host_1, username_1, password_1, db_name_1], args_1, true), void 0, function (host, username, password, db_name, db_engine, timeout, ca_cert, cert, key) {
|
|
107
|
+
var client, e_1, q, e_2;
|
|
88
108
|
if (db_engine === void 0) { db_engine = 'ENGINE=Atomic'; }
|
|
89
109
|
return __generator(this, function (_a) {
|
|
90
110
|
switch (_a.label) {
|
|
91
111
|
case 0:
|
|
92
|
-
client = connect(host, username, password);
|
|
93
|
-
q = "CREATE DATABASE IF NOT EXISTS \"".concat(db_name, "\" ").concat(db_engine);
|
|
112
|
+
client = connect(host, username, password, undefined, timeout, ca_cert, cert, key);
|
|
94
113
|
_a.label = 1;
|
|
95
114
|
case 1:
|
|
96
115
|
_a.trys.push([1, 3, , 4]);
|
|
97
|
-
return [4 /*yield*/, client.
|
|
98
|
-
query: q,
|
|
99
|
-
clickhouse_settings: {
|
|
100
|
-
wait_end_of_query: 1,
|
|
101
|
-
},
|
|
102
|
-
})];
|
|
116
|
+
return [4 /*yield*/, client.ping()];
|
|
103
117
|
case 2:
|
|
104
118
|
_a.sent();
|
|
105
119
|
return [3 /*break*/, 4];
|
|
106
120
|
case 3:
|
|
107
121
|
e_1 = _a.sent();
|
|
108
|
-
log('error', "
|
|
122
|
+
log('error', "Failed to connect to ClickHouse", e_1.message);
|
|
109
123
|
process.exit(1);
|
|
110
124
|
return [3 /*break*/, 4];
|
|
111
|
-
case 4:
|
|
125
|
+
case 4:
|
|
126
|
+
q = "CREATE DATABASE IF NOT EXISTS \"".concat(db_name, "\" ").concat(db_engine);
|
|
127
|
+
_a.label = 5;
|
|
112
128
|
case 5:
|
|
129
|
+
_a.trys.push([5, 7, , 8]);
|
|
130
|
+
return [4 /*yield*/, client.exec({
|
|
131
|
+
query: q,
|
|
132
|
+
clickhouse_settings: {
|
|
133
|
+
wait_end_of_query: 1,
|
|
134
|
+
},
|
|
135
|
+
})];
|
|
136
|
+
case 6:
|
|
137
|
+
_a.sent();
|
|
138
|
+
return [3 /*break*/, 8];
|
|
139
|
+
case 7:
|
|
140
|
+
e_2 = _a.sent();
|
|
141
|
+
log('error', "can't create the database ".concat(db_name, "."), e_2.message);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
return [3 /*break*/, 8];
|
|
144
|
+
case 8: return [4 /*yield*/, client.close()];
|
|
145
|
+
case 9:
|
|
113
146
|
_a.sent();
|
|
114
147
|
return [2 /*return*/];
|
|
115
148
|
}
|
|
@@ -117,7 +150,7 @@ var create_db = function (host_1, username_1, password_1, db_name_1) {
|
|
|
117
150
|
});
|
|
118
151
|
};
|
|
119
152
|
var init_migration_table = function (client) { return __awaiter(void 0, void 0, void 0, function () {
|
|
120
|
-
var q,
|
|
153
|
+
var q, e_3;
|
|
121
154
|
return __generator(this, function (_a) {
|
|
122
155
|
switch (_a.label) {
|
|
123
156
|
case 0:
|
|
@@ -135,8 +168,8 @@ var init_migration_table = function (client) { return __awaiter(void 0, void 0,
|
|
|
135
168
|
_a.sent();
|
|
136
169
|
return [3 /*break*/, 4];
|
|
137
170
|
case 3:
|
|
138
|
-
|
|
139
|
-
log('error', "can't create the _migrations table.",
|
|
171
|
+
e_3 = _a.sent();
|
|
172
|
+
log('error', "can't create the _migrations table.", e_3.message);
|
|
140
173
|
process.exit(1);
|
|
141
174
|
return [3 /*break*/, 4];
|
|
142
175
|
case 4: return [2 /*return*/];
|
|
@@ -154,14 +187,15 @@ var get_migrations = function (migrations_home) {
|
|
|
154
187
|
}
|
|
155
188
|
var migrations = [];
|
|
156
189
|
files.forEach(function (file) {
|
|
190
|
+
// Manage only .sql files.
|
|
191
|
+
if (!file.endsWith('.sql')) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
157
194
|
var version = Number(file.split('_')[0]);
|
|
158
195
|
if (!version) {
|
|
159
196
|
log('error', "a migration name should start from number, example: 1_init.sql. Please check, if the migration ".concat(file, " is named correctly"));
|
|
160
197
|
process.exit(1);
|
|
161
198
|
}
|
|
162
|
-
// Manage only .sql files.
|
|
163
|
-
if (!file.endsWith('.sql'))
|
|
164
|
-
return;
|
|
165
199
|
migrations.push({
|
|
166
200
|
version: version,
|
|
167
201
|
file: file,
|
|
@@ -175,7 +209,7 @@ var get_migrations = function (migrations_home) {
|
|
|
175
209
|
return migrations;
|
|
176
210
|
};
|
|
177
211
|
var apply_migrations = function (client, migrations, migrations_home) { return __awaiter(void 0, void 0, void 0, function () {
|
|
178
|
-
var migration_query_result, resultSet,
|
|
212
|
+
var migration_query_result, resultSet, e_4, migrations_applied, applied_migrations, _i, migrations_1, migration_1, content, checksum, queries, sets, _a, queries_1, query, e_5, e_6;
|
|
179
213
|
return __generator(this, function (_b) {
|
|
180
214
|
switch (_b.label) {
|
|
181
215
|
case 0:
|
|
@@ -194,8 +228,8 @@ var apply_migrations = function (client, migrations, migrations_home) { return _
|
|
|
194
228
|
migration_query_result = _b.sent();
|
|
195
229
|
return [3 /*break*/, 5];
|
|
196
230
|
case 4:
|
|
197
|
-
|
|
198
|
-
log('error', "can't select data from the _migrations table.",
|
|
231
|
+
e_4 = _b.sent();
|
|
232
|
+
log('error', "can't select data from the _migrations table.", e_4.message);
|
|
199
233
|
process.exit(1);
|
|
200
234
|
return [3 /*break*/, 5];
|
|
201
235
|
case 5:
|
|
@@ -251,11 +285,11 @@ var apply_migrations = function (client, migrations, migrations_home) { return _
|
|
|
251
285
|
_b.sent();
|
|
252
286
|
return [3 /*break*/, 11];
|
|
253
287
|
case 10:
|
|
254
|
-
|
|
288
|
+
e_5 = _b.sent();
|
|
255
289
|
if (applied_migrations) {
|
|
256
290
|
log('info', "The migration(s) ".concat(applied_migrations, " was successfully applied!"));
|
|
257
291
|
}
|
|
258
|
-
log('error', "the migrations ".concat(migration_1.file, " has an error. Please, fix it (be sure that already executed parts of the migration would not be run second time) and re-run migration script."),
|
|
292
|
+
log('error', "the migrations ".concat(migration_1.file, " has an error. Please, fix it (be sure that already executed parts of the migration would not be run second time) and re-run migration script."), e_5.message);
|
|
259
293
|
process.exit(1);
|
|
260
294
|
return [3 /*break*/, 11];
|
|
261
295
|
case 11:
|
|
@@ -272,8 +306,8 @@ var apply_migrations = function (client, migrations, migrations_home) { return _
|
|
|
272
306
|
_b.sent();
|
|
273
307
|
return [3 /*break*/, 15];
|
|
274
308
|
case 14:
|
|
275
|
-
|
|
276
|
-
log('error', "can't insert a data into the table _migrations.",
|
|
309
|
+
e_6 = _b.sent();
|
|
310
|
+
log('error', "can't insert a data into the table _migrations.", e_6.message);
|
|
277
311
|
process.exit(1);
|
|
278
312
|
return [3 /*break*/, 15];
|
|
279
313
|
case 15:
|
|
@@ -293,16 +327,16 @@ var apply_migrations = function (client, migrations, migrations_home) { return _
|
|
|
293
327
|
}
|
|
294
328
|
});
|
|
295
329
|
}); };
|
|
296
|
-
var migration = function (migrations_home, host, username, password, db_name, db_engine, timeout) { return __awaiter(void 0, void 0, void 0, function () {
|
|
330
|
+
var migration = function (migrations_home, host, username, password, db_name, db_engine, timeout, ca_cert, cert, key) { return __awaiter(void 0, void 0, void 0, function () {
|
|
297
331
|
var migrations, client;
|
|
298
332
|
return __generator(this, function (_a) {
|
|
299
333
|
switch (_a.label) {
|
|
300
334
|
case 0:
|
|
301
335
|
migrations = get_migrations(migrations_home);
|
|
302
|
-
return [4 /*yield*/, create_db(host, username, password, db_name, db_engine)];
|
|
336
|
+
return [4 /*yield*/, create_db(host, username, password, db_name, db_engine, timeout, ca_cert, cert, key)];
|
|
303
337
|
case 1:
|
|
304
338
|
_a.sent();
|
|
305
|
-
client = connect(host, username, password, db_name, timeout);
|
|
339
|
+
client = connect(host, username, password, db_name, timeout, ca_cert, cert, key);
|
|
306
340
|
return [4 /*yield*/, init_migration_table(client)];
|
|
307
341
|
case 2:
|
|
308
342
|
_a.sent();
|
|
@@ -319,7 +353,7 @@ var migration = function (migrations_home, host, username, password, db_name, db
|
|
|
319
353
|
exports.migration = migration;
|
|
320
354
|
var migrate = function () {
|
|
321
355
|
var program = new commander_1.Command();
|
|
322
|
-
program.name('clickhouse-migrations').description('ClickHouse migrations.').version('1.0
|
|
356
|
+
program.name('clickhouse-migrations').description('ClickHouse migrations.').version('1.1.0');
|
|
323
357
|
program
|
|
324
358
|
.command('migrate')
|
|
325
359
|
.description('Apply migrations.')
|
|
@@ -330,10 +364,13 @@ var migrate = function () {
|
|
|
330
364
|
.requiredOption('--migrations-home <dir>', "Migrations' directory", process.env.CH_MIGRATIONS_HOME)
|
|
331
365
|
.option('--db-engine <value>', 'ON CLUSTER and/or ENGINE clauses for database (default: "ENGINE=Atomic")', process.env.CH_MIGRATIONS_DB_ENGINE)
|
|
332
366
|
.option('--timeout <value>', 'Client request timeout (milliseconds, default value 30000)', process.env.CH_MIGRATIONS_TIMEOUT)
|
|
367
|
+
.option('--ca-cert <path>', 'CA certificate file path', process.env.CH_MIGRATIONS_CA_CERT)
|
|
368
|
+
.option('--cert <path>', 'Client certificate file path', process.env.CH_MIGRATIONS_CERT)
|
|
369
|
+
.option('--key <path>', 'Client key file path', process.env.CH_MIGRATIONS_KEY)
|
|
333
370
|
.action(function (options) { return __awaiter(void 0, void 0, void 0, function () {
|
|
334
371
|
return __generator(this, function (_a) {
|
|
335
372
|
switch (_a.label) {
|
|
336
|
-
case 0: return [4 /*yield*/, migration(options.migrationsHome, options.host, options.user, options.password, options.db, options.dbEngine, options.timeout)];
|
|
373
|
+
case 0: return [4 /*yield*/, migration(options.migrationsHome, options.host, options.user, options.password, options.db, options.dbEngine, options.timeout, options.caCert, options.cert, options.key)];
|
|
337
374
|
case 1:
|
|
338
375
|
_a.sent();
|
|
339
376
|
return [2 /*return*/];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clickhouse-migrations",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "ClickHouse Migrations",
|
|
5
5
|
"bin": {
|
|
6
6
|
"clickhouse-migrations": "lib/cli.js"
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
"scripts": {
|
|
18
18
|
"build": "rm lib/*; tsc",
|
|
19
19
|
"test": "jest --config jestconfig.json",
|
|
20
|
+
"test:unit": "jest --config jestconfig.json --testPathPatterns=\"\\.(unit|integration)\\.test\\.ts$\"",
|
|
21
|
+
"test:e2e": "jest --config jestconfig.json --testPathPatterns=\"\\.e2e\\.test\\.ts$\"",
|
|
20
22
|
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
|
|
21
23
|
"lint": "eslint ./src",
|
|
22
24
|
"prepare": "npm run build",
|
|
@@ -26,23 +28,23 @@
|
|
|
26
28
|
"postversion": "git push && git push --tags"
|
|
27
29
|
},
|
|
28
30
|
"dependencies": {
|
|
29
|
-
"@clickhouse/client": "^1.
|
|
30
|
-
"commander": "^
|
|
31
|
+
"@clickhouse/client": "^1.12.0",
|
|
32
|
+
"commander": "^14.0.0"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
33
|
-
"@eslint/js": "^9.
|
|
34
|
-
"@types/jest": "^
|
|
35
|
-
"@types/node": "^
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
37
|
-
"@typescript-eslint/parser": "^8.
|
|
38
|
-
"eslint": "^9.
|
|
39
|
-
"eslint-config-prettier": "^10.
|
|
40
|
-
"eslint-plugin-prettier": "^5.
|
|
41
|
-
"jest": "^
|
|
42
|
-
"prettier": "^3.
|
|
43
|
-
"ts-jest": "^29.
|
|
44
|
-
"typescript": "^5.
|
|
45
|
-
"typescript-eslint": "^8.
|
|
35
|
+
"@eslint/js": "^9.33.0",
|
|
36
|
+
"@types/jest": "^30.0.0",
|
|
37
|
+
"@types/node": "^24.2.1",
|
|
38
|
+
"@typescript-eslint/eslint-plugin": "^8.39.0",
|
|
39
|
+
"@typescript-eslint/parser": "^8.39.0",
|
|
40
|
+
"eslint": "^9.33.0",
|
|
41
|
+
"eslint-config-prettier": "^10.1.8",
|
|
42
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
43
|
+
"jest": "^30.0.5",
|
|
44
|
+
"prettier": "^3.6.2",
|
|
45
|
+
"ts-jest": "^29.4.1",
|
|
46
|
+
"typescript": "^5.9.2",
|
|
47
|
+
"typescript-eslint": "^8.39.0"
|
|
46
48
|
},
|
|
47
49
|
"files": [
|
|
48
50
|
"lib/**/*"
|