stock-bot/libs/data/postgres/src/simple-postgres.ts
2025-06-26 16:12:27 -04:00

215 lines
5.2 KiB
TypeScript

/**
* Simple PostgreSQL client for testing
*/
export class SimplePostgresClient {
private tables = new Map<string, any[]>();
private connected = false;
constructor(private config: any) {}
async query(sql: string, params?: any[]): Promise<{ rows: any[]; rowCount: number }> {
// Simple mock implementation
return { rows: [], rowCount: 0 };
}
async findOne(table: string, where: any): Promise<any | null> {
const rows = this.tables.get(table) || [];
for (const row of rows) {
let match = true;
for (const [key, value] of Object.entries(where)) {
if (row[key] !== value) {
match = false;
break;
}
}
if (match) {
return row;
}
}
return null;
}
async find(table: string, where: any): Promise<any[]> {
const rows = this.tables.get(table) || [];
if (Object.keys(where).length === 0) {
return rows;
}
return rows.filter(row => {
for (const [key, value] of Object.entries(where)) {
if (row[key] !== value) {
return false;
}
}
return true;
});
}
async insert(table: string, data: any): Promise<any> {
const rows = this.tables.get(table) || [];
const newRow = { ...data, id: rows.length + 1 };
rows.push(newRow);
this.tables.set(table, rows);
return newRow;
}
async update(table: string, where: any, data: any): Promise<number> {
const rows = this.tables.get(table) || [];
let updated = 0;
for (const row of rows) {
let match = true;
for (const [key, value] of Object.entries(where)) {
if (row[key] !== value) {
match = false;
break;
}
}
if (match) {
Object.assign(row, data);
updated++;
}
}
return updated;
}
async delete(table: string, where: any): Promise<number> {
const rows = this.tables.get(table) || [];
const remaining = rows.filter(row => {
for (const [key, value] of Object.entries(where)) {
if (row[key] !== value) {
return true;
}
}
return false;
});
const deleted = rows.length - remaining.length;
this.tables.set(table, remaining);
return deleted;
}
async healthCheck(): Promise<{ status: string; isConnected: boolean; error?: string }> {
return {
status: 'healthy',
isConnected: true,
};
}
async disconnect(): Promise<void> {
this.connected = false;
}
}
export class SimpleQueryBuilder {
private parts: string[] = [];
private params: any[] = [];
select(columns: string[] | string = '*'): SimpleQueryBuilder {
const cols = Array.isArray(columns) ? columns.join(', ') : columns;
this.parts.push(`SELECT ${cols}`);
return this;
}
from(table: string): SimpleQueryBuilder {
this.parts.push(`FROM ${table}`);
return this;
}
where(conditions: any): SimpleQueryBuilder {
const whereClause = Object.entries(conditions)
.map(([key], i) => {
this.params.push(conditions[key]);
return `${key} = $${this.params.length}`;
})
.join(' AND ');
this.parts.push(`WHERE ${whereClause}`);
return this;
}
orderBy(column: string, direction = 'ASC'): SimpleQueryBuilder {
this.parts.push(`ORDER BY ${column} ${direction}`);
return this;
}
limit(count: number): SimpleQueryBuilder {
this.parts.push(`LIMIT ${count}`);
return this;
}
insert(table: string, data: any): SimpleQueryBuilder {
const columns = Object.keys(data);
const values = Object.values(data);
this.params.push(...values);
const placeholders = columns.map((_, i) => `$${i + 1}`);
this.parts.push(
`INSERT INTO ${table} (${columns.join(', ')}) VALUES (${placeholders.join(', ')})`
);
return this;
}
update(table: string): SimpleQueryBuilder {
this.parts.push(`UPDATE ${table}`);
return this;
}
set(data: any): SimpleQueryBuilder {
const setClause = Object.entries(data)
.map(([key, value]) => {
this.params.push(value);
return `${key} = $${this.params.length}`;
})
.join(', ');
this.parts.push(`SET ${setClause}`);
return this;
}
delete(table: string): SimpleQueryBuilder {
this.parts.push(`DELETE FROM ${table}`);
return this;
}
returning(columns: string): SimpleQueryBuilder {
this.parts.push(`RETURNING ${columns}`);
return this;
}
join(table: string, condition: string): SimpleQueryBuilder {
this.parts.push(`JOIN ${table} ON ${condition}`);
return this;
}
build(): { text: string; values: any[] } {
return {
text: this.parts.join(' '),
values: this.params,
};
}
}
export class SimpleTransactionManager {
constructor(private pool: any) {}
async transaction<T>(fn: (client: any) => Promise<T>): Promise<T> {
const mockClient = {
query: async (sql?: string) => ({ rows: [], rowCount: 0 }),
release: () => {},
};
await mockClient.query('BEGIN');
try {
const result = await fn(mockClient);
await mockClient.query('COMMIT');
return result;
} catch (error) {
await mockClient.query('ROLLBACK');
throw error;
} finally {
mockClient.release();
}
}
}