running prettier for cleanup

This commit is contained in:
Boki 2025-06-11 10:13:25 -04:00
parent fe7733aeb5
commit d85cd58acd
151 changed files with 29158 additions and 27966 deletions

View file

@ -1,268 +1,270 @@
import type { QueryResultRow } from 'pg';
import type { PostgreSQLClient } from './client';
import type { WhereCondition, JoinCondition, OrderByCondition, QueryResult } from './types';
/**
* PostgreSQL Query Builder
*
* Provides a fluent interface for building SQL queries
*/
export class PostgreSQLQueryBuilder {
private queryType: 'SELECT' | 'INSERT' | 'UPDATE' | 'DELETE' | null = null;
private selectColumns: string[] = [];
private fromTable: string = '';
private joins: JoinCondition[] = [];
private whereConditions: WhereCondition[] = [];
private groupByColumns: string[] = [];
private havingConditions: WhereCondition[] = [];
private orderByConditions: OrderByCondition[] = [];
private limitCount: number | null = null;
private offsetCount: number | null = null;
private insertValues: Record<string, any> = {};
private updateValues: Record<string, any> = {};
private readonly client: PostgreSQLClient;
constructor(client: PostgreSQLClient) {
this.client = client;
}
/**
* SELECT statement
*/
select(columns: string | string[] = '*'): this {
this.queryType = 'SELECT';
this.selectColumns = Array.isArray(columns) ? columns : [columns];
return this;
}
/**
* FROM clause
*/
from(table: string): this {
this.fromTable = table;
return this;
}
/**
* JOIN clause
*/
join(table: string, on: string, type: 'INNER' | 'LEFT' | 'RIGHT' | 'FULL' = 'INNER'): this {
this.joins.push({ type, table, on });
return this;
}
/**
* WHERE clause
*/
where(column: string, operator: string, value?: any): this {
this.whereConditions.push({ column, operator: operator as any, value });
return this;
}
/**
* GROUP BY clause
*/
groupBy(columns: string | string[]): this {
this.groupByColumns = Array.isArray(columns) ? columns : [columns];
return this;
}
/**
* ORDER BY clause
*/
orderBy(column: string, direction: 'ASC' | 'DESC' = 'ASC'): this {
this.orderByConditions.push({ column, direction });
return this;
}
/**
* LIMIT clause
*/
limit(count: number): this {
this.limitCount = count;
return this;
}
/**
* OFFSET clause
*/
offset(count: number): this {
this.offsetCount = count;
return this;
}
/**
* INSERT statement
*/
insert(table: string): this {
this.queryType = 'INSERT';
this.fromTable = table;
return this;
}
/**
* VALUES for INSERT
*/
values(data: Record<string, any>): this {
this.insertValues = data;
return this;
}
/**
* UPDATE statement
*/
update(table: string): this {
this.queryType = 'UPDATE';
this.fromTable = table;
return this;
}
/**
* SET for UPDATE
*/
set(data: Record<string, any>): this {
this.updateValues = data;
return this;
}
/**
* DELETE statement
*/
delete(table: string): this {
this.queryType = 'DELETE';
this.fromTable = table;
return this;
}
/**
* Build and execute the query
*/
async execute<T extends QueryResultRow = any>(): Promise<QueryResult<T>> {
const { sql, params } = this.build();
return await this.client.query<T>(sql, params);
}
/**
* Build the SQL query
*/
build(): { sql: string; params: any[] } {
const params: any[] = [];
let sql = '';
switch (this.queryType) {
case 'SELECT':
sql = this.buildSelectQuery(params);
break;
case 'INSERT':
sql = this.buildInsertQuery(params);
break;
case 'UPDATE':
sql = this.buildUpdateQuery(params);
break;
case 'DELETE':
sql = this.buildDeleteQuery(params);
break;
default:
throw new Error('Query type not specified');
}
return { sql, params };
}
private buildSelectQuery(params: any[]): string {
let sql = `SELECT ${this.selectColumns.join(', ')}`;
if (this.fromTable) {
sql += ` FROM ${this.fromTable}`;
}
// Add JOINs
for (const join of this.joins) {
sql += ` ${join.type} JOIN ${join.table} ON ${join.on}`;
}
// Add WHERE
if (this.whereConditions.length > 0) {
sql += ' WHERE ' + this.buildWhereClause(this.whereConditions, params);
}
// Add GROUP BY
if (this.groupByColumns.length > 0) {
sql += ` GROUP BY ${this.groupByColumns.join(', ')}`;
}
// Add HAVING
if (this.havingConditions.length > 0) {
sql += ' HAVING ' + this.buildWhereClause(this.havingConditions, params);
}
// Add ORDER BY
if (this.orderByConditions.length > 0) {
const orderBy = this.orderByConditions
.map(order => `${order.column} ${order.direction}`)
.join(', ');
sql += ` ORDER BY ${orderBy}`;
}
// Add LIMIT
if (this.limitCount !== null) {
sql += ` LIMIT $${params.length + 1}`;
params.push(this.limitCount);
}
// Add OFFSET
if (this.offsetCount !== null) {
sql += ` OFFSET $${params.length + 1}`;
params.push(this.offsetCount);
}
return sql;
}
private buildInsertQuery(params: any[]): string {
const columns = Object.keys(this.insertValues);
const placeholders = columns.map((_, i) => `$${params.length + i + 1}`);
params.push(...Object.values(this.insertValues));
return `INSERT INTO ${this.fromTable} (${columns.join(', ')}) VALUES (${placeholders.join(', ')})`;
}
private buildUpdateQuery(params: any[]): string {
const sets = Object.keys(this.updateValues).map((key, i) => {
return `${key} = $${params.length + i + 1}`;
});
params.push(...Object.values(this.updateValues));
let sql = `UPDATE ${this.fromTable} SET ${sets.join(', ')}`;
if (this.whereConditions.length > 0) {
sql += ' WHERE ' + this.buildWhereClause(this.whereConditions, params);
}
return sql;
}
private buildDeleteQuery(params: any[]): string {
let sql = `DELETE FROM ${this.fromTable}`;
if (this.whereConditions.length > 0) {
sql += ' WHERE ' + this.buildWhereClause(this.whereConditions, params);
}
return sql;
}
private buildWhereClause(conditions: WhereCondition[], params: any[]): string {
return conditions.map(condition => {
if (condition.operator === 'IS NULL' || condition.operator === 'IS NOT NULL') {
return `${condition.column} ${condition.operator}`;
} else {
params.push(condition.value);
return `${condition.column} ${condition.operator} $${params.length}`;
}
}).join(' AND ');
}
}
import type { QueryResultRow } from 'pg';
import type { PostgreSQLClient } from './client';
import type { JoinCondition, OrderByCondition, QueryResult, WhereCondition } from './types';
/**
* PostgreSQL Query Builder
*
* Provides a fluent interface for building SQL queries
*/
export class PostgreSQLQueryBuilder {
private queryType: 'SELECT' | 'INSERT' | 'UPDATE' | 'DELETE' | null = null;
private selectColumns: string[] = [];
private fromTable: string = '';
private joins: JoinCondition[] = [];
private whereConditions: WhereCondition[] = [];
private groupByColumns: string[] = [];
private havingConditions: WhereCondition[] = [];
private orderByConditions: OrderByCondition[] = [];
private limitCount: number | null = null;
private offsetCount: number | null = null;
private insertValues: Record<string, any> = {};
private updateValues: Record<string, any> = {};
private readonly client: PostgreSQLClient;
constructor(client: PostgreSQLClient) {
this.client = client;
}
/**
* SELECT statement
*/
select(columns: string | string[] = '*'): this {
this.queryType = 'SELECT';
this.selectColumns = Array.isArray(columns) ? columns : [columns];
return this;
}
/**
* FROM clause
*/
from(table: string): this {
this.fromTable = table;
return this;
}
/**
* JOIN clause
*/
join(table: string, on: string, type: 'INNER' | 'LEFT' | 'RIGHT' | 'FULL' = 'INNER'): this {
this.joins.push({ type, table, on });
return this;
}
/**
* WHERE clause
*/
where(column: string, operator: string, value?: any): this {
this.whereConditions.push({ column, operator: operator as any, value });
return this;
}
/**
* GROUP BY clause
*/
groupBy(columns: string | string[]): this {
this.groupByColumns = Array.isArray(columns) ? columns : [columns];
return this;
}
/**
* ORDER BY clause
*/
orderBy(column: string, direction: 'ASC' | 'DESC' = 'ASC'): this {
this.orderByConditions.push({ column, direction });
return this;
}
/**
* LIMIT clause
*/
limit(count: number): this {
this.limitCount = count;
return this;
}
/**
* OFFSET clause
*/
offset(count: number): this {
this.offsetCount = count;
return this;
}
/**
* INSERT statement
*/
insert(table: string): this {
this.queryType = 'INSERT';
this.fromTable = table;
return this;
}
/**
* VALUES for INSERT
*/
values(data: Record<string, any>): this {
this.insertValues = data;
return this;
}
/**
* UPDATE statement
*/
update(table: string): this {
this.queryType = 'UPDATE';
this.fromTable = table;
return this;
}
/**
* SET for UPDATE
*/
set(data: Record<string, any>): this {
this.updateValues = data;
return this;
}
/**
* DELETE statement
*/
delete(table: string): this {
this.queryType = 'DELETE';
this.fromTable = table;
return this;
}
/**
* Build and execute the query
*/
async execute<T extends QueryResultRow = any>(): Promise<QueryResult<T>> {
const { sql, params } = this.build();
return await this.client.query<T>(sql, params);
}
/**
* Build the SQL query
*/
build(): { sql: string; params: any[] } {
const params: any[] = [];
let sql = '';
switch (this.queryType) {
case 'SELECT':
sql = this.buildSelectQuery(params);
break;
case 'INSERT':
sql = this.buildInsertQuery(params);
break;
case 'UPDATE':
sql = this.buildUpdateQuery(params);
break;
case 'DELETE':
sql = this.buildDeleteQuery(params);
break;
default:
throw new Error('Query type not specified');
}
return { sql, params };
}
private buildSelectQuery(params: any[]): string {
let sql = `SELECT ${this.selectColumns.join(', ')}`;
if (this.fromTable) {
sql += ` FROM ${this.fromTable}`;
}
// Add JOINs
for (const join of this.joins) {
sql += ` ${join.type} JOIN ${join.table} ON ${join.on}`;
}
// Add WHERE
if (this.whereConditions.length > 0) {
sql += ' WHERE ' + this.buildWhereClause(this.whereConditions, params);
}
// Add GROUP BY
if (this.groupByColumns.length > 0) {
sql += ` GROUP BY ${this.groupByColumns.join(', ')}`;
}
// Add HAVING
if (this.havingConditions.length > 0) {
sql += ' HAVING ' + this.buildWhereClause(this.havingConditions, params);
}
// Add ORDER BY
if (this.orderByConditions.length > 0) {
const orderBy = this.orderByConditions
.map(order => `${order.column} ${order.direction}`)
.join(', ');
sql += ` ORDER BY ${orderBy}`;
}
// Add LIMIT
if (this.limitCount !== null) {
sql += ` LIMIT $${params.length + 1}`;
params.push(this.limitCount);
}
// Add OFFSET
if (this.offsetCount !== null) {
sql += ` OFFSET $${params.length + 1}`;
params.push(this.offsetCount);
}
return sql;
}
private buildInsertQuery(params: any[]): string {
const columns = Object.keys(this.insertValues);
const placeholders = columns.map((_, i) => `$${params.length + i + 1}`);
params.push(...Object.values(this.insertValues));
return `INSERT INTO ${this.fromTable} (${columns.join(', ')}) VALUES (${placeholders.join(', ')})`;
}
private buildUpdateQuery(params: any[]): string {
const sets = Object.keys(this.updateValues).map((key, i) => {
return `${key} = $${params.length + i + 1}`;
});
params.push(...Object.values(this.updateValues));
let sql = `UPDATE ${this.fromTable} SET ${sets.join(', ')}`;
if (this.whereConditions.length > 0) {
sql += ' WHERE ' + this.buildWhereClause(this.whereConditions, params);
}
return sql;
}
private buildDeleteQuery(params: any[]): string {
let sql = `DELETE FROM ${this.fromTable}`;
if (this.whereConditions.length > 0) {
sql += ' WHERE ' + this.buildWhereClause(this.whereConditions, params);
}
return sql;
}
private buildWhereClause(conditions: WhereCondition[], params: any[]): string {
return conditions
.map(condition => {
if (condition.operator === 'IS NULL' || condition.operator === 'IS NOT NULL') {
return `${condition.column} ${condition.operator}`;
} else {
params.push(condition.value);
return `${condition.column} ${condition.operator} $${params.length}`;
}
})
.join(' AND ');
}
}