Skip to content

Commit

Permalink
feat: add statement_timeout option, BasePgStoreModule (#6)
Browse files Browse the repository at this point in the history
* feat: add statement timeout

* 1.1.0

* chore: specify units

* chore: add all methods to module
  • Loading branch information
rafaelcr authored Aug 24, 2023
1 parent c2a831a commit 5492206
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 7 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hirosystems/api-toolkit",
"version": "1.0.0",
"version": "1.1.0",
"description": "API development toolkit",
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",
Expand Down
7 changes: 7 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const isDevEnv = process.env.NODE_ENV === 'development';
export const isTestEnv = process.env.NODE_ENV === 'test';
export const isProdEnv =
process.env.NODE_ENV === 'production' ||
process.env.NODE_ENV === 'prod' ||
!process.env.NODE_ENV ||
(!isTestEnv && !isDevEnv);
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './helpers';
export * from './logger';
export * from './postgres';
export * from './server-version';
Expand Down
41 changes: 41 additions & 0 deletions src/postgres/base-pg-store.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AsyncLocalStorage } from 'async_hooks';
import { PgSqlClient } from '.';
import { isProdEnv } from '../helpers';

/**
* AsyncLocalStorage used to determine if the current async context is running inside a SQL
Expand Down Expand Up @@ -73,4 +74,44 @@ export class BasePgStore {
): Promise<UnwrapPromiseArray<T>> {
return this.sqlTransaction(callback, false);
}

/**
* Refreshes a materialized view concurrently depending on the current environment.
* @param viewName - Materialized view name
*/
async refreshMaterializedView(viewName: string): Promise<void> {
await this.sql`REFRESH MATERIALIZED VIEW ${
isProdEnv ? this.sql`CONCURRENTLY` : this.sql``
} ${this.sql(viewName)}`;
}
}

/**
* Base module that extends PgStore functionality and allows organizing queries in separate files.
*/
export class BasePgStoreModule {
private readonly parent: BasePgStore;

constructor(db: BasePgStore) {
this.parent = db;
}

protected get sql(): PgSqlClient {
return this.parent.sql;
}

async sqlTransaction<T>(
callback: (sql: PgSqlClient) => T | Promise<T>,
readOnly = true
): Promise<UnwrapPromiseArray<T>> {
return this.parent.sqlTransaction(callback, readOnly);
}
async sqlWriteTransaction<T>(
callback: (sql: PgSqlClient) => T | Promise<T>
): Promise<UnwrapPromiseArray<T>> {
return this.sqlTransaction(callback, false);
}
async refreshMaterializedView(viewName: string): Promise<void> {
return this.parent.refreshMaterializedView(viewName);
}
}
12 changes: 9 additions & 3 deletions src/postgres/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type PgConnectionVars = {
user?: string;
password?: string;
host?: string;
port?: string;
port?: number;
schema?: string;
ssl?: boolean;
application_name?: string;
Expand All @@ -24,8 +24,13 @@ export type PgConnectionVars = {
export type PgConnectionArgs = PgConnectionUri | PgConnectionVars;
/** Postgres connection options */
export type PgConnectionOptions = {
/** Time to wait before automatically closing an idle connection (s) */
idleTimeout?: number;
/** Maximum allowed duration of any statement (ms) */
statementTimeout?: number;
/** Maximum time a connection can exist (s) */
maxLifetime?: number;
/** Max number of connections */
poolMax?: number;
};

Expand All @@ -49,7 +54,7 @@ export function standardizedConnectionArgs(
user: process.env.PGUSER,
password: process.env.PGPASSWORD,
host: process.env.PGHOST,
port: process.env.PGPORT ?? '5432',
port: parseInt(process.env.PGPORT ?? '5432'),
ssl: true,
application_name: `${appName}:${appUsage}`,
};
Expand Down Expand Up @@ -150,7 +155,7 @@ export function getPostgres({
user: args.user,
password: args.password,
host: args.host,
port: args.port ? parseInt(args.port) : undefined,
port: args.port,
ssl: args.ssl,
idle_timeout: connectionConfig?.idleTimeout,
max_lifetime: connectionConfig?.maxLifetime,
Expand All @@ -159,6 +164,7 @@ export function getPostgres({
connection: {
application_name: args.application_name,
search_path: args.schema,
statement_timeout: connectionConfig?.statementTimeout?.toString(),
},
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/postgres/migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export async function runMigrations(
? args
: {
host: args.host,
port: args.port ? parseInt(args.port) : undefined,
port: args.port,
user: args.user,
password: args.password,
database: args.database,
Expand Down

0 comments on commit 5492206

Please sign in to comment.