almost working

This commit is contained in:
Boki 2025-06-22 09:57:38 -04:00
parent a07a71d92a
commit 8165994fde
7 changed files with 64 additions and 17 deletions

2
.env
View file

@ -39,7 +39,7 @@ POSTGRES_SSL=false
QUESTDB_HOST=localhost QUESTDB_HOST=localhost
QUESTDB_PORT=9000 QUESTDB_PORT=9000
QUESTDB_DB=qdb QUESTDB_DB=qdb
QUESTDB_USER=admin QUESTDB_USERNAME=admin
QUESTDB_PASSWORD=quest QUESTDB_PASSWORD=quest
# MongoDB Configuration # MongoDB Configuration

View file

@ -76,6 +76,13 @@ async function initializeServices() {
user: config.database.postgres.user, user: config.database.postgres.user,
password: config.database.postgres.password, password: config.database.postgres.password,
}, },
questdb: {
host: config.database.questdb.host,
httpPort: config.database.questdb.httpPort,
pgPort: config.database.questdb.pgPort,
influxPort: config.database.questdb.ilpPort,
database: config.database.questdb.database,
},
proxy: { proxy: {
cachePrefix: 'proxy:', cachePrefix: 'proxy:',
ttl: 3600, ttl: 3600,

View file

@ -20,8 +20,8 @@ export const questdbConfigSchema = z.object({
httpPort: z.number().default(9000), httpPort: z.number().default(9000),
pgPort: z.number().default(8812), pgPort: z.number().default(8812),
database: z.string().default('questdb'), database: z.string().default('questdb'),
user: z.string().default('admin'), user: z.string().optional(), // No default - QuestDB doesn't require auth by default
password: z.string().default('quest'), password: z.string().optional(), // No default - QuestDB doesn't require auth by default
bufferSize: z.number().default(65536), bufferSize: z.number().default(65536),
flushInterval: z.number().default(1000), flushInterval: z.number().default(1000),
}); });

View file

