UNPKG

@t1mmen/srtd

Version:

Supabase Repeatable Template Definitions (srtd): 🪄 Live-reloading SQL templates for Supabase DX. Make your database changes reviewable and migrations maintainable! 🚀

106 lines (105 loc) • 3.13 kB
/** * DatabaseService - Centralized database connection and SQL execution service * Handles connection pooling, retry logic, and SQL execution with transaction management */ import { EventEmitter } from 'node:events'; import pg from 'pg'; import type { CLIConfig, MigrationError } from '../types.js'; export interface DatabaseServiceConfig { connectionString: string; connectionTimeoutMillis?: number; maxConnections?: number; idleTimeoutMillis?: number; maxUses?: number; maxRetries?: number; retryDelayMs?: number; wrapInTransaction?: boolean; } export interface ConnectionStats { total: number; idle: number; active: number; } export declare enum DatabaseErrorType { CONNECTION_ERROR = "CONNECTION_ERROR", SYNTAX_ERROR = "SYNTAX_ERROR", CONSTRAINT_VIOLATION = "CONSTRAINT_VIOLATION", TIMEOUT_ERROR = "TIMEOUT_ERROR", TRANSACTION_ERROR = "TRANSACTION_ERROR", POOL_EXHAUSTED = "POOL_EXHAUSTED", UNKNOWN_ERROR = "UNKNOWN_ERROR" } export interface DatabaseError { type: DatabaseErrorType; message: string; originalError?: Error; code?: string; detail?: string; hint?: string; } export interface SqlExecutionResult { success: boolean; error?: string; databaseError?: DatabaseError; rows?: unknown[]; rowCount?: number; data?: unknown; } export interface ExecutionConfig { templateName?: string; useTransaction?: boolean; silent?: boolean; parameters?: unknown[]; isolationLevel?: 'READ UNCOMMITTED' | 'READ COMMITTED' | 'REPEATABLE READ' | 'SERIALIZABLE'; } export declare class DatabaseService extends EventEmitter { private config; private pool; private connectionAttempts; private disposed; constructor(config: DatabaseServiceConfig); /** * Categorize database errors for better error handling */ private categorizeError; /** * Create and configure database connection pool */ private createPool; /** * Establish database connection with retry logic */ private retryConnection; /** * Get a database connection with retry logic */ connect(params?: { silent?: boolean; }): Promise<pg.PoolClient>; /** * Test database connectivity */ testConnection(): Promise<boolean>; /** * Execute SQL with optional transaction wrapping and parameterized queries * Core method for running template content or any SQL */ executeSQL(sql: string, config?: ExecutionConfig): Promise<SqlExecutionResult>; /** * Execute SQL and return migration-compatible result * Used by migration/template application logic */ executeMigration(content: string, templateName: string, silent?: boolean): Promise<true | MigrationError>; /** * Get connection pool statistics */ getConnectionStats(): ConnectionStats | null; /** * Gracefully close all database connections */ dispose(): Promise<void>; /** * Create DatabaseService from CLI config */ static fromConfig(config: CLIConfig): DatabaseService; }