@transitive-sdk/clickhouse 0.3.0 → 0.3.2
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/index.js +40 -21
- package/package.json +1 -1
- package/test/clickhouse.test.js +5 -2
package/index.js
CHANGED
|
@@ -19,6 +19,21 @@ const MULTI_TENANT_SCHEMA = {
|
|
|
19
19
|
]
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
+
/** Given a Topic path (array), return an array of conditions to use in a
|
|
23
|
+
* WHERE clause. */
|
|
24
|
+
const path2where = (path) => {
|
|
25
|
+
const where = [];
|
|
26
|
+
_.forEach(path, (value, i) => {
|
|
27
|
+
if (!['+','#'].includes(value[0])) {
|
|
28
|
+
// it's a constant, filter by it
|
|
29
|
+
where.push(`TopicParts[${i + 1}] = '${value}'`);
|
|
30
|
+
// Note that ClickHouse/SQL index starting at 1, not 0
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
return where;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
|
|
22
37
|
/** Singleton ClickHouse client wrapper with multi-tenant table support */
|
|
23
38
|
class ClickHouse {
|
|
24
39
|
|
|
@@ -258,18 +273,19 @@ class ClickHouse {
|
|
|
258
273
|
}
|
|
259
274
|
|
|
260
275
|
// list of TopicParts indices and selected value to use in WHERE statement
|
|
261
|
-
const topicPartSelectors = [
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
];
|
|
276
|
+
// const topicPartSelectors = [
|
|
277
|
+
// [2, path[2]],
|
|
278
|
+
// [3, path[3]]
|
|
279
|
+
// ];
|
|
265
280
|
|
|
266
|
-
path.slice(5).forEach((value, i) => topicPartSelectors.push([i, value]));
|
|
281
|
+
// path.slice(5).forEach((value, i) => topicPartSelectors.push([i + 5, value]));
|
|
267
282
|
|
|
268
|
-
const where = topicPartSelectors
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
283
|
+
// const where = topicPartSelectors
|
|
284
|
+
// // filter out wildcards
|
|
285
|
+
// .filter(([i, value]) => !['+','#'].includes(value[0]))
|
|
286
|
+
// // map to WHERE conditions
|
|
287
|
+
// .map(([i, value]) => `((TopicParts[${i + 1}]) = '${value}')`);
|
|
288
|
+
const where = path2where(path);
|
|
273
289
|
|
|
274
290
|
if (where.length == 0) {
|
|
275
291
|
// underspecified, don't set TTL
|
|
@@ -288,11 +304,13 @@ class ClickHouse {
|
|
|
288
304
|
const ttls = matched ? matched[1].split(',').map(x => x.trim()) : [];
|
|
289
305
|
|
|
290
306
|
const whereStatement = `WHERE ${where.join(' AND ')}`;
|
|
291
|
-
|
|
307
|
+
const newTTLStatement =
|
|
308
|
+
`toDateTime(Timestamp) + toIntervalDay(${ttlDays}) ${whereStatement}`;
|
|
292
309
|
|
|
310
|
+
let present = false;
|
|
293
311
|
// check if TTL statement already present on table definiton
|
|
294
312
|
ttls.forEach((ttl, i) => {
|
|
295
|
-
if (ttl.endsWith(whereStatement)) {
|
|
313
|
+
if (ttl.replace(/[()]/g, '').endsWith(whereStatement)) {
|
|
296
314
|
// condition already present, just replace it to update time
|
|
297
315
|
ttls[i] = newTTLStatement;
|
|
298
316
|
present = true;
|
|
@@ -300,7 +318,7 @@ class ClickHouse {
|
|
|
300
318
|
});
|
|
301
319
|
|
|
302
320
|
if (!present) {
|
|
303
|
-
ttls.push(
|
|
321
|
+
ttls.push(newTTLStatement);
|
|
304
322
|
}
|
|
305
323
|
|
|
306
324
|
await this.client.command({
|
|
@@ -327,14 +345,15 @@ class ClickHouse {
|
|
|
327
345
|
const path = topicToPath(topicSelector);
|
|
328
346
|
|
|
329
347
|
// interpret wildcards
|
|
330
|
-
const where = [];
|
|
331
|
-
_.forEach(path, (value, i) => {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
});
|
|
348
|
+
// const where = [];
|
|
349
|
+
// _.forEach(path, (value, i) => {
|
|
350
|
+
// if (!['+','#'].includes(value[0])) {
|
|
351
|
+
// // it's a constant, filter by it
|
|
352
|
+
// where.push(`TopicParts[${i + 1}] = '${value}'`);
|
|
353
|
+
// // Note that ClickHouse/SQL index starting at 1, not 0
|
|
354
|
+
// }
|
|
355
|
+
// });
|
|
356
|
+
const where = path2where(path);
|
|
338
357
|
|
|
339
358
|
since && where.push(`Timestamp >= fromUnixTimestamp64Milli(${since.getTime()})`);
|
|
340
359
|
until && where.push(`Timestamp <= fromUnixTimestamp64Milli(${until.getTime()})`);
|
package/package.json
CHANGED
package/test/clickhouse.test.js
CHANGED
|
@@ -61,8 +61,7 @@ describe('ClickHouse', function() {
|
|
|
61
61
|
|
|
62
62
|
await clickhouse.enableHistory({
|
|
63
63
|
dataCache,
|
|
64
|
-
tableName: TABLE_NAME
|
|
65
|
-
ttlDays: 31
|
|
64
|
+
tableName: TABLE_NAME
|
|
66
65
|
});
|
|
67
66
|
|
|
68
67
|
await clickhouse.registerMqttTopicForStorage(STANDARD_TOPIC_PATTERN);
|
|
@@ -194,6 +193,10 @@ describe('ClickHouse', function() {
|
|
|
194
193
|
assert.equal(rows.length, 1);
|
|
195
194
|
});
|
|
196
195
|
|
|
196
|
+
it('updates TTL without crashing', async () => {
|
|
197
|
+
await clickhouse.registerMqttTopicForStorage('/+/+/myscope/+/+/#', 13);
|
|
198
|
+
await clickhouse.registerMqttTopicForStorage('/+/+/myscope/+/+/#', 15);
|
|
199
|
+
});
|
|
197
200
|
});
|
|
198
201
|
|
|
199
202
|
|