pogi 2.10.2 → 3.0.0-beta2
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 +11 -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 +3 -3
- package/lib/bin/generateInterface.js.map +1 -1
- package/lib/connectionOptions.d.ts +10 -0
- package/lib/index.d.ts +1 -1
- package/lib/pgConverters.d.ts +9 -8
- package/lib/pgConverters.js +46 -32
- package/lib/pgConverters.js.map +1 -1
- package/lib/pgConverters.test.d.ts +1 -0
- package/lib/pgConverters.test.js +13 -0
- package/lib/pgConverters.test.js.map +1 -0
- package/lib/pgDb.d.ts +27 -27
- package/lib/pgDb.js +293 -100
- package/lib/pgDb.js.map +1 -1
- package/lib/pgDb.test.d.ts +1 -0
- package/lib/pgDb.test.js +1126 -0
- package/lib/pgDb.test.js.map +1 -0
- package/lib/pgDbInterface.d.ts +53 -0
- package/lib/pgDbInterface.js +11 -0
- package/lib/pgDbInterface.js.map +1 -0
- package/lib/pgDbOperators.d.ts +3 -3
- package/lib/pgDbOperators.js +4 -7
- package/lib/pgDbOperators.js.map +1 -1
- package/lib/pgDbOperators.test.d.ts +1 -0
- package/lib/pgDbOperators.test.js +313 -0
- package/lib/pgDbOperators.test.js.map +1 -0
- package/lib/pgSchema.d.ts +10 -9
- package/lib/pgSchema.js.map +1 -1
- package/lib/pgSchemaInterface.d.ts +12 -0
- package/lib/pgSchemaInterface.js +3 -0
- package/lib/pgSchemaInterface.js.map +1 -0
- package/lib/pgTable.d.ts +15 -40
- package/lib/pgTable.js +54 -54
- package/lib/pgTable.js.map +1 -1
- package/lib/pgTableInterface.d.ts +102 -0
- package/lib/pgTableInterface.js +4 -0
- package/lib/pgTableInterface.js.map +1 -0
- package/lib/pgUtils.d.ts +16 -6
- package/lib/pgUtils.js +162 -31
- package/lib/pgUtils.js.map +1 -1
- package/lib/queryAble.d.ts +20 -53
- package/lib/queryAble.js +149 -80
- package/lib/queryAble.js.map +1 -1
- package/lib/queryAbleInterface.d.ts +55 -0
- package/lib/queryAbleInterface.js +7 -0
- package/lib/queryAbleInterface.js.map +1 -0
- package/lib/queryWhere.d.ts +2 -2
- package/lib/queryWhere.js +19 -23
- package/lib/queryWhere.js.map +1 -1
- package/mkdocs.yml +1 -0
- package/package.json +21 -11
- package/src/bin/generateInterface.ts +2 -2
- package/src/connectionOptions.ts +48 -13
- package/src/index.d.ts +7 -0
- package/src/index.ts +1 -1
- package/src/pgConverters.test.ts +10 -0
- package/src/pgConverters.ts +34 -22
- package/src/pgDb.test.ts +1324 -0
- package/src/pgDb.ts +318 -122
- 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 +66 -98
- package/src/pgTableInterface.ts +131 -0
- package/src/pgUtils.ts +166 -42
- package/src/queryAble.ts +167 -125
- package/src/queryAbleInterface.ts +104 -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} +12 -11
- 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
package/src/queryWhere.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import operationsMap from "./pgDbOperators";
|
|
2
|
-
import {FieldType} from "./pgDb";
|
|
2
|
+
import { FieldType } from "./pgDb";
|
|
3
|
+
import _ = require("lodash");
|
|
4
|
+
import util = require("util");
|
|
5
|
+
import { pgUtils } from "./pgUtils";
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
const util = require("util");
|
|
6
|
-
|
|
7
|
-
class FieldAndOperator {
|
|
7
|
+
interface FieldAndOperator {
|
|
8
8
|
field: string;
|
|
9
9
|
quotedField: string;
|
|
10
10
|
operator: string;
|
|
@@ -12,8 +12,14 @@ class FieldAndOperator {
|
|
|
12
12
|
mutator?: Function;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
interface Result {
|
|
16
|
+
params: any[],
|
|
17
|
+
predicates: string[],
|
|
18
|
+
offset: number
|
|
19
|
+
}
|
|
20
|
+
|
|
15
21
|
/** public */
|
|
16
|
-
function generateWhere(conditions, fieldTypes: { [index: string]: FieldType }, tableName: string, placeholderOffset = 0, skipUndefined): { where: string, params: Array<any> } {
|
|
22
|
+
function generateWhere(conditions: Record<string, any>, fieldTypes: { [index: string]: FieldType }, tableName: string, placeholderOffset = 0, skipUndefined?: boolean): { where: string, params: Array<any> } {
|
|
17
23
|
let result = generate({
|
|
18
24
|
params: [],
|
|
19
25
|
predicates: [],
|
|
@@ -27,7 +33,7 @@ function generateWhere(conditions, fieldTypes: { [index: string]: FieldType }, t
|
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
/** private */
|
|
30
|
-
function generate(result, conditions, fieldTypes: { [index: string]: FieldType }, tableName: string, skipUndefined) {
|
|
36
|
+
function generate(result: Result, conditions: Record<string, any>, fieldTypes: { [index: string]: FieldType }, tableName: string, skipUndefined?: boolean): Result {
|
|
31
37
|
_.each(conditions, (value, key) => {
|
|
32
38
|
//get the column field and the operator if specified
|
|
33
39
|
let fieldAndOperator = parseKey(key);
|
|
@@ -53,7 +59,7 @@ function generate(result, conditions, fieldTypes: { [index: string]: FieldType }
|
|
|
53
59
|
return result;
|
|
54
60
|
}
|
|
55
61
|
|
|
56
|
-
function handleOrAnd(result, fieldAndOperator, value, fieldTypes: { [index: string]: FieldType }, tableName: string, skipUndefined) {
|
|
62
|
+
function handleOrAnd(result: Result, fieldAndOperator: FieldAndOperator, value: any, fieldTypes: { [index: string]: FieldType }, tableName: string, skipUndefined?: boolean): Result {
|
|
57
63
|
if (!Array.isArray(value)) {
|
|
58
64
|
value = [value];
|
|
59
65
|
}
|
|
@@ -67,12 +73,12 @@ function handleOrAnd(result, fieldAndOperator, value, fieldTypes: { [index: stri
|
|
|
67
73
|
}, v, fieldTypes, tableName, skipUndefined);
|
|
68
74
|
|
|
69
75
|
// encapsulate and join the individual predicates with AND to create the complete subgroup predicate
|
|
70
|
-
acc.predicates.push(
|
|
76
|
+
acc.predicates.push('(' + subResult.predicates.join(' AND ') + ')');
|
|
71
77
|
acc.params = acc.params.concat(subResult.params);
|
|
72
78
|
acc.offset += subResult.params.length;
|
|
73
79
|
|
|
74
80
|
return acc;
|
|
75
|
-
}, {
|
|
81
|
+
}, <Result>{
|
|
76
82
|
params: [],
|
|
77
83
|
predicates: [],
|
|
78
84
|
offset: result.offset
|
|
@@ -91,30 +97,29 @@ function handleOrAnd(result, fieldAndOperator, value, fieldTypes: { [index: stri
|
|
|
91
97
|
return result;
|
|
92
98
|
}
|
|
93
99
|
|
|
94
|
-
function handleNullValue(result, fieldAndOperator, value) {
|
|
100
|
+
function handleNullValue(result: Result, fieldAndOperator: FieldAndOperator, value: any): Result {
|
|
95
101
|
fieldAndOperator.operator = fieldAndOperator.operator === '=' ? 'IS' : 'IS NOT';
|
|
96
102
|
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, value));
|
|
97
103
|
return result;
|
|
98
104
|
}
|
|
99
105
|
|
|
100
|
-
function handleArrayValue(result, fieldAndOperator, value, fieldTypes: { [index: string]: FieldType }) {
|
|
106
|
+
function handleArrayValue(result: Result, fieldAndOperator: FieldAndOperator, value: any[], fieldTypes: { [index: string]: FieldType }): Result {
|
|
101
107
|
if (fieldAndOperator.mutator) {
|
|
102
|
-
value = value.map(v => fieldAndOperator.mutator(v));
|
|
108
|
+
value = value.map((v: any) => fieldAndOperator.mutator!(v));
|
|
103
109
|
}
|
|
104
110
|
let fieldType = fieldTypes[fieldAndOperator.field];
|
|
105
111
|
|
|
112
|
+
let position = '$' + (result.params.length + 1 + result.offset);
|
|
106
113
|
if (fieldType == FieldType.JSON &&
|
|
107
114
|
['?|', '?&'].indexOf(fieldAndOperator.operator) != -1) {
|
|
108
115
|
result.params.push(value);
|
|
109
|
-
|
|
110
|
-
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, value));
|
|
116
|
+
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
111
117
|
return result;
|
|
112
118
|
}
|
|
113
119
|
else if (fieldType == FieldType.JSON &&
|
|
114
120
|
['@>', '<@', '&&'].indexOf(fieldAndOperator.operator) != -1) {
|
|
115
121
|
result.params.push(JSON.stringify(value));
|
|
116
|
-
|
|
117
|
-
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, value));
|
|
122
|
+
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
118
123
|
return result;
|
|
119
124
|
}
|
|
120
125
|
else if ((!fieldType || fieldType == FieldType.TIME) &&
|
|
@@ -131,31 +136,27 @@ function handleArrayValue(result, fieldAndOperator, value, fieldTypes: { [index:
|
|
|
131
136
|
}
|
|
132
137
|
|
|
133
138
|
result.params.push(value
|
|
134
|
-
.map(v => (fieldType == FieldType.TIME && !(
|
|
139
|
+
.map(v => (fieldType == FieldType.TIME && !(v instanceof Date)) ? new Date(v) : v)
|
|
135
140
|
);
|
|
136
|
-
|
|
137
|
-
result.predicates.push(util.format('%s %s (%s)', fieldAndOperator.quotedField, fieldAndOperator.operator, value));
|
|
141
|
+
result.predicates.push(util.format('%s %s (%s)', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
138
142
|
return result;
|
|
139
143
|
}
|
|
140
144
|
else if (!fieldType && ['LIKE', 'ILIKE', 'SIMILAR TO', '~', '~*'].indexOf(fieldAndOperator.operator) != -1) {
|
|
141
145
|
//defaults to any
|
|
142
146
|
result.params.push(value);
|
|
143
|
-
|
|
144
|
-
result.predicates.push(util.format('%s %s ANY(%s)', fieldAndOperator.quotedField, fieldAndOperator.operator, value));
|
|
147
|
+
result.predicates.push(util.format('%s %s ANY(%s)', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
145
148
|
return result;
|
|
146
149
|
}
|
|
147
150
|
else if (!fieldType && ['NOT LIKE', 'NOT ILIKE', 'NOT SIMILAR TO', '!~', '!~*'].indexOf(fieldAndOperator.operator) != -1) {
|
|
148
151
|
//defaults to all
|
|
149
152
|
result.params.push(value);
|
|
150
|
-
|
|
151
|
-
result.predicates.push(util.format('%s %s ALL(%s)', fieldAndOperator.quotedField, fieldAndOperator.operator, value));
|
|
153
|
+
result.predicates.push(util.format('%s %s ALL(%s)', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
152
154
|
return result;
|
|
153
155
|
}
|
|
154
156
|
else if (fieldType == FieldType.ARRAY &&
|
|
155
157
|
['=', '<>', '<', '>', '<=', '>=', '@>', '<@', '&&'].indexOf(fieldAndOperator.operator) != -1) {
|
|
156
158
|
result.params.push(value);
|
|
157
|
-
|
|
158
|
-
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, value));
|
|
159
|
+
result.predicates.push(util.format('%s %s %s', fieldAndOperator.quotedField, fieldAndOperator.operator, position));
|
|
159
160
|
return result;
|
|
160
161
|
}
|
|
161
162
|
|
|
@@ -163,7 +164,7 @@ function handleArrayValue(result, fieldAndOperator, value, fieldTypes: { [index:
|
|
|
163
164
|
}
|
|
164
165
|
|
|
165
166
|
|
|
166
|
-
function handleSingleValue(result, fieldAndOperator: FieldAndOperator, value, fieldTypes: { [index: string]: FieldType }, tableName) {
|
|
167
|
+
function handleSingleValue(result: Result, fieldAndOperator: FieldAndOperator, value: any, fieldTypes: { [index: string]: FieldType }, tableName: string): Result {
|
|
167
168
|
if (fieldAndOperator.mutator) {
|
|
168
169
|
value = fieldAndOperator.mutator(value);
|
|
169
170
|
}
|
|
@@ -237,11 +238,11 @@ function handleSingleValue(result, fieldAndOperator: FieldAndOperator, value, fi
|
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
|
|
240
|
-
function strip(arr) {
|
|
241
|
+
function strip(arr: string[]): string[] {
|
|
241
242
|
return arr.map((s) => s.trim()).filter(v => v != '');
|
|
242
243
|
}
|
|
243
244
|
|
|
244
|
-
function getOp(str) {
|
|
245
|
+
function getOp(str: string): string {
|
|
245
246
|
for (let i = 0; i < str.length; i++) {
|
|
246
247
|
if (operationsMap[str.substr(i)]) {
|
|
247
248
|
return str.substr(i);
|
|
@@ -266,7 +267,7 @@ function getOp(str) {
|
|
|
266
267
|
* @param {String} key Key in a format resembling "field [JSON operation+path] operation"
|
|
267
268
|
* @return {Object} [description]
|
|
268
269
|
*/
|
|
269
|
-
function parseKey(key): FieldAndOperator {
|
|
270
|
+
function parseKey(key: string): FieldAndOperator {
|
|
270
271
|
key = key.trim();
|
|
271
272
|
|
|
272
273
|
let userOp = getOp(key);
|
|
@@ -276,32 +277,30 @@ function parseKey(key): FieldAndOperator {
|
|
|
276
277
|
let operation = operationsMap[userOp] || {};
|
|
277
278
|
let jsonRegexp = /(->[^>]|->>|#>[^>]|#>>)/;
|
|
278
279
|
|
|
279
|
-
let field;
|
|
280
|
-
let quotedField;
|
|
280
|
+
let field: string | undefined;
|
|
281
|
+
let quotedField: string;
|
|
281
282
|
|
|
282
283
|
let quotedByUser = key.indexOf('"') > -1; //key[0]=='"'; -> lets make it possible to write transformed columns, e.g. LOWER("field")
|
|
283
284
|
if (quotedByUser) {
|
|
284
285
|
quotedField = key;
|
|
285
286
|
//field is used for find out the type of the field, so lets restore it if possible, grab the first quoted string
|
|
286
|
-
field = /[^"]*"([^"]*)".*/.exec(key)[1];
|
|
287
|
+
field = /[^"]*"([^"]*)".*/.exec(key)?.[1];
|
|
287
288
|
if (!quotedField || !field) {
|
|
288
|
-
|
|
289
|
+
throw new Error('Invalid field:' + key);
|
|
289
290
|
}
|
|
290
291
|
} else {
|
|
291
292
|
let parts = strip(key.split(jsonRegexp));
|
|
292
|
-
|
|
293
293
|
field = parts.shift();
|
|
294
|
-
|
|
294
|
+
if (!field) {
|
|
295
|
+
throw new Error('Invalid field:' + key);
|
|
296
|
+
}
|
|
297
|
+
quotedField = pgUtils.quoteFieldName(field);
|
|
295
298
|
|
|
296
299
|
if (parts.length > 1) {
|
|
297
|
-
let jsonOp = parts.shift()
|
|
298
|
-
let jsonKey = parts.shift()
|
|
299
|
-
|
|
300
|
-
// treat numeric json keys as array indices, otherwise quote it
|
|
301
|
-
if (isNaN(jsonKey) && jsonKey.indexOf("'") == -1) {
|
|
302
|
-
jsonKey = util.format("'%s'", jsonKey);
|
|
303
|
-
}
|
|
300
|
+
let jsonOp = parts.shift()!;
|
|
301
|
+
let jsonKey = parts.shift()!;
|
|
304
302
|
|
|
303
|
+
jsonKey = pgUtils.quoteFieldNameJsonbOrPosition(jsonKey);
|
|
305
304
|
quotedField = util.format('%s%s%s', quotedField, jsonOp, jsonKey);
|
|
306
305
|
}
|
|
307
306
|
}
|
|
@@ -6,6 +6,7 @@ DROP FUNCTION IF EXISTS increment();
|
|
|
6
6
|
DROP VIEW IF EXISTS "users_view";
|
|
7
7
|
DROP TABLE IF EXISTS "users";
|
|
8
8
|
DROP TABLE IF EXISTS "groups";
|
|
9
|
+
DROP TABLE IF EXISTS "types";
|
|
9
10
|
-- drop sequences
|
|
10
11
|
DROP SEQUENCE IF EXISTS "users_id_seq";
|
|
11
12
|
-- drop types
|
|
@@ -57,6 +58,28 @@ CREATE TABLE IF NOT EXISTS "users" (
|
|
|
57
58
|
"createdtz" timestamptz
|
|
58
59
|
);
|
|
59
60
|
|
|
61
|
+
CREATE TABLE IF NOT EXISTS "types" (
|
|
62
|
+
"text" varchar,
|
|
63
|
+
"int" integer,
|
|
64
|
+
"bigInt" bigInt,
|
|
65
|
+
"real" real,
|
|
66
|
+
"double" float8,
|
|
67
|
+
"bool" boolean,
|
|
68
|
+
"json" json,
|
|
69
|
+
"jsonB" jsonb,
|
|
70
|
+
"timestamptz" timestamptz,
|
|
71
|
+
|
|
72
|
+
"arrayText" varchar[],
|
|
73
|
+
"arrayInt" integer[],
|
|
74
|
+
"arrayBigInt" bigInt[],
|
|
75
|
+
"arrayReal" real[],
|
|
76
|
+
"arrayDouble" float8[],
|
|
77
|
+
"arrayBool" boolean[],
|
|
78
|
+
"arrayJson" json[],
|
|
79
|
+
"arrayJsonB" jsonb[],
|
|
80
|
+
"arrayTimestamptz" timestamptz[]
|
|
81
|
+
);
|
|
82
|
+
|
|
60
83
|
|
|
61
84
|
CREATE OR REPLACE FUNCTION update_updated_column() RETURNS TRIGGER AS $$
|
|
62
85
|
BEGIN
|