@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 CHANGED
@@ -348,29 +348,17 @@ class ClickHouse {
348
348
  topicSelector,
349
349
  since = undefined,
350
350
  until = undefined,
351
- orderBy = 'Timestamp ASC',
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transitive-sdk/clickhouse",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "A tiny ClickHouse utility class for use in the Transitive framework.",
5
5
  "homepage": "https://transitiverobotics.com",
6
6
  "repository": {
@@ -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', `cap${i % 100}`, `1.${i % 100}.0`, 'data', i],
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 < rows[1].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/+/+/+/data`,
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/+/data`,
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: `/+/+/+/+/+/data`,
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: `/+/+/+/+/+/data`,
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/+/+/+/+/data`,
419
+ topicSelector: `/org23/+/+/+/+/+`,
402
420
  since: new Date(now + (ROWS - 400) * GAP),
403
421
  limit: 2 * ROWS,
404
422
  });