@sprucelabs/postgres-data-store 3.0.2 → 3.0.3
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.
|
@@ -1,12 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
4
24
|
};
|
|
5
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
26
|
const data_stores_1 = require("@sprucelabs/data-stores");
|
|
7
27
|
const schema_1 = require("@sprucelabs/schema");
|
|
8
28
|
const pg_1 = require("pg");
|
|
9
|
-
const QueryBuilder_1 =
|
|
29
|
+
const QueryBuilder_1 = __importStar(require("./QueryBuilder"));
|
|
10
30
|
class PostgresDatabase {
|
|
11
31
|
constructor(connectionString) {
|
|
12
32
|
this.idCount = 1;
|
|
@@ -172,7 +192,7 @@ class PostgresDatabase {
|
|
|
172
192
|
const { fields, values } = parsed;
|
|
173
193
|
throw new data_stores_1.DataStoresError({
|
|
174
194
|
code: 'DUPLICATE_RECORD',
|
|
175
|
-
duplicateFields: fields,
|
|
195
|
+
duplicateFields: fields.map((f) => f.replace(/"/g, '')),
|
|
176
196
|
duplicateValues: values,
|
|
177
197
|
collectionName: tableName,
|
|
178
198
|
action,
|
|
@@ -311,7 +331,7 @@ class PostgresDatabase {
|
|
|
311
331
|
const parts = field.split('.');
|
|
312
332
|
return `(${parts[0]}->>'${parts[1]}')`;
|
|
313
333
|
}
|
|
314
|
-
return field;
|
|
334
|
+
return (0, QueryBuilder_1.quote)(field);
|
|
315
335
|
}
|
|
316
336
|
generateIndexName(collection, fields) {
|
|
317
337
|
return `${collection}_${fields
|
package/build/QueryBuilder.d.ts
CHANGED
package/build/QueryBuilder.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.quote = void 0;
|
|
3
4
|
class QueryBuilder {
|
|
4
5
|
constructor() { }
|
|
5
6
|
static Builder() {
|
|
@@ -44,34 +45,34 @@ class QueryBuilder {
|
|
|
44
45
|
let value = query[k];
|
|
45
46
|
if (value === null || value === void 0 ? void 0 : value.$in) {
|
|
46
47
|
values.push(...value.$in.map((v) => this.normalizeValue(v)));
|
|
47
|
-
set.push(
|
|
48
|
+
set.push(`"${k}" IN (${value.$in
|
|
48
49
|
.map(() => `$${++placeholderCount}`)
|
|
49
50
|
.join(', ')})`);
|
|
50
51
|
}
|
|
51
52
|
else if (value === null || value === void 0 ? void 0 : value.$regex) {
|
|
52
53
|
values.push(this.normalizeValue(value.$regex));
|
|
53
|
-
set.push(
|
|
54
|
+
set.push(`"${k}" ~* $${++placeholderCount}`);
|
|
54
55
|
}
|
|
55
56
|
else if (value === null || value === void 0 ? void 0 : value.$lte) {
|
|
56
57
|
values.push(this.normalizeValue(value.$lte));
|
|
57
|
-
set.push(
|
|
58
|
+
set.push(`"${k}" <= $${++placeholderCount}`);
|
|
58
59
|
}
|
|
59
60
|
else if (value === null || value === void 0 ? void 0 : value.$lt) {
|
|
60
61
|
values.push(this.normalizeValue(value.$lt));
|
|
61
|
-
set.push(
|
|
62
|
+
set.push(`"${k}" < $${++placeholderCount}`);
|
|
62
63
|
}
|
|
63
64
|
else if (value === null || value === void 0 ? void 0 : value.$gte) {
|
|
64
65
|
values.push(this.normalizeValue(value.$gte));
|
|
65
|
-
set.push(
|
|
66
|
+
set.push(`"${k}" >= $${++placeholderCount}`);
|
|
66
67
|
}
|
|
67
68
|
else if (value === null || value === void 0 ? void 0 : value.$gt) {
|
|
68
69
|
values.push(this.normalizeValue(value.$gt));
|
|
69
|
-
set.push(
|
|
70
|
+
set.push(`"${k}" > $${++placeholderCount}`);
|
|
70
71
|
}
|
|
71
72
|
else if (typeof (value === null || value === void 0 ? void 0 : value.$ne) !== 'undefined') {
|
|
72
73
|
const v = value.$ne;
|
|
73
74
|
v !== null && values.push(this.normalizeValue(v));
|
|
74
|
-
set.push(
|
|
75
|
+
set.push(`"${k}" ${v === null ? 'IS NOT NULL' : `!= $${++placeholderCount}`}`);
|
|
75
76
|
}
|
|
76
77
|
else if (k === '$or') {
|
|
77
78
|
const { set: orWheres, values: orValues } = this.buildSetClausFor$Or(value, placeholderCount);
|
|
@@ -88,7 +89,7 @@ class QueryBuilder {
|
|
|
88
89
|
set.push(...sub.set);
|
|
89
90
|
}
|
|
90
91
|
else if (value === null || value === undefined) {
|
|
91
|
-
set.push(
|
|
92
|
+
set.push(`"${k}" IS NULL`);
|
|
92
93
|
}
|
|
93
94
|
else {
|
|
94
95
|
placeholderCount++;
|
|
@@ -104,11 +105,11 @@ class QueryBuilder {
|
|
|
104
105
|
}
|
|
105
106
|
else {
|
|
106
107
|
k = field;
|
|
107
|
-
placeholder =
|
|
108
|
+
placeholder = `"${k}" || jsonb_build_object('${prop}', ${placeholder}::text)`;
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
values.push(this.normalizeValue(value));
|
|
111
|
-
set.push(`${k} = ${placeholder}`);
|
|
112
|
+
set.push(`${quote(k)} = ${placeholder}`);
|
|
112
113
|
}
|
|
113
114
|
});
|
|
114
115
|
return { set, values };
|
|
@@ -136,7 +137,9 @@ class QueryBuilder {
|
|
|
136
137
|
}
|
|
137
138
|
createWithoutReturning(tableName, records) {
|
|
138
139
|
const { fields, placeholders, values } = this.splitRecordsIntoFieldsPlaceholdersAndValues(records);
|
|
139
|
-
const sql = `INSERT INTO ${this.buildTableName(tableName)} (${fields
|
|
140
|
+
const sql = `INSERT INTO ${this.buildTableName(tableName)} (${fields
|
|
141
|
+
.map((f) => `"${f}"`)
|
|
142
|
+
.join(', ')}) VALUES ${placeholders.join(', ')}`;
|
|
140
143
|
return { sql, values };
|
|
141
144
|
}
|
|
142
145
|
splitRecordsIntoFieldsPlaceholdersAndValues(records) {
|
|
@@ -180,7 +183,7 @@ class QueryBuilder {
|
|
|
180
183
|
}
|
|
181
184
|
optionallyBuildSort(sort) {
|
|
182
185
|
if (sort) {
|
|
183
|
-
const sortSpecs = sort.map((s) =>
|
|
186
|
+
const sortSpecs = sort.map((s) => `"${s.field}" ${s.direction.toUpperCase()}`);
|
|
184
187
|
return ` ORDER BY ${sortSpecs.join(', ')}`;
|
|
185
188
|
}
|
|
186
189
|
return '';
|
|
@@ -198,7 +201,7 @@ class QueryBuilder {
|
|
|
198
201
|
return '';
|
|
199
202
|
}
|
|
200
203
|
buildColumnListFromIncludeFields(includeFields) {
|
|
201
|
-
return !includeFields ? '*' : includeFields.join(', ');
|
|
204
|
+
return !includeFields ? '*' : includeFields.map((f) => quote(f)).join(', ');
|
|
202
205
|
}
|
|
203
206
|
update(tableName, query, updates, shouldReturnUpdatedRecords = true) {
|
|
204
207
|
const { set: set, values } = this.buildSetClause({
|
|
@@ -245,3 +248,7 @@ class QueryBuilder {
|
|
|
245
248
|
}
|
|
246
249
|
}
|
|
247
250
|
exports.default = QueryBuilder;
|
|
251
|
+
function quote(f) {
|
|
252
|
+
return f.includes(' ') ? f : `"${f}"`;
|
|
253
|
+
}
|
|
254
|
+
exports.quote = quote;
|
|
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { DataStoresError, } from '@sprucelabs/data-stores';
|
|
11
11
|
import { assertOptions } from '@sprucelabs/schema';
|
|
12
12
|
import { Client } from 'pg';
|
|
13
|
-
import QueryBuilder from './QueryBuilder.js';
|
|
13
|
+
import QueryBuilder, { quote } from './QueryBuilder.js';
|
|
14
14
|
export default class PostgresDatabase {
|
|
15
15
|
constructor(connectionString) {
|
|
16
16
|
this.idCount = 1;
|
|
@@ -213,7 +213,7 @@ export default class PostgresDatabase {
|
|
|
213
213
|
const { fields, values } = parsed;
|
|
214
214
|
throw new DataStoresError({
|
|
215
215
|
code: 'DUPLICATE_RECORD',
|
|
216
|
-
duplicateFields: fields,
|
|
216
|
+
duplicateFields: fields.map((f) => f.replace(/"/g, '')),
|
|
217
217
|
duplicateValues: values,
|
|
218
218
|
collectionName: tableName,
|
|
219
219
|
action,
|
|
@@ -371,7 +371,7 @@ export default class PostgresDatabase {
|
|
|
371
371
|
const parts = field.split('.');
|
|
372
372
|
return `(${parts[0]}->>'${parts[1]}')`;
|
|
373
373
|
}
|
|
374
|
-
return field;
|
|
374
|
+
return quote(field);
|
|
375
375
|
}
|
|
376
376
|
generateIndexName(collection, fields) {
|
|
377
377
|
return `${collection}_${fields
|
|
@@ -42,34 +42,34 @@ export default class QueryBuilder {
|
|
|
42
42
|
let value = query[k];
|
|
43
43
|
if (value === null || value === void 0 ? void 0 : value.$in) {
|
|
44
44
|
values.push(...value.$in.map((v) => this.normalizeValue(v)));
|
|
45
|
-
set.push(
|
|
45
|
+
set.push(`"${k}" IN (${value.$in
|
|
46
46
|
.map(() => `$${++placeholderCount}`)
|
|
47
47
|
.join(', ')})`);
|
|
48
48
|
}
|
|
49
49
|
else if (value === null || value === void 0 ? void 0 : value.$regex) {
|
|
50
50
|
values.push(this.normalizeValue(value.$regex));
|
|
51
|
-
set.push(
|
|
51
|
+
set.push(`"${k}" ~* $${++placeholderCount}`);
|
|
52
52
|
}
|
|
53
53
|
else if (value === null || value === void 0 ? void 0 : value.$lte) {
|
|
54
54
|
values.push(this.normalizeValue(value.$lte));
|
|
55
|
-
set.push(
|
|
55
|
+
set.push(`"${k}" <= $${++placeholderCount}`);
|
|
56
56
|
}
|
|
57
57
|
else if (value === null || value === void 0 ? void 0 : value.$lt) {
|
|
58
58
|
values.push(this.normalizeValue(value.$lt));
|
|
59
|
-
set.push(
|
|
59
|
+
set.push(`"${k}" < $${++placeholderCount}`);
|
|
60
60
|
}
|
|
61
61
|
else if (value === null || value === void 0 ? void 0 : value.$gte) {
|
|
62
62
|
values.push(this.normalizeValue(value.$gte));
|
|
63
|
-
set.push(
|
|
63
|
+
set.push(`"${k}" >= $${++placeholderCount}`);
|
|
64
64
|
}
|
|
65
65
|
else if (value === null || value === void 0 ? void 0 : value.$gt) {
|
|
66
66
|
values.push(this.normalizeValue(value.$gt));
|
|
67
|
-
set.push(
|
|
67
|
+
set.push(`"${k}" > $${++placeholderCount}`);
|
|
68
68
|
}
|
|
69
69
|
else if (typeof (value === null || value === void 0 ? void 0 : value.$ne) !== 'undefined') {
|
|
70
70
|
const v = value.$ne;
|
|
71
71
|
v !== null && values.push(this.normalizeValue(v));
|
|
72
|
-
set.push(
|
|
72
|
+
set.push(`"${k}" ${v === null ? 'IS NOT NULL' : `!= $${++placeholderCount}`}`);
|
|
73
73
|
}
|
|
74
74
|
else if (k === '$or') {
|
|
75
75
|
const { set: orWheres, values: orValues } = this.buildSetClausFor$Or(value, placeholderCount);
|
|
@@ -86,7 +86,7 @@ export default class QueryBuilder {
|
|
|
86
86
|
set.push(...sub.set);
|
|
87
87
|
}
|
|
88
88
|
else if (value === null || value === undefined) {
|
|
89
|
-
set.push(
|
|
89
|
+
set.push(`"${k}" IS NULL`);
|
|
90
90
|
}
|
|
91
91
|
else {
|
|
92
92
|
placeholderCount++;
|
|
@@ -102,11 +102,11 @@ export default class QueryBuilder {
|
|
|
102
102
|
}
|
|
103
103
|
else {
|
|
104
104
|
k = field;
|
|
105
|
-
placeholder =
|
|
105
|
+
placeholder = `"${k}" || jsonb_build_object('${prop}', ${placeholder}::text)`;
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
values.push(this.normalizeValue(value));
|
|
109
|
-
set.push(`${k} = ${placeholder}`);
|
|
109
|
+
set.push(`${quote(k)} = ${placeholder}`);
|
|
110
110
|
}
|
|
111
111
|
});
|
|
112
112
|
return { set, values };
|
|
@@ -134,7 +134,9 @@ export default class QueryBuilder {
|
|
|
134
134
|
}
|
|
135
135
|
createWithoutReturning(tableName, records) {
|
|
136
136
|
const { fields, placeholders, values } = this.splitRecordsIntoFieldsPlaceholdersAndValues(records);
|
|
137
|
-
const sql = `INSERT INTO ${this.buildTableName(tableName)} (${fields
|
|
137
|
+
const sql = `INSERT INTO ${this.buildTableName(tableName)} (${fields
|
|
138
|
+
.map((f) => `"${f}"`)
|
|
139
|
+
.join(', ')}) VALUES ${placeholders.join(', ')}`;
|
|
138
140
|
return { sql, values };
|
|
139
141
|
}
|
|
140
142
|
splitRecordsIntoFieldsPlaceholdersAndValues(records) {
|
|
@@ -178,7 +180,7 @@ export default class QueryBuilder {
|
|
|
178
180
|
}
|
|
179
181
|
optionallyBuildSort(sort) {
|
|
180
182
|
if (sort) {
|
|
181
|
-
const sortSpecs = sort.map((s) =>
|
|
183
|
+
const sortSpecs = sort.map((s) => `"${s.field}" ${s.direction.toUpperCase()}`);
|
|
182
184
|
return ` ORDER BY ${sortSpecs.join(', ')}`;
|
|
183
185
|
}
|
|
184
186
|
return '';
|
|
@@ -196,7 +198,7 @@ export default class QueryBuilder {
|
|
|
196
198
|
return '';
|
|
197
199
|
}
|
|
198
200
|
buildColumnListFromIncludeFields(includeFields) {
|
|
199
|
-
return !includeFields ? '*' : includeFields.join(', ');
|
|
201
|
+
return !includeFields ? '*' : includeFields.map((f) => quote(f)).join(', ');
|
|
200
202
|
}
|
|
201
203
|
update(tableName, query, updates, shouldReturnUpdatedRecords = true) {
|
|
202
204
|
const { set: set, values } = this.buildSetClause({
|
|
@@ -242,3 +244,6 @@ export default class QueryBuilder {
|
|
|
242
244
|
};
|
|
243
245
|
}
|
|
244
246
|
}
|
|
247
|
+
export function quote(f) {
|
|
248
|
+
return f.includes(' ') ? f : `"${f}"`;
|
|
249
|
+
}
|
package/package.json
CHANGED