103 lines
2.4 KiB
TypeScript
103 lines
2.4 KiB
TypeScript
import { Pool, PoolClient, QueryResult } from 'pg';
|
|
import dotenv from 'dotenv';
|
|
|
|
dotenv.config();
|
|
|
|
const pool = new Pool({
|
|
host: process.env.DB_HOST || 'localhost',
|
|
port: parseInt(process.env.DB_PORT || '5432'),
|
|
database: process.env.DB_NAME || 'erp_retail',
|
|
user: process.env.DB_USER || 'retail_admin',
|
|
password: process.env.DB_PASSWORD,
|
|
max: 20,
|
|
idleTimeoutMillis: 30000,
|
|
connectionTimeoutMillis: 2000,
|
|
});
|
|
|
|
pool.on('error', (err) => {
|
|
console.error('Unexpected error on idle client', err);
|
|
process.exit(-1);
|
|
});
|
|
|
|
export async function query<T = any>(
|
|
text: string,
|
|
params?: any[]
|
|
): Promise<QueryResult<T>> {
|
|
const start = Date.now();
|
|
const res = await pool.query<T>(text, params);
|
|
const duration = Date.now() - start;
|
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.log('executed query', { text: text.substring(0, 100), duration, rows: res.rowCount });
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
export async function queryOne<T = any>(
|
|
text: string,
|
|
params?: any[]
|
|
): Promise<T | null> {
|
|
const res = await query<T>(text, params);
|
|
return res.rows[0] || null;
|
|
}
|
|
|
|
export async function getClient(): Promise<PoolClient> {
|
|
const client = await pool.connect();
|
|
const release = client.release.bind(client);
|
|
|
|
// Override release to track slow queries
|
|
client.release = () => {
|
|
release();
|
|
};
|
|
|
|
return client;
|
|
}
|
|
|
|
export async function transaction<T>(
|
|
callback: (client: PoolClient) => Promise<T>
|
|
): Promise<T> {
|
|
const client = await getClient();
|
|
|
|
try {
|
|
await client.query('BEGIN');
|
|
const result = await callback(client);
|
|
await client.query('COMMIT');
|
|
return result;
|
|
} catch (error) {
|
|
await client.query('ROLLBACK');
|
|
throw error;
|
|
} finally {
|
|
client.release();
|
|
}
|
|
}
|
|
|
|
export async function setTenantContext(
|
|
client: PoolClient,
|
|
tenantId: string
|
|
): Promise<void> {
|
|
await client.query(
|
|
`SELECT set_config('app.current_tenant_id', $1, true)`,
|
|
[tenantId]
|
|
);
|
|
}
|
|
|
|
export async function initDatabase(): Promise<void> {
|
|
try {
|
|
const client = await pool.connect();
|
|
await client.query('SELECT NOW()');
|
|
client.release();
|
|
console.log('PostgreSQL pool connected successfully');
|
|
} catch (error) {
|
|
console.error('Failed to connect to PostgreSQL:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function closeDatabase(): Promise<void> {
|
|
await pool.end();
|
|
console.log('PostgreSQL pool closed');
|
|
}
|
|
|
|
export { pool };
|