node-red-contrib-questdb 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/examples/examples.json +1 -1
- package/nodes/write.js +57 -23
- package/nul +46 -0
- package/package.json +1 -1
package/examples/examples.json
CHANGED
|
@@ -755,7 +755,7 @@
|
|
|
755
755
|
"type": "function",
|
|
756
756
|
"z": "questdb-examples-tab",
|
|
757
757
|
"name": "Generate random metrics",
|
|
758
|
-
"func": "msg.payload = {\n symbols: {\n host: \"server-\" + Math.floor(Math.random() * 3 + 1),\n region: [\"us-east\", \"us-west\", \"eu-west\"][Math.floor(Math.random() * 3)]\n },\n columns: {\n cpu: Math.random() * 100,\n memory: Math.random() * 100,\n disk_io:
|
|
758
|
+
"func": "msg.payload = {\n symbols: {\n host: \"server-\" + Math.floor(Math.random() * 3 + 1),\n region: [\"us-east\", \"us-west\", \"eu-west\"][Math.floor(Math.random() * 3)]\n },\n columns: {\n cpu: Math.random() * 100,\n memory: Math.random() * 100,\n disk_io: Math.random() * 1000,\n connections: Math.floor(Math.random() * 1000),\n avg_latency: Math.random() * 100\n },\n timestamp: Date.now()\n};\nreturn msg;",
|
|
759
759
|
"outputs": 1,
|
|
760
760
|
"x": 410,
|
|
761
761
|
"y": 1360,
|
package/nodes/write.js
CHANGED
|
@@ -299,35 +299,60 @@ module.exports = function(RED) {
|
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
if (payload.columns && typeof payload.columns === 'object') {
|
|
302
|
+
// Check which methods are available in the sender
|
|
303
|
+
const hasLongColumn = typeof connection.sender.longColumn === 'function';
|
|
304
|
+
const hasDoubleColumn = typeof connection.sender.doubleColumn === 'function';
|
|
305
|
+
const hasArrayColumn = typeof connection.sender.arrayColumn === 'function';
|
|
306
|
+
const hasDecimalColumn = typeof connection.sender.decimalColumn === 'function';
|
|
307
|
+
|
|
302
308
|
for (const [key, value] of Object.entries(payload.columns)) {
|
|
303
309
|
if (value === null || value === undefined) continue;
|
|
304
310
|
|
|
305
311
|
// Check for explicit type specification: { value: x, type: 'int'|'long'|'float'|'double'|'decimal'|'array' }
|
|
306
|
-
if (typeof value === 'object' && value.type && value.value !== undefined) {
|
|
312
|
+
if (typeof value === 'object' && !Array.isArray(value) && value.type && value.value !== undefined) {
|
|
307
313
|
const colType = value.type.toLowerCase();
|
|
308
314
|
const colValue = value.value;
|
|
309
315
|
|
|
310
316
|
if (colType === 'int' || colType === 'integer') {
|
|
311
317
|
connection.sender.intColumn(key, Math.trunc(colValue));
|
|
312
318
|
} else if (colType === 'long') {
|
|
313
|
-
|
|
319
|
+
if (hasLongColumn) {
|
|
320
|
+
connection.sender.longColumn(key, BigInt(Math.trunc(colValue)));
|
|
321
|
+
} else {
|
|
322
|
+
// Fallback: use intColumn for smaller values, floatColumn for larger
|
|
323
|
+
const intVal = Math.trunc(colValue);
|
|
324
|
+
if (intVal >= -2147483648 && intVal <= 2147483647) {
|
|
325
|
+
connection.sender.intColumn(key, intVal);
|
|
326
|
+
} else {
|
|
327
|
+
connection.sender.floatColumn(key, colValue);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
314
330
|
} else if (colType === 'float') {
|
|
315
331
|
connection.sender.floatColumn(key, colValue);
|
|
316
332
|
} else if (colType === 'double') {
|
|
317
|
-
|
|
333
|
+
if (hasDoubleColumn) {
|
|
334
|
+
connection.sender.doubleColumn(key, colValue);
|
|
335
|
+
} else {
|
|
336
|
+
connection.sender.floatColumn(key, colValue);
|
|
337
|
+
}
|
|
318
338
|
} else if (colType === 'decimal') {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
339
|
+
if (hasDecimalColumn) {
|
|
340
|
+
if (value.mantissa !== undefined && value.scale !== undefined) {
|
|
341
|
+
connection.sender.decimalColumn(key, BigInt(value.mantissa), value.scale);
|
|
342
|
+
} else {
|
|
343
|
+
connection.sender.decimalColumnText(key, String(colValue));
|
|
344
|
+
}
|
|
322
345
|
} else {
|
|
323
|
-
//
|
|
324
|
-
connection.sender.
|
|
346
|
+
// Fallback: store as string
|
|
347
|
+
connection.sender.stringColumn(key, String(colValue));
|
|
325
348
|
}
|
|
326
349
|
} else if (colType === 'array') {
|
|
327
|
-
|
|
328
|
-
if (Array.isArray(colValue)) {
|
|
350
|
+
if (hasArrayColumn && Array.isArray(colValue)) {
|
|
329
351
|
const elementType = (value.elementType || 'double').toLowerCase();
|
|
330
352
|
connection.sender.arrayColumn(key, elementType, colValue);
|
|
353
|
+
} else if (Array.isArray(colValue)) {
|
|
354
|
+
// Fallback: store as JSON string
|
|
355
|
+
connection.sender.stringColumn(key, JSON.stringify(colValue));
|
|
331
356
|
} else {
|
|
332
357
|
node.warn(`Array column '${key}' value must be an array`);
|
|
333
358
|
}
|
|
@@ -346,17 +371,22 @@ module.exports = function(RED) {
|
|
|
346
371
|
|
|
347
372
|
// Array detection (auto)
|
|
348
373
|
if (Array.isArray(value)) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
374
|
+
if (hasArrayColumn) {
|
|
375
|
+
// Detect element type from first non-null element
|
|
376
|
+
const firstElement = value.find(v => v !== null && v !== undefined);
|
|
377
|
+
let elementType = 'double'; // default
|
|
378
|
+
if (typeof firstElement === 'string') {
|
|
379
|
+
elementType = 'string';
|
|
380
|
+
} else if (typeof firstElement === 'boolean') {
|
|
381
|
+
elementType = 'boolean';
|
|
382
|
+
} else if (typeof firstElement === 'bigint') {
|
|
383
|
+
elementType = 'long';
|
|
384
|
+
}
|
|
385
|
+
connection.sender.arrayColumn(key, elementType, value);
|
|
386
|
+
} else {
|
|
387
|
+
// Fallback: store as JSON string
|
|
388
|
+
connection.sender.stringColumn(key, JSON.stringify(value));
|
|
358
389
|
}
|
|
359
|
-
connection.sender.arrayColumn(key, elementType, value);
|
|
360
390
|
continue;
|
|
361
391
|
}
|
|
362
392
|
|
|
@@ -365,10 +395,14 @@ module.exports = function(RED) {
|
|
|
365
395
|
node.warn(`Skipping non-finite number for column '${key}'`);
|
|
366
396
|
continue;
|
|
367
397
|
}
|
|
368
|
-
//
|
|
369
|
-
connection.sender.
|
|
398
|
+
// Use floatColumn (available in all versions)
|
|
399
|
+
connection.sender.floatColumn(key, value);
|
|
370
400
|
} else if (typeof value === 'bigint') {
|
|
371
|
-
|
|
401
|
+
if (hasLongColumn) {
|
|
402
|
+
connection.sender.longColumn(key, value);
|
|
403
|
+
} else {
|
|
404
|
+
connection.sender.floatColumn(key, Number(value));
|
|
405
|
+
}
|
|
372
406
|
} else if (typeof value === 'boolean') {
|
|
373
407
|
connection.sender.booleanColumn(key, value);
|
|
374
408
|
} else if (typeof value === 'string') {
|
package/nul
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[
|
|
2
|
+
"0.0.1",
|
|
3
|
+
"0.0.2",
|
|
4
|
+
"0.0.4",
|
|
5
|
+
"0.0.5",
|
|
6
|
+
"0.0.6",
|
|
7
|
+
"0.0.7",
|
|
8
|
+
"0.0.8",
|
|
9
|
+
"0.0.9",
|
|
10
|
+
"0.0.10",
|
|
11
|
+
"0.0.11",
|
|
12
|
+
"0.0.12",
|
|
13
|
+
"0.0.14",
|
|
14
|
+
"0.0.15",
|
|
15
|
+
"0.0.16",
|
|
16
|
+
"0.0.17",
|
|
17
|
+
"0.0.18",
|
|
18
|
+
"0.0.20",
|
|
19
|
+
"0.0.21",
|
|
20
|
+
"0.0.22",
|
|
21
|
+
"0.0.23",
|
|
22
|
+
"0.0.24",
|
|
23
|
+
"0.0.25",
|
|
24
|
+
"0.0.26",
|
|
25
|
+
"0.0.27",
|
|
26
|
+
"0.0.28",
|
|
27
|
+
"0.0.29",
|
|
28
|
+
"0.0.30",
|
|
29
|
+
"0.0.31",
|
|
30
|
+
"0.0.32",
|
|
31
|
+
"0.0.33",
|
|
32
|
+
"0.0.34",
|
|
33
|
+
"1.0.0",
|
|
34
|
+
"1.0.1",
|
|
35
|
+
"1.0.2",
|
|
36
|
+
"1.0.3",
|
|
37
|
+
"1.0.4",
|
|
38
|
+
"1.0.5",
|
|
39
|
+
"2.0.0",
|
|
40
|
+
"2.1.0",
|
|
41
|
+
"3.0.0",
|
|
42
|
+
"4.0.1",
|
|
43
|
+
"4.0.2",
|
|
44
|
+
"4.1.0",
|
|
45
|
+
"4.2.0"
|
|
46
|
+
]
|