@agendajs/postgres-backend 1.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +25 -0
- package/README.md +215 -0
- package/dist/PostgresBackend.d.ts +75 -0
- package/dist/PostgresBackend.js +123 -0
- package/dist/PostgresBackend.js.map +1 -0
- package/dist/PostgresJobRepository.d.ts +53 -0
- package/dist/PostgresJobRepository.js +559 -0
- package/dist/PostgresJobRepository.js.map +1 -0
- package/dist/PostgresNotificationChannel.d.ts +41 -0
- package/dist/PostgresNotificationChannel.js +170 -0
- package/dist/PostgresNotificationChannel.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.d.ts +10 -0
- package/dist/schema.js +72 -0
- package/dist/schema.js.map +1 -0
- package/dist/types.d.ts +52 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
import { Pool } from 'pg';
|
|
3
|
+
import { toJobId, computeJobState } from 'agenda';
|
|
4
|
+
import { getCreateTableSQL, getCreateIndexesSQL, getUpdateTimestampTriggerSQL } from './schema.js';
|
|
5
|
+
const log = debug('agenda:postgres:repository');
|
|
6
|
+
/**
|
|
7
|
+
* PostgreSQL implementation of JobRepository
|
|
8
|
+
*/
|
|
9
|
+
export class PostgresJobRepository {
|
|
10
|
+
config;
|
|
11
|
+
pool;
|
|
12
|
+
ownPool;
|
|
13
|
+
tableName;
|
|
14
|
+
ensureSchema;
|
|
15
|
+
sort;
|
|
16
|
+
disconnected = false;
|
|
17
|
+
constructor(config) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
this.tableName = config.tableName || 'agenda_jobs';
|
|
20
|
+
this.ensureSchema = config.ensureSchema ?? true;
|
|
21
|
+
this.sort = config.sort || { nextRunAt: 'asc', priority: 'desc' };
|
|
22
|
+
// Use existing pool or create a new one
|
|
23
|
+
if (config.pool) {
|
|
24
|
+
// Use existing pool (won't be closed on disconnect)
|
|
25
|
+
this.pool = config.pool;
|
|
26
|
+
this.ownPool = false;
|
|
27
|
+
}
|
|
28
|
+
else if (config.connectionString || config.poolConfig) {
|
|
29
|
+
this.ownPool = true;
|
|
30
|
+
this.createPool();
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
throw new Error('PostgresBackend requires pool, connectionString, or poolConfig');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
createPool() {
|
|
37
|
+
if (this.config.connectionString) {
|
|
38
|
+
this.pool = new Pool({ connectionString: this.config.connectionString });
|
|
39
|
+
}
|
|
40
|
+
else if (this.config.poolConfig) {
|
|
41
|
+
this.pool = new Pool(this.config.poolConfig);
|
|
42
|
+
}
|
|
43
|
+
this.disconnected = false;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get the underlying pool (for use by notification channel)
|
|
47
|
+
*/
|
|
48
|
+
getPool() {
|
|
49
|
+
return this.pool;
|
|
50
|
+
}
|
|
51
|
+
async connect() {
|
|
52
|
+
log('connecting to PostgreSQL');
|
|
53
|
+
// Recreate pool if it was disconnected
|
|
54
|
+
if (this.disconnected && this.ownPool) {
|
|
55
|
+
log('recreating pool after disconnect');
|
|
56
|
+
this.createPool();
|
|
57
|
+
}
|
|
58
|
+
// Test connection
|
|
59
|
+
const client = await this.pool.connect();
|
|
60
|
+
try {
|
|
61
|
+
await client.query('SELECT 1');
|
|
62
|
+
log('connection successful');
|
|
63
|
+
if (this.ensureSchema) {
|
|
64
|
+
await this.createSchema(client);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
client.release();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async createSchema(client) {
|
|
72
|
+
log('ensuring schema exists');
|
|
73
|
+
// Create table
|
|
74
|
+
await client.query(getCreateTableSQL(this.tableName));
|
|
75
|
+
log('table created or already exists');
|
|
76
|
+
// Create indexes
|
|
77
|
+
for (const sql of getCreateIndexesSQL(this.tableName)) {
|
|
78
|
+
await client.query(sql);
|
|
79
|
+
}
|
|
80
|
+
log('indexes created or already exist');
|
|
81
|
+
// Create update trigger
|
|
82
|
+
await client.query(getUpdateTimestampTriggerSQL(this.tableName));
|
|
83
|
+
log('update trigger created');
|
|
84
|
+
}
|
|
85
|
+
async disconnect() {
|
|
86
|
+
log('disconnecting from PostgreSQL');
|
|
87
|
+
if (this.ownPool && this.pool && !this.disconnected) {
|
|
88
|
+
log('closing owned pool');
|
|
89
|
+
await this.pool.end();
|
|
90
|
+
this.disconnected = true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Force close the pool - should only be called on application shutdown
|
|
95
|
+
* or when you're sure the backend won't be reused
|
|
96
|
+
*/
|
|
97
|
+
async close() {
|
|
98
|
+
log('closing PostgreSQL pool');
|
|
99
|
+
if (this.ownPool && !this.disconnected) {
|
|
100
|
+
await this.pool.end();
|
|
101
|
+
this.disconnected = true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Convert PostgreSQL row to JobParameters
|
|
106
|
+
*/
|
|
107
|
+
rowToJob(row) {
|
|
108
|
+
return {
|
|
109
|
+
_id: toJobId(row.id),
|
|
110
|
+
name: row.name,
|
|
111
|
+
priority: row.priority,
|
|
112
|
+
nextRunAt: row.next_run_at,
|
|
113
|
+
type: row.type,
|
|
114
|
+
lockedAt: row.locked_at ?? undefined,
|
|
115
|
+
lastFinishedAt: row.last_finished_at ?? undefined,
|
|
116
|
+
failedAt: row.failed_at ?? undefined,
|
|
117
|
+
failCount: row.fail_count ?? undefined,
|
|
118
|
+
failReason: row.fail_reason ?? undefined,
|
|
119
|
+
repeatTimezone: row.repeat_timezone ?? undefined,
|
|
120
|
+
lastRunAt: row.last_run_at ?? undefined,
|
|
121
|
+
repeatInterval: row.repeat_interval ?? undefined,
|
|
122
|
+
data: row.data,
|
|
123
|
+
repeatAt: row.repeat_at ?? undefined,
|
|
124
|
+
disabled: row.disabled,
|
|
125
|
+
progress: row.progress ?? undefined,
|
|
126
|
+
fork: row.fork ?? undefined,
|
|
127
|
+
lastModifiedBy: row.last_modified_by ?? undefined
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Convert SortDirection to SQL ASC/DESC
|
|
132
|
+
*/
|
|
133
|
+
toSqlDirection(dir) {
|
|
134
|
+
return dir === 'asc' ? 'ASC' : 'DESC';
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Convert sort options to PostgreSQL ORDER BY clause
|
|
138
|
+
*/
|
|
139
|
+
toOrderByClause(sort) {
|
|
140
|
+
if (!sort) {
|
|
141
|
+
return 'next_run_at DESC NULLS LAST, last_run_at DESC NULLS LAST';
|
|
142
|
+
}
|
|
143
|
+
const parts = [];
|
|
144
|
+
if (sort.nextRunAt !== undefined) {
|
|
145
|
+
parts.push(`next_run_at ${this.toSqlDirection(sort.nextRunAt)} NULLS LAST`);
|
|
146
|
+
}
|
|
147
|
+
if (sort.lastRunAt !== undefined) {
|
|
148
|
+
parts.push(`last_run_at ${this.toSqlDirection(sort.lastRunAt)} NULLS LAST`);
|
|
149
|
+
}
|
|
150
|
+
if (sort.lastFinishedAt !== undefined) {
|
|
151
|
+
parts.push(`last_finished_at ${this.toSqlDirection(sort.lastFinishedAt)} NULLS LAST`);
|
|
152
|
+
}
|
|
153
|
+
if (sort.priority !== undefined) {
|
|
154
|
+
parts.push(`priority ${this.toSqlDirection(sort.priority)}`);
|
|
155
|
+
}
|
|
156
|
+
if (sort.name !== undefined) {
|
|
157
|
+
parts.push(`name ${this.toSqlDirection(sort.name)}`);
|
|
158
|
+
}
|
|
159
|
+
return parts.length > 0
|
|
160
|
+
? parts.join(', ')
|
|
161
|
+
: 'next_run_at DESC NULLS LAST, last_run_at DESC NULLS LAST';
|
|
162
|
+
}
|
|
163
|
+
async getJobById(id) {
|
|
164
|
+
const result = await this.pool.query(`SELECT * FROM "${this.tableName}" WHERE id = $1`, [id]);
|
|
165
|
+
if (result.rows.length === 0) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
return this.rowToJob(result.rows[0]);
|
|
169
|
+
}
|
|
170
|
+
async queryJobs(options = {}) {
|
|
171
|
+
const { name, names, state, id, ids, search, data, includeDisabled = true, sort, skip = 0, limit = 0 } = options;
|
|
172
|
+
const now = new Date();
|
|
173
|
+
// Build query
|
|
174
|
+
const conditions = [];
|
|
175
|
+
const params = [];
|
|
176
|
+
let paramIndex = 1;
|
|
177
|
+
if (name) {
|
|
178
|
+
conditions.push(`name = $${paramIndex++}`);
|
|
179
|
+
params.push(name);
|
|
180
|
+
}
|
|
181
|
+
else if (names && names.length > 0) {
|
|
182
|
+
conditions.push(`name = ANY($${paramIndex++})`);
|
|
183
|
+
params.push(names);
|
|
184
|
+
}
|
|
185
|
+
if (id) {
|
|
186
|
+
conditions.push(`id = $${paramIndex++}`);
|
|
187
|
+
params.push(id);
|
|
188
|
+
}
|
|
189
|
+
else if (ids && ids.length > 0) {
|
|
190
|
+
conditions.push(`id = ANY($${paramIndex++}::uuid[])`);
|
|
191
|
+
params.push(ids);
|
|
192
|
+
}
|
|
193
|
+
if (search) {
|
|
194
|
+
conditions.push(`name ILIKE $${paramIndex++}`);
|
|
195
|
+
params.push(`%${search}%`);
|
|
196
|
+
}
|
|
197
|
+
if (data !== undefined) {
|
|
198
|
+
conditions.push(`data @> $${paramIndex++}::jsonb`);
|
|
199
|
+
params.push(JSON.stringify(data));
|
|
200
|
+
}
|
|
201
|
+
if (!includeDisabled) {
|
|
202
|
+
conditions.push('disabled = FALSE');
|
|
203
|
+
}
|
|
204
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
205
|
+
const orderByClause = this.toOrderByClause(sort);
|
|
206
|
+
const query = `
|
|
207
|
+
SELECT * FROM "${this.tableName}"
|
|
208
|
+
${whereClause}
|
|
209
|
+
ORDER BY ${orderByClause}
|
|
210
|
+
`;
|
|
211
|
+
const result = await this.pool.query(query, params);
|
|
212
|
+
// Compute states and filter by state if specified
|
|
213
|
+
let jobsWithState = result.rows
|
|
214
|
+
.map(row => {
|
|
215
|
+
const job = this.rowToJob(row);
|
|
216
|
+
return {
|
|
217
|
+
...job,
|
|
218
|
+
_id: job._id,
|
|
219
|
+
state: computeJobState(job, now)
|
|
220
|
+
};
|
|
221
|
+
})
|
|
222
|
+
.filter(job => !state || job.state === state);
|
|
223
|
+
// Apply pagination after state filtering
|
|
224
|
+
const total = jobsWithState.length;
|
|
225
|
+
if (limit > 0) {
|
|
226
|
+
jobsWithState = jobsWithState.slice(skip, skip + limit);
|
|
227
|
+
}
|
|
228
|
+
else if (skip > 0) {
|
|
229
|
+
jobsWithState = jobsWithState.slice(skip);
|
|
230
|
+
}
|
|
231
|
+
return { jobs: jobsWithState, total };
|
|
232
|
+
}
|
|
233
|
+
async getJobsOverview() {
|
|
234
|
+
const now = new Date();
|
|
235
|
+
const names = await this.getDistinctJobNames();
|
|
236
|
+
const overviews = await Promise.all(names.map(async (name) => {
|
|
237
|
+
const result = await this.pool.query(`SELECT * FROM "${this.tableName}" WHERE name = $1`, [name]);
|
|
238
|
+
const overview = {
|
|
239
|
+
name,
|
|
240
|
+
total: result.rows.length,
|
|
241
|
+
running: 0,
|
|
242
|
+
scheduled: 0,
|
|
243
|
+
queued: 0,
|
|
244
|
+
completed: 0,
|
|
245
|
+
failed: 0,
|
|
246
|
+
repeating: 0
|
|
247
|
+
};
|
|
248
|
+
for (const row of result.rows) {
|
|
249
|
+
const job = this.rowToJob(row);
|
|
250
|
+
const state = computeJobState(job, now);
|
|
251
|
+
overview[state]++;
|
|
252
|
+
}
|
|
253
|
+
return overview;
|
|
254
|
+
}));
|
|
255
|
+
return overviews;
|
|
256
|
+
}
|
|
257
|
+
async getDistinctJobNames() {
|
|
258
|
+
const result = await this.pool.query(`SELECT DISTINCT name FROM "${this.tableName}" ORDER BY name`);
|
|
259
|
+
return result.rows.map(row => row.name);
|
|
260
|
+
}
|
|
261
|
+
async getQueueSize() {
|
|
262
|
+
const result = await this.pool.query(`SELECT COUNT(*) as count FROM "${this.tableName}" WHERE next_run_at < NOW()`);
|
|
263
|
+
return parseInt(result.rows[0].count, 10);
|
|
264
|
+
}
|
|
265
|
+
async removeJobs(options) {
|
|
266
|
+
const conditions = [];
|
|
267
|
+
const params = [];
|
|
268
|
+
let paramIndex = 1;
|
|
269
|
+
if (options.id) {
|
|
270
|
+
conditions.push(`id = $${paramIndex++}`);
|
|
271
|
+
params.push(options.id.toString());
|
|
272
|
+
}
|
|
273
|
+
else if (options.ids && options.ids.length > 0) {
|
|
274
|
+
conditions.push(`id = ANY($${paramIndex++}::uuid[])`);
|
|
275
|
+
params.push(options.ids.map(id => id.toString()));
|
|
276
|
+
}
|
|
277
|
+
if (options.name) {
|
|
278
|
+
conditions.push(`name = $${paramIndex++}`);
|
|
279
|
+
params.push(options.name);
|
|
280
|
+
}
|
|
281
|
+
else if (options.names && options.names.length > 0) {
|
|
282
|
+
conditions.push(`name = ANY($${paramIndex++})`);
|
|
283
|
+
params.push(options.names);
|
|
284
|
+
}
|
|
285
|
+
else if (options.notNames && options.notNames.length > 0) {
|
|
286
|
+
conditions.push(`name != ALL($${paramIndex++})`);
|
|
287
|
+
params.push(options.notNames);
|
|
288
|
+
}
|
|
289
|
+
if (options.data !== undefined) {
|
|
290
|
+
conditions.push(`data @> $${paramIndex++}::jsonb`);
|
|
291
|
+
params.push(JSON.stringify(options.data));
|
|
292
|
+
}
|
|
293
|
+
// If no criteria provided, don't delete anything
|
|
294
|
+
if (conditions.length === 0) {
|
|
295
|
+
return 0;
|
|
296
|
+
}
|
|
297
|
+
const result = await this.pool.query(`DELETE FROM "${this.tableName}" WHERE ${conditions.join(' AND ')}`, params);
|
|
298
|
+
return result.rowCount || 0;
|
|
299
|
+
}
|
|
300
|
+
async unlockJob(job) {
|
|
301
|
+
if (!job._id)
|
|
302
|
+
return;
|
|
303
|
+
// Only unlock jobs which are not currently processed (nextRunAt is not null)
|
|
304
|
+
await this.pool.query(`UPDATE "${this.tableName}"
|
|
305
|
+
SET locked_at = NULL
|
|
306
|
+
WHERE id = $1 AND next_run_at IS NOT NULL`, [job._id.toString()]);
|
|
307
|
+
}
|
|
308
|
+
async unlockJobs(jobIds) {
|
|
309
|
+
if (jobIds.length === 0)
|
|
310
|
+
return;
|
|
311
|
+
const ids = jobIds.map(id => id.toString());
|
|
312
|
+
await this.pool.query(`UPDATE "${this.tableName}"
|
|
313
|
+
SET locked_at = NULL
|
|
314
|
+
WHERE id = ANY($1::uuid[])`, [ids]);
|
|
315
|
+
}
|
|
316
|
+
async lockJob(job, options) {
|
|
317
|
+
if (!job._id)
|
|
318
|
+
return undefined;
|
|
319
|
+
const orderBy = `next_run_at ${this.toSqlDirection(this.sort.nextRunAt || 'asc')} NULLS LAST, priority ${this.toSqlDirection(this.sort.priority || 'desc')}`;
|
|
320
|
+
// Atomic lock using UPDATE ... RETURNING
|
|
321
|
+
const result = await this.pool.query(`UPDATE "${this.tableName}"
|
|
322
|
+
SET locked_at = NOW(), last_modified_by = $4
|
|
323
|
+
WHERE id = (
|
|
324
|
+
SELECT id FROM "${this.tableName}"
|
|
325
|
+
WHERE id = $1
|
|
326
|
+
AND name = $2
|
|
327
|
+
AND locked_at IS NULL
|
|
328
|
+
AND next_run_at = $3
|
|
329
|
+
AND disabled = FALSE
|
|
330
|
+
ORDER BY ${orderBy}
|
|
331
|
+
LIMIT 1
|
|
332
|
+
FOR UPDATE SKIP LOCKED
|
|
333
|
+
)
|
|
334
|
+
RETURNING *`, [job._id.toString(), job.name, job.nextRunAt, options?.lastModifiedBy || null]);
|
|
335
|
+
if (result.rows.length === 0) {
|
|
336
|
+
return undefined;
|
|
337
|
+
}
|
|
338
|
+
return this.rowToJob(result.rows[0]);
|
|
339
|
+
}
|
|
340
|
+
async getNextJobToRun(jobName, nextScanAt, lockDeadline, now, options) {
|
|
341
|
+
const lockTime = now ?? new Date();
|
|
342
|
+
const orderBy = `next_run_at ${this.toSqlDirection(this.sort.nextRunAt || 'asc')} NULLS LAST, priority ${this.toSqlDirection(this.sort.priority || 'desc')}`;
|
|
343
|
+
// Find and lock job atomically using UPDATE ... RETURNING with subquery
|
|
344
|
+
const result = await this.pool.query(`UPDATE "${this.tableName}"
|
|
345
|
+
SET locked_at = $1, last_modified_by = $5
|
|
346
|
+
WHERE id = (
|
|
347
|
+
SELECT id FROM "${this.tableName}"
|
|
348
|
+
WHERE name = $2
|
|
349
|
+
AND disabled = FALSE
|
|
350
|
+
AND (
|
|
351
|
+
(locked_at IS NULL AND next_run_at <= $3)
|
|
352
|
+
OR locked_at <= $4
|
|
353
|
+
)
|
|
354
|
+
ORDER BY ${orderBy}
|
|
355
|
+
LIMIT 1
|
|
356
|
+
FOR UPDATE SKIP LOCKED
|
|
357
|
+
)
|
|
358
|
+
RETURNING *`, [lockTime, jobName, nextScanAt, lockDeadline, options?.lastModifiedBy || null]);
|
|
359
|
+
if (result.rows.length === 0) {
|
|
360
|
+
return undefined;
|
|
361
|
+
}
|
|
362
|
+
return this.rowToJob(result.rows[0]);
|
|
363
|
+
}
|
|
364
|
+
async saveJobState(job, options) {
|
|
365
|
+
if (!job._id) {
|
|
366
|
+
throw new Error('Cannot save job state without job ID');
|
|
367
|
+
}
|
|
368
|
+
const result = await this.pool.query(`UPDATE "${this.tableName}"
|
|
369
|
+
SET locked_at = $2,
|
|
370
|
+
next_run_at = $3,
|
|
371
|
+
last_run_at = $4,
|
|
372
|
+
progress = $5,
|
|
373
|
+
fail_reason = $6,
|
|
374
|
+
fail_count = $7,
|
|
375
|
+
failed_at = $8,
|
|
376
|
+
last_finished_at = $9,
|
|
377
|
+
last_modified_by = $11
|
|
378
|
+
WHERE id = $1 AND name = $10`, [
|
|
379
|
+
job._id.toString(),
|
|
380
|
+
job.lockedAt || null,
|
|
381
|
+
job.nextRunAt || null,
|
|
382
|
+
job.lastRunAt || null,
|
|
383
|
+
job.progress ?? null,
|
|
384
|
+
job.failReason ?? null,
|
|
385
|
+
job.failCount ?? null,
|
|
386
|
+
job.failedAt || null,
|
|
387
|
+
job.lastFinishedAt || null,
|
|
388
|
+
job.name,
|
|
389
|
+
options?.lastModifiedBy || null
|
|
390
|
+
]);
|
|
391
|
+
if (result.rowCount !== 1) {
|
|
392
|
+
throw new Error(`job ${job._id} (name: ${job.name}) cannot be updated in the database, maybe it does not exist anymore?`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
async saveJob(job, options) {
|
|
396
|
+
log('attempting to save a job');
|
|
397
|
+
const { _id, unique, uniqueOpts, ...props } = job;
|
|
398
|
+
// If the job already has an ID, update it
|
|
399
|
+
if (_id) {
|
|
400
|
+
log('job already has _id, updating');
|
|
401
|
+
const result = await this.pool.query(`UPDATE "${this.tableName}"
|
|
402
|
+
SET name = $2,
|
|
403
|
+
priority = $3,
|
|
404
|
+
next_run_at = $4,
|
|
405
|
+
type = $5,
|
|
406
|
+
repeat_timezone = $6,
|
|
407
|
+
repeat_interval = $7,
|
|
408
|
+
data = $8,
|
|
409
|
+
repeat_at = $9,
|
|
410
|
+
disabled = $10,
|
|
411
|
+
fork = $11,
|
|
412
|
+
fail_reason = $12,
|
|
413
|
+
fail_count = $13,
|
|
414
|
+
failed_at = $14,
|
|
415
|
+
last_modified_by = $15
|
|
416
|
+
WHERE id = $1 AND name = $2
|
|
417
|
+
RETURNING *`, [
|
|
418
|
+
_id.toString(),
|
|
419
|
+
props.name,
|
|
420
|
+
props.priority,
|
|
421
|
+
props.nextRunAt || null,
|
|
422
|
+
props.type,
|
|
423
|
+
props.repeatTimezone || null,
|
|
424
|
+
props.repeatInterval || null,
|
|
425
|
+
JSON.stringify(props.data),
|
|
426
|
+
props.repeatAt || null,
|
|
427
|
+
props.disabled || false,
|
|
428
|
+
props.fork || false,
|
|
429
|
+
props.failReason ?? null,
|
|
430
|
+
props.failCount ?? null,
|
|
431
|
+
props.failedAt || null,
|
|
432
|
+
options?.lastModifiedBy || null
|
|
433
|
+
]);
|
|
434
|
+
if (result.rows.length === 0) {
|
|
435
|
+
// Job was removed, return original data unchanged
|
|
436
|
+
log('job %s was not found for update, returning original data', _id);
|
|
437
|
+
return job;
|
|
438
|
+
}
|
|
439
|
+
return this.rowToJob(result.rows[0]);
|
|
440
|
+
}
|
|
441
|
+
// Handle 'single' type jobs - upsert by name
|
|
442
|
+
if (props.type === 'single') {
|
|
443
|
+
log('job with type of "single" found');
|
|
444
|
+
const now = new Date();
|
|
445
|
+
const shouldProtectNextRunAt = props.nextRunAt && props.nextRunAt <= now;
|
|
446
|
+
// Use ON CONFLICT to upsert
|
|
447
|
+
const result = await this.pool.query(`INSERT INTO "${this.tableName}" (
|
|
448
|
+
name, priority, next_run_at, type, repeat_timezone,
|
|
449
|
+
repeat_interval, data, repeat_at, disabled, fork, last_modified_by
|
|
450
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
|
451
|
+
ON CONFLICT ((name)) WHERE type = 'single'
|
|
452
|
+
DO UPDATE SET
|
|
453
|
+
priority = EXCLUDED.priority,
|
|
454
|
+
next_run_at = ${shouldProtectNextRunAt
|
|
455
|
+
? `COALESCE("${this.tableName}".next_run_at, EXCLUDED.next_run_at)`
|
|
456
|
+
: 'EXCLUDED.next_run_at'},
|
|
457
|
+
repeat_timezone = EXCLUDED.repeat_timezone,
|
|
458
|
+
repeat_interval = EXCLUDED.repeat_interval,
|
|
459
|
+
data = EXCLUDED.data,
|
|
460
|
+
repeat_at = EXCLUDED.repeat_at,
|
|
461
|
+
disabled = EXCLUDED.disabled,
|
|
462
|
+
fork = EXCLUDED.fork,
|
|
463
|
+
last_modified_by = EXCLUDED.last_modified_by
|
|
464
|
+
RETURNING *`, [
|
|
465
|
+
props.name,
|
|
466
|
+
props.priority,
|
|
467
|
+
props.nextRunAt || null,
|
|
468
|
+
props.type,
|
|
469
|
+
props.repeatTimezone || null,
|
|
470
|
+
props.repeatInterval || null,
|
|
471
|
+
JSON.stringify(props.data),
|
|
472
|
+
props.repeatAt || null,
|
|
473
|
+
props.disabled || false,
|
|
474
|
+
props.fork || false,
|
|
475
|
+
options?.lastModifiedBy || null
|
|
476
|
+
]);
|
|
477
|
+
return this.rowToJob(result.rows[0]);
|
|
478
|
+
}
|
|
479
|
+
// Handle unique constraint
|
|
480
|
+
if (unique) {
|
|
481
|
+
log('calling upsert with unique constraint');
|
|
482
|
+
// Build conditions from unique object
|
|
483
|
+
const conditions = ['name = $1'];
|
|
484
|
+
const params = [props.name];
|
|
485
|
+
let paramIndex = 2;
|
|
486
|
+
for (const [key, value] of Object.entries(unique)) {
|
|
487
|
+
if (key.startsWith('data.')) {
|
|
488
|
+
// Handle data sub-paths like 'data.userId'
|
|
489
|
+
const dataPath = key.substring(5);
|
|
490
|
+
conditions.push(`data->>'${dataPath}' = $${paramIndex++}`);
|
|
491
|
+
params.push(String(value));
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
// Direct column (snake_case conversion)
|
|
495
|
+
const columnName = key.replace(/([A-Z])/g, '_$1').toLowerCase();
|
|
496
|
+
conditions.push(`${columnName} = $${paramIndex++}`);
|
|
497
|
+
params.push(value);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
// Check if record exists
|
|
501
|
+
const existingResult = await this.pool.query(`SELECT * FROM "${this.tableName}" WHERE ${conditions.join(' AND ')} LIMIT 1`, params);
|
|
502
|
+
if (existingResult.rows.length > 0) {
|
|
503
|
+
// Record exists
|
|
504
|
+
if (uniqueOpts?.insertOnly) {
|
|
505
|
+
// Return existing record without update
|
|
506
|
+
return this.rowToJob(existingResult.rows[0]);
|
|
507
|
+
}
|
|
508
|
+
// Update existing record
|
|
509
|
+
const updateResult = await this.pool.query(`UPDATE "${this.tableName}"
|
|
510
|
+
SET priority = $${paramIndex},
|
|
511
|
+
next_run_at = $${paramIndex + 1},
|
|
512
|
+
type = $${paramIndex + 2},
|
|
513
|
+
repeat_timezone = $${paramIndex + 3},
|
|
514
|
+
repeat_interval = $${paramIndex + 4},
|
|
515
|
+
data = $${paramIndex + 5},
|
|
516
|
+
repeat_at = $${paramIndex + 6},
|
|
517
|
+
disabled = $${paramIndex + 7},
|
|
518
|
+
fork = $${paramIndex + 8},
|
|
519
|
+
last_modified_by = $${paramIndex + 9}
|
|
520
|
+
WHERE ${conditions.join(' AND ')}
|
|
521
|
+
RETURNING *`, [
|
|
522
|
+
...params,
|
|
523
|
+
props.priority,
|
|
524
|
+
props.nextRunAt || null,
|
|
525
|
+
props.type,
|
|
526
|
+
props.repeatTimezone || null,
|
|
527
|
+
props.repeatInterval || null,
|
|
528
|
+
JSON.stringify(props.data),
|
|
529
|
+
props.repeatAt || null,
|
|
530
|
+
props.disabled || false,
|
|
531
|
+
props.fork || false,
|
|
532
|
+
options?.lastModifiedBy || null
|
|
533
|
+
]);
|
|
534
|
+
return this.rowToJob(updateResult.rows[0]);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
// Insert new job
|
|
538
|
+
log('inserting new job');
|
|
539
|
+
const result = await this.pool.query(`INSERT INTO "${this.tableName}" (
|
|
540
|
+
name, priority, next_run_at, type, repeat_timezone,
|
|
541
|
+
repeat_interval, data, repeat_at, disabled, fork, last_modified_by
|
|
542
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
|
543
|
+
RETURNING *`, [
|
|
544
|
+
props.name,
|
|
545
|
+
props.priority,
|
|
546
|
+
props.nextRunAt || null,
|
|
547
|
+
props.type,
|
|
548
|
+
props.repeatTimezone || null,
|
|
549
|
+
props.repeatInterval || null,
|
|
550
|
+
JSON.stringify(props.data),
|
|
551
|
+
props.repeatAt || null,
|
|
552
|
+
props.disabled || false,
|
|
553
|
+
props.fork || false,
|
|
554
|
+
options?.lastModifiedBy || null
|
|
555
|
+
]);
|
|
556
|
+
return this.rowToJob(result.rows[0]);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
//# sourceMappingURL=PostgresJobRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostgresJobRepository.js","sourceRoot":"","sources":["../src/PostgresJobRepository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,IAAI,EAAc,MAAM,IAAI,CAAC;AACtC,OAAO,EACN,OAAO,EACP,eAAe,EACf,MAAM,QAAQ,CAAC;AAehB,OAAO,EACN,iBAAiB,EACjB,mBAAmB,EACnB,4BAA4B,EAC5B,MAAM,aAAa,CAAC;AAErB,MAAM,GAAG,GAAG,KAAK,CAAC,4BAA4B,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,OAAO,qBAAqB;IAQb;IAPZ,IAAI,CAAQ;IACZ,OAAO,CAAU;IACjB,SAAS,CAAS;IAClB,YAAY,CAAU;IACtB,IAAI,CAA0D;IAC9D,YAAY,GAAY,KAAK,CAAC;IAEtC,YAAoB,MAA6B;QAA7B,WAAM,GAAN,MAAM,CAAuB;QAChD,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,aAAa,CAAC;QACnD,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC;QAChD,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAElE,wCAAwC;QACxC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YACjB,oDAAoD;YACpD,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACtB,CAAC;aAAM,IAAI,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACzD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,UAAU,EAAE,CAAC;QACnB,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACnF,CAAC;IACF,CAAC;IAEO,UAAU;QACjB,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAClC,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAC1E,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,OAAO;QACN,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,OAAO;QACZ,GAAG,CAAC,0BAA0B,CAAC,CAAC;QAEhC,uCAAuC;QACvC,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACvC,GAAG,CAAC,kCAAkC,CAAC,CAAC;YACxC,IAAI,CAAC,UAAU,EAAE,CAAC;QACnB,CAAC;QAED,kBAAkB;QAClB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACzC,IAAI,CAAC;YACJ,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC/B,GAAG,CAAC,uBAAuB,CAAC,CAAC;YAE7B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACvB,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YACjC,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,MAAM,CAAC,OAAO,EAAE,CAAC;QAClB,CAAC;IACF,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,MAAkB;QAC5C,GAAG,CAAC,wBAAwB,CAAC,CAAC;QAE9B,eAAe;QACf,MAAM,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACtD,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAEvC,iBAAiB;QACjB,KAAK,MAAM,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACvD,MAAM,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAExC,wBAAwB;QACxB,MAAM,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACjE,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,UAAU;QACf,GAAG,CAAC,+BAA+B,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACrD,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAC1B,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC1B,CAAC;IACF,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK;QACV,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAC/B,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACxC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC1B,CAAC;IACF,CAAC;IAED;;OAEG;IACK,QAAQ,CAAiB,GAAmB;QACnD,OAAO;YACN,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAU;YAC7B,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,SAAS,EAAE,GAAG,CAAC,WAAW;YAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,QAAQ,EAAE,GAAG,CAAC,SAAS,IAAI,SAAS;YACpC,cAAc,EAAE,GAAG,CAAC,gBAAgB,IAAI,SAAS;YACjD,QAAQ,EAAE,GAAG,CAAC,SAAS,IAAI,SAAS;YACpC,SAAS,EAAE,GAAG,CAAC,UAAU,IAAI,SAAS;YACtC,UAAU,EAAE,GAAG,CAAC,WAAW,IAAI,SAAS;YACxC,cAAc,EAAE,GAAG,CAAC,eAAe,IAAI,SAAS;YAChD,SAAS,EAAE,GAAG,CAAC,WAAW,IAAI,SAAS;YACvC,cAAc,EAAE,GAAG,CAAC,eAAe,IAAI,SAAS;YAChD,IAAI,EAAE,GAAG,CAAC,IAAY;YACtB,QAAQ,EAAE,GAAG,CAAC,SAAS,IAAI,SAAS;YACpC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,SAAS;YACnC,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,SAAS;YAC3B,cAAc,EAAE,GAAG,CAAC,gBAAgB,IAAI,SAAS;SACjD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,GAAkB;QACxC,OAAO,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IACvC,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,IAAe;QACtC,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,0DAA0D,CAAC;QACnE,CAAC;QAED,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC7E,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC7E,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC;YACtB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;YAClB,CAAC,CAAC,0DAA0D,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU;QAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,kBAAkB,IAAI,CAAC,SAAS,iBAAiB,EACjD,CAAC,EAAE,CAAC,CACJ,CAAC;QAEF,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC;QACb,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,UAA4B,EAAE;QAC7C,MAAM,EACL,IAAI,EACJ,KAAK,EACL,KAAK,EACL,EAAE,EACF,GAAG,EACH,MAAM,EACN,IAAI,EACJ,eAAe,GAAG,IAAI,EACtB,IAAI,EACJ,IAAI,GAAG,CAAC,EACR,KAAK,GAAG,CAAC,EACT,GAAG,OAAO,CAAC;QACZ,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAEvB,cAAc;QACd,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,IAAI,IAAI,EAAE,CAAC;YACV,UAAU,CAAC,IAAI,CAAC,WAAW,UAAU,EAAE,EAAE,CAAC,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;aAAM,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,UAAU,CAAC,IAAI,CAAC,eAAe,UAAU,EAAE,GAAG,CAAC,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QAED,IAAI,EAAE,EAAE,CAAC;YACR,UAAU,CAAC,IAAI,CAAC,SAAS,UAAU,EAAE,EAAE,CAAC,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;aAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,UAAU,CAAC,IAAI,CAAC,aAAa,UAAU,EAAE,WAAW,CAAC,CAAC;YACtD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACZ,UAAU,CAAC,IAAI,CAAC,eAAe,UAAU,EAAE,EAAE,CAAC,CAAC;YAC/C,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC;QAC5B,CAAC;QAED,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,UAAU,CAAC,IAAI,CAAC,YAAY,UAAU,EAAE,SAAS,CAAC,CAAC;YACnD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,CAAC,eAAe,EAAE,CAAC;YACtB,UAAU,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACrC,CAAC;QAED,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrF,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAEjD,MAAM,KAAK,GAAG;oBACI,IAAI,CAAC,SAAS;KAC7B,WAAW;cACF,aAAa;GACxB,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAiB,KAAK,EAAE,MAAM,CAAC,CAAC;QAEpE,kDAAkD;QAClD,IAAI,aAAa,GAAmB,MAAM,CAAC,IAAI;aAC7C,GAAG,CAAC,GAAG,CAAC,EAAE;YACV,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC/B,OAAO;gBACN,GAAG,GAAG;gBACN,GAAG,EAAE,GAAG,CAAC,GAAY;gBACrB,KAAK,EAAE,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC;aAChC,CAAC;QACH,CAAC,CAAC;aACD,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QAE/C,yCAAyC;QACzC,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC;QACnC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACf,aAAa,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,KAAK,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACrB,aAAa,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,eAAe;QACpB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAE/C,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE;YACtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,kBAAkB,IAAI,CAAC,SAAS,mBAAmB,EACnD,CAAC,IAAI,CAAC,CACN,CAAC;YAEF,MAAM,QAAQ,GAAiB;gBAC9B,IAAI;gBACJ,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;gBACzB,OAAO,EAAE,CAAC;gBACV,SAAS,EAAE,CAAC;gBACZ,MAAM,EAAE,CAAC;gBACT,SAAS,EAAE,CAAC;gBACZ,MAAM,EAAE,CAAC;gBACT,SAAS,EAAE,CAAC;aACZ,CAAC;YAEF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC/B,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBACxC,QAAQ,CAAC,KAA8B,CAAC,EAAE,CAAC;YAC5C,CAAC;YAED,OAAO,QAAQ,CAAC;QACjB,CAAC,CAAC,CACF,CAAC;QAEF,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,mBAAmB;QACxB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,8BAA8B,IAAI,CAAC,SAAS,iBAAiB,CAC7D,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,YAAY;QACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,kCAAkC,IAAI,CAAC,SAAS,6BAA6B,CAC7E,CAAC;QACF,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAA0B;QAC1C,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;YAChB,UAAU,CAAC,IAAI,CAAC,SAAS,UAAU,EAAE,EAAE,CAAC,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpC,CAAC;aAAM,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,UAAU,CAAC,IAAI,CAAC,aAAa,UAAU,EAAE,WAAW,CAAC,CAAC;YACtD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,UAAU,CAAC,IAAI,CAAC,WAAW,UAAU,EAAE,EAAE,CAAC,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtD,UAAU,CAAC,IAAI,CAAC,eAAe,UAAU,EAAE,GAAG,CAAC,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5D,UAAU,CAAC,IAAI,CAAC,gBAAgB,UAAU,EAAE,GAAG,CAAC,CAAC;YACjD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAChC,UAAU,CAAC,IAAI,CAAC,YAAY,UAAU,EAAE,SAAS,CAAC,CAAC;YACnD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,iDAAiD;QACjD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,CAAC;QACV,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,gBAAgB,IAAI,CAAC,SAAS,WAAW,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EACnE,MAAM,CACN,CAAC;QAEF,OAAO,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAkB;QACjC,IAAI,CAAC,GAAG,CAAC,GAAG;YAAE,OAAO;QAErB,6EAA6E;QAC7E,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACpB,WAAW,IAAI,CAAC,SAAS;;8CAEkB,EAC3C,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CACpB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAA0B;QAC1C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEhC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACpB,WAAW,IAAI,CAAC,SAAS;;+BAEG,EAC5B,CAAC,GAAG,CAAC,CACL,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CACZ,GAAkB,EAClB,OAAyC;QAEzC,IAAI,CAAC,GAAG,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAE/B,MAAM,OAAO,GAAG,eAAe,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,EAAE,CAAC;QAE7J,yCAAyC;QACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,WAAW,IAAI,CAAC,SAAS;;;uBAGL,IAAI,CAAC,SAAS;;;;;;gBAMrB,OAAO;;;;gBAIP,EACb,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,cAAc,IAAI,IAAI,CAAC,CAC9E,CAAC;QAEF,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,eAAe,CACpB,OAAe,EACf,UAAgB,EAChB,YAAkB,EAClB,GAAqB,EACrB,OAAyC;QAEzC,MAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,eAAe,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,EAAE,CAAC;QAE7J,wEAAwE;QACxE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,WAAW,IAAI,CAAC,SAAS;;;uBAGL,IAAI,CAAC,SAAS;;;;;;;gBAOrB,OAAO;;;;gBAIP,EACb,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,IAAI,IAAI,CAAC,CAC9E,CAAC;QAEF,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,YAAY,CACjB,GAAkB,EAClB,OAAyC;QAEzC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,WAAW,IAAI,CAAC,SAAS;;;;;;;;;;iCAUK,EAC9B;YACC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE;YAClB,GAAG,CAAC,QAAQ,IAAI,IAAI;YACpB,GAAG,CAAC,SAAS,IAAI,IAAI;YACrB,GAAG,CAAC,SAAS,IAAI,IAAI;YACrB,GAAG,CAAC,QAAQ,IAAI,IAAI;YACpB,GAAG,CAAC,UAAU,IAAI,IAAI;YACtB,GAAG,CAAC,SAAS,IAAI,IAAI;YACrB,GAAG,CAAC,QAAQ,IAAI,IAAI;YACpB,GAAG,CAAC,cAAc,IAAI,IAAI;YAC1B,GAAG,CAAC,IAAI;YACR,OAAO,EAAE,cAAc,IAAI,IAAI;SAC/B,CACD,CAAC;QAEF,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACd,OAAO,GAAG,CAAC,GAAG,WAAW,GAAG,CAAC,IAAI,uEAAuE,CACxG,CAAC;QACH,CAAC;IACF,CAAC;IAED,KAAK,CAAC,OAAO,CACZ,GAAwB,EACxB,OAAyC;QAEzC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QAEhC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,GAAG,GAAG,CAAC;QAElD,0CAA0C;QAC1C,IAAI,GAAG,EAAE,CAAC;YACT,GAAG,CAAC,+BAA+B,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,WAAW,IAAI,CAAC,SAAS;;;;;;;;;;;;;;;;iBAgBZ,EACb;gBACC,GAAG,CAAC,QAAQ,EAAE;gBACd,KAAK,CAAC,IAAI;gBACV,KAAK,CAAC,QAAQ;gBACd,KAAK,CAAC,SAAS,IAAI,IAAI;gBACvB,KAAK,CAAC,IAAI;gBACV,KAAK,CAAC,cAAc,IAAI,IAAI;gBAC5B,KAAK,CAAC,cAAc,IAAI,IAAI;gBAC5B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;gBAC1B,KAAK,CAAC,QAAQ,IAAI,IAAI;gBACtB,KAAK,CAAC,QAAQ,IAAI,KAAK;gBACvB,KAAK,CAAC,IAAI,IAAI,KAAK;gBACnB,KAAK,CAAC,UAAU,IAAI,IAAI;gBACxB,KAAK,CAAC,SAAS,IAAI,IAAI;gBACvB,KAAK,CAAC,QAAQ,IAAI,IAAI;gBACtB,OAAO,EAAE,cAAc,IAAI,IAAI;aAC/B,CACD,CAAC;YAEF,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC9B,kDAAkD;gBAClD,GAAG,CAAC,0DAA0D,EAAE,GAAG,CAAC,CAAC;gBACrE,OAAO,GAAG,CAAC;YACZ,CAAC;YAED,OAAO,IAAI,CAAC,QAAQ,CAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC;QAED,6CAA6C;QAC7C,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,GAAG,CAAC,iCAAiC,CAAC,CAAC;YAEvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,sBAAsB,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,IAAI,GAAG,CAAC;YAEzE,4BAA4B;YAC5B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,gBAAgB,IAAI,CAAC,SAAS;;;;;;;qBAOb,sBAAsB;gBACrC,CAAC,CAAC,aAAa,IAAI,CAAC,SAAS,sCAAsC;gBACnE,CAAC,CAAC,sBAAsB;;;;;;;;iBAQb,EACb;gBACC,KAAK,CAAC,IAAI;gBACV,KAAK,CAAC,QAAQ;gBACd,KAAK,CAAC,SAAS,IAAI,IAAI;gBACvB,KAAK,CAAC,IAAI;gBACV,KAAK,CAAC,cAAc,IAAI,IAAI;gBAC5B,KAAK,CAAC,cAAc,IAAI,IAAI;gBAC5B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;gBAC1B,KAAK,CAAC,QAAQ,IAAI,IAAI;gBACtB,KAAK,CAAC,QAAQ,IAAI,KAAK;gBACvB,KAAK,CAAC,IAAI,IAAI,KAAK;gBACnB,OAAO,EAAE,cAAc,IAAI,IAAI;aAC/B,CACD,CAAC;YAEF,OAAO,IAAI,CAAC,QAAQ,CAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC;QAED,2BAA2B;QAC3B,IAAI,MAAM,EAAE,CAAC;YACZ,GAAG,CAAC,uCAAuC,CAAC,CAAC;YAE7C,sCAAsC;YACtC,MAAM,UAAU,GAAa,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,UAAU,GAAG,CAAC,CAAC;YAEnB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnD,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC7B,2CAA2C;oBAC3C,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;oBAClC,UAAU,CAAC,IAAI,CAAC,WAAW,QAAQ,QAAQ,UAAU,EAAE,EAAE,CAAC,CAAC;oBAC3D,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC5B,CAAC;qBAAM,CAAC;oBACP,wCAAwC;oBACxC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;oBAChE,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,OAAO,UAAU,EAAE,EAAE,CAAC,CAAC;oBACpD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpB,CAAC;YACF,CAAC;YAED,yBAAyB;YACzB,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAC3C,kBAAkB,IAAI,CAAC,SAAS,WAAW,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAC7E,MAAM,CACN,CAAC;YAEF,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpC,gBAAgB;gBAChB,IAAI,UAAU,EAAE,UAAU,EAAE,CAAC;oBAC5B,wCAAwC;oBACxC,OAAO,IAAI,CAAC,QAAQ,CAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,CAAC;gBAED,yBAAyB;gBACzB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACzC,WAAW,IAAI,CAAC,SAAS;wBACN,UAAU;wBACV,UAAU,GAAG,CAAC;iBACrB,UAAU,GAAG,CAAC;4BACH,UAAU,GAAG,CAAC;4BACd,UAAU,GAAG,CAAC;iBACzB,UAAU,GAAG,CAAC;sBACT,UAAU,GAAG,CAAC;qBACf,UAAU,GAAG,CAAC;iBAClB,UAAU,GAAG,CAAC;6BACF,UAAU,GAAG,CAAC;cAC7B,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;kBACpB,EACb;oBACC,GAAG,MAAM;oBACT,KAAK,CAAC,QAAQ;oBACd,KAAK,CAAC,SAAS,IAAI,IAAI;oBACvB,KAAK,CAAC,IAAI;oBACV,KAAK,CAAC,cAAc,IAAI,IAAI;oBAC5B,KAAK,CAAC,cAAc,IAAI,IAAI;oBAC5B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;oBAC1B,KAAK,CAAC,QAAQ,IAAI,IAAI;oBACtB,KAAK,CAAC,QAAQ,IAAI,KAAK;oBACvB,KAAK,CAAC,IAAI,IAAI,KAAK;oBACnB,OAAO,EAAE,cAAc,IAAI,IAAI;iBAC/B,CACD,CAAC;gBAEF,OAAO,IAAI,CAAC,QAAQ,CAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAClD,CAAC;QACF,CAAC;QAED,iBAAiB;QACjB,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,gBAAgB,IAAI,CAAC,SAAS;;;;gBAIjB,EACb;YACC,KAAK,CAAC,IAAI;YACV,KAAK,CAAC,QAAQ;YACd,KAAK,CAAC,SAAS,IAAI,IAAI;YACvB,KAAK,CAAC,IAAI;YACV,KAAK,CAAC,cAAc,IAAI,IAAI;YAC5B,KAAK,CAAC,cAAc,IAAI,IAAI;YAC5B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;YAC1B,KAAK,CAAC,QAAQ,IAAI,IAAI;YACtB,KAAK,CAAC,QAAQ,IAAI,KAAK;YACvB,KAAK,CAAC,IAAI,IAAI,KAAK;YACnB,OAAO,EAAE,cAAc,IAAI,IAAI;SAC/B,CACD,CAAC;QAEF,OAAO,IAAI,CAAC,QAAQ,CAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;CACD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Pool } from 'pg';
|
|
2
|
+
import type { JobNotification, NotificationChannelConfig } from 'agenda';
|
|
3
|
+
import { BaseNotificationChannel } from 'agenda';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for PostgresNotificationChannel
|
|
6
|
+
*/
|
|
7
|
+
export interface PostgresNotificationChannelConfig extends NotificationChannelConfig {
|
|
8
|
+
/** PostgreSQL connection pool (shared with repository) */
|
|
9
|
+
pool?: Pool;
|
|
10
|
+
/** PostgreSQL connection string (if not sharing pool) */
|
|
11
|
+
connectionString?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* PostgreSQL notification channel using LISTEN/NOTIFY
|
|
15
|
+
*
|
|
16
|
+
* This implementation uses PostgreSQL's built-in pub/sub mechanism
|
|
17
|
+
* for real-time job notifications across multiple processes.
|
|
18
|
+
*/
|
|
19
|
+
export declare class PostgresNotificationChannel extends BaseNotificationChannel {
|
|
20
|
+
private pool?;
|
|
21
|
+
private ownPool;
|
|
22
|
+
private connectionString?;
|
|
23
|
+
private listenClient?;
|
|
24
|
+
constructor(config?: PostgresNotificationChannelConfig);
|
|
25
|
+
/**
|
|
26
|
+
* Set the pool (used when created by PostgresBackend)
|
|
27
|
+
*/
|
|
28
|
+
setPool(pool: Pool): void;
|
|
29
|
+
connect(): Promise<void>;
|
|
30
|
+
private handleConnectionLoss;
|
|
31
|
+
disconnect(): Promise<void>;
|
|
32
|
+
publish(notification: JobNotification): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Serialize notification to JSON string for NOTIFY payload
|
|
35
|
+
*/
|
|
36
|
+
private serializeNotification;
|
|
37
|
+
/**
|
|
38
|
+
* Parse notification from JSON string received via LISTEN
|
|
39
|
+
*/
|
|
40
|
+
private parseNotification;
|
|
41
|
+
}
|