fix: realtime improvements
This commit is contained in:
@@ -73,18 +73,20 @@ export class Query<T = any> {
|
||||
};
|
||||
private _transform?: Record<string, (item: T) => any>;
|
||||
private _union?: Query;
|
||||
private _dateRegex = /\d{4}-\d{2}-\d{2}([\s\:\d\.]+)?/g;
|
||||
private _dateRegex = /\d{4}-\d{2}-\d{2}([\s:\d.]+)?/g;
|
||||
constructor(
|
||||
private client: ClickHouseClient,
|
||||
private timezone: string,
|
||||
private timezone: string
|
||||
) {}
|
||||
|
||||
// Select methods
|
||||
select<U>(
|
||||
columns: (string | Expression | null | undefined | false)[],
|
||||
type: 'merge' | 'replace' = 'replace',
|
||||
type: 'merge' | 'replace' = 'replace'
|
||||
): Query<U> {
|
||||
if (this._skipNext) return this as unknown as Query<U>;
|
||||
if (this._skipNext) {
|
||||
return this as unknown as Query<U>;
|
||||
}
|
||||
if (type === 'merge') {
|
||||
this._select = [
|
||||
...this._select,
|
||||
@@ -92,7 +94,7 @@ export class Query<T = any> {
|
||||
];
|
||||
} else {
|
||||
this._select = columns.filter((col): col is string | Expression =>
|
||||
Boolean(col),
|
||||
Boolean(col)
|
||||
);
|
||||
}
|
||||
return this as unknown as Query<U>;
|
||||
@@ -122,8 +124,12 @@ export class Query<T = any> {
|
||||
|
||||
// Where methods
|
||||
private escapeValue(value: SqlParam): string {
|
||||
if (value === null) return 'NULL';
|
||||
if (value instanceof Expression) return `(${value.toString()})`;
|
||||
if (value === null) {
|
||||
return 'NULL';
|
||||
}
|
||||
if (value instanceof Expression) {
|
||||
return `(${value.toString()})`;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return `(${value.map((v) => this.escapeValue(v)).join(', ')})`;
|
||||
}
|
||||
@@ -139,7 +145,9 @@ export class Query<T = any> {
|
||||
}
|
||||
|
||||
where(column: string, operator: Operator, value?: SqlParam): this {
|
||||
if (this._skipNext) return this;
|
||||
if (this._skipNext) {
|
||||
return this;
|
||||
}
|
||||
const condition = this.buildCondition(column, operator, value);
|
||||
this._where.push({ condition, operator: 'AND' });
|
||||
return this;
|
||||
@@ -148,7 +156,7 @@ export class Query<T = any> {
|
||||
public buildCondition(
|
||||
column: string,
|
||||
operator: Operator,
|
||||
value?: SqlParam,
|
||||
value?: SqlParam
|
||||
): string {
|
||||
switch (operator) {
|
||||
case 'IS NULL':
|
||||
@@ -162,7 +170,7 @@ export class Query<T = any> {
|
||||
throw new Error('BETWEEN operator requires an array of two values');
|
||||
case 'IN':
|
||||
case 'NOT IN':
|
||||
if (!Array.isArray(value) && !(value instanceof Expression)) {
|
||||
if (!(Array.isArray(value) || value instanceof Expression)) {
|
||||
throw new Error(`${operator} operator requires an array value`);
|
||||
}
|
||||
return `${column} ${operator} ${this.escapeValue(value)}`;
|
||||
@@ -224,7 +232,9 @@ export class Query<T = any> {
|
||||
|
||||
// Order by methods
|
||||
orderBy(column: string, direction: 'ASC' | 'DESC' = 'ASC'): this {
|
||||
if (this._skipNext) return this;
|
||||
if (this._skipNext) {
|
||||
return this;
|
||||
}
|
||||
this._orderBy.push({ column, direction });
|
||||
return this;
|
||||
}
|
||||
@@ -259,7 +269,7 @@ export class Query<T = any> {
|
||||
fill(
|
||||
from: string | Date | Expression,
|
||||
to: string | Date | Expression,
|
||||
step: string | Expression,
|
||||
step: string | Expression
|
||||
): this {
|
||||
this._fill = {
|
||||
from:
|
||||
@@ -288,7 +298,7 @@ export class Query<T = any> {
|
||||
innerJoin(
|
||||
table: string | Expression,
|
||||
condition: string,
|
||||
alias?: string,
|
||||
alias?: string
|
||||
): this {
|
||||
return this.joinWithType('INNER', table, condition, alias);
|
||||
}
|
||||
@@ -296,7 +306,7 @@ export class Query<T = any> {
|
||||
leftJoin(
|
||||
table: string | Expression | Query,
|
||||
condition: string,
|
||||
alias?: string,
|
||||
alias?: string
|
||||
): this {
|
||||
return this.joinWithType('LEFT', table, condition, alias);
|
||||
}
|
||||
@@ -304,7 +314,7 @@ export class Query<T = any> {
|
||||
leftAnyJoin(
|
||||
table: string | Expression | Query,
|
||||
condition: string,
|
||||
alias?: string,
|
||||
alias?: string
|
||||
): this {
|
||||
return this.joinWithType('LEFT ANY', table, condition, alias);
|
||||
}
|
||||
@@ -312,7 +322,7 @@ export class Query<T = any> {
|
||||
rightJoin(
|
||||
table: string | Expression,
|
||||
condition: string,
|
||||
alias?: string,
|
||||
alias?: string
|
||||
): this {
|
||||
return this.joinWithType('RIGHT', table, condition, alias);
|
||||
}
|
||||
@@ -320,7 +330,7 @@ export class Query<T = any> {
|
||||
fullJoin(
|
||||
table: string | Expression,
|
||||
condition: string,
|
||||
alias?: string,
|
||||
alias?: string
|
||||
): this {
|
||||
return this.joinWithType('FULL', table, condition, alias);
|
||||
}
|
||||
@@ -333,9 +343,11 @@ export class Query<T = any> {
|
||||
type: JoinType,
|
||||
table: string | Expression | Query,
|
||||
condition: string,
|
||||
alias?: string,
|
||||
alias?: string
|
||||
): this {
|
||||
if (this._skipNext) return this;
|
||||
if (this._skipNext) {
|
||||
return this;
|
||||
}
|
||||
this._joins.push({
|
||||
type,
|
||||
table,
|
||||
@@ -386,9 +398,9 @@ export class Query<T = any> {
|
||||
// on them, otherwise any embedded date strings get double-escaped
|
||||
// (e.g. ''2025-12-16 23:59:59'') which ClickHouse rejects.
|
||||
.map((col) =>
|
||||
col instanceof Expression ? col.toString() : this.escapeDate(col),
|
||||
col instanceof Expression ? col.toString() : this.escapeDate(col)
|
||||
)
|
||||
.join(', '),
|
||||
.join(', ')
|
||||
);
|
||||
} else {
|
||||
parts.push('SELECT *');
|
||||
@@ -411,7 +423,7 @@ export class Query<T = any> {
|
||||
const aliasClause = join.alias ? ` ${join.alias} ` : ' ';
|
||||
const conditionStr = join.condition ? `ON ${join.condition}` : '';
|
||||
parts.push(
|
||||
`${join.type} JOIN ${join.table instanceof Query ? `(${join.table.toSQL()})` : join.table instanceof Expression ? `(${join.table.toString()})` : join.table}${aliasClause}${conditionStr}`,
|
||||
`${join.type} JOIN ${join.table instanceof Query ? `(${join.table.toSQL()})` : join.table instanceof Expression ? `(${join.table.toString()})` : join.table}${aliasClause}${conditionStr}`
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -524,10 +536,10 @@ export class Query<T = any> {
|
||||
// Execution methods
|
||||
async execute(): Promise<T[]> {
|
||||
const query = this.buildQuery();
|
||||
console.log(
|
||||
'query',
|
||||
`${query.replaceAll('\n', ' ').replaceAll('\t', ' ').replaceAll('\r', ' ')} SETTINGS session_timezone = '${this.timezone}'`,
|
||||
);
|
||||
// console.log(
|
||||
// 'query',
|
||||
// `${query.replaceAll('\n', ' ').replaceAll('\t', ' ').replaceAll('\r', ' ')} SETTINGS session_timezone = '${this.timezone}'`,
|
||||
// );
|
||||
|
||||
const result = await this.client.query({
|
||||
query,
|
||||
@@ -574,7 +586,9 @@ export class Query<T = any> {
|
||||
|
||||
// Add merge method
|
||||
merge(query: Query): this {
|
||||
if (this._skipNext) return this;
|
||||
if (this._skipNext) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this._from = query._from;
|
||||
|
||||
@@ -621,7 +635,7 @@ export class WhereGroupBuilder {
|
||||
|
||||
constructor(
|
||||
private query: Query,
|
||||
private groupOperator: 'AND' | 'OR',
|
||||
private groupOperator: 'AND' | 'OR'
|
||||
) {}
|
||||
|
||||
where(column: string, operator: Operator, value?: SqlParam): this {
|
||||
@@ -706,7 +720,7 @@ clix.toStartOf = (node: string, interval: IInterval, timezone?: string) => {
|
||||
clix.toStartOfInterval = (
|
||||
node: string,
|
||||
interval: IInterval,
|
||||
origin: string | Date,
|
||||
origin: string | Date
|
||||
) => {
|
||||
switch (interval) {
|
||||
case 'minute': {
|
||||
|
||||
Reference in New Issue
Block a user