Skip to content

Commit c03e3b9

Browse files
author
Uroš Marolt
committed
bugfix for pg promise named parameters
1 parent e93e16d commit c03e3b9

File tree

3 files changed

+60
-7
lines changed

3 files changed

+60
-7
lines changed

services/apps/data_sink_worker/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"format": "prettier --write \"src/**/*.ts\"",
1515
"format-check": "prettier --check .",
1616
"tsc-check": "tsc --noEmit",
17-
"script:restart-failed-results": "node -r tsconfig-paths/register -r ts-node/register src/bin/restart-failed-results.ts --transpile-only"
17+
"script:restart-failed-results": "node -r tsconfig-paths/register -r ts-node/register src/bin/restart-failed-results.ts --transpile-only",
18+
"script:restart-result": "node -r tsconfig-paths/register -r ts-node/register src/bin/restart-result.ts --transpile-only"
1819
},
1920
"dependencies": {
2021
"@crowd/common": "file:../../libs/common",
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { DB_CONFIG, SQS_CONFIG } from '@/conf'
2+
import DataSinkRepository from '@/repo/dataSink.repo'
3+
import { DbStore, getDbConnection } from '@crowd/database'
4+
import { getServiceLogger } from '@crowd/logging'
5+
import { DataSinkWorkerEmitter, getSqsClient } from '@crowd/sqs'
6+
import { ProcessIntegrationResultQueueMessage } from '@crowd/types'
7+
8+
const log = getServiceLogger()
9+
10+
const processArguments = process.argv.slice(3)
11+
12+
if (processArguments.length !== 1) {
13+
log.error('Expected 1 argument: resultId')
14+
process.exit(1)
15+
}
16+
17+
const resultId = processArguments[0]
18+
19+
setImmediate(async () => {
20+
const sqsClient = getSqsClient(SQS_CONFIG())
21+
const emitter = new DataSinkWorkerEmitter(sqsClient, log)
22+
await emitter.init()
23+
24+
const dbConnection = getDbConnection(DB_CONFIG())
25+
const store = new DbStore(log, dbConnection)
26+
27+
const repo = new DataSinkRepository(store, log)
28+
29+
const result = await repo.getResultInfo(resultId)
30+
if (!result) {
31+
log.error(`Result ${resultId} not found!`)
32+
process.exit(1)
33+
} else {
34+
await emitter.sendMessage(
35+
`results-${result.tenantId}-${result.platform}`,
36+
new ProcessIntegrationResultQueueMessage(result.id),
37+
)
38+
}
39+
})

services/libs/database/src/repoBase.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,15 @@ export abstract class RepositoryBase<TRepo extends RepositoryBase<TRepo>> extend
144144
const obj: any = {}
145145

146146
for (const column of columnSet.columns) {
147-
obj[column.name] =
148-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
149-
(entity as any)[column.name] !== undefined
150-
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
151-
(entity as any)[column.name]
152-
: undefined
147+
let value = (entity as unknown as Record<string, unknown>)[column.name]
148+
if (value !== undefined) {
149+
if (typeof value === 'string') {
150+
value = this.escapeString(value)
151+
}
152+
obj[column.name] = value
153+
} else {
154+
obj[column.name] = undefined
155+
}
153156
}
154157

155158
return obj
@@ -165,4 +168,14 @@ export abstract class RepositoryBase<TRepo extends RepositoryBase<TRepo>> extend
165168
)
166169
}
167170
}
171+
172+
public static escapeString(str: string): string {
173+
// need to escape $(), $<>, $[] and $// and prepend with another dollar sign
174+
// to avoid pg-promise named parameter parsing
175+
return str
176+
.replace(/(\$[{])/g, '$$$$1') // Replace ${ with $${ to escape it
177+
.replace(/(\$[[(])/g, '$$$$1') // Replace $[ with $$[ to escape it
178+
.replace(/(\$[<])/g, '$$$$1') // Replace $< with $$< to escape it
179+
.replace(/(\$[\\/])/g, '$$$$1') // Replace $/ with $$/ to escape it;
180+
}
168181
}

0 commit comments

Comments
 (0)