@lossless.org/client 0.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/.smartconfig.json +37 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/classes.losslessorgclient.d.ts +32 -0
- package/dist_ts/classes.losslessorgclient.js +103 -0
- package/dist_ts/core/classes.error.d.ts +16 -0
- package/dist_ts/core/classes.error.js +29 -0
- package/dist_ts/core/classes.operation.d.ts +17 -0
- package/dist_ts/core/classes.operation.js +70 -0
- package/dist_ts/core/interfaces.d.ts +18 -0
- package/dist_ts/core/interfaces.js +2 -0
- package/dist_ts/index.d.ts +4 -0
- package/dist_ts/index.js +3 -0
- package/dist_ts/nosqldb/classes.atomicdelete.d.ts +26 -0
- package/dist_ts/nosqldb/classes.atomicdelete.js +44 -0
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.d.ts +27 -0
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.js +86 -0
- package/dist_ts/nosqldb/classes.atomicupdate.d.ts +26 -0
- package/dist_ts/nosqldb/classes.atomicupdate.js +55 -0
- package/dist_ts/nosqldb/classes.bootstraprecord.d.ts +14 -0
- package/dist_ts/nosqldb/classes.bootstraprecord.js +80 -0
- package/dist_ts/nosqldb/classes.bsonassertion.d.ts +2 -0
- package/dist_ts/nosqldb/classes.bsonassertion.js +29 -0
- package/dist_ts/nosqldb/classes.bsonobjectid.d.ts +2 -0
- package/dist_ts/nosqldb/classes.bsonobjectid.js +50 -0
- package/dist_ts/nosqldb/classes.bsonsnapshot.d.ts +3 -0
- package/dist_ts/nosqldb/classes.bsonsnapshot.js +126 -0
- package/dist_ts/nosqldb/classes.cached-document.d.ts +27 -0
- package/dist_ts/nosqldb/classes.cached-document.js +112 -0
- package/dist_ts/nosqldb/classes.collection.d.ts +302 -0
- package/dist_ts/nosqldb/classes.collection.js +1568 -0
- package/dist_ts/nosqldb/classes.collectionfactory.d.ts +30 -0
- package/dist_ts/nosqldb/classes.collectionfactory.js +65 -0
- package/dist_ts/nosqldb/classes.collectionlifecycle.d.ts +4 -0
- package/dist_ts/nosqldb/classes.collectionlifecycle.js +15 -0
- package/dist_ts/nosqldb/classes.collectionpreparation.d.ts +34 -0
- package/dist_ts/nosqldb/classes.collectionpreparation.js +134 -0
- package/dist_ts/nosqldb/classes.collectiontopology.d.ts +47 -0
- package/dist_ts/nosqldb/classes.collectiontopology.js +388 -0
- package/dist_ts/nosqldb/classes.connection.d.ts +18 -0
- package/dist_ts/nosqldb/classes.connection.js +23 -0
- package/dist_ts/nosqldb/classes.convenience.d.ts +1 -0
- package/dist_ts/nosqldb/classes.convenience.js +5 -0
- package/dist_ts/nosqldb/classes.cursor.d.ts +15 -0
- package/dist_ts/nosqldb/classes.cursor.js +82 -0
- package/dist_ts/nosqldb/classes.cursoroperation.d.ts +7 -0
- package/dist_ts/nosqldb/classes.cursoroperation.js +36 -0
- package/dist_ts/nosqldb/classes.db.d.ts +98 -0
- package/dist_ts/nosqldb/classes.db.js +434 -0
- package/dist_ts/nosqldb/classes.distributedcoordinator.d.ts +52 -0
- package/dist_ts/nosqldb/classes.distributedcoordinator.js +314 -0
- package/dist_ts/nosqldb/classes.doc.d.ts +722 -0
- package/dist_ts/nosqldb/classes.doc.js +2976 -0
- package/dist_ts/nosqldb/classes.easystore.d.ts +42 -0
- package/dist_ts/nosqldb/classes.easystore.js +199 -0
- package/dist_ts/nosqldb/classes.exactpersistence.d.ts +141 -0
- package/dist_ts/nosqldb/classes.exactpersistence.js +1110 -0
- package/dist_ts/nosqldb/classes.lucene.adapter.d.ts +173 -0
- package/dist_ts/nosqldb/classes.lucene.adapter.js +623 -0
- package/dist_ts/nosqldb/classes.mongoadministration.d.ts +73 -0
- package/dist_ts/nosqldb/classes.mongoadministration.js +497 -0
- package/dist_ts/nosqldb/classes.namespaceinspection.d.ts +42 -0
- package/dist_ts/nosqldb/classes.namespaceinspection.js +138 -0
- package/dist_ts/nosqldb/classes.operationbudget.d.ts +22 -0
- package/dist_ts/nosqldb/classes.operationbudget.js +65 -0
- package/dist_ts/nosqldb/classes.ordinarypersistence.d.ts +18 -0
- package/dist_ts/nosqldb/classes.ordinarypersistence.js +71 -0
- package/dist_ts/nosqldb/classes.persistence.d.ts +14 -0
- package/dist_ts/nosqldb/classes.persistence.js +34 -0
- package/dist_ts/nosqldb/classes.session.d.ts +28 -0
- package/dist_ts/nosqldb/classes.session.js +246 -0
- package/dist_ts/nosqldb/classes.storedinspection.d.ts +44 -0
- package/dist_ts/nosqldb/classes.storedinspection.js +100 -0
- package/dist_ts/nosqldb/classes.testdatabase.d.ts +56 -0
- package/dist_ts/nosqldb/classes.testdatabase.js +250 -0
- package/dist_ts/nosqldb/classes.watcher.d.ts +37 -0
- package/dist_ts/nosqldb/classes.watcher.js +98 -0
- package/dist_ts/nosqldb/index.d.ts +27 -0
- package/dist_ts/nosqldb/index.js +18 -0
- package/dist_ts/nosqldb/logging.d.ts +2 -0
- package/dist_ts/nosqldb/logging.js +3 -0
- package/dist_ts/nosqldb/plugins.d.ts +17 -0
- package/dist_ts/nosqldb/plugins.js +20 -0
- package/dist_ts/nosqldb/shim.d.ts +1 -0
- package/dist_ts/nosqldb/shim.js +8 -0
- package/dist_ts/nosqldb/testsupport.d.ts +3 -0
- package/dist_ts/nosqldb/testsupport.js +3 -0
- package/dist_ts/objectstorage/classes.bucket.d.ts +227 -0
- package/dist_ts/objectstorage/classes.bucket.js +939 -0
- package/dist_ts/objectstorage/classes.connection.d.ts +21 -0
- package/dist_ts/objectstorage/classes.connection.js +27 -0
- package/dist_ts/objectstorage/classes.directory.d.ts +124 -0
- package/dist_ts/objectstorage/classes.directory.js +335 -0
- package/dist_ts/objectstorage/classes.exactpathpurgeerror.d.ts +5 -0
- package/dist_ts/objectstorage/classes.exactpathpurgeerror.js +18 -0
- package/dist_ts/objectstorage/classes.exactuploaderror.d.ts +5 -0
- package/dist_ts/objectstorage/classes.exactuploaderror.js +19 -0
- package/dist_ts/objectstorage/classes.file.d.ts +91 -0
- package/dist_ts/objectstorage/classes.file.js +255 -0
- package/dist_ts/objectstorage/classes.listcursor.d.ts +41 -0
- package/dist_ts/objectstorage/classes.listcursor.js +67 -0
- package/dist_ts/objectstorage/classes.metadata.d.ts +57 -0
- package/dist_ts/objectstorage/classes.metadata.js +113 -0
- package/dist_ts/objectstorage/classes.smartbucket.d.ts +57 -0
- package/dist_ts/objectstorage/classes.smartbucket.js +357 -0
- package/dist_ts/objectstorage/classes.trash.d.ts +11 -0
- package/dist_ts/objectstorage/classes.trash.js +22 -0
- package/dist_ts/objectstorage/classes.watcher.d.ts +79 -0
- package/dist_ts/objectstorage/classes.watcher.js +249 -0
- package/dist_ts/objectstorage/helpers.d.ts +25 -0
- package/dist_ts/objectstorage/helpers.js +215 -0
- package/dist_ts/objectstorage/index.d.ts +13 -0
- package/dist_ts/objectstorage/index.js +13 -0
- package/dist_ts/objectstorage/interfaces.d.ts +276 -0
- package/dist_ts/objectstorage/interfaces.js +2 -0
- package/dist_ts/objectstorage/internal.exactpathpurge.operations.d.ts +11 -0
- package/dist_ts/objectstorage/internal.exactpathpurge.operations.js +1069 -0
- package/dist_ts/objectstorage/internal.exactupload.capability.d.ts +40 -0
- package/dist_ts/objectstorage/internal.exactupload.capability.js +382 -0
- package/dist_ts/objectstorage/internal.exactupload.operations.d.ts +11 -0
- package/dist_ts/objectstorage/internal.exactupload.operations.js +1104 -0
- package/dist_ts/objectstorage/internal.multipart.planner.d.ts +8 -0
- package/dist_ts/objectstorage/internal.multipart.planner.js +63 -0
- package/dist_ts/objectstorage/internal.multipart.stream.d.ts +17 -0
- package/dist_ts/objectstorage/internal.multipart.stream.js +440 -0
- package/dist_ts/objectstorage/internal.multipart.types.d.ts +82 -0
- package/dist_ts/objectstorage/internal.multipart.types.js +2 -0
- package/dist_ts/objectstorage/plugins.d.ts +17 -0
- package/dist_ts/objectstorage/plugins.js +23 -0
- package/dist_ts/plugins.d.ts +4 -0
- package/dist_ts/plugins.js +5 -0
- package/dist_ts/sqldb/classes.clickhouseconnection.d.ts +39 -0
- package/dist_ts/sqldb/classes.clickhouseconnection.js +225 -0
- package/dist_ts/sqldb/classes.sqlconnection.d.ts +50 -0
- package/dist_ts/sqldb/classes.sqlconnection.js +376 -0
- package/dist_ts/sqldb/classes.sqltable.d.ts +29 -0
- package/dist_ts/sqldb/classes.sqltable.js +70 -0
- package/dist_ts/sqldb/clickhouse/classes.metricwriter.d.ts +27 -0
- package/dist_ts/sqldb/clickhouse/classes.metricwriter.js +89 -0
- package/dist_ts/sqldb/clickhouse/index.d.ts +9 -0
- package/dist_ts/sqldb/clickhouse/index.js +13 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.d.ts +88 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.js +304 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.d.ts +28 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.js +46 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.d.ts +43 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.js +155 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.d.ts +13 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.js +36 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.d.ts +49 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.js +106 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.d.ts +51 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.js +96 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.d.ts +5 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.js +6 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.types.d.ts +53 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.types.js +41 -0
- package/dist_ts/sqldb/index.d.ts +6 -0
- package/dist_ts/sqldb/index.js +6 -0
- package/dist_ts/sqldb/interfaces.d.ts +53 -0
- package/dist_ts/sqldb/interfaces.js +19 -0
- package/dist_ts/sqldb/internal.sqlpool.d.ts +51 -0
- package/dist_ts/sqldb/internal.sqlpool.js +214 -0
- package/dist_ts/sqldb/plugins.clickhouse.d.ts +4 -0
- package/dist_ts/sqldb/plugins.clickhouse.js +5 -0
- package/dist_ts/sqldb/plugins.mariadb.d.ts +4 -0
- package/dist_ts/sqldb/plugins.mariadb.js +5 -0
- package/docs/source/smartbucket/license.md +19 -0
- package/docs/source/smartclickhouse/license.md +19 -0
- package/license.md +21 -0
- package/package.json +101 -0
- package/readme.md +157 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/classes.losslessorgclient.ts +104 -0
- package/ts/core/classes.error.ts +31 -0
- package/ts/core/classes.operation.ts +60 -0
- package/ts/core/interfaces.ts +24 -0
- package/ts/index.ts +4 -0
- package/ts/nosqldb/classes.atomicdelete.ts +81 -0
- package/ts/nosqldb/classes.atomicfindoneandupdate.ts +152 -0
- package/ts/nosqldb/classes.atomicupdate.ts +99 -0
- package/ts/nosqldb/classes.bootstraprecord.ts +107 -0
- package/ts/nosqldb/classes.bsonassertion.ts +25 -0
- package/ts/nosqldb/classes.bsonobjectid.ts +45 -0
- package/ts/nosqldb/classes.bsonsnapshot.ts +105 -0
- package/ts/nosqldb/classes.cached-document.ts +67 -0
- package/ts/nosqldb/classes.collection.ts +2399 -0
- package/ts/nosqldb/classes.collectionfactory.ts +87 -0
- package/ts/nosqldb/classes.collectionlifecycle.ts +24 -0
- package/ts/nosqldb/classes.collectionpreparation.ts +164 -0
- package/ts/nosqldb/classes.collectiontopology.ts +645 -0
- package/ts/nosqldb/classes.connection.ts +31 -0
- package/ts/nosqldb/classes.convenience.ts +5 -0
- package/ts/nosqldb/classes.cursor.ts +88 -0
- package/ts/nosqldb/classes.cursoroperation.ts +38 -0
- package/ts/nosqldb/classes.db.ts +637 -0
- package/ts/nosqldb/classes.distributedcoordinator.ts +305 -0
- package/ts/nosqldb/classes.doc.ts +4928 -0
- package/ts/nosqldb/classes.easystore.ts +154 -0
- package/ts/nosqldb/classes.exactpersistence.ts +1974 -0
- package/ts/nosqldb/classes.lucene.adapter.ts +780 -0
- package/ts/nosqldb/classes.mongoadministration.ts +867 -0
- package/ts/nosqldb/classes.namespaceinspection.ts +199 -0
- package/ts/nosqldb/classes.operationbudget.ts +75 -0
- package/ts/nosqldb/classes.ordinarypersistence.ts +84 -0
- package/ts/nosqldb/classes.persistence.ts +62 -0
- package/ts/nosqldb/classes.session.ts +389 -0
- package/ts/nosqldb/classes.storedinspection.ts +151 -0
- package/ts/nosqldb/classes.testdatabase.ts +272 -0
- package/ts/nosqldb/classes.watcher.ts +96 -0
- package/ts/nosqldb/index.ts +51 -0
- package/ts/nosqldb/logging.ts +3 -0
- package/ts/nosqldb/plugins.ts +37 -0
- package/ts/nosqldb/shim.ts +6 -0
- package/ts/nosqldb/testsupport.ts +13 -0
- package/ts/objectstorage/classes.bucket.ts +1114 -0
- package/ts/objectstorage/classes.connection.ts +36 -0
- package/ts/objectstorage/classes.directory.ts +425 -0
- package/ts/objectstorage/classes.exactpathpurgeerror.ts +24 -0
- package/ts/objectstorage/classes.exactuploaderror.ts +25 -0
- package/ts/objectstorage/classes.file.ts +303 -0
- package/ts/objectstorage/classes.listcursor.ts +89 -0
- package/ts/objectstorage/classes.metadata.ts +134 -0
- package/ts/objectstorage/classes.smartbucket.ts +445 -0
- package/ts/objectstorage/classes.trash.ts +30 -0
- package/ts/objectstorage/classes.watcher.ts +289 -0
- package/ts/objectstorage/helpers.ts +254 -0
- package/ts/objectstorage/index.ts +13 -0
- package/ts/objectstorage/interfaces.ts +389 -0
- package/ts/objectstorage/internal.exactpathpurge.operations.ts +1936 -0
- package/ts/objectstorage/internal.exactupload.capability.ts +580 -0
- package/ts/objectstorage/internal.exactupload.operations.ts +1715 -0
- package/ts/objectstorage/internal.multipart.planner.ts +90 -0
- package/ts/objectstorage/internal.multipart.stream.ts +606 -0
- package/ts/objectstorage/internal.multipart.types.ts +106 -0
- package/ts/objectstorage/plugins.ts +35 -0
- package/ts/plugins.ts +4 -0
- package/ts/sqldb/classes.clickhouseconnection.ts +189 -0
- package/ts/sqldb/classes.sqlconnection.ts +350 -0
- package/ts/sqldb/classes.sqltable.ts +70 -0
- package/ts/sqldb/clickhouse/classes.metricwriter.ts +72 -0
- package/ts/sqldb/clickhouse/index.ts +16 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.ts +372 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.ts +52 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.ts +120 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.resultset.ts +44 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.ts +123 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.ts +114 -0
- package/ts/sqldb/clickhouse/smartclickhouse.plugins.ts +5 -0
- package/ts/sqldb/clickhouse/smartclickhouse.types.ts +134 -0
- package/ts/sqldb/index.ts +6 -0
- package/ts/sqldb/interfaces.ts +61 -0
- package/ts/sqldb/internal.sqlpool.ts +179 -0
- package/ts/sqldb/plugins.clickhouse.ts +4 -0
- package/ts/sqldb/plugins.mariadb.ts +4 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { ClickhouseResultSet } from './smartclickhouse.classes.resultset.js';
|
|
2
|
+
import { quoteClickHouseIdentifier as quoteIdentifier } from '../interfaces.js';
|
|
3
|
+
import { LosslessClientError } from '../../core/classes.error.js';
|
|
4
|
+
/** Identifier methods quote names. Methods ending in Raw and having() accept trusted SQL expressions. */
|
|
5
|
+
export class ClickhouseQueryBuilder {
|
|
6
|
+
tableName;
|
|
7
|
+
database;
|
|
8
|
+
httpClient;
|
|
9
|
+
selectColumns = ['*'];
|
|
10
|
+
whereClauses = [];
|
|
11
|
+
orderByClauses = [];
|
|
12
|
+
groupByClauses = [];
|
|
13
|
+
havingClauses = [];
|
|
14
|
+
limitValue = null;
|
|
15
|
+
offsetValue = null;
|
|
16
|
+
values = {};
|
|
17
|
+
constructor(tableName, database, httpClient) {
|
|
18
|
+
this.tableName = tableName;
|
|
19
|
+
this.database = database;
|
|
20
|
+
this.httpClient = httpClient;
|
|
21
|
+
}
|
|
22
|
+
select(...columns) {
|
|
23
|
+
this.selectColumns = columns.map(quoteIdentifier);
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
selectRaw(...expressions) { this.selectColumns = expressions; return this; }
|
|
27
|
+
where(column, operator, value) {
|
|
28
|
+
return this.and(column, operator, value);
|
|
29
|
+
}
|
|
30
|
+
and(column, operator, value) {
|
|
31
|
+
this.whereClauses.push({ connector: 'AND', expression: this.buildCondition(column, operator, value) });
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
or(column, operator, value) {
|
|
35
|
+
this.whereClauses.push({ connector: 'OR', expression: this.buildCondition(column, operator, value) });
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
whereRaw(expression) {
|
|
39
|
+
this.whereClauses.push({ connector: 'AND', expression });
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
orderBy(column, direction = 'ASC') {
|
|
43
|
+
if (!['ASC', 'DESC'].includes(direction))
|
|
44
|
+
throw new RangeError('Invalid sort direction.');
|
|
45
|
+
this.orderByClauses.push(quoteIdentifier(column) + ' ' + direction);
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
groupBy(...columns) {
|
|
49
|
+
this.groupByClauses.push(...columns.map(quoteIdentifier));
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
having(expression) { this.havingClauses.push(expression); return this; }
|
|
53
|
+
limit(count) { this.validateCount(count); this.limitValue = count; return this; }
|
|
54
|
+
offset(count) { this.validateCount(count); this.offsetValue = count; return this; }
|
|
55
|
+
validateCount(count) {
|
|
56
|
+
if (!Number.isSafeInteger(count) || count < 0)
|
|
57
|
+
throw new RangeError('Limit and offset must be nonnegative safe integers.');
|
|
58
|
+
}
|
|
59
|
+
async execute(options = {}) {
|
|
60
|
+
return new ClickhouseResultSet(await this.httpClient.queryTyped(this.toSQL(), this.parameters, options));
|
|
61
|
+
}
|
|
62
|
+
async first() { this.limitValue = 1; return (await this.execute()).first(); }
|
|
63
|
+
async count() {
|
|
64
|
+
const selected = this.selectColumns;
|
|
65
|
+
this.selectColumns = ['count() as _count'];
|
|
66
|
+
let sql;
|
|
67
|
+
try {
|
|
68
|
+
sql = this.toSQL();
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
this.selectColumns = selected;
|
|
72
|
+
}
|
|
73
|
+
const rows = await this.httpClient.queryTyped(sql, this.parameters);
|
|
74
|
+
const count = Number(rows[0]?._count ?? 0);
|
|
75
|
+
if (!Number.isSafeInteger(count))
|
|
76
|
+
throw new RangeError('Count exceeds a safe JavaScript integer; select count() as a string.');
|
|
77
|
+
return count;
|
|
78
|
+
}
|
|
79
|
+
async toArray(options = {}) { return (await this.execute(options)).toArray(); }
|
|
80
|
+
/** SQL contains typed placeholders. Pass parameters alongside it, or use toStatement(). */
|
|
81
|
+
toSQL() {
|
|
82
|
+
const parts = ['SELECT ' + this.selectColumns.join(', '), 'FROM ' + quoteIdentifier(this.database) + '.' + quoteIdentifier(this.tableName)];
|
|
83
|
+
const where = this.buildWhereClause();
|
|
84
|
+
if (where)
|
|
85
|
+
parts.push('WHERE ' + where);
|
|
86
|
+
if (this.groupByClauses.length)
|
|
87
|
+
parts.push('GROUP BY ' + this.groupByClauses.join(', '));
|
|
88
|
+
if (this.havingClauses.length)
|
|
89
|
+
parts.push('HAVING ' + this.havingClauses.join(' AND '));
|
|
90
|
+
if (this.orderByClauses.length)
|
|
91
|
+
parts.push('ORDER BY ' + this.orderByClauses.join(', '));
|
|
92
|
+
if (this.limitValue !== null)
|
|
93
|
+
parts.push('LIMIT ' + this.limitValue);
|
|
94
|
+
if (this.offsetValue !== null)
|
|
95
|
+
parts.push('OFFSET ' + this.offsetValue);
|
|
96
|
+
return parts.join(' ');
|
|
97
|
+
}
|
|
98
|
+
get parameters() { return { ...this.values }; }
|
|
99
|
+
toStatement() { return { sql: this.toSQL(), values: this.parameters }; }
|
|
100
|
+
buildWhereClause() {
|
|
101
|
+
return this.whereClauses.map((clause, index) => (index ? clause.connector + ' ' : '') + '(' + clause.expression + ')').join(' ');
|
|
102
|
+
}
|
|
103
|
+
/** Bind a scalar for table mutations as well as predicates. */
|
|
104
|
+
bind(value) {
|
|
105
|
+
let type;
|
|
106
|
+
if (value === null)
|
|
107
|
+
type = 'Nullable(String)';
|
|
108
|
+
else if (typeof value === 'string')
|
|
109
|
+
type = 'String';
|
|
110
|
+
else if (typeof value === 'boolean')
|
|
111
|
+
type = 'Bool';
|
|
112
|
+
else if (typeof value === 'bigint') {
|
|
113
|
+
if (value < -(2n ** 255n) || value >= 2n ** 255n)
|
|
114
|
+
throw new RangeError('Integer exceeds Int256.');
|
|
115
|
+
type = 'Int256';
|
|
116
|
+
value = value.toString();
|
|
117
|
+
}
|
|
118
|
+
else if (typeof value === 'number' && Number.isFinite(value)) {
|
|
119
|
+
if (Number.isInteger(value) && !Number.isSafeInteger(value))
|
|
120
|
+
throw new RangeError('Use bigint for large integers.');
|
|
121
|
+
type = Number.isInteger(value) ? 'Int64' : 'Float64';
|
|
122
|
+
}
|
|
123
|
+
else if (value instanceof Date && Number.isFinite(value.getTime())) {
|
|
124
|
+
type = "DateTime64(3, 'UTC')";
|
|
125
|
+
value = value.toISOString().replace('T', ' ').replace('Z', '');
|
|
126
|
+
}
|
|
127
|
+
else
|
|
128
|
+
throw new LosslessClientError('invalid_argument', 'Use a supported scalar query parameter.');
|
|
129
|
+
const key = 'p' + Object.keys(this.values).length;
|
|
130
|
+
this.values[key] = value;
|
|
131
|
+
return '{' + key + ':' + type + '}';
|
|
132
|
+
}
|
|
133
|
+
buildCondition(column, operator, value) {
|
|
134
|
+
const name = quoteIdentifier(column);
|
|
135
|
+
if (!['=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN'].includes(operator)) {
|
|
136
|
+
throw new RangeError('Invalid comparison operator.');
|
|
137
|
+
}
|
|
138
|
+
if (value === null && (operator === '=' || operator === '!='))
|
|
139
|
+
return name + (operator === '=' ? ' IS NULL' : ' IS NOT NULL');
|
|
140
|
+
if (operator === 'IN' || operator === 'NOT IN') {
|
|
141
|
+
if (!Array.isArray(value))
|
|
142
|
+
throw new RangeError('IN requires an array.');
|
|
143
|
+
if (!value.length)
|
|
144
|
+
return operator === 'IN' ? '0' : '1';
|
|
145
|
+
return name + ' ' + operator + ' (' + value.map(item => this.bind(item)).join(', ') + ')';
|
|
146
|
+
}
|
|
147
|
+
if (operator === 'BETWEEN') {
|
|
148
|
+
if (!Array.isArray(value) || value.length !== 2)
|
|
149
|
+
throw new RangeError('BETWEEN requires two values.');
|
|
150
|
+
return name + ' BETWEEN ' + this.bind(value[0]) + ' AND ' + this.bind(value[1]);
|
|
151
|
+
}
|
|
152
|
+
return name + ' ' + operator + ' ' + this.bind(value);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRjbGlja2hvdXNlLmNsYXNzZXMucXVlcnlidWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvc3FsZGIvY2xpY2tob3VzZS9zbWFydGNsaWNraG91c2UuY2xhc3Nlcy5xdWVyeWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFFN0UsT0FBTyxFQUFFLHlCQUF5QixJQUFJLGVBQWUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRWhGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBSWxFLHlHQUF5RztBQUN6RyxNQUFNLE9BQU8sc0JBQXNCO0lBVWI7SUFBMkI7SUFBMEI7SUFUakUsYUFBYSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDdEIsWUFBWSxHQUFtQixFQUFFLENBQUM7SUFDbEMsY0FBYyxHQUFhLEVBQUUsQ0FBQztJQUM5QixjQUFjLEdBQWEsRUFBRSxDQUFDO0lBQzlCLGFBQWEsR0FBYSxFQUFFLENBQUM7SUFDN0IsVUFBVSxHQUFrQixJQUFJLENBQUM7SUFDakMsV0FBVyxHQUFrQixJQUFJLENBQUM7SUFDekIsTUFBTSxHQUE0QixFQUFFLENBQUM7SUFFdEQsWUFBb0IsU0FBaUIsRUFBVSxRQUFnQixFQUFVLFVBQWdDO1FBQXJGLGNBQVMsR0FBVCxTQUFTLENBQVE7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFRO1FBQVUsZUFBVSxHQUFWLFVBQVUsQ0FBc0I7SUFBRyxDQUFDO0lBRXRHLE1BQU0sQ0FBNkIsR0FBRyxPQUFZO1FBQ3ZELElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUFDLE9BQU8sSUFBSSxDQUFDO0lBQ2pFLENBQUM7SUFDTSxTQUFTLENBQUMsR0FBRyxXQUFxQixJQUFVLElBQUksQ0FBQyxhQUFhLEdBQUcs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U0FBUyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDekcsTUFBTSxJQUFJLFVBQVUsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFDRCxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssR0FBRyxJQUFJLFFBQVEsS0FBSyxJQUFJLENBQUM7WUFBRSxPQUFPLElBQUksR0FBRyxDQUFDLFFBQVEsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDOUgsSUFBSSxRQUFRLEtBQUssSUFBSSxJQUFJLFFBQVEsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7Z0JBQUUsTUFBTSxJQUFJLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1lBQ3pFLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTTtnQkFBRSxPQUFPLFFBQVEsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQ3hELE9BQU8sSUFBSSxHQUFHLEdBQUcsR0FBRyxRQUFRLEdBQUcsSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQztRQUM1RixDQUFDO1FBQ0QsSUFBSSxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDO2dCQUFFLE1BQU0sSUFBSSxVQUFVLENBQUMsOEJBQThCLENBQUMsQ0FBQztZQUN0RyxPQUFPLElBQUksR0FBRyxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRixDQUFDO1FBQ0QsT0FBTyxJQUFJLEdBQUcsR0FBRyxHQUFHLFFBQVEsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN4RCxDQUFDO0NBQ0YifQ==
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as plugins from './smartclickhouse.plugins.js';
|
|
2
|
+
export declare class ClickhouseResultSet<T> {
|
|
3
|
+
rows: T[];
|
|
4
|
+
rowCount: number;
|
|
5
|
+
constructor(rows: T[]);
|
|
6
|
+
first(): T | null;
|
|
7
|
+
last(): T | null;
|
|
8
|
+
isEmpty(): boolean;
|
|
9
|
+
toArray(): T[];
|
|
10
|
+
map<U>(fn: (row: T) => U): U[];
|
|
11
|
+
filter(fn: (row: T) => boolean): ClickhouseResultSet<T>;
|
|
12
|
+
toObservable(): plugins.smartrx.rxjs.Observable<T>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as plugins from './smartclickhouse.plugins.js';
|
|
2
|
+
export class ClickhouseResultSet {
|
|
3
|
+
rows;
|
|
4
|
+
rowCount;
|
|
5
|
+
constructor(rows) {
|
|
6
|
+
this.rows = rows;
|
|
7
|
+
this.rowCount = rows.length;
|
|
8
|
+
}
|
|
9
|
+
first() {
|
|
10
|
+
return this.rows[0] ?? null;
|
|
11
|
+
}
|
|
12
|
+
last() {
|
|
13
|
+
return this.rows[this.rows.length - 1] ?? null;
|
|
14
|
+
}
|
|
15
|
+
isEmpty() {
|
|
16
|
+
return this.rows.length === 0;
|
|
17
|
+
}
|
|
18
|
+
toArray() {
|
|
19
|
+
return this.rows;
|
|
20
|
+
}
|
|
21
|
+
map(fn) {
|
|
22
|
+
return this.rows.map(fn);
|
|
23
|
+
}
|
|
24
|
+
filter(fn) {
|
|
25
|
+
return new ClickhouseResultSet(this.rows.filter(fn));
|
|
26
|
+
}
|
|
27
|
+
toObservable() {
|
|
28
|
+
return new plugins.smartrx.rxjs.Observable((observer) => {
|
|
29
|
+
for (const row of this.rows) {
|
|
30
|
+
observer.next(row);
|
|
31
|
+
}
|
|
32
|
+
observer.complete();
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRjbGlja2hvdXNlLmNsYXNzZXMucmVzdWx0c2V0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvc3FsZGIvY2xpY2tob3VzZS9zbWFydGNsaWNraG91c2UuY2xhc3Nlcy5yZXN1bHRzZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSw4QkFBOEIsQ0FBQztBQUV4RCxNQUFNLE9BQU8sbUJBQW1CO0lBQ3ZCLElBQUksQ0FBTTtJQUNWLFFBQVEsQ0FBUztJQUV4QixZQUFZLElBQVM7UUFDbkIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQzlCLENBQUM7SUFFTSxLQUFLO1FBQ1YsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQztJQUM5QixDQUFDO0lBRU0sSUFBSTtRQUNULE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7SUFDakQsQ0FBQztJQUVNLE9BQU87UUFDWixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRU0sT0FBTztRQUNaLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQztJQUNuQixDQUFDO0lBRU0sR0FBRyxDQUFJLEVBQWlCO1FBQzdCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUVNLE1BQU0sQ0FBQyxFQUF1QjtRQUNuQyxPQUFPLElBQUksbUJBQW1CLENBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRU0sWUFBWTtRQUNqQixPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFJLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDekQsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQzVCLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckIsQ0FBQztZQUNELFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN0QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRiJ9
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ClickhouseTable } from './smartclickhouse.classes.clickhousetable.js';
|
|
2
|
+
import { TimeDataTable } from './smartclickhouse.classes.timedatatable.js';
|
|
3
|
+
import { ClickhouseHttpClient } from './smartclickhouse.classes.httpclient.js';
|
|
4
|
+
import type { IClickhouseTableOptions } from './smartclickhouse.types.js';
|
|
5
|
+
import type { ClickHouseConnection } from '../classes.clickhouseconnection.js';
|
|
6
|
+
import type { MetricWriter } from './classes.metricwriter.js';
|
|
7
|
+
export interface IClickhouseConstructorOptions {
|
|
8
|
+
url: string;
|
|
9
|
+
database: string;
|
|
10
|
+
username?: string;
|
|
11
|
+
password?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Allow services to exit when waiting for clickhouse startup.
|
|
14
|
+
* This allows to leave the lifecycle flow to other processes
|
|
15
|
+
* like a listening server.
|
|
16
|
+
*/
|
|
17
|
+
unref?: boolean;
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class SmartClickHouseDb {
|
|
21
|
+
options: IClickhouseConstructorOptions;
|
|
22
|
+
clickhouseHttpClient: ClickhouseHttpClient;
|
|
23
|
+
private readonly writers;
|
|
24
|
+
private closing?;
|
|
25
|
+
private stopping;
|
|
26
|
+
private readonly canonical;
|
|
27
|
+
constructor(optionsArg: IClickhouseConstructorOptions, connection?: ClickHouseConnection);
|
|
28
|
+
/**
|
|
29
|
+
* Starts the connection to the Clickhouse db
|
|
30
|
+
*/
|
|
31
|
+
start(dropOld?: boolean): Promise<void>;
|
|
32
|
+
ownWriter<Row>(writer: MetricWriter<Row>): MetricWriter<Row>;
|
|
33
|
+
closeWriters(): Promise<void>;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
createDatabase(dropOld?: boolean): Promise<void>;
|
|
36
|
+
pingDatabaseUntilAvailable(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Create a typed ClickHouse table with full configuration
|
|
39
|
+
*/
|
|
40
|
+
createTable<T extends Record<string, any>>(options: IClickhouseTableOptions<T>): Promise<ClickhouseTable<T>>;
|
|
41
|
+
/**
|
|
42
|
+
* Get a TimeDataTable (backward compatible)
|
|
43
|
+
*/
|
|
44
|
+
getTable(tableName: string): Promise<TimeDataTable>;
|
|
45
|
+
/**
|
|
46
|
+
* Execute a raw SQL query and return typed results
|
|
47
|
+
*/
|
|
48
|
+
query<T = any>(sql: string): Promise<T[]>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import * as plugins from './smartclickhouse.plugins.js';
|
|
2
|
+
import { ClickhouseTable } from './smartclickhouse.classes.clickhousetable.js';
|
|
3
|
+
import { TimeDataTable } from './smartclickhouse.classes.timedatatable.js';
|
|
4
|
+
import { ClickhouseHttpClient } from './smartclickhouse.classes.httpclient.js';
|
|
5
|
+
import { quoteClickHouseIdentifier as quoteIdentifier } from '../interfaces.js';
|
|
6
|
+
import { Operation } from '../../core/classes.operation.js';
|
|
7
|
+
import { LosslessClientError } from '../../core/classes.error.js';
|
|
8
|
+
export class SmartClickHouseDb {
|
|
9
|
+
options;
|
|
10
|
+
clickhouseHttpClient;
|
|
11
|
+
writers = new Set();
|
|
12
|
+
closing;
|
|
13
|
+
stopping = false;
|
|
14
|
+
canonical;
|
|
15
|
+
constructor(optionsArg, connection) {
|
|
16
|
+
this.options = optionsArg;
|
|
17
|
+
this.canonical = Boolean(connection);
|
|
18
|
+
if (connection)
|
|
19
|
+
this.clickhouseHttpClient = new ClickhouseHttpClient(optionsArg, connection);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Starts the connection to the Clickhouse db
|
|
23
|
+
*/
|
|
24
|
+
async start(dropOld = false) {
|
|
25
|
+
if (this.clickhouseHttpClient)
|
|
26
|
+
return;
|
|
27
|
+
this.clickhouseHttpClient = await ClickhouseHttpClient.createAndStart(this.options);
|
|
28
|
+
try {
|
|
29
|
+
await this.createDatabase(dropOld);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
await this.clickhouseHttpClient.close();
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
ownWriter(writer) {
|
|
37
|
+
if (this.stopping)
|
|
38
|
+
throw new LosslessClientError('closed', 'Metrics connection is closing.');
|
|
39
|
+
this.writers.add(writer);
|
|
40
|
+
return writer;
|
|
41
|
+
}
|
|
42
|
+
closeWriters() {
|
|
43
|
+
return this.closing ??= (async () => {
|
|
44
|
+
this.stopping = true;
|
|
45
|
+
const results = await Promise.allSettled([...this.writers].map(writer => writer.close()));
|
|
46
|
+
this.writers.clear();
|
|
47
|
+
const errors = results.flatMap(result => result.status === 'rejected' ? [result.reason] : []);
|
|
48
|
+
if (errors.length)
|
|
49
|
+
throw new AggregateError(errors, 'Metrics writer flush failed.');
|
|
50
|
+
})();
|
|
51
|
+
}
|
|
52
|
+
async close() {
|
|
53
|
+
try {
|
|
54
|
+
await this.closeWriters();
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
await this.clickhouseHttpClient?.close();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async createDatabase(dropOld = false) {
|
|
61
|
+
if (dropOld) {
|
|
62
|
+
await this.clickhouseHttpClient.queryPromise(`DROP DATABASE IF EXISTS ${quoteIdentifier(this.options.database)}`);
|
|
63
|
+
}
|
|
64
|
+
await this.clickhouseHttpClient.queryPromise(`CREATE DATABASE IF NOT EXISTS ${quoteIdentifier(this.options.database)}`);
|
|
65
|
+
}
|
|
66
|
+
async pingDatabaseUntilAvailable() {
|
|
67
|
+
const operation = new Operation({ timeoutMs: this.options.timeoutMs });
|
|
68
|
+
try {
|
|
69
|
+
while (true) {
|
|
70
|
+
operation.check();
|
|
71
|
+
if (await this.clickhouseHttpClient.ping({ signal: operation.signal }))
|
|
72
|
+
return;
|
|
73
|
+
await plugins.smartdelay.delayFor(100, null, this.options.unref);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
operation.dispose();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// ---- NEW: Generic typed table factory ----
|
|
81
|
+
/**
|
|
82
|
+
* Create a typed ClickHouse table with full configuration
|
|
83
|
+
*/
|
|
84
|
+
async createTable(options) {
|
|
85
|
+
return ClickhouseTable.create(this, {
|
|
86
|
+
autoSchemaEvolution: !this.canonical,
|
|
87
|
+
...options,
|
|
88
|
+
database: options.database || this.options.database,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// ---- BACKWARD COMPAT: TimeDataTable factory ----
|
|
92
|
+
/**
|
|
93
|
+
* Get a TimeDataTable (backward compatible)
|
|
94
|
+
*/
|
|
95
|
+
async getTable(tableName) {
|
|
96
|
+
return TimeDataTable.getTable(this, tableName);
|
|
97
|
+
}
|
|
98
|
+
// ---- RAW QUERY ----
|
|
99
|
+
/**
|
|
100
|
+
* Execute a raw SQL query and return typed results
|
|
101
|
+
*/
|
|
102
|
+
async query(sql) {
|
|
103
|
+
return this.clickhouseHttpClient.queryTyped(sql);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRjbGlja2hvdXNlLmNsYXNzZXMuc21hcnRjbGlja2hvdXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvc3FsZGIvY2xpY2tob3VzZS9zbWFydGNsaWNraG91c2UuY2xhc3Nlcy5zbWFydGNsaWNraG91c2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSw4QkFBOEIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDL0UsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBRy9FLE9BQU8sRUFBRSx5QkFBeUIsSUFBSSxlQUFlLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFNUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFnQmxFLE1BQU0sT0FBTyxpQkFBaUI7SUFDckIsT0FBTyxDQUFnQztJQUN2QyxvQkFBb0IsQ0FBd0I7SUFDbEMsT0FBTyxHQUFHLElBQUksR0FBRyxFQUF5QixDQUFDO0lBQ3BELE9BQU8sQ0FBaUI7SUFDeEIsUUFBUSxHQUFHLEtBQUssQ0FBQztJQUNSLFNBQVMsQ0FBVTtJQUVwQyxZQUFZLFVBQXlDLEVBQUUsVUFBaUM7UUFDdEYsSUFBSSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUM7UUFDMUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDckMsSUFBSSxVQUFVO1lBQUUsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksb0JBQW9CLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQy9GLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxLQUFLLENB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
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as plugins from './smartclickhouse.plugins.js';
|
|
2
|
+
import type { SmartClickHouseDb } from './smartclickhouse.classes.smartclickhouse.js';
|
|
3
|
+
import { ClickhouseTable } from './smartclickhouse.classes.clickhousetable.js';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a pre-configured ClickhouseTable for time-series data.
|
|
6
|
+
* This is the backward-compatible equivalent of the old TimeDataTable class.
|
|
7
|
+
*
|
|
8
|
+
* The table uses MergeTree engine, orders by timestamp, and has auto-schema evolution enabled.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createTimeDataTable(db: SmartClickHouseDb, tableName: string, retainDataForDays?: number): Promise<TimeDataTable>;
|
|
11
|
+
/**
|
|
12
|
+
* TimeDataTable — a ClickhouseTable pre-configured for time-series data.
|
|
13
|
+
* Provides backward-compatible convenience methods (addData, getLastEntries, etc.).
|
|
14
|
+
*/
|
|
15
|
+
export declare class TimeDataTable extends ClickhouseTable<any> {
|
|
16
|
+
/**
|
|
17
|
+
* Static factory for backward compatibility
|
|
18
|
+
*/
|
|
19
|
+
static getTable(smartClickHouseDbRefArg: SmartClickHouseDb, tableNameArg: string, retainDataForDays?: number): Promise<TimeDataTable>;
|
|
20
|
+
constructor(db: SmartClickHouseDb, tableName: string, retainDataForDays?: number);
|
|
21
|
+
/**
|
|
22
|
+
* Insert data with auto-schema evolution and object flattening.
|
|
23
|
+
* Backward-compatible: accepts arbitrary JSON objects with a timestamp field.
|
|
24
|
+
*/
|
|
25
|
+
addData(dataArg: any): Promise<any>;
|
|
26
|
+
/**
|
|
27
|
+
* Get the last N entries ordered by timestamp DESC
|
|
28
|
+
*/
|
|
29
|
+
getLastEntries(count: number): Promise<any[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Get entries newer than a unix timestamp (in milliseconds)
|
|
32
|
+
*/
|
|
33
|
+
getEntriesNewerThan(unixTimestamp: number): Promise<any[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Get entries between two unix timestamps (in milliseconds)
|
|
36
|
+
*/
|
|
37
|
+
getEntriesBetween(unixTimestampStart: number, unixTimestampEnd: number): Promise<any[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Delete entries older than N days
|
|
40
|
+
*/
|
|
41
|
+
deleteOldEntries(days: number): Promise<void>;
|
|
42
|
+
private validateTimestamp;
|
|
43
|
+
/**
|
|
44
|
+
* Drop the table (backward-compatible alias for drop())
|
|
45
|
+
*/
|
|
46
|
+
delete(): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Watch for new entries via polling (backward-compatible wrapper)
|
|
49
|
+
*/
|
|
50
|
+
watchNewEntries(): plugins.smartrx.rxjs.Observable<any>;
|
|
51
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import * as plugins from './smartclickhouse.plugins.js';
|
|
2
|
+
import { ClickhouseTable } from './smartclickhouse.classes.clickhousetable.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a pre-configured ClickhouseTable for time-series data.
|
|
5
|
+
* This is the backward-compatible equivalent of the old TimeDataTable class.
|
|
6
|
+
*
|
|
7
|
+
* The table uses MergeTree engine, orders by timestamp, and has auto-schema evolution enabled.
|
|
8
|
+
*/
|
|
9
|
+
export async function createTimeDataTable(db, tableName, retainDataForDays = 30) {
|
|
10
|
+
const table = new TimeDataTable(db, tableName, retainDataForDays);
|
|
11
|
+
await table.setup();
|
|
12
|
+
return table;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* TimeDataTable — a ClickhouseTable pre-configured for time-series data.
|
|
16
|
+
* Provides backward-compatible convenience methods (addData, getLastEntries, etc.).
|
|
17
|
+
*/
|
|
18
|
+
export class TimeDataTable extends ClickhouseTable {
|
|
19
|
+
/**
|
|
20
|
+
* Static factory for backward compatibility
|
|
21
|
+
*/
|
|
22
|
+
static async getTable(smartClickHouseDbRefArg, tableNameArg, retainDataForDays = 30) {
|
|
23
|
+
return createTimeDataTable(smartClickHouseDbRefArg, tableNameArg, retainDataForDays);
|
|
24
|
+
}
|
|
25
|
+
constructor(db, tableName, retainDataForDays = 30) {
|
|
26
|
+
super(db, {
|
|
27
|
+
tableName,
|
|
28
|
+
engine: { engine: 'MergeTree' },
|
|
29
|
+
orderBy: 'timestamp',
|
|
30
|
+
retainDataForDays,
|
|
31
|
+
autoSchemaEvolution: true,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Insert data with auto-schema evolution and object flattening.
|
|
36
|
+
* Backward-compatible: accepts arbitrary JSON objects with a timestamp field.
|
|
37
|
+
*/
|
|
38
|
+
async addData(dataArg) {
|
|
39
|
+
if (!dataArg.timestamp || typeof dataArg.timestamp !== 'number') {
|
|
40
|
+
throw new Error('timestamp must be of type number');
|
|
41
|
+
}
|
|
42
|
+
return this.insert(dataArg);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get the last N entries ordered by timestamp DESC
|
|
46
|
+
*/
|
|
47
|
+
async getLastEntries(count) {
|
|
48
|
+
return this.query()
|
|
49
|
+
.orderBy('timestamp', 'DESC')
|
|
50
|
+
.limit(count)
|
|
51
|
+
.toArray();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get entries newer than a unix timestamp (in milliseconds)
|
|
55
|
+
*/
|
|
56
|
+
async getEntriesNewerThan(unixTimestamp) {
|
|
57
|
+
return this.db.clickhouseHttpClient.queryPromise(`
|
|
58
|
+
SELECT * FROM ${this.qualifiedName}
|
|
59
|
+
WHERE timestamp > fromUnixTimestamp64Milli({timestamp:Int64})
|
|
60
|
+
`, { timestamp: this.validateTimestamp(unixTimestamp) });
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get entries between two unix timestamps (in milliseconds)
|
|
64
|
+
*/
|
|
65
|
+
async getEntriesBetween(unixTimestampStart, unixTimestampEnd) {
|
|
66
|
+
return this.db.clickhouseHttpClient.queryPromise(`
|
|
67
|
+
SELECT * FROM ${this.qualifiedName}
|
|
68
|
+
WHERE timestamp > fromUnixTimestamp64Milli({start:Int64})
|
|
69
|
+
AND timestamp < fromUnixTimestamp64Milli({end:Int64})
|
|
70
|
+
`, { start: this.validateTimestamp(unixTimestampStart), end: this.validateTimestamp(unixTimestampEnd) });
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Delete entries older than N days
|
|
74
|
+
*/
|
|
75
|
+
async deleteOldEntries(days) {
|
|
76
|
+
await this.deleteOlderThan('timestamp', days + ' DAY');
|
|
77
|
+
}
|
|
78
|
+
validateTimestamp(value) {
|
|
79
|
+
if (!Number.isSafeInteger(value))
|
|
80
|
+
throw new RangeError('Timestamp must be an integer in milliseconds.');
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Drop the table (backward-compatible alias for drop())
|
|
85
|
+
*/
|
|
86
|
+
async delete() {
|
|
87
|
+
return this.drop();
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Watch for new entries via polling (backward-compatible wrapper)
|
|
91
|
+
*/
|
|
92
|
+
watchNewEntries() {
|
|
93
|
+
return this.watch();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRjbGlja2hvdXNlLmNsYXNzZXMudGltZWRhdGF0YWJsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3NxbGRiL2NsaWNraG91c2Uvc21hcnRjbGlja2hvdXNlLmNsYXNzZXMudGltZWRhdGF0YWJsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDhCQUE4QixDQUFDO0FBRXhELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUUvRTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsbUJBQW1CLENBQ3ZDLEVBQXFCLEVBQ3JCLFNBQWlCLEVBQ2pCLG9CQUE0QixFQUFFO0lBRTlCLE1BQU0sS0FBSyxHQUFHLElBQUksYUFBYSxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUNsRSxNQUFNLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNwQixPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sYUFBYyxTQUFRLGVBQW9CO0lBQ3JEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQzFCLHVCQUEwQyxFQUMxQyxZQUFvQixFQUNwQixvQkFBNEIsRUFBRTtRQUU5QixPQUFPLG1CQUFtQixDQUFDLHVCQUF1QixFQUFFLFlBQVksRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFFRCxZQUFZLEVBQXFCLEVBQUUsU0FBaUIsRUFBRSxvQkFBNEIsRUFBRTtRQUNsRixLQUFLLENBQUMsRUFBRSxFQUFFO1lBQ1IsU0FBUztZQUNULE1BQU0sRUFBRSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUU7WUFDL0IsT0FBTyxFQUFFLFdBQWtCO1lBQzNCLGlCQUFpQjtZQUNqQixtQkFBbUIsRUFBRSxJQUFJO1NBQzFCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7O09BR0c7SUFDSSxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQVk7UUFDL0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLElBQUksT0FBTyxPQUFPLENBQUMsU0FBUyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ2hFLE1BQU0sSUFBSSxLQUFLLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBYTtRQUN2QyxPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUU7YUFDaEIsT0FBTyxDQUFDLFdBQWtCLEVBQUUsTUFBTSxDQUFDO2FBQ25DLEtBQUssQ0FBQyxLQUFLLENBQUM7YUFDWixPQUFPLEVBQUUsQ0FBQztJQUNmLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxhQUFxQjtRQUNwRCxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDO3NCQUMvQixJQUFJLENBQUMsYUFBYTs7S0FFbkMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxrQkFBMEIsRUFBRSxnQkFBd0I7UUFDakYsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQztzQkFDL0IsSUFBSSxDQUFDLGFBQWE7OztLQUduQyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDM0csQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLGdCQUFnQixDQUFDLElBQVk7UUFDeEMsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsRUFBRSxJQUFJLEdBQUcsTUFBTSxDQUFDLENBQUM7SUFDekQsQ0FBQztJQUVPLGlCQUFpQixDQUFDLEtBQWE7UUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDO1lBQUUsTUFBTSxJQUFJLFVBQVUsQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO1FBQ3hHLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLE1BQU07UUFDakIsT0FBTyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksZUFBZTtRQUNwQixPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN0QixDQUFDO0NBQ0YifQ==
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as smartdelay from '@push.rocks/smartdelay';
|
|
2
|
+
import * as smartobject from '@push.rocks/smartobject';
|
|
3
|
+
import * as smartpromise from '@push.rocks/smartpromise';
|
|
4
|
+
import * as smartrx from '@push.rocks/smartrx';
|
|
5
|
+
export { smartdelay, smartobject, smartpromise, smartrx };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as smartdelay from '@push.rocks/smartdelay';
|
|
2
|
+
import * as smartobject from '@push.rocks/smartobject';
|
|
3
|
+
import * as smartpromise from '@push.rocks/smartpromise';
|
|
4
|
+
import * as smartrx from '@push.rocks/smartrx';
|
|
5
|
+
export { smartdelay, smartobject, smartpromise, smartrx };
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRjbGlja2hvdXNlLnBsdWdpbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zcWxkYi9jbGlja2hvdXNlL3NtYXJ0Y2xpY2tob3VzZS5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxVQUFVLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxLQUFLLFdBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxPQUFPLE1BQU0scUJBQXFCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxDQUFDIn0=
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export type TClickhouseColumnType = 'String' | 'UInt8' | 'UInt16' | 'UInt32' | 'UInt64' | 'Int8' | 'Int16' | 'Int32' | 'Int64' | 'Float32' | 'Float64' | 'Bool' | 'Date' | 'Date32' | 'DateTime' | 'DateTime64' | 'UUID' | 'IPv4' | 'IPv6' | (string & {});
|
|
2
|
+
export type TClickhouseEngine = 'MergeTree' | 'ReplacingMergeTree' | 'SummingMergeTree' | 'AggregatingMergeTree' | 'CollapsingMergeTree' | 'VersionedCollapsingMergeTree';
|
|
3
|
+
export interface IEngineConfig {
|
|
4
|
+
engine: TClickhouseEngine;
|
|
5
|
+
/** For ReplacingMergeTree: the version column name */
|
|
6
|
+
versionColumn?: string;
|
|
7
|
+
/** For CollapsingMergeTree: the sign column name */
|
|
8
|
+
signColumn?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface IColumnDefinition {
|
|
11
|
+
name: string;
|
|
12
|
+
type: TClickhouseColumnType;
|
|
13
|
+
defaultExpression?: string;
|
|
14
|
+
codec?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface IClickhouseTableOptions<T = any> {
|
|
17
|
+
tableName: string;
|
|
18
|
+
database?: string;
|
|
19
|
+
engine?: IEngineConfig;
|
|
20
|
+
orderBy: (keyof T & string) | (keyof T & string)[];
|
|
21
|
+
partitionBy?: string;
|
|
22
|
+
primaryKey?: (keyof T & string) | (keyof T & string)[];
|
|
23
|
+
ttl?: {
|
|
24
|
+
column: keyof T & string;
|
|
25
|
+
interval: string;
|
|
26
|
+
};
|
|
27
|
+
columns?: IColumnDefinition[];
|
|
28
|
+
/** Enable auto-schema evolution (add columns from data). Default: true */
|
|
29
|
+
autoSchemaEvolution?: boolean;
|
|
30
|
+
/** Data retention in days (shorthand for ttl). If ttl is set, this is ignored. */
|
|
31
|
+
retainDataForDays?: number;
|
|
32
|
+
}
|
|
33
|
+
export interface IColumnInfo {
|
|
34
|
+
database: string;
|
|
35
|
+
table: string;
|
|
36
|
+
name: string;
|
|
37
|
+
type: string;
|
|
38
|
+
position: string;
|
|
39
|
+
default_kind: string;
|
|
40
|
+
default_expression: string;
|
|
41
|
+
data_compressed_bytes: string;
|
|
42
|
+
data_uncompressed_bytes: string;
|
|
43
|
+
marks_bytes: string;
|
|
44
|
+
comment: string;
|
|
45
|
+
is_in_partition_key: 0 | 1;
|
|
46
|
+
is_in_sorting_key: 0 | 1;
|
|
47
|
+
is_in_primary_key: 0 | 1;
|
|
48
|
+
is_in_sampling_key: 0 | 1;
|
|
49
|
+
compression_codec: string;
|
|
50
|
+
}
|
|
51
|
+
export type TComparisonOperator = '=' | '!=' | '>' | '>=' | '<' | '<=' | 'LIKE' | 'NOT LIKE' | 'IN' | 'NOT IN' | 'BETWEEN';
|
|
52
|
+
export declare function escapeClickhouseValue(value: any): string;
|
|
53
|
+
export declare function detectClickhouseType(value: any): TClickhouseColumnType | null;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Value Escaping (SQL Injection Prevention)
|
|
3
|
+
// ============================================================
|
|
4
|
+
export function escapeClickhouseValue(value) {
|
|
5
|
+
if (value === null || value === undefined)
|
|
6
|
+
return 'NULL';
|
|
7
|
+
if (typeof value === 'number')
|
|
8
|
+
return String(value);
|
|
9
|
+
if (typeof value === 'boolean')
|
|
10
|
+
return value ? '1' : '0';
|
|
11
|
+
if (value instanceof Date)
|
|
12
|
+
return `'${value.toISOString().replace('T', ' ').replace('Z', '')}'`;
|
|
13
|
+
if (Array.isArray(value)) {
|
|
14
|
+
return `(${value.map(escapeClickhouseValue).join(', ')})`;
|
|
15
|
+
}
|
|
16
|
+
// String: escape single quotes and backslashes
|
|
17
|
+
return `'${String(value).replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
|
|
18
|
+
}
|
|
19
|
+
// ============================================================
|
|
20
|
+
// ClickHouse Type Detection from JS Values
|
|
21
|
+
// ============================================================
|
|
22
|
+
export function detectClickhouseType(value) {
|
|
23
|
+
if (value === null || value === undefined)
|
|
24
|
+
return null;
|
|
25
|
+
if (typeof value === 'string')
|
|
26
|
+
return 'String';
|
|
27
|
+
if (typeof value === 'number')
|
|
28
|
+
return 'Float64';
|
|
29
|
+
if (typeof value === 'boolean')
|
|
30
|
+
return 'UInt8';
|
|
31
|
+
if (value instanceof Array) {
|
|
32
|
+
if (value.length === 0)
|
|
33
|
+
return null;
|
|
34
|
+
const elementType = detectClickhouseType(value[0]);
|
|
35
|
+
if (!elementType)
|
|
36
|
+
return null;
|
|
37
|
+
return `Array(${elementType})`;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRjbGlja2hvdXNlLnR5cGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvc3FsZGIvY2xpY2tob3VzZS9zbWFydGNsaWNraG91c2UudHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBdUdBLCtEQUErRDtBQUMvRCw0Q0FBNEM7QUFDNUMsK0RBQStEO0FBQy9ELE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxLQUFVO0lBQzlDLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxLQUFLLEtBQUssU0FBUztRQUFFLE9BQU8sTUFBTSxDQUFDO0lBQ3pELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUTtRQUFFLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BELElBQUksT0FBTyxLQUFLLEtBQUssU0FBUztRQUFFLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUN6RCxJQUFJLEtBQUssWUFBWSxJQUFJO1FBQUUsT0FBTyxJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQztJQUNoRyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN6QixPQUFPLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQzVELENBQUM7SUFDRCwrQ0FBK0M7SUFDL0MsT0FBTyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQztBQUMxRSxDQUFDO0FBRUQsK0RBQStEO0FBQy9ELDJDQUEyQztBQUMzQywrREFBK0Q7QUFDL0QsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEtBQVU7SUFDN0MsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDdkQsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxRQUFRLENBQUM7SUFDL0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDaEQsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxPQUFPLENBQUM7SUFDL0MsSUFBSSxLQUFLLFlBQVksS0FBSyxFQUFFLENBQUM7UUFDM0IsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUNwQyxNQUFNLFdBQVcsR0FBRyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsV0FBVztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQzlCLE9BQU8sU0FBUyxXQUFXLEdBQTRCLENBQUM7SUFDMUQsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyJ9
|