114 lines
3.6 KiB
TypeScript
114 lines
3.6 KiB
TypeScript
import * as plugins from './smartclickhouse.plugins.js';
|
|
import type { SmartClickHouseDb } from './smartclickhouse.classes.smartclickhouse.js';
|
|
import { ClickhouseTable } from './smartclickhouse.classes.clickhousetable.js';
|
|
|
|
/**
|
|
* Creates a pre-configured ClickhouseTable for time-series data.
|
|
* This is the backward-compatible equivalent of the old TimeDataTable class.
|
|
*
|
|
* The table uses MergeTree engine, orders by timestamp, and has auto-schema evolution enabled.
|
|
*/
|
|
export async function createTimeDataTable(
|
|
db: SmartClickHouseDb,
|
|
tableName: string,
|
|
retainDataForDays: number = 30,
|
|
): Promise<TimeDataTable> {
|
|
const table = new TimeDataTable(db, tableName, retainDataForDays);
|
|
await table.setup();
|
|
return table;
|
|
}
|
|
|
|
/**
|
|
* TimeDataTable — a ClickhouseTable pre-configured for time-series data.
|
|
* Provides backward-compatible convenience methods (addData, getLastEntries, etc.).
|
|
*/
|
|
export class TimeDataTable extends ClickhouseTable<any> {
|
|
/**
|
|
* Static factory for backward compatibility
|
|
*/
|
|
public static async getTable(
|
|
smartClickHouseDbRefArg: SmartClickHouseDb,
|
|
tableNameArg: string,
|
|
retainDataForDays: number = 30,
|
|
): Promise<TimeDataTable> {
|
|
return createTimeDataTable(smartClickHouseDbRefArg, tableNameArg, retainDataForDays);
|
|
}
|
|
|
|
constructor(db: SmartClickHouseDb, tableName: string, retainDataForDays: number = 30) {
|
|
super(db, {
|
|
tableName,
|
|
engine: { engine: 'MergeTree' },
|
|
orderBy: 'timestamp' as any,
|
|
retainDataForDays,
|
|
autoSchemaEvolution: true,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Insert data with auto-schema evolution and object flattening.
|
|
* Backward-compatible: accepts arbitrary JSON objects with a timestamp field.
|
|
*/
|
|
public async addData(dataArg: any): Promise<any> {
|
|
if (!dataArg.timestamp || typeof dataArg.timestamp !== 'number') {
|
|
throw new Error('timestamp must be of type number');
|
|
}
|
|
return this.insert(dataArg);
|
|
}
|
|
|
|
/**
|
|
* Get the last N entries ordered by timestamp DESC
|
|
*/
|
|
public async getLastEntries(count: number): Promise<any[]> {
|
|
return this.query()
|
|
.orderBy('timestamp' as any, 'DESC')
|
|
.limit(count)
|
|
.toArray();
|
|
}
|
|
|
|
/**
|
|
* Get entries newer than a unix timestamp (in milliseconds)
|
|
*/
|
|
public async getEntriesNewerThan(unixTimestamp: number): Promise<any[]> {
|
|
return this.db.clickhouseHttpClient.queryPromise(`
|
|
SELECT * FROM ${this.options.database}.${this.options.tableName}
|
|
WHERE timestamp > toDateTime(${unixTimestamp / 1000}) FORMAT JSONEachRow
|
|
`);
|
|
}
|
|
|
|
/**
|
|
* Get entries between two unix timestamps (in milliseconds)
|
|
*/
|
|
public async getEntriesBetween(unixTimestampStart: number, unixTimestampEnd: number): Promise<any[]> {
|
|
return this.db.clickhouseHttpClient.queryPromise(`
|
|
SELECT * FROM ${this.options.database}.${this.options.tableName}
|
|
WHERE timestamp > toDateTime(${unixTimestampStart / 1000})
|
|
AND timestamp < toDateTime(${unixTimestampEnd / 1000}) FORMAT JSONEachRow
|
|
`);
|
|
}
|
|
|
|
/**
|
|
* Delete entries older than N days
|
|
*/
|
|
public async deleteOldEntries(days: number): Promise<void> {
|
|
await this.db.clickhouseHttpClient.mutatePromise(`
|
|
ALTER TABLE ${this.options.database}.${this.options.tableName}
|
|
DELETE WHERE timestamp < now() - INTERVAL ${days} DAY
|
|
`);
|
|
await this.waitForMutations();
|
|
}
|
|
|
|
/**
|
|
* Drop the table (backward-compatible alias for drop())
|
|
*/
|
|
public async delete(): Promise<void> {
|
|
return this.drop();
|
|
}
|
|
|
|
/**
|
|
* Watch for new entries via polling (backward-compatible wrapper)
|
|
*/
|
|
public watchNewEntries(): plugins.smartrx.rxjs.Observable<any> {
|
|
return this.watch();
|
|
}
|
|
}
|