@transitive-sdk/clickhouse 0.3.7 → 0.3.8
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 +2 -14
- package/package.json +1 -1
- package/test/clickhouse.test.js +25 -7
package/index.js
CHANGED
|
@@ -348,29 +348,17 @@ class ClickHouse {
|
|
|
348
348
|
topicSelector,
|
|
349
349
|
since = undefined,
|
|
350
350
|
until = undefined,
|
|
351
|
-
orderBy = 'Timestamp
|
|
351
|
+
orderBy = 'Timestamp DESC',
|
|
352
352
|
limit = 1000
|
|
353
353
|
} = options;
|
|
354
354
|
|
|
355
355
|
const path = topicToPath(topicSelector);
|
|
356
356
|
|
|
357
357
|
// interpret wildcards
|
|
358
|
-
// const where = [];
|
|
359
|
-
// _.forEach(path, (value, i) => {
|
|
360
|
-
// if (!['+','#'].includes(value[0])) {
|
|
361
|
-
// // it's a constant, filter by it
|
|
362
|
-
// where.push(`TopicParts[${i + 1}] = '${value}'`);
|
|
363
|
-
// // Note that ClickHouse/SQL index starting at 1, not 0
|
|
364
|
-
// }
|
|
365
|
-
// });
|
|
366
358
|
const where = path2where(path);
|
|
367
|
-
|
|
368
359
|
since && where.push(`Timestamp >= fromUnixTimestamp64Milli(${since.getTime()})`);
|
|
369
360
|
until && where.push(`Timestamp <= fromUnixTimestamp64Milli(${until.getTime()})`);
|
|
370
|
-
|
|
371
|
-
const whereStatement = where.length > 0
|
|
372
|
-
? `WHERE ${where.join(' AND ')}`
|
|
373
|
-
: '';
|
|
361
|
+
const whereStatement = where.length > 0 ? `WHERE ${where.join(' AND ')}` : '';
|
|
374
362
|
|
|
375
363
|
const result = await this.client.query({
|
|
376
364
|
query: `SELECT Payload,TopicParts,Timestamp FROM default.${this.mqttHistoryTable} ${
|
package/package.json
CHANGED
package/test/clickhouse.test.js
CHANGED
|
@@ -33,6 +33,7 @@ const interceptInserts = () => {
|
|
|
33
33
|
const queryRowsByOrg = async (org, options = {}) =>
|
|
34
34
|
await clickhouse.queryMQTTHistory({
|
|
35
35
|
topicSelector: `/${org}/+/+/+/+/+`,
|
|
36
|
+
orderBy: 'Timestamp ASC',
|
|
36
37
|
...options
|
|
37
38
|
});
|
|
38
39
|
|
|
@@ -245,12 +246,14 @@ describe('ClickHouse', function() {
|
|
|
245
246
|
|
|
246
247
|
it('queries with wild cards', async () => {
|
|
247
248
|
const rows = await clickhouse.queryMQTTHistory({
|
|
249
|
+
orderBy: 'Timestamp ASC',
|
|
248
250
|
topicSelector: `/${org}/+/+/+/+/+` });
|
|
249
251
|
assert(rows.length > 0);
|
|
250
252
|
});
|
|
251
253
|
|
|
252
254
|
it('queries with multiple selectors', async () => {
|
|
253
255
|
const [row] = await clickhouse.queryMQTTHistory({
|
|
256
|
+
orderBy: 'Timestamp ASC',
|
|
254
257
|
topicSelector: `/${org}/+/+/capdata/+/+` });
|
|
255
258
|
assert.strictEqual(row.DeviceId, 'device1');
|
|
256
259
|
assert.deepEqual(row.SubTopic, ['data']);
|
|
@@ -260,6 +263,7 @@ describe('ClickHouse', function() {
|
|
|
260
263
|
|
|
261
264
|
it('queries based on sub-topic selectors', async () => {
|
|
262
265
|
const [row] = await clickhouse.queryMQTTHistory({
|
|
266
|
+
orderBy: 'Timestamp ASC',
|
|
263
267
|
topicSelector: `/${org}/+/+/+/+/data2` });
|
|
264
268
|
assert.strictEqual(row.DeviceId, 'device1');
|
|
265
269
|
assert.deepStrictEqual(row.Payload, { y: 2 });
|
|
@@ -267,12 +271,14 @@ describe('ClickHouse', function() {
|
|
|
267
271
|
|
|
268
272
|
it('queries based on sub-topic selectors with wildcards', async () => {
|
|
269
273
|
const [row] = await clickhouse.queryMQTTHistory({
|
|
274
|
+
orderBy: 'Timestamp ASC',
|
|
270
275
|
topicSelector: `/${org}/+/+/+/+/+/sub2/+` });
|
|
271
276
|
assert.deepStrictEqual(row.SubTopic[2], 'sub3.1');
|
|
272
277
|
});
|
|
273
278
|
|
|
274
279
|
it('queries based on multiple sub-topic selectors with wildcards', async () => {
|
|
275
280
|
const rows = await clickhouse.queryMQTTHistory({
|
|
281
|
+
orderBy: 'Timestamp ASC',
|
|
276
282
|
topicSelector: `/${org}/+/+/+/+/sub1/+/+` });
|
|
277
283
|
assert.strictEqual(rows[0].SubTopic.length, 3);
|
|
278
284
|
assert.strictEqual(rows[0].SubTopic[2], 'sub3.1');
|
|
@@ -281,6 +287,7 @@ describe('ClickHouse', function() {
|
|
|
281
287
|
|
|
282
288
|
it('returns the history', async () => {
|
|
283
289
|
const rows = await clickhouse.queryMQTTHistory({
|
|
290
|
+
orderBy: 'Timestamp ASC',
|
|
284
291
|
topicSelector: `/${org}/+/+/+/+/data/+/+` });
|
|
285
292
|
assert.deepStrictEqual(rows.length, 2);
|
|
286
293
|
assert.deepStrictEqual(rows[0].Payload, {x: 1});
|
|
@@ -290,6 +297,7 @@ describe('ClickHouse', function() {
|
|
|
290
297
|
|
|
291
298
|
it('handles null values', async () => {
|
|
292
299
|
const rows = await clickhouse.queryMQTTHistory({
|
|
300
|
+
orderBy: 'Timestamp ASC',
|
|
293
301
|
topicSelector: `/${org}/+/+/+/+/willBeNull` });
|
|
294
302
|
assert.strictEqual(rows.at(-1).Payload, null);
|
|
295
303
|
});
|
|
@@ -314,7 +322,8 @@ describe('ClickHouse', function() {
|
|
|
314
322
|
for (let i = 0; i < ROWS; i++) {
|
|
315
323
|
rows.push({
|
|
316
324
|
Timestamp: new Date(now + i * GAP), // use current date to avoid immediate TTL cleanup
|
|
317
|
-
TopicParts: [`org${i % 50}`, `device${i % 1000}`, '@myscope',
|
|
325
|
+
TopicParts: [`org${i % 50}`, `device${i % 1000}`, '@myscope',
|
|
326
|
+
`cap${i % 100}`, `1.${i % 100}.0`, `data_${i % 1000}`, i],
|
|
318
327
|
Payload: { i },
|
|
319
328
|
})
|
|
320
329
|
}
|
|
@@ -345,7 +354,7 @@ describe('ClickHouse', function() {
|
|
|
345
354
|
limit: 2 * ROWS,
|
|
346
355
|
});
|
|
347
356
|
assert.equal(rows.length, ROWS);
|
|
348
|
-
assert(rows[0].Timestamp
|
|
357
|
+
assert(rows[0].Timestamp > rows[1].Timestamp);
|
|
349
358
|
assertTimelimit(ROWS / 100);
|
|
350
359
|
});
|
|
351
360
|
|
|
@@ -360,7 +369,7 @@ describe('ClickHouse', function() {
|
|
|
360
369
|
|
|
361
370
|
it('quickly filters by DeviceId', async () => {
|
|
362
371
|
const rows = await clickhouse.queryMQTTHistory({
|
|
363
|
-
topicSelector: `/+/device123
|
|
372
|
+
topicSelector: `/+/device123/+/+/+/+`,
|
|
364
373
|
limit: 2 * ROWS,
|
|
365
374
|
});
|
|
366
375
|
assert.equal(rows.length, ROWS / 1000);
|
|
@@ -369,16 +378,25 @@ describe('ClickHouse', function() {
|
|
|
369
378
|
|
|
370
379
|
it('quickly filters by CapabilityName', async () => {
|
|
371
380
|
const rows = await clickhouse.queryMQTTHistory({
|
|
372
|
-
topicSelector: `/+/+/+/cap34
|
|
381
|
+
topicSelector: `/+/+/+/cap34/+/+`,
|
|
373
382
|
limit: 2 * ROWS,
|
|
374
383
|
});
|
|
375
384
|
assert.equal(rows.length, ROWS / 100);
|
|
376
385
|
assertTimelimit(ROWS / 1000);
|
|
377
386
|
});
|
|
378
387
|
|
|
388
|
+
it('quickly filters by SubTopic', async () => {
|
|
389
|
+
const rows = await clickhouse.queryMQTTHistory({
|
|
390
|
+
topicSelector: `/+/+/+/+/+/data_123`,
|
|
391
|
+
limit: 2 * ROWS,
|
|
392
|
+
});
|
|
393
|
+
assert.equal(rows.length, ROWS / 1000);
|
|
394
|
+
assertTimelimit(ROWS / 1000);
|
|
395
|
+
});
|
|
396
|
+
|
|
379
397
|
it('quickly filters by time: since', async () => {
|
|
380
398
|
const rows = await clickhouse.queryMQTTHistory({
|
|
381
|
-
topicSelector:
|
|
399
|
+
topicSelector: `/+/+/+/+/+/+`,
|
|
382
400
|
since: new Date(now + (ROWS - 400) * GAP),
|
|
383
401
|
limit: 2 * ROWS,
|
|
384
402
|
});
|
|
@@ -388,7 +406,7 @@ describe('ClickHouse', function() {
|
|
|
388
406
|
|
|
389
407
|
it('quickly filters by time: until', async () => {
|
|
390
408
|
const rows = await clickhouse.queryMQTTHistory({
|
|
391
|
-
topicSelector:
|
|
409
|
+
topicSelector: `/+/+/+/+/+/+`,
|
|
392
410
|
until: new Date(now + 400 * GAP),
|
|
393
411
|
limit: 2 * ROWS,
|
|
394
412
|
});
|
|
@@ -398,7 +416,7 @@ describe('ClickHouse', function() {
|
|
|
398
416
|
|
|
399
417
|
it('quickly filters by org and time: since', async () => {
|
|
400
418
|
const rows = await clickhouse.queryMQTTHistory({
|
|
401
|
-
topicSelector: `/org23
|
|
419
|
+
topicSelector: `/org23/+/+/+/+/+`,
|
|
402
420
|
since: new Date(now + (ROWS - 400) * GAP),
|
|
403
421
|
limit: 2 * ROWS,
|
|
404
422
|
});
|