Skip to content

Commit 3b08f66

Browse files
authored
Merge pull request #36 from darkgnotic/messages-option
feat: "messages" pgoutput option to receive messages from pg_logical_emit_message()
2 parents 15930f2 + 70ebd43 commit 3b08f66

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

src/output-plugins/pgoutput/pgoutput-plugin.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class PgoutputPlugin extends AbstractPlugin<Options> {
2525
const options = [
2626
`proto_version '${this.options.protoVersion}'`,
2727
`publication_names '${this.options.publicationNames.join(',')}'`,
28+
`messages '${this.options.messages ?? false}'`,
2829
];
2930

3031
const sql = `START_REPLICATION SLOT "${slotName}" LOGICAL ${lastLsn} (${options.join(', ')})`;

src/output-plugins/pgoutput/pgoutput.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
export interface Options {
33
protoVersion: 1 | 2
44
publicationNames: string[]
5+
messages?: boolean
56
}
67

78
export type Message =

src/test/decoder-pgoutput.spec.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,55 @@ describe('pgoutput', () => {
267267
await service.stop();
268268
});
269269

270+
it('Message', async () => {
271+
const service = new LogicalReplicationService(TestClientConfig);
272+
const plugin = new PgoutputPlugin({ protoVersion: 1, publicationNames: [publicationName], messages: true });
273+
const messages: Pgoutput.Message[] = [];
274+
275+
service.on('data', (lsn: string, log: Pgoutput.Message) => {
276+
messages.push(log);
277+
});
278+
279+
service.subscribe(plugin, slotName).catch((e) => {
280+
console.error('Error from .subscribe', e);
281+
});
282+
283+
await sleep(100);
284+
285+
await client.query(
286+
//language=sql
287+
`SELECT pg_logical_emit_message(true, 'test_prefix', 'test_content')`
288+
);
289+
await client.query(
290+
//language=sql
291+
`SELECT pg_logical_emit_message(true, 'test_prefix2', 'test_content2')`
292+
);
293+
294+
await sleep(1000);
295+
296+
const msgs = messages.filter((msg) => msg.tag === 'message');
297+
expect(msgs.length).toBe(2);
298+
299+
expect(msgs[0]).toStrictEqual({
300+
content: Buffer.from('test_content'),
301+
flags: 1,
302+
messageLsn: expect.stringMatching(lsnRe),
303+
prefix: 'test_prefix',
304+
tag: 'message',
305+
transactional: true,
306+
});
307+
expect(msgs[1]).toStrictEqual({
308+
content: Buffer.from('test_content2'),
309+
flags: 1,
310+
messageLsn: expect.stringMatching(lsnRe),
311+
prefix: 'test_prefix2',
312+
tag: 'message',
313+
transactional: true,
314+
});
315+
316+
await service.stop();
317+
});
318+
270319
it('Huge transaction', async () => {
271320
const service = new LogicalReplicationService(TestClientConfig);
272321
const plugin = new PgoutputPlugin({ protoVersion: 1, publicationNames: [publicationName] });

0 commit comments

Comments
 (0)