@sprucelabs/postgres-data-store 3.0.1 → 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 __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
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 = __importDefault(require("./QueryBuilder"));
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,
@@ -183,11 +203,11 @@ class PostgresDatabase {
183
203
  }
184
204
  async connect() {
185
205
  var _a;
186
- const client = new pg_1.Client({
206
+ this.client = new pg_1.Client({
187
207
  connectionString: this.connectionString,
188
208
  });
189
209
  try {
190
- await client.connect();
210
+ await this.client.connect();
191
211
  }
192
212
  catch (err) {
193
213
  const message = err.message;
@@ -210,7 +230,6 @@ class PostgresDatabase {
210
230
  originalError: err,
211
231
  });
212
232
  }
213
- this.client = client;
214
233
  }
215
234
  async getUniqueIndexes(collectionName) {
216
235
  const isUnique = true;
@@ -312,7 +331,7 @@ class PostgresDatabase {
312
331
  const parts = field.split('.');
313
332
  return `(${parts[0]}->>'${parts[1]}')`;
314
333
  }
315
- return field;
334
+ return (0, QueryBuilder_1.quote)(field);
316
335
  }
317
336
  generateIndexName(collection, fields) {
318
337
  return `${collection}_${fields
@@ -324,7 +343,7 @@ class PostgresDatabase {
324
343
  }
325
344
  isConnected() {
326
345
  //@ts-ignore
327
- return this.client._connected && !this.client._ending;
346
+ return this.client ? this.client._connected && !this.client._ending : false;
328
347
  }
329
348
  parseIndexViolatedForFieldsAndValues(input) {
330
349
  const regex = /Key \((.*)\)=\((.*)\) already exists\./;
@@ -36,3 +36,4 @@ export interface BuiltQuery {
36
36
  sql: string;
37
37
  values: unknown[];
38
38
  }
39
+ export declare function quote(f: string): string;
@@ -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(`${k} IN (${value.$in
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(`${k} ~* $${++placeholderCount}`);
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(`${k} <= $${++placeholderCount}`);
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(`${k} < $${++placeholderCount}`);
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(`${k} >= $${++placeholderCount}`);
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(`${k} > $${++placeholderCount}`);
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(`${k} ${v === null ? 'IS NOT NULL' : `!= $${++placeholderCount}`}`);
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(`${k} IS NULL`);
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 = `${k} || jsonb_build_object('${prop}', ${placeholder}::text)`;
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.join(', ')}) VALUES ${placeholders.join(', ')}`;
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) => `${s.field} ${s.direction.toUpperCase()}`);
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,
@@ -226,11 +226,11 @@ export default class PostgresDatabase {
226
226
  connect() {
227
227
  var _a;
228
228
  return __awaiter(this, void 0, void 0, function* () {
229
- const client = new Client({
229
+ this.client = new Client({
230
230
  connectionString: this.connectionString,
231
231
  });
232
232
  try {
233
- yield client.connect();
233
+ yield this.client.connect();
234
234
  }
235
235
  catch (err) {
236
236
  const message = err.message;
@@ -253,7 +253,6 @@ export default class PostgresDatabase {
253
253
  originalError: err,
254
254
  });
255
255
  }
256
- this.client = client;
257
256
  });
258
257
  }
259
258
  getUniqueIndexes(collectionName) {
@@ -372,7 +371,7 @@ export default class PostgresDatabase {
372
371
  const parts = field.split('.');
373
372
  return `(${parts[0]}->>'${parts[1]}')`;
374
373
  }
375
- return field;
374
+ return quote(field);
376
375
  }
377
376
  generateIndexName(collection, fields) {
378
377
  return `${collection}_${fields
@@ -386,7 +385,7 @@ export default class PostgresDatabase {
386
385
  }
387
386
  isConnected() {
388
387
  //@ts-ignore
389
- return this.client._connected && !this.client._ending;
388
+ return this.client ? this.client._connected && !this.client._ending : false;
390
389
  }
391
390
  parseIndexViolatedForFieldsAndValues(input) {
392
391
  const regex = /Key \((.*)\)=\((.*)\) already exists\./;
@@ -36,3 +36,4 @@ export interface BuiltQuery {
36
36
  sql: string;
37
37
  values: unknown[];
38
38
  }
39
+ export declare function quote(f: string): string;
@@ -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(`${k} IN (${value.$in
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(`${k} ~* $${++placeholderCount}`);
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(`${k} <= $${++placeholderCount}`);
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(`${k} < $${++placeholderCount}`);
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(`${k} >= $${++placeholderCount}`);
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(`${k} > $${++placeholderCount}`);
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(`${k} ${v === null ? 'IS NOT NULL' : `!= $${++placeholderCount}`}`);
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(`${k} IS NULL`);
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 = `${k} || jsonb_build_object('${prop}', ${placeholder}::text)`;
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.join(', ')}) VALUES ${placeholders.join(', ')}`;
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) => `${s.field} ${s.direction.toUpperCase()}`);
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
@@ -22,7 +22,7 @@
22
22
  "sprucebot",
23
23
  "sprucelabs"
24
24
  ],
25
- "version": "3.0.1",
25
+ "version": "3.0.3",
26
26
  "scripts": {
27
27
  "build.ci": "yarn build.tsc && yarn build.resolve-paths && yarn lint",
28
28
  "build.dev": "yarn build.tsc --sourceMap ; yarn resolve-paths.lint",