@timescaledb/core
Version:
The `@timescaledb/core` package provides fundamental building blocks for working with TimescaleDB in TypeScript/JavaScript applications. It includes SQL query builders and utilities for managing hypertables, continuous aggregates, compression, and other T
96 lines • 5.41 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CandlestickBuilder = exports.CandlestickAggregateBuilder = void 0;
const schemas_1 = require("@timescaledb/schemas");
const utils_1 = require("@timescaledb/utils");
const debug_1 = require("./debug");
const debug = (0, debug_1.debugCore)('Candlestick');
class CandlestickAggregateBuilder {
constructor(tableName, options) {
this.statements = [];
this.tableName = tableName;
this.options = schemas_1.CandlestickAggregateOptionsSchema.parse(options);
}
buildWhere(where, paramOffset = 1) {
if (!where) {
return { sql: '', params: [] };
}
const { sql, params } = (0, utils_1.buildWhereClause)(where, paramOffset);
return { sql: ` AND ${sql}`, params };
}
build({ where, range } = {}) {
debug(`Building candlestick query for table '${this.tableName}'`);
const tableName = (0, utils_1.escapeIdentifier)(this.tableName);
const timeColumn = (0, utils_1.escapeIdentifier)(this.options.time_column);
const priceColumn = (0, utils_1.escapeIdentifier)(this.options.price_column);
const volumeColumn = this.options.volume_column ? (0, utils_1.escapeIdentifier)(this.options.volume_column) : null;
const interval = '$1::interval';
this.statements = [];
this.statements.push(`SELECT`);
this.statements.push(` time_bucket(${interval}, ${timeColumn}) as bucket_time,`);
this.statements.push(` open(candlestick_agg(${timeColumn}, ${priceColumn}${volumeColumn ? `, ${volumeColumn}` : ''})) as open,`);
this.statements.push(` high(candlestick_agg(${timeColumn}, ${priceColumn}${volumeColumn ? `, ${volumeColumn}` : ''})) as high,`);
this.statements.push(` low(candlestick_agg(${timeColumn}, ${priceColumn}${volumeColumn ? `, ${volumeColumn}` : ''})) as low,`);
this.statements.push(` close(candlestick_agg(${timeColumn}, ${priceColumn}${volumeColumn ? `, ${volumeColumn}` : ''})) as close,`);
this.statements.push(` open_time(candlestick_agg(${timeColumn}, ${priceColumn}${volumeColumn ? `, ${volumeColumn}` : ''})) as open_time,`);
this.statements.push(` high_time(candlestick_agg(${timeColumn}, ${priceColumn}${volumeColumn ? `, ${volumeColumn}` : ''})) as high_time,`);
this.statements.push(` low_time(candlestick_agg(${timeColumn}, ${priceColumn}${volumeColumn ? `, ${volumeColumn}` : ''})) as low_time,`);
this.statements.push(` close_time(candlestick_agg(${timeColumn}, ${priceColumn}${volumeColumn ? `, ${volumeColumn}` : ''})) as close_time`);
if (volumeColumn) {
this.statements.push(` ,volume(candlestick_agg(${timeColumn}, ${priceColumn}, ${volumeColumn})) as volume,`);
this.statements.push(` vwap(candlestick_agg(${timeColumn}, ${priceColumn}, ${volumeColumn})) as vwap`);
}
this.statements.push(`FROM ${tableName}`);
const params = [this.options.bucket_interval || '1 hour'];
if (range) {
params.push(range.start, range.end);
}
const whereClause = this.buildWhere(where, params.length + 1);
const timeRangeWhere = range ? `WHERE ${timeColumn} >= $2 AND ${timeColumn} <= $3` : '';
const fullWhere = timeRangeWhere + whereClause.sql;
if (fullWhere) {
this.statements.push(fullWhere);
}
params.push(...whereClause.params);
this.statements.push(`GROUP BY bucket_time`);
this.statements.push(`ORDER BY bucket_time ASC;`);
const result = {
sql: this.statements.join('\n'),
params,
};
debug(`Candlestick query built for '${this.tableName}':\n${result.sql}`);
return result;
}
}
exports.CandlestickAggregateBuilder = CandlestickAggregateBuilder;
class CandlestickBuilder {
static generateSQL(metadata, isRollup = false) {
debug(`Generating SQL for candlestick ${isRollup ? 'rollup' : 'aggregation'}`);
if (!metadata)
return '';
const targetColumn = (0, utils_1.escapeIdentifier)(metadata.propertyName);
if (isRollup) {
if (!metadata.sourceColumn) {
debug('Error: source_column missing for rollup');
throw new Error('source_column must be specified for candlestick rollups');
}
const sourceColumn = (0, utils_1.escapeIdentifier)(metadata.sourceColumn);
const result = `rollup(${sourceColumn}) as ${targetColumn}`;
debug(`Generated rollup SQL: ${result}`);
return result;
}
if (!metadata.timeColumn || !metadata.priceColumn) {
debug('Error: required columns missing for aggregation');
throw new Error('time_column and price_column must be specified for candlestick aggregation');
}
const args = [(0, utils_1.escapeIdentifier)(metadata.timeColumn), (0, utils_1.escapeIdentifier)(metadata.priceColumn)];
if (metadata.volumeColumn) {
args.push((0, utils_1.escapeIdentifier)(metadata.volumeColumn));
}
const result = `candlestick_agg(${args.join(', ')}) as ${targetColumn}`;
debug(`Generated aggregation SQL: ${result}`);
return result;
}
}
exports.CandlestickBuilder = CandlestickBuilder;
//# sourceMappingURL=candlestick.js.map