I have tried setting up connection pooling using @sap/hana-client
library - both approaches implicit, explicit and neither work. So I ended up with this implementation:
import { Connection, createConnection, ConnectionOptions } from '@ibsolution/types-hana-client';
import { createPool, Pool, Factory, Options } from 'generic-pool';
export class HanaService {
private readonly pool: Pool<Connection>;
constructor(config: CONFIG) {
this.pool = HanaService.createConnectionPool(HanaService.getConnectionOptions(config));
}
private static createConnectionPool(connectionOptions: ConnectionOptions): Pool<Connection> {
const factory: Factory<Connection> = {
create(): Promise<Connection> {
const connection = createConnection();
return new Promise((resolve, reject) =>
connection.connect(connectionOptions, (err: Error) => {
if (err) {
reject(err);
}
resolve(connection);
}),
);
},
destroy(connection: Connection): Promise<void> {
return new Promise((resolve, reject) =>
connection.disconnect((err: Error) => {
if (err) {
reject(err);
}
resolve();
}),
);
},
};
const opts: Options = {
max: 50,
min: 5,
idleTimeoutMillis: 60000,
autostart: true,
};
return createPool(factory, opts);
}
private static getConnectionOptions(config: CONFIG): ConnectionOptions {
return {
pwd: 'PWD',
uid: 'UID',
host: 'HOST',
port: 'PORT',
};
}
async query<T extends object>(sql: string, sqlArgs?: unknown[]): Promise<T[]> {
const conn = await this.pool.acquire();
return new Promise((resolve, reject) => {
conn.exec(sql, sqlArgs, (err, rows) => {
this.pool.release(conn);
if (err) {
reject(err);
}
resolve(rows as T[]);
});
});
}
}