pogi 2.10.1 → 3.0.0-beta
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/.vscode/launch.json +47 -15
- package/CHANGELOG.md +20 -0
- package/docs/API/PgDb.md +25 -0
- package/docs/notification.md +19 -0
- package/jest.config.js +23 -0
- package/lib/bin/generateInterface.js +2 -2
- package/lib/bin/generateInterface.js.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/pgConverters.d.ts +2 -0
- package/lib/pgConverters.js +27 -10
- package/lib/pgConverters.js.map +1 -1
- package/lib/pgDb.d.ts +15 -6
- package/lib/pgDb.js +263 -67
- package/lib/pgDb.js.map +1 -1
- package/lib/pgTable.js +7 -7
- package/lib/pgTable.js.map +1 -1
- package/lib/pgUtils.d.ts +3 -1
- package/lib/pgUtils.js +61 -23
- package/lib/pgUtils.js.map +1 -1
- package/lib/queryAble.d.ts +16 -1
- package/lib/queryAble.js +124 -56
- package/lib/queryAble.js.map +1 -1
- package/lib/src/bin/generateInterface.d.ts +1 -0
- package/lib/src/bin/generateInterface.js +53 -0
- package/lib/src/bin/generateInterface.js.map +1 -0
- package/lib/src/connectionOptions.d.ts +34 -0
- package/lib/src/connectionOptions.js +3 -0
- package/lib/src/connectionOptions.js.map +1 -0
- package/lib/src/index.d.ts +6 -0
- package/lib/src/index.js +12 -0
- package/lib/src/index.js.map +1 -0
- package/lib/src/pgConverters.d.ts +9 -0
- package/lib/src/pgConverters.js +71 -0
- package/lib/src/pgConverters.js.map +1 -0
- package/lib/src/pgConverters.test.d.ts +1 -0
- package/lib/src/pgConverters.test.js +13 -0
- package/lib/src/pgConverters.test.js.map +1 -0
- package/lib/src/pgDb.d.ts +79 -0
- package/lib/src/pgDb.js +764 -0
- package/lib/src/pgDb.js.map +1 -0
- package/lib/src/pgDb.test.d.ts +1 -0
- package/lib/src/pgDb.test.js +1126 -0
- package/lib/src/pgDb.test.js.map +1 -0
- package/lib/src/pgDbInterface.js +11 -0
- package/lib/src/pgDbInterface.js.map +1 -0
- package/lib/src/pgDbLogger.d.ts +5 -0
- package/lib/src/pgDbLogger.js +3 -0
- package/lib/src/pgDbLogger.js.map +1 -0
- package/lib/src/pgDbOperators.d.ts +113 -0
- package/lib/src/pgDbOperators.js +41 -0
- package/lib/src/pgDbOperators.js.map +1 -0
- package/lib/src/pgDbOperators.test.d.ts +1 -0
- package/lib/src/pgDbOperators.test.js +313 -0
- package/lib/src/pgDbOperators.test.js.map +1 -0
- package/lib/src/pgSchema.d.ts +17 -0
- package/lib/src/pgSchema.js +16 -0
- package/lib/src/pgSchema.js.map +1 -0
- package/lib/src/pgSchemaInterface.d.ts +12 -0
- package/lib/src/pgSchemaInterface.js +3 -0
- package/lib/src/pgSchemaInterface.js.map +1 -0
- package/lib/src/pgTable.d.ts +105 -0
- package/lib/src/pgTable.js +322 -0
- package/lib/src/pgTable.js.map +1 -0
- package/lib/src/pgTableInterface.d.ts +102 -0
- package/lib/src/pgTableInterface.js +4 -0
- package/lib/src/pgTableInterface.js.map +1 -0
- package/lib/src/pgUtils.d.ts +41 -0
- package/lib/src/pgUtils.js +282 -0
- package/lib/src/pgUtils.js.map +1 -0
- package/lib/src/queryAble.d.ts +40 -0
- package/lib/src/queryAble.js +338 -0
- package/lib/src/queryAble.js.map +1 -0
- package/lib/src/queryAbleInterface.d.ts +59 -0
- package/lib/src/queryAbleInterface.js +7 -0
- package/lib/src/queryAbleInterface.js.map +1 -0
- package/lib/src/queryWhere.d.ts +8 -0
- package/lib/src/queryWhere.js +245 -0
- package/lib/src/queryWhere.js.map +1 -0
- package/mkdocs.yml +1 -0
- package/package.json +23 -14
- package/src/bin/generateInterface.ts +2 -2
- package/src/connectionOptions.ts +46 -13
- package/src/index.d.ts +7 -0
- package/src/pgConverters.test.ts +10 -0
- package/src/pgConverters.ts +34 -22
- package/src/pgDb.test.ts +1324 -0
- package/src/pgDb.ts +321 -125
- package/src/pgDbInterface.ts +57 -0
- package/src/pgDbOperators.test.ts +478 -0
- package/src/pgDbOperators.ts +45 -22
- package/src/pgSchema.ts +10 -9
- package/src/pgSchemaInterface.ts +12 -0
- package/src/pgTable.ts +65 -97
- package/src/pgTableInterface.ts +131 -0
- package/src/pgUtils.ts +156 -42
- package/src/queryAble.ts +167 -125
- package/src/queryAbleInterface.ts +108 -0
- package/src/queryWhere.ts +42 -43
- package/{spec/resources → src/test}/init.sql +23 -0
- package/src/test/pgServiceRestartTest.ts +1500 -0
- package/{spec/resources → src/test}/throw_exception.sql +0 -0
- package/{spec/resources → src/test}/tricky.sql +0 -0
- package/{src/tsconfig.json → tsconfig.json} +9 -6
- package/spec/run.js +0 -5
- package/spec/support/jasmine.json +0 -9
- package/src/test/pgDbOperatorSpec.ts +0 -492
- package/src/test/pgDbSpec.ts +0 -994
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const pgDbOperators_1 = require("./pgDbOperators");
|
|
4
|
+
const pgDb_1 = require("./pgDb");
|
|
5
|
+
const _ = require("lodash");
|
|
6
|
+
const util = require("util");
|
|
7
|
+
const pgUtils_1 = require("./pgUtils");
|
|
8
|
+
function generateWhere(conditions, fieldTypes, tableName, placeholderOffset = 0, skipUndefined) {
|
|
9
|
+
let result = generate({
|
|
10
|
+
params: [],
|
|
11
|
+
predicates: [],
|
|
12
|
+
offset: placeholderOffset,
|
|
13
|
+
}, conditions, fieldTypes, tableName, skipUndefined);
|
|
14
|
+
return {
|
|
15
|
+
where: result.predicates.length > 0 ? ' WHERE ' + result.predicates.join(' AND ') : '',
|
|
16
|
+
params: result.params
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function generate(result, conditions, fieldTypes, tableName, skipUndefined) {
|
|
20
|
+
_.each(conditions, (value, key) => {
|
|
21
|
+
let fieldAndOperator = parseKey(key);
|
|
22
|
+
if (value === undefined) {
|
|
23
|
+
if (skipUndefined === true)
|
|
24
|
+
return;
|
|
25
|
+
throw new Error('Invalid conditions! Field value undefined: "' + fieldAndOperator.field + '". Either delete the field, set it to null or use the options.skipUndefined parameter.');
|
|
26
|
+
}
|
|
27
|
+
else if (fieldAndOperator.field === 'or' || fieldAndOperator.field === 'and') {
|
|
28
|
+
result = handleOrAnd(result, fieldAndOperator, value, fieldTypes, tableName, skipUndefined);
|
|
29
|
+
}
|
|
30
|
+
else if (value === null) {
|
|
31
|
+
result = handleNullValue(result, fieldAndOperator, value);
|
|
32
|
+
}
|
|
33
|
+
else if (Array.isArray(value)) {
|
|
34
|
+
result = handleArrayValue(result, fieldAndOperator, value, fieldTypes);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
result = handleSingleValue(result, fieldAndOperator, value, fieldTypes, tableName);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
function handleOrAnd(result, fieldAndOperator, value, fieldTypes, tableName, skipUndefined) {
|
|
43
|
+
if (!Array.isArray(value)) {
|
|
44
|
+
value = [value];
|
|
45
|
+
}
|
|
46
|
+
let groupResult = _.reduce(value, (acc, v) => {
|
|
47
|
+
let subResult = generate({
|
|
48
|
+
params: [],
|
|
49
|
+
predicates: [],
|
|
50
|
+
offset: result.params.length + acc.offset
|
|
51
|
+
}, v, fieldTypes, tableName, skipUndefined);
|
|
52
|
+
acc.predicates.push('(' + subResult.predicates.join(' AND ') + ')');
|
|
53
|
+
acc.params = acc.params.concat(subResult.params);
|
|
54
|
+
acc.offset += subResult.params.length;
|
|
55
|
+
return acc;
|
|
56
|
+
}, {
|
|
57
|
+
params: [],
|
|
58
|
+
predicates: [],
|
|
59
|
+
offset: result.offset
|
|
60
|
+
});
|
|
61
|
+
result.params = result.params.concat(groupResult.params);
|
|
62
|
+
if (groupResult.predicates.length) {
|
|
63
|
+
if (fieldAndOperator.field === 'and') {
|
|
64
|
+
result.predicates.push(util.format('(%s)', groupResult.predicates.join(' AND ')));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
result.predicates.push(util.format('(%s)', groupResult.predicates.join(' OR ')));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
function handleNullValue(result, fieldAndOperator, value) {
|
|
73
|
+
fieldAndOperator.operator = fieldAndOperator.operator === '=' ? 'IS' : 'IS NOT';
|
|
74
|
+
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, value));
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
function handleArrayValue(result, fieldAndOperator, value, fieldTypes) {
|
|
78
|
+
if (fieldAndOperator.mutator) {
|
|
79
|
+
value = value.map((v) => fieldAndOperator.mutator(v));
|
|
80
|
+
}
|
|
81
|
+
let fieldType = fieldTypes[fieldAndOperator.field];
|
|
82
|
+
let position = '$' + (result.params.length + 1 + result.offset);
|
|
83
|
+
if (fieldType == pgDb_1.FieldType.JSON &&
|
|
84
|
+
['?|', '?&'].indexOf(fieldAndOperator.operator) != -1) {
|
|
85
|
+
result.params.push(value);
|
|
86
|
+
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
else if (fieldType == pgDb_1.FieldType.JSON &&
|
|
90
|
+
['@>', '<@', '&&'].indexOf(fieldAndOperator.operator) != -1) {
|
|
91
|
+
result.params.push(JSON.stringify(value));
|
|
92
|
+
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
else if ((!fieldType || fieldType == pgDb_1.FieldType.TIME) &&
|
|
96
|
+
['=', '<>', 'IN', 'NOT IN'].includes(fieldAndOperator.operator)) {
|
|
97
|
+
if (fieldAndOperator.operator === '=' || fieldAndOperator.operator === 'IN') {
|
|
98
|
+
fieldAndOperator.operator = '= ANY';
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
fieldAndOperator.operator = '<> ALL';
|
|
102
|
+
}
|
|
103
|
+
if (value.length === 0) {
|
|
104
|
+
throw new Error('Invalid conditions! empty array for field:"' + fieldAndOperator.field + '" and operator:"' + fieldAndOperator.operator + '"');
|
|
105
|
+
}
|
|
106
|
+
result.params.push(value
|
|
107
|
+
.map(v => (fieldType == pgDb_1.FieldType.TIME && !(v instanceof Date)) ? new Date(v) : v));
|
|
108
|
+
result.predicates.push(util.format('%s %s (%s)', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
else if (!fieldType && ['LIKE', 'ILIKE', 'SIMILAR TO', '~', '~*'].indexOf(fieldAndOperator.operator) != -1) {
|
|
112
|
+
result.params.push(value);
|
|
113
|
+
result.predicates.push(util.format('%s %s ANY(%s)', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
else if (!fieldType && ['NOT LIKE', 'NOT ILIKE', 'NOT SIMILAR TO', '!~', '!~*'].indexOf(fieldAndOperator.operator) != -1) {
|
|
117
|
+
result.params.push(value);
|
|
118
|
+
result.predicates.push(util.format('%s %s ALL(%s)', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
else if (fieldType == pgDb_1.FieldType.ARRAY &&
|
|
122
|
+
['=', '<>', '<', '>', '<=', '>=', '@>', '<@', '&&'].indexOf(fieldAndOperator.operator) != -1) {
|
|
123
|
+
result.params.push(value);
|
|
124
|
+
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
throw new Error('[325] Not implemented operator: "' + fieldAndOperator.operator + '" for field ' + fieldAndOperator.field + ' with type ' + fieldType);
|
|
128
|
+
}
|
|
129
|
+
function handleSingleValue(result, fieldAndOperator, value, fieldTypes, tableName) {
|
|
130
|
+
if (fieldAndOperator.mutator) {
|
|
131
|
+
value = fieldAndOperator.mutator(value);
|
|
132
|
+
}
|
|
133
|
+
let fieldType = fieldTypes[fieldAndOperator.field];
|
|
134
|
+
if (fieldAndOperator.operator === '@@') {
|
|
135
|
+
if (typeof value == 'object') {
|
|
136
|
+
if (!(value.lang || value.language) || !(value.query || value.plainquery)) {
|
|
137
|
+
throw new Error('[499] only "lang"/"language" and "query/plainquery" properties are supported!');
|
|
138
|
+
}
|
|
139
|
+
if (fieldType == pgDb_1.FieldType.TSVECTOR) {
|
|
140
|
+
result.params.push(value.lang || value.language);
|
|
141
|
+
result.params.push(value.query || value.plainquery);
|
|
142
|
+
let template = value.query ? "%s %s to_tsquery($%s, $%s)" : "%s %s plainto_tsquery($%s, $%s)";
|
|
143
|
+
result.predicates.push(util.format(template, fieldAndOperator.quotedField, fieldAndOperator.operator, result.params.length - 1 + result.offset, result.params.length + result.offset));
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
result.params.push(value.lang || value.language);
|
|
147
|
+
result.params.push(value.lang || value.language);
|
|
148
|
+
result.params.push(value.query || value.plainquery);
|
|
149
|
+
let template = value.query ? "to_tsvector($%s, %s) %s to_tsquery($%s, $%s)" : "to_tsvector($%s, %s) %s plainto_tsquery($%s, $%s)";
|
|
150
|
+
result.predicates.push(util.format(template, result.params.length - 2 + result.offset, fieldAndOperator.quotedField, fieldAndOperator.operator, result.params.length - 1 + result.offset, result.params.length + result.offset));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
result.params.push(value);
|
|
155
|
+
let template = fieldType == pgDb_1.FieldType.TSVECTOR ? "%s %s plainto_tsquery($%s)" : "to_tsvector(%s) %s plainto_tsquery($%s)";
|
|
156
|
+
result.predicates.push(util.format(template, fieldAndOperator.quotedField, fieldAndOperator.operator, result.params.length + result.offset));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else if (fieldType == pgDb_1.FieldType.ARRAY) {
|
|
160
|
+
if (['=', '<>'].indexOf(fieldAndOperator.operator) != -1) {
|
|
161
|
+
if (fieldAndOperator.originalOp == '=*') {
|
|
162
|
+
result.params.push([value]);
|
|
163
|
+
value = util.format("$%s", result.params.length + result.offset);
|
|
164
|
+
result.predicates.push(util.format('%s && %s', fieldAndOperator.quotedField, value));
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
result.params.push(value);
|
|
168
|
+
value = util.format("$%s", result.params.length + result.offset);
|
|
169
|
+
result.predicates.push(util.format('%s %s ANY(%s)', value, fieldAndOperator.operator, fieldAndOperator.quotedField));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else if (['LIKE', 'ILIKE', 'NOT LIKE', 'NOT ILIKE', 'SIMILAR TO', 'NOT SIMILAR TO'].indexOf(fieldAndOperator.operator) != -1) {
|
|
173
|
+
result.params.push(value);
|
|
174
|
+
value = util.format("$%s", result.params.length + result.offset);
|
|
175
|
+
let q = 'EXISTS (SELECT * FROM (SELECT UNNEST(' + tableName + '.%s) _el) _arr WHERE _arr._el %s %s)';
|
|
176
|
+
result.predicates.push(util.format(q, fieldAndOperator.quotedField, fieldAndOperator.operator, value));
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
throw new Error('[326] Not implemented operator: "' + fieldAndOperator.operator + '" for type ' + fieldType);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
result.params.push((fieldType == pgDb_1.FieldType.TIME && !(value instanceof Date)) ? new Date(value) : value);
|
|
184
|
+
value = util.format("$%s", result.params.length + result.offset);
|
|
185
|
+
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, value));
|
|
186
|
+
}
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
function strip(arr) {
|
|
190
|
+
return arr.map((s) => s.trim()).filter(v => v != '');
|
|
191
|
+
}
|
|
192
|
+
function getOp(str) {
|
|
193
|
+
for (let i = 0; i < str.length; i++) {
|
|
194
|
+
if (pgDbOperators_1.default[str.substr(i)]) {
|
|
195
|
+
return str.substr(i);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return '';
|
|
199
|
+
}
|
|
200
|
+
function parseKey(key) {
|
|
201
|
+
var _a;
|
|
202
|
+
key = key.trim();
|
|
203
|
+
let userOp = getOp(key);
|
|
204
|
+
if (userOp) {
|
|
205
|
+
key = key.substr(0, key.length - userOp.length);
|
|
206
|
+
}
|
|
207
|
+
let operation = pgDbOperators_1.default[userOp] || {};
|
|
208
|
+
let jsonRegexp = /(->[^>]|->>|#>[^>]|#>>)/;
|
|
209
|
+
let field;
|
|
210
|
+
let quotedField;
|
|
211
|
+
let quotedByUser = key.indexOf('"') > -1;
|
|
212
|
+
if (quotedByUser) {
|
|
213
|
+
quotedField = key;
|
|
214
|
+
field = (_a = /[^"]*"([^"]*)".*/.exec(key)) === null || _a === void 0 ? void 0 : _a[1];
|
|
215
|
+
if (!quotedField || !field) {
|
|
216
|
+
throw new Error('Invalid field:' + key);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
let parts = strip(key.split(jsonRegexp));
|
|
221
|
+
field = parts.shift();
|
|
222
|
+
if (!field) {
|
|
223
|
+
throw new Error('Invalid field:' + key);
|
|
224
|
+
}
|
|
225
|
+
quotedField = pgUtils_1.pgUtils.quoteFieldName(field);
|
|
226
|
+
if (parts.length > 1) {
|
|
227
|
+
let jsonOp = parts.shift();
|
|
228
|
+
let jsonKey = parts.shift();
|
|
229
|
+
jsonKey = pgUtils_1.pgUtils.quoteFieldNameJsonbOrPosition(jsonKey);
|
|
230
|
+
quotedField = util.format('%s%s%s', quotedField, jsonOp, jsonKey);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (operation.fieldMutator) {
|
|
234
|
+
quotedField = operation.fieldMutator(field, quotedField);
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
field: field,
|
|
238
|
+
quotedField: quotedField,
|
|
239
|
+
operator: (operation.operator || '=').toUpperCase(),
|
|
240
|
+
mutator: operation.mutator,
|
|
241
|
+
originalOp: userOp
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
exports.default = generateWhere;
|
|
245
|
+
//# sourceMappingURL=queryWhere.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryWhere.js","sourceRoot":"","sources":["../../src/queryWhere.ts"],"names":[],"mappings":"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"}
|
package/mkdocs.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pogi",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-beta",
|
|
4
4
|
"description": "An easy PostgreSQL query handler on top of pg.js",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build": "tsc -p
|
|
8
|
+
"build": "tsc -p ./tsconfig.json",
|
|
9
9
|
"test": "node spec/run.js",
|
|
10
10
|
"test_debug": "node --inspect-brk=9229 spec/run.js",
|
|
11
11
|
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
|
|
@@ -26,21 +26,30 @@
|
|
|
26
26
|
"pg"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"handlebars": "^4.7.
|
|
30
|
-
"lodash": "^4.17.
|
|
29
|
+
"handlebars": "^4.7.6",
|
|
30
|
+
"lodash": "^4.17.20",
|
|
31
31
|
"minimatch": "^3.0.4",
|
|
32
|
-
"moment": "^2.
|
|
33
|
-
"pg": "8.
|
|
34
|
-
"pg-query-stream": "^
|
|
32
|
+
"moment": "^2.29.1",
|
|
33
|
+
"pg": "^8.7.1",
|
|
34
|
+
"pg-query-stream": "^4.2.1",
|
|
35
35
|
"through": "~2.3.8",
|
|
36
|
-
"tslib": "^
|
|
36
|
+
"tslib": "^2.3.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@types/jasmine": "
|
|
40
|
-
"@types/
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
39
|
+
"@types/jasmine": "^3.10.3",
|
|
40
|
+
"@types/lodash": "^4.14.178",
|
|
41
|
+
"@types/node": "^17.0.12",
|
|
42
|
+
"@types/pg": "^8.6.4",
|
|
43
|
+
"@types/through": "^0.0.30",
|
|
44
|
+
"@types/yargs": "^17.0.8",
|
|
45
|
+
"dotenv": "^14.3.2",
|
|
46
|
+
"jasmine": "^4.0.2",
|
|
47
|
+
"jest": "^27.4.7",
|
|
48
|
+
"semantic-release": "^19.0.2",
|
|
49
|
+
"shelljs": "^0.8.5",
|
|
50
|
+
"ts-jest": "^27.1.3",
|
|
51
|
+
"typescript": "^4.5.5",
|
|
52
|
+
"yargs": "^17.3.1"
|
|
44
53
|
},
|
|
45
54
|
"author": "Laszlo Radics<laszlo.radics@labcup.net>, Geza Radics<radicsge@protonmail.com>",
|
|
46
55
|
"license": "MIT",
|
|
@@ -59,4 +68,4 @@
|
|
|
59
68
|
"path": "./node_modules/semantic-release/src/lib/plugin-noop.js"
|
|
60
69
|
}
|
|
61
70
|
}
|
|
62
|
-
}
|
|
71
|
+
}
|
|
@@ -16,7 +16,7 @@ import {PgTable} from "../pgTable";
|
|
|
16
16
|
|
|
17
17
|
for (let schemaName in pgdb.schemas) {
|
|
18
18
|
if (!(pgdb[schemaName] instanceof PgSchema)) {
|
|
19
|
-
throw Error('Already existing property: ' + schemaName + '!');
|
|
19
|
+
throw new Error('Already existing property: ' + schemaName + '!');
|
|
20
20
|
}
|
|
21
21
|
console.log(` '${schemaName}': PgSchema_${schemaName};`); //need to add a PgSchema_ prefix in order to handle schemas starting with number
|
|
22
22
|
}
|
|
@@ -32,7 +32,7 @@ import {PgTable} from "../pgTable";
|
|
|
32
32
|
console.log(`export interface PgSchema_${schemaName} extends PgSchema {`);
|
|
33
33
|
for (let tableName in pgdb.schemas[schemaName].tables) {
|
|
34
34
|
if (!(pgdb[schemaName][tableName] instanceof PgTable)) {
|
|
35
|
-
throw Error('Already existing property: ' + tableName + ' on schema:' + schemaName + '!');
|
|
35
|
+
throw new Error('Already existing property: ' + tableName + ' on schema:' + schemaName + '!');
|
|
36
36
|
}
|
|
37
37
|
console.log(` '${tableName}': PgTable<any>;`);
|
|
38
38
|
}
|
package/src/connectionOptions.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {PgDbLogger} from './pgDbLogger';
|
|
1
|
+
import { PgDbLogger } from './pgDbLogger';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @property connectionString e.g.: "postgres://user@localhost/database"
|
|
5
|
-
* @property
|
|
5
|
+
* @property host can be specified through PGHOST env variable
|
|
6
6
|
* @property user can be specified through PGUSER env variable (defaults USER env var)
|
|
7
7
|
* @property database can be specified through PGDATABASE env variable (defaults USER env var)
|
|
8
8
|
* @property password can be specified through PGPASSWORD env variable
|
|
@@ -12,18 +12,35 @@ import {PgDbLogger} from './pgDbLogger';
|
|
|
12
12
|
* @property logSQLDetailsOnError - log sql and params in case of sql error (this might contain sensitive information)
|
|
13
13
|
*/
|
|
14
14
|
export interface ConnectionOptions {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
/** host can be specified through PGHOST env variable (defaults USER env var) */
|
|
16
|
+
host?: string;
|
|
17
|
+
/** user can be specified through PGUSER env variable (defaults USER env var) */
|
|
18
|
+
user?: string;
|
|
19
|
+
/** can be specified through PGDATABASE env variable (defaults USER env var) */
|
|
20
|
+
database?: string;
|
|
21
|
+
/** can be specified through PGPASSWORD env variable */
|
|
22
|
+
password?: string;
|
|
23
|
+
/** can be specified through PGPORT env variable */
|
|
24
|
+
port?: number;
|
|
20
25
|
poolSize?: number;
|
|
21
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Turn on some basic sql injection protection
|
|
29
|
+
*/
|
|
30
|
+
forceEscapeColumns?: boolean | {
|
|
31
|
+
select?: boolean
|
|
32
|
+
where?: boolean
|
|
33
|
+
orderBy?: boolean
|
|
34
|
+
groupBy?: boolean
|
|
35
|
+
//warningOnly?: boolean
|
|
36
|
+
}
|
|
37
|
+
|
|
22
38
|
//number of rows to return at a time from a prepared statement's portal. 0 will return all rows at once
|
|
23
39
|
rows?: number;
|
|
24
|
-
|
|
25
|
-
min?: number;
|
|
26
|
-
|
|
40
|
+
/** set min pool size */
|
|
41
|
+
min?: number;
|
|
42
|
+
/** set pool max size */
|
|
43
|
+
max?: number;
|
|
27
44
|
|
|
28
45
|
binary?: boolean;
|
|
29
46
|
poolIdleTimeout?: number;
|
|
@@ -31,12 +48,28 @@ export interface ConnectionOptions {
|
|
|
31
48
|
poolLog?: boolean;
|
|
32
49
|
client_encoding?: string;
|
|
33
50
|
ssl?: boolean | any; //| TlsOptions;
|
|
34
|
-
|
|
51
|
+
/** default:process.env.PGAPPNAME - name displayed in the pg_stat_activity view and included in CSV log entries */
|
|
52
|
+
application_name?: string;
|
|
35
53
|
fallback_application_name?: string;
|
|
36
54
|
parseInputDatesAsUTC?: boolean;
|
|
55
|
+
/** e.g.: "postgres://user@localhost/database" */
|
|
37
56
|
connectionString?: string;
|
|
38
|
-
|
|
57
|
+
/** how long a client is allowed to remain idle before being closed */
|
|
58
|
+
idleTimeoutMillis?: number;
|
|
39
59
|
|
|
40
60
|
logger?: PgDbLogger;
|
|
41
|
-
|
|
61
|
+
/** if there is a undefined value in the condition, what should pogi do. Default is 'none', meaning raise error if a value is undefined. */
|
|
62
|
+
skipUndefined?: 'all' | 'select' | 'none';
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* escape all ddl parameter (select, from, where, order by, group by, ...), default: true
|
|
66
|
+
* notes:
|
|
67
|
+
* - insert statements columns are always quoted
|
|
68
|
+
* - update statements "SET" columns are always quoted
|
|
69
|
+
* */
|
|
70
|
+
strictDdl?: boolean,
|
|
71
|
+
/** escape all "SELECT" ddl parameter, default: true */
|
|
72
|
+
strictDdlSelect?: boolean,
|
|
73
|
+
/** escape all "WHERE" ddl parameter, default: true */
|
|
74
|
+
strictDdlWhere?: boolean,
|
|
42
75
|
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { parseArray } from "./pgConverters";
|
|
2
|
+
|
|
3
|
+
describe("pgConverters.test", () => {
|
|
4
|
+
it("parseArray", async () => {
|
|
5
|
+
expect(parseArray('{}')).toEqual([]);
|
|
6
|
+
expect(parseArray('{1,2}')).toEqual(['1', '2']);
|
|
7
|
+
expect(parseArray('{NULL,""}')).toEqual([null, '']);
|
|
8
|
+
expect(parseArray('{"\\\\","\\""}')).toEqual(['\\', '"']);
|
|
9
|
+
});
|
|
10
|
+
});
|
package/src/pgConverters.ts
CHANGED
|
@@ -1,46 +1,58 @@
|
|
|
1
1
|
import * as moment from 'moment';
|
|
2
2
|
|
|
3
3
|
//--- add parsing for array types --------------------------------
|
|
4
|
-
export
|
|
5
|
-
if (
|
|
6
|
-
|
|
4
|
+
export function parseArray(s: string): (string | null)[] {
|
|
5
|
+
if (!s || s[0] !== '{' || s[s.length - 1] !== '}') throw new Error('Invalid array value:' + s);
|
|
6
|
+
if (s == "{}") return [];
|
|
7
|
+
s = s.slice(1, s.length - 1); //cut off {}
|
|
7
8
|
let e = /(?:("(?:[^"\\]|\\.)*")|([^,"]*))(?:,|$)/g; //has to be mutable because of exec
|
|
8
|
-
let valList = [];
|
|
9
|
+
let valList: (string | null)[] = [];
|
|
9
10
|
let parsingResult;
|
|
10
11
|
do {
|
|
11
|
-
parsingResult = e.exec(
|
|
12
|
-
|
|
12
|
+
parsingResult = e.exec(s);
|
|
13
|
+
if (!parsingResult) throw new Error('Invalid array value:' + s);
|
|
14
|
+
let valStr = (parsingResult[2] === 'NULL') ? null :
|
|
13
15
|
(parsingResult[1] == null ? parsingResult[2] : unescapeString(parsingResult[1])); // for string parsing, escape \
|
|
14
16
|
valList.push(valStr);
|
|
15
|
-
} while (e.lastIndex <
|
|
17
|
+
} while (e.lastIndex < s.length);
|
|
16
18
|
return valList;
|
|
17
19
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
|
|
21
|
+
export function parseNumberWithValidation(s: string): number | null {
|
|
22
|
+
if (s === 'NULL') {
|
|
20
23
|
return null;
|
|
21
24
|
}
|
|
22
|
-
let v = +
|
|
25
|
+
let v = +s;
|
|
23
26
|
if (v > Number.MAX_SAFE_INTEGER || v < Number.MIN_SAFE_INTEGER) {
|
|
24
|
-
throw Error("Number can't be represented in javascript precisely: " +
|
|
27
|
+
throw new Error("Number can't be represented in javascript precisely: " + s);
|
|
25
28
|
}
|
|
26
29
|
return v;
|
|
27
30
|
};
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
|
|
32
|
+
export function parseNumberOrNull(s: string): number | null {
|
|
33
|
+
if (s === 'NULL') {
|
|
30
34
|
return null;
|
|
31
35
|
}
|
|
32
|
-
return +
|
|
36
|
+
return +s;
|
|
33
37
|
};
|
|
34
|
-
|
|
35
|
-
export
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
|
|
39
|
+
export function parseBoolOrNull(s: string): boolean | null {
|
|
40
|
+
if (s === 'NULL') {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return s == 't';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export let parseBooleanArray = (s: string): (boolean | null)[] => s == "{}" ? [] : s.substring(1, s.length - 1).split(',').map(parseBoolOrNull);
|
|
47
|
+
export let parseNumberArray = (s: string): (number | null)[] => s == "{}" ? [] : s.substring(1, s.length - 1).split(',').map(parseNumberOrNull);
|
|
48
|
+
export let parseNumberArrayWithValidation = (s: string[]) => s.map(parseNumberWithValidation);
|
|
49
|
+
export let parseDateArray = (s: string): (Date | null)[] => s == "{}" ? [] : s.substring(1, s.length - 1).split(',').map(d => d == 'NULL' ? null : moment(d.substring(1, d.length - 1)).toDate());
|
|
50
|
+
export let parseJsonArray = (s: string): (Object | null)[] => {
|
|
51
|
+
let vals = parseArray(s);
|
|
52
|
+
return vals.map(s2 => typeof s2 === 'string' ? JSON.parse(s2) : s2);
|
|
41
53
|
};
|
|
42
54
|
|
|
43
|
-
function unescapeString(s) {
|
|
55
|
+
function unescapeString(s: string): string {
|
|
44
56
|
return s.slice(1, s.length - 1) // cut the first and the last "
|
|
45
57
|
.replace(/\\"/g, '"') // \" -> "
|
|
46
58
|
.replace(/\\\\/g, '\\') // \\ -> \
|