import * as plugins from './smartclickhouse.plugins.js'; import { TimeDataTable } from './smartclickhouse.classes.timedatatable.js'; export interface IClickhouseConstructorOptions { url: string; database: string; password?: string; } export class SmartClickHouseDb { public options: IClickhouseConstructorOptions; public defaultClient: plugins.clickhouse.ClickHouseClient; public clickhouseClient: plugins.clickhouse.ClickHouseClient; constructor(optionsArg: IClickhouseConstructorOptions) { this.options = optionsArg; } /** * starts the connection to the Clickhouse db */ public async start(dropOld = false) { console.log(`Connecting to default database first.`); const defaultOptions: {[keyArg: string]: string} = {}; // the protocol, url and host const parsedUrl = plugins.smarturl.Smarturl.createFromUrl(this.options.url); parsedUrl.protocol === 'https' ? defaultOptions.protocol = plugins.clickhouse.ClickHouseConnectionProtocol.HTTPS : null; parsedUrl.protocol === 'http' ? defaultOptions.protocol = plugins.clickhouse.ClickHouseConnectionProtocol.HTTP : null; defaultOptions.host = parsedUrl.hostname; defaultOptions.port = parsedUrl.port; // the database defaultOptions.database = this.options.database; // the password this.options.password ? defaultOptions.password = this.options.password : null; // lets connect this.defaultClient = new plugins.clickhouse.ClickHouseClient({ ...defaultOptions, database: 'default', }); await this.pingDatabaseUntilAvailable(); console.log(`Create database ${this.options.database}, if it does not exist...`); await this.createDatabase(dropOld); console.log(`Ensured database. Now connecting to wanted database: ${this.options.database}`); this.clickhouseClient = new plugins.clickhouse.ClickHouseClient({ ...defaultOptions }); } public async createDatabase(dropOld: boolean = false) { if (dropOld) { await this.defaultClient.queryPromise(`DROP DATABASE IF EXISTS ${this.options.database}`); } await this.defaultClient.queryPromise(`CREATE DATABASE IF NOT EXISTS ${this.options.database}`); } public async pingDatabaseUntilAvailable() { let available = false; while(!available) { available = await this.defaultClient.ping().catch(err => { return false; }); if (!available) { console.log(`NOT OK: tried pinging ${this.options.url}... Trying again in 5 seconds.`); await plugins.smartdelay.delayFor(5000); } } } /** * gets a table */ public async getTable(tableName: string) { const newTable = TimeDataTable.getTable(this, tableName); return newTable; } }