@ -3,15 +3,15 @@
* Creates a decoupled, reusable dependency injection container * Creates a decoupled, reusable dependency injection container
*/ */
import { createContainer, asFunction, asValue, InjectionMode, type AwilixContainer } from 'awilix'; import { Browser } from '@stock-bot/browser';
import { createCache, type CacheProvider } from '@stock-bot/cache'; import { createCache, type CacheProvider } from '@stock-bot/cache';
import { ProxyManager } from '@stock-bot/proxy'; import type { IServiceContainer } from '@stock-bot/handlers';
import { getLogger } from '@stock-bot/logger'; import { getLogger } from '@stock-bot/logger';
import { createMongoDBClient } from '@stock-bot/mongodb'; import { createMongoDBClient } from '@stock-bot/mongodb';
import { createPostgreSQLClient } from '@stock-bot/postgres'; import { createPostgreSQLClient } from '@stock-bot/postgres';
import { ProxyManager } from '@stock-bot/proxy';
import { createQuestDBClient } from '@stock-bot/questdb'; import { createQuestDBClient } from '@stock-bot/questdb';
import { Browser } from '@stock-bot/browser'; import { asFunction, asValue, createContainer, InjectionMode, type AwilixContainer } from 'awilix';
import type { IServiceContainer } from '@stock-bot/handlers';
// Configuration types // Configuration types
export interface AppConfig { export interface AppConfig {
@ -35,7 +35,10 @@ export interface AppConfig {
}; };
questdb?: { questdb?: {
host: string; host: string;
port: number; httpPort?: number;
pgPort?: number;
influxPort?: number;
database?: string;
}; };
proxy?: { proxy?: {
cachePrefix?: string; cachePrefix?: string;
@ -62,7 +65,7 @@ export function createServiceContainer(config: AppConfig): AwilixContainer {
redisConfig: asValue(config.redis), redisConfig: asValue(config.redis),
mongoConfig: asValue(config.mongodb), mongoConfig: asValue(config.mongodb),
postgresConfig: asValue(config.postgres), postgresConfig: asValue(config.postgres),
questdbConfig: asValue(config.questdb || { host: 'localhost', port: 9009 }), questdbConfig: asValue(config.questdb || { host: 'localhost', httpPort: 9000, pgPort: 8812, influxPort: 9009 }),
// Core services with dependency injection // Core services with dependency injection
logger: asFunction(() => getLogger('app')).singleton(), logger: asFunction(() => getLogger('app')).singleton(),
@ -119,13 +122,17 @@ export function createServiceContainer(config: AppConfig): AwilixContainer {
}).singleton(), }).singleton(),
questdbClient: asFunction(({ questdbConfig, logger }) => { questdbClient: asFunction(({ questdbConfig, logger }) => {
console.log('Creating QuestDB client with config:', questdbConfig);
return createQuestDBClient( return createQuestDBClient(
{ {
host: questdbConfig.host, host: questdbConfig.host,
httpPort: 9000, httpPort: questdbConfig.httpPort,
pgPort: questdbConfig.port || 8812, pgPort: questdbConfig.pgPort,
influxPort: 9009, influxPort: questdbConfig.influxPort,
database: 'questdb', database: questdbConfig.database,
// QuestDB appears to require default credentials
user: 'admin',
password: 'quest',
}, },
logger logger
); );

View file

@ -37,6 +37,18 @@ export class QuestDBClient {
...options, ...options,
}; };
// Debug: log the received config
console.log('DEBUG: QuestDB client constructor called with config:', {
...config,
user: config.user || '[NOT PROVIDED]',
password: config.password ? '[PROVIDED]' : '[NOT PROVIDED]'
});
this.logger.debug('QuestDB client created with config:', {
...config,
user: config.user || '[NOT PROVIDED]',
password: config.password ? '[PROVIDED]' : '[NOT PROVIDED]'
});
this.healthMonitor = new QuestDBHealthMonitor(this); this.healthMonitor = new QuestDBHealthMonitor(this);
this.influxWriter = new QuestDBInfluxWriter(this); this.influxWriter = new QuestDBInfluxWriter(this);
this.schemaManager = new QuestDBSchemaManager(this); this.schemaManager = new QuestDBSchemaManager(this);
@ -407,12 +419,10 @@ export class QuestDBClient {
private buildPgPoolConfig(): any { private buildPgPoolConfig(): any {
return { const config: any = {
host: this.config.host, host: this.config.host,
port: this.config.pgPort, port: this.config.pgPort,
database: this.config.database, database: this.config.database,
user: this.config.user,
password: this.config.password,
connectionTimeoutMillis: this.config.timeouts?.connection, connectionTimeoutMillis: this.config.timeouts?.connection,
query_timeout: this.config.timeouts?.request, query_timeout: this.config.timeouts?.request,
ssl: this.config.tls?.enabled ssl: this.config.tls?.enabled
@ -423,6 +433,29 @@ export class QuestDBClient {
min: 2, min: 2,
max: 10, max: 10,
}; };
// Only add user/password if they are provided
if (this.config.user) {
console.log('DEBUG: Adding user to QuestDB pool config:', this.config.user);
this.logger.debug('Adding user to QuestDB pool config:', this.config.user);
config.user = this.config.user;
} else {
console.log('DEBUG: No user provided for QuestDB connection');
this.logger.debug('No user provided for QuestDB connection');
}
if (this.config.password) {
console.log('DEBUG: Adding password to QuestDB pool config');
this.logger.debug('Adding password to QuestDB pool config');
config.password = this.config.password;
} else {
console.log('DEBUG: No password provided for QuestDB connection');
this.logger.debug('No password provided for QuestDB connection');
}
console.log('DEBUG: Final QuestDB pool config:', { ...config, password: config.password ? '[REDACTED]' : undefined });
this.logger.debug('Final QuestDB pool config:', { ...config, password: config.password ? '[REDACTED]' : undefined });
return config;
} }
private mapDataType(typeId: number): string { private mapDataType(typeId: number): string {

View file

@ -326,7 +326,7 @@ export class QuestDBSchemaManager {
// Add designated timestamp // Add designated timestamp
const timestampColumn = schema.columns.find(col => col.designated); const timestampColumn = schema.columns.find(col => col.designated);
if (timestampColumn) { if (timestampColumn) {
sql += ` timestamp(${timestampColumn.name})`; sql += ` TIMESTAMP(${timestampColumn.name})`;
} }
// Add partition by // Add partition by