Skip to content

Commit 90a9baa

Browse files
committed
feat: provide bridge as a class
1 parent ad92104 commit 90a9baa

File tree

3 files changed

+114
-108
lines changed

3 files changed

+114
-108
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ Wraps [`postgres`](https://www.npmjs.com/package/postgres) API in a [`pg`](https
99

1010
```ts
1111
import postgres from 'postgres';
12-
import { PostgresBridge } from 'postgres-bridge';
12+
import { createBridge } from 'postgres-bridge';
13+
14+
const PostgresBridge = createBridge(postgres);
1315

1416
// pg.Pool Configuration
1517
const configuration = {
@@ -20,7 +22,7 @@ const configuration = {
2022
connectionTimeoutMillis: 2000,
2123
};
2224

23-
const pool = new PostgresBridge(postgres, configuration);
25+
const pool = new PostgresBridge(configuration);
2426

2527
const connection = await pool.connect();
2628

src/bridge.ts

Lines changed: 106 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -38,107 +38,109 @@ type QueryResult = {
3838
rows: Row[],
3939
};
4040

41-
export class PostgresBridge {
42-
private readonly poolEvents: EventEmitter;
43-
44-
private readonly pool: GenericPool<AnySql & {events: EventEmitter, }>;
45-
46-
public constructor (postgres: typeof Postgres, poolConfiguration: PgPool) {
47-
this.poolEvents = new EventEmitter();
48-
49-
this.pool = genericPool.createPool<AnySql & {events: EventEmitter, }>({
50-
create: async () => {
51-
const connectionEvents = new EventEmitter();
52-
53-
const connection = postgres({
54-
database: poolConfiguration.database,
55-
host: poolConfiguration.host ?? 'localhost',
56-
idle_timeout: poolConfiguration.idleTimeoutMillis ? poolConfiguration.idleTimeoutMillis / 1_000 : 0,
57-
max: 1,
58-
onnotice: (notice) => {
59-
connectionEvents.emit('notice', {
60-
code: notice.code,
61-
file: notice.file,
62-
line: notice.line,
63-
message: notice.message,
64-
routine: notice.routine,
65-
severity: notice.severity,
66-
where: notice.where,
67-
});
68-
},
69-
password: poolConfiguration.password,
70-
port: poolConfiguration.port ?? 5_432,
71-
ssl: poolConfiguration.ssl,
72-
username: poolConfiguration.user,
73-
}) as AnySql & {events: EventEmitter, };
74-
75-
connection.events = connectionEvents;
76-
77-
return connection;
78-
},
79-
destroy: (client: Sql<{}>) => {
80-
return client.end({
81-
timeout: 5,
82-
});
83-
},
84-
}, {
85-
max: poolConfiguration.max ?? 10,
86-
min: poolConfiguration.min ?? 0,
87-
});
88-
}
89-
90-
public async connect () {
91-
const connection = await this.pool.acquire();
92-
93-
const compatibleConnection = {
94-
end: async () => {
95-
await this.pool.destroy(connection);
96-
},
97-
off: connection.events.off.bind(connection.events),
98-
on: connection.events.on.bind(connection.events),
99-
query: async (sql: string): Promise<QueryResult> => {
100-
// https://github.com/porsager/postgres#result-array
101-
const resultArray = await connection.unsafe(sql);
102-
103-
return {
104-
command: resultArray.command as Command,
105-
fields: resultArray.columns?.map((column) => {
106-
return {
107-
dataTypeID: column.type,
108-
name: column.name,
109-
};
110-
}) ?? [],
111-
rowCount: resultArray.count,
112-
rows: Array.from(resultArray),
113-
};
114-
},
115-
release: async () => {
116-
await this.pool.release(connection);
117-
},
118-
};
119-
120-
this.poolEvents.emit('connect', compatibleConnection);
121-
122-
return compatibleConnection;
123-
}
124-
125-
public get idleCount () {
126-
return this.pool.available;
127-
}
128-
129-
public off (eventName: string, listener: (...args: any[]) => void) {
130-
return this.poolEvents.off(eventName, listener);
131-
}
132-
133-
public on (eventName: string, listener: (...args: any[]) => void) {
134-
return this.poolEvents.on(eventName, listener);
135-
}
136-
137-
public get totalCount () {
138-
return this.pool.size;
139-
}
140-
141-
public get waitingCount () {
142-
return this.pool.pending;
143-
}
144-
}
41+
export const createBridge = (postgres: typeof Postgres) => {
42+
return class PostgresBridge {
43+
private readonly poolEvents: EventEmitter;
44+
45+
private readonly pool: GenericPool<AnySql & {events: EventEmitter, }>;
46+
47+
public constructor (poolConfiguration: PgPool) {
48+
this.poolEvents = new EventEmitter();
49+
50+
this.pool = genericPool.createPool<AnySql & {events: EventEmitter, }>({
51+
create: async () => {
52+
const connectionEvents = new EventEmitter();
53+
54+
const connection = postgres({
55+
database: poolConfiguration.database,
56+
host: poolConfiguration.host ?? 'localhost',
57+
idle_timeout: poolConfiguration.idleTimeoutMillis ? poolConfiguration.idleTimeoutMillis / 1_000 : 0,
58+
max: 1,
59+
onnotice: (notice) => {
60+
connectionEvents.emit('notice', {
61+
code: notice.code,
62+
file: notice.file,
63+
line: notice.line,
64+
message: notice.message,
65+
routine: notice.routine,
66+
severity: notice.severity,
67+
where: notice.where,
68+
});
69+
},
70+
password: poolConfiguration.password,
71+
port: poolConfiguration.port ?? 5_432,
72+
ssl: poolConfiguration.ssl,
73+
username: poolConfiguration.user,
74+
}) as AnySql & {events: EventEmitter, };
75+
76+
connection.events = connectionEvents;
77+
78+
return connection;
79+
},
80+
destroy: (client: Sql<{}>) => {
81+
return client.end({
82+
timeout: 5,
83+
});
84+
},
85+
}, {
86+
max: poolConfiguration.max ?? 10,
87+
min: poolConfiguration.min ?? 0,
88+
});
89+
}
90+
91+
public async connect () {
92+
const connection = await this.pool.acquire();
93+
94+
const compatibleConnection = {
95+
end: async () => {
96+
await this.pool.destroy(connection);
97+
},
98+
off: connection.events.off.bind(connection.events),
99+
on: connection.events.on.bind(connection.events),
100+
query: async (sql: string): Promise<QueryResult> => {
101+
// https://github.com/porsager/postgres#result-array
102+
const resultArray = await connection.unsafe(sql);
103+
104+
return {
105+
command: resultArray.command as Command,
106+
fields: resultArray.columns?.map((column) => {
107+
return {
108+
dataTypeID: column.type,
109+
name: column.name,
110+
};
111+
}) ?? [],
112+
rowCount: resultArray.count,
113+
rows: Array.from(resultArray),
114+
};
115+
},
116+
release: async () => {
117+
await this.pool.release(connection);
118+
},
119+
};
120+
121+
this.poolEvents.emit('connect', compatibleConnection);
122+
123+
return compatibleConnection;
124+
}
125+
126+
public get idleCount () {
127+
return this.pool.available;
128+
}
129+
130+
public off (eventName: string, listener: (...args: any[]) => void) {
131+
return this.poolEvents.off(eventName, listener);
132+
}
133+
134+
public on (eventName: string, listener: (...args: any[]) => void) {
135+
return this.poolEvents.on(eventName, listener);
136+
}
137+
138+
public get totalCount () {
139+
return this.pool.size;
140+
}
141+
142+
public get waitingCount () {
143+
return this.pool.pending;
144+
}
145+
};
146+
};

test/postgres-bridge/bridge.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
import postgres from 'postgres';
66
import * as sinon from 'sinon';
77
import {
8-
PostgresBridge,
8+
createBridge,
99
} from '../../src/bridge';
1010

1111
const clients = [
@@ -18,7 +18,9 @@ const createPool = (clientName: string, poolConfiguration) => {
1818
return new Pool(poolConfiguration);
1919
}
2020

21-
return new PostgresBridge(postgres, {
21+
const PostgresBridge = createBridge(postgres);
22+
23+
return new PostgresBridge({
2224
...poolConfiguration,
2325
});
2426
};

0 commit comments

Comments
 (0)