Skip to content

Commit 5d986dc

Browse files
committed
Added typing for update queries and extracted dedicated methods
1 parent 3a679e5 commit 5d986dc

File tree

3 files changed

+69
-48
lines changed

3 files changed

+69
-48
lines changed

src/packages/pongo/src/main/typing.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,16 @@ export type PongoFilterOperator<T> = {
3737
$nin?: T[];
3838
};
3939

40+
export type $set<T> = Partial<T>;
41+
export type $unset<T> = { [P in keyof T]?: '' };
42+
export type $inc<T> = { [P in keyof T]?: number };
43+
export type $push<T> = { [P in keyof T]?: T[P] };
44+
4045
export type PongoUpdate<T> = {
4146
$set?: Partial<T>;
42-
$unset?: { [P in keyof T]?: '' };
43-
$inc?: { [P in keyof T]?: number };
44-
$push?: { [P in keyof T]?: T[P] };
47+
$unset?: $unset<T>;
48+
$inc?: $inc<T>;
49+
$push?: $push<T>;
4550
};
4651

4752
export interface PongoInsertOneResult {

src/packages/pongo/src/postgres/client.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { executeSQL } from './execute';
1313
import { constructFilterQuery } from './filter';
1414
import { endPool, getPool } from './pool';
1515
import { sql } from './sql';
16-
import { constructUpdateQuery } from './update';
16+
import { buildUpdateQuery } from './update';
1717

1818
export const postgresClient = (
1919
connectionString: string,
@@ -69,7 +69,7 @@ export const postgresCollection = <T>(
6969
await createCollection;
7070

7171
const filterQuery = constructFilterQuery(filter);
72-
const updateQuery = constructUpdateQuery(update);
72+
const updateQuery = buildUpdateQuery(update);
7373

7474
const result = await executeSQL(
7575
pool,
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,65 @@
1-
import format from 'pg-format';
2-
import type { PongoUpdate } from '../../main';
3-
4-
export const constructUpdateQuery = <T>(update: PongoUpdate<T>): string => {
5-
let updateQuery = 'data';
6-
7-
if ('$set' in update) {
8-
const setUpdate = update.$set!;
9-
updateQuery = format(
10-
'jsonb_set(%s, %L, data || %L)',
11-
updateQuery,
12-
'{}',
13-
JSON.stringify(setUpdate),
14-
);
15-
}
1+
import type { $inc, $push, $set, $unset, PongoUpdate } from '../../main';
2+
import { sql, type SQL } from '../sql';
163

17-
if ('$unset' in update) {
18-
const unsetUpdate = Object.keys(update.$unset!);
19-
updateQuery = format('%s - %L', updateQuery, unsetUpdate.join(', '));
20-
}
4+
export const buildUpdateQuery = <T>(update: PongoUpdate<T>): SQL => {
5+
let updateQuery = sql('data');
216

22-
if ('$inc' in update) {
23-
const incUpdate = update.$inc!;
24-
for (const [key, value] of Object.entries(incUpdate)) {
25-
updateQuery = format(
26-
"jsonb_set(%s, '{%s}', to_jsonb((data->>'%s')::numeric + %L))",
27-
updateQuery,
28-
key,
29-
key,
30-
value,
31-
);
32-
}
33-
}
7+
if ('$set' in update && update.$set)
8+
updateQuery = buildSetQuery(update.$set, updateQuery);
349

35-
if ('$push' in update) {
36-
const pushUpdate = update.$push!;
37-
for (const [key, value] of Object.entries(pushUpdate)) {
38-
updateQuery = format(
39-
"jsonb_set(%s, '{%s}', (COALESCE(data->'%s', '[]'::jsonb) || '[%s]'::jsonb))",
40-
updateQuery,
41-
key,
42-
key,
43-
JSON.stringify(value),
44-
);
45-
}
46-
}
10+
if ('$unset' in update && update.$unset)
11+
updateQuery = buildUnsetQuery(update.$unset, updateQuery);
12+
13+
if ('$inc' in update && update.$inc)
14+
updateQuery = buildIncQuery(update.$inc, updateQuery);
15+
16+
if ('$push' in update && update.$push)
17+
updateQuery = buildPushQuery(update.$push, updateQuery);
4718

4819
return updateQuery;
4920
};
21+
22+
export const buildSetQuery = <T>(set: $set<T>, currentUpdateQuery: SQL): SQL =>
23+
sql(
24+
'jsonb_set(%s, %L, data || %L)',
25+
currentUpdateQuery,
26+
'{}',
27+
JSON.stringify(set),
28+
);
29+
30+
export const buildUnsetQuery = <T>(
31+
unset: $unset<T>,
32+
currentUpdateQuery: SQL,
33+
): SQL => sql('%s - %L', currentUpdateQuery, Object.keys(unset).join(', '));
34+
35+
export const buildIncQuery = <T>(
36+
inc: $inc<T>,
37+
currentUpdateQuery: SQL,
38+
): SQL => {
39+
for (const [key, value] of Object.entries(inc)) {
40+
currentUpdateQuery = sql(
41+
"jsonb_set(%s, '{%s}', to_jsonb((data->>'%s')::numeric + %L))",
42+
currentUpdateQuery,
43+
key,
44+
key,
45+
value,
46+
);
47+
}
48+
return currentUpdateQuery;
49+
};
50+
51+
export const buildPushQuery = <T>(
52+
push: $push<T>,
53+
currentUpdateQuery: SQL,
54+
): SQL => {
55+
for (const [key, value] of Object.entries(push)) {
56+
currentUpdateQuery = sql(
57+
"jsonb_set(%s, '{%s}', (COALESCE(data->'%s', '[]'::jsonb) || '[%s]'::jsonb))",
58+
currentUpdateQuery,
59+
key,
60+
key,
61+
JSON.stringify(value),
62+
);
63+
}
64+
return currentUpdateQuery;
65+
};

0 commit comments

Comments
 (0)