pogi 3.0.0-beta → 3.0.0-beta5
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/.env +5 -0
- package/lib/bin/generateInterface.js +1 -1
- package/lib/connectionOptions.d.ts +7 -0
- package/lib/index.d.ts +1 -1
- package/lib/pgConverters.d.ts +9 -10
- package/lib/pgConverters.js +44 -39
- package/lib/pgConverters.js.map +1 -1
- package/lib/{src/pgConverters.test.d.ts → pgConverters.test.d.ts} +0 -0
- package/lib/{src/pgConverters.test.js → pgConverters.test.js} +0 -0
- package/lib/pgConverters.test.js.map +1 -0
- package/lib/pgDb.d.ts +24 -31
- package/lib/pgDb.js +66 -69
- package/lib/pgDb.js.map +1 -1
- package/lib/{src/pgDb.test.d.ts → pgDb.test.d.ts} +0 -0
- package/lib/{src/pgDb.test.js → pgDb.test.js} +6 -0
- package/lib/pgDb.test.js.map +1 -0
- package/lib/pgDbInterface.d.ts +22 -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/{src/pgDbOperators.test.d.ts → pgDbOperators.test.d.ts} +0 -0
- package/lib/{src/pgDbOperators.test.js → pgDbOperators.test.js} +0 -0
- package/lib/pgDbOperators.test.js.map +1 -0
- package/lib/pgSchema.d.ts +2 -3
- package/lib/pgSchema.js.map +1 -1
- package/lib/pgSchemaInterface.d.ts +0 -0
- package/lib/pgSchemaInterface.js +2 -0
- package/lib/pgSchemaInterface.js.map +1 -0
- package/lib/pgTable.d.ts +13 -38
- package/lib/pgTable.js +54 -54
- package/lib/pgTable.js.map +1 -1
- package/lib/pgTableInterface.d.ts +28 -0
- package/lib/{src/pgTableInterface.js → pgTableInterface.js} +0 -0
- package/lib/pgTableInterface.js.map +1 -0
- package/lib/pgUtils.d.ts +15 -5
- package/lib/pgUtils.js +118 -24
- package/lib/pgUtils.js.map +1 -1
- package/lib/queryAble.d.ts +15 -64
- package/lib/queryAble.js +46 -45
- package/lib/queryAble.js.map +1 -1
- package/lib/{src/queryAbleInterface.d.ts → queryAbleInterface.d.ts} +6 -10
- package/lib/{src/queryAbleInterface.js → queryAbleInterface.js} +0 -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/lib/{src/bin/generateInterface.d.ts → test/pgDbOperatorSpec.d.ts} +0 -0
- package/lib/test/pgDbOperatorSpec.js +326 -0
- package/lib/test/pgDbOperatorSpec.js.map +1 -0
- package/lib/test/pgDbSpec.d.ts +1 -0
- package/lib/test/pgDbSpec.js +1139 -0
- package/lib/test/pgDbSpec.js.map +1 -0
- package/lib/test/pgServiceRestartTest.d.ts +1 -0
- package/lib/test/pgServiceRestartTest.js +1532 -0
- package/lib/test/pgServiceRestartTest.js.map +1 -0
- package/package.json +2 -1
- package/tsconfig.json +3 -5
- package/lib/src/bin/generateInterface.js +0 -53
- package/lib/src/bin/generateInterface.js.map +0 -1
- package/lib/src/connectionOptions.d.ts +0 -34
- package/lib/src/connectionOptions.js +0 -3
- package/lib/src/connectionOptions.js.map +0 -1
- package/lib/src/index.d.ts +0 -6
- package/lib/src/index.js +0 -12
- package/lib/src/index.js.map +0 -1
- package/lib/src/pgConverters.d.ts +0 -9
- package/lib/src/pgConverters.js +0 -71
- package/lib/src/pgConverters.js.map +0 -1
- package/lib/src/pgConverters.test.js.map +0 -1
- package/lib/src/pgDb.d.ts +0 -79
- package/lib/src/pgDb.js +0 -764
- package/lib/src/pgDb.js.map +0 -1
- package/lib/src/pgDb.test.js.map +0 -1
- package/lib/src/pgDbInterface.js +0 -11
- package/lib/src/pgDbInterface.js.map +0 -1
- package/lib/src/pgDbLogger.d.ts +0 -5
- package/lib/src/pgDbLogger.js +0 -3
- package/lib/src/pgDbLogger.js.map +0 -1
- package/lib/src/pgDbOperators.d.ts +0 -113
- package/lib/src/pgDbOperators.js +0 -41
- package/lib/src/pgDbOperators.js.map +0 -1
- package/lib/src/pgDbOperators.test.js.map +0 -1
- package/lib/src/pgSchema.d.ts +0 -17
- package/lib/src/pgSchema.js +0 -16
- package/lib/src/pgSchema.js.map +0 -1
- package/lib/src/pgSchemaInterface.d.ts +0 -12
- package/lib/src/pgSchemaInterface.js +0 -3
- package/lib/src/pgSchemaInterface.js.map +0 -1
- package/lib/src/pgTable.d.ts +0 -105
- package/lib/src/pgTable.js +0 -322
- package/lib/src/pgTable.js.map +0 -1
- package/lib/src/pgTableInterface.d.ts +0 -102
- package/lib/src/pgTableInterface.js.map +0 -1
- package/lib/src/pgUtils.d.ts +0 -41
- package/lib/src/pgUtils.js +0 -282
- package/lib/src/pgUtils.js.map +0 -1
- package/lib/src/queryAble.d.ts +0 -40
- package/lib/src/queryAble.js +0 -338
- package/lib/src/queryAble.js.map +0 -1
- package/lib/src/queryAbleInterface.js.map +0 -1
- package/lib/src/queryWhere.d.ts +0 -8
- package/lib/src/queryWhere.js +0 -245
- package/lib/src/queryWhere.js.map +0 -1
- package/src/bin/generateInterface.ts +0 -54
- package/src/connectionOptions.ts +0 -75
- package/src/index.d.ts +0 -7
- package/src/index.ts +0 -6
- package/src/pgConverters.test.ts +0 -10
- package/src/pgConverters.ts +0 -59
- package/src/pgDb.test.ts +0 -1324
- package/src/pgDb.ts +0 -842
- package/src/pgDbInterface.ts +0 -57
- package/src/pgDbLogger.ts +0 -13
- package/src/pgDbOperators.test.ts +0 -478
- package/src/pgDbOperators.ts +0 -85
- package/src/pgSchema.ts +0 -16
- package/src/pgSchemaInterface.ts +0 -12
- package/src/pgTable.ts +0 -369
- package/src/pgTableInterface.ts +0 -131
- package/src/pgUtils.ts +0 -290
- package/src/queryAble.ts +0 -365
- package/src/queryAbleInterface.ts +0 -108
- package/src/queryWhere.ts +0 -325
- package/src/test/init.sql +0 -122
- package/src/test/pgServiceRestartTest.ts +0 -1500
- package/src/test/throw_exception.sql +0 -5
- package/src/test/tricky.sql +0 -13
package/src/pgTable.ts
DELETED
|
@@ -1,369 +0,0 @@
|
|
|
1
|
-
import { QueryAble, QueryOptions } from "./queryAble";
|
|
2
|
-
import { FieldType } from "./pgDb";
|
|
3
|
-
import { IPgDb } from "./pgDbInterface";
|
|
4
|
-
import { PgDbLogger } from "./pgDbLogger"
|
|
5
|
-
import generateWhere from "./queryWhere";
|
|
6
|
-
import { PgSchema } from "./pgSchema";
|
|
7
|
-
import { pgUtils } from "./pgUtils";
|
|
8
|
-
import * as _ from 'lodash';
|
|
9
|
-
import * as stream from "stream";
|
|
10
|
-
import { IPgTable, TruncateOptions, InsertOption, Return, UpdateDeleteOption, UpsertOption, Stream, CountOption } from "./pgTableInterface";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export class PgTable<T> extends QueryAble implements IPgTable<T> {
|
|
14
|
-
qualifiedName: string;
|
|
15
|
-
pkey: string;
|
|
16
|
-
db: IPgDb;
|
|
17
|
-
fieldTypes: { [index: string]: FieldType }; //written directly
|
|
18
|
-
|
|
19
|
-
constructor(public schema: PgSchema, protected desc: { name: string, pkey?: string, schema: string }, fieldTypes: Record<string, FieldType> = {}) {
|
|
20
|
-
super();
|
|
21
|
-
this.db = schema.db;
|
|
22
|
-
this.qualifiedName = `${pgUtils.quoteFieldName(desc.schema)}.${pgUtils.quoteFieldName(desc.name)}`;
|
|
23
|
-
this.pkey = desc.pkey || desc.name + "_pkey"; //poor man's pkey (could be queried by why?)
|
|
24
|
-
this.fieldTypes = fieldTypes;
|
|
25
|
-
return this
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
toString() {
|
|
29
|
-
return this.qualifiedName;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* If you dont want to use the result set the options.return to false
|
|
34
|
-
* by default it is true. Also can set it to the fields that need to be returned,
|
|
35
|
-
* e.g.:
|
|
36
|
-
*
|
|
37
|
-
* let res = await table.insert([{username:'anonymous'},{username:'anonymous2'}], {return:['id']})
|
|
38
|
-
* res; // [{id:1},{id:2}]
|
|
39
|
-
*
|
|
40
|
-
* let res = await table.insert({username:'anonymous'}, {return:false})
|
|
41
|
-
* res; // void
|
|
42
|
-
*
|
|
43
|
-
* let res = await table.insert({username:'anonymous'})
|
|
44
|
-
* res; // {id:1, name:'anonymous', created:'...'}
|
|
45
|
-
*
|
|
46
|
-
*/
|
|
47
|
-
async insert(records: T[], options?: InsertOption): Promise<number>
|
|
48
|
-
async insert(records: T, options?: InsertOption): Promise<number>
|
|
49
|
-
async insert(records: any, options?: any): Promise<any> {
|
|
50
|
-
options = options || {};
|
|
51
|
-
|
|
52
|
-
if (!records) {
|
|
53
|
-
throw new Error("insert should be called with data");
|
|
54
|
-
} else if (!Array.isArray(records)) {
|
|
55
|
-
records = [records];
|
|
56
|
-
} else if (records.length === 0) {
|
|
57
|
-
return 0; // just return empty arrays so bulk inserting variable-length lists is more friendly
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
let { sql, parameters } = this.getInsertQuery(records);
|
|
61
|
-
sql = "WITH __RESULT as ( " + sql + " RETURNING 1) SELECT SUM(1) FROM __RESULT";
|
|
62
|
-
let result = await this.query(sql, parameters, { logger: options.logger });
|
|
63
|
-
return result[0].sum;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async insertAndGet(records: T[], options?: InsertOption & Return): Promise<T[]>
|
|
67
|
-
async insertAndGet(records: T, options?: InsertOption & Return): Promise<T>
|
|
68
|
-
async insertAndGet(records: any, options?: InsertOption & Return): Promise<any> {
|
|
69
|
-
let returnSingle = false;
|
|
70
|
-
options = options || {};
|
|
71
|
-
|
|
72
|
-
if (!records) {
|
|
73
|
-
throw new Error("insert should be called with data");
|
|
74
|
-
} else if (!Array.isArray(records)) {
|
|
75
|
-
returnSingle = true;
|
|
76
|
-
records = [records];
|
|
77
|
-
} else if (records.length === 0) {
|
|
78
|
-
return []; // just return empty arrays so bulk inserting variable-length lists is more friendly
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
let { sql, parameters } = this.getInsertQuery(records);
|
|
82
|
-
|
|
83
|
-
sql += " RETURNING " + (options && options.return && Array.isArray(options.return) ? options.return.map(pgUtils.quoteFieldName).join(',') : '*');
|
|
84
|
-
|
|
85
|
-
let result = await this.query(sql, parameters, { logger: options.logger });
|
|
86
|
-
if (options.return && options.return.length == 0) {
|
|
87
|
-
return new Array(returnSingle ? 1 : records.length).fill({});
|
|
88
|
-
}
|
|
89
|
-
if (returnSingle) {
|
|
90
|
-
return result[0];
|
|
91
|
-
} else {
|
|
92
|
-
return result;
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
async updateOne(conditions: { [k: string]: any }, fields: { [k: string]: any }, options?: UpdateDeleteOption): Promise<number> {
|
|
97
|
-
let affected = await this.update(conditions, fields, options);
|
|
98
|
-
if (affected > 1) {
|
|
99
|
-
throw new Error('More then one record has been updated!');
|
|
100
|
-
}
|
|
101
|
-
return affected;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async updateAndGetOne(conditions: { [k: string]: any }, fields: { [k: string]: any }, options?: UpdateDeleteOption & Return): Promise<T> {
|
|
105
|
-
let result = await this.updateAndGet(conditions, fields, options);
|
|
106
|
-
if (result.length > 1) {
|
|
107
|
-
throw new Error('More then one record has been updated!');
|
|
108
|
-
}
|
|
109
|
-
return result[0];
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async update(conditions: { [k: string]: any }, fields: { [k: string]: any }, options?: UpdateDeleteOption): Promise<number> {
|
|
113
|
-
let { sql, parameters } = this.getUpdateQuery(conditions, fields, options);
|
|
114
|
-
sql = "WITH __RESULT as ( " + sql + " RETURNING 1) SELECT SUM(1) FROM __RESULT";
|
|
115
|
-
let res = await this.query(sql, parameters, options);
|
|
116
|
-
return res[0].sum;
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
async updateAndGet(conditions: { [k: string]: any }, fields: { [k: string]: any }, options?: UpdateDeleteOption & Return): Promise<T[]> {
|
|
120
|
-
let { sql, parameters } = this.getUpdateQuery(conditions, fields, options);
|
|
121
|
-
sql += " RETURNING " + (options && options.return && Array.isArray(options.return) ? options.return.map(pgUtils.quoteFieldName).join(',') : '*');
|
|
122
|
-
return this.query(sql, parameters, options);
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* columnsOrConstraintName is by default the primary key
|
|
127
|
-
*/
|
|
128
|
-
async upsert(record: T, options?: UpsertOption): Promise<number> {
|
|
129
|
-
options = options || {};
|
|
130
|
-
if (!record) {
|
|
131
|
-
throw new Error("insert should be called with data");
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
let { sql, parameters } = this.getUpsertQuery(record, options);
|
|
135
|
-
sql = "WITH __RESULT as ( " + sql + " RETURNING 1) SELECT SUM(1) FROM __RESULT";
|
|
136
|
-
let result = await this.query(sql, parameters, { logger: options.logger });
|
|
137
|
-
return result[0].sum;
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* columnsOrConstraintName is by default the primary key
|
|
142
|
-
*/
|
|
143
|
-
async upsertAndGet(record: T, options?: UpsertOption & Return): Promise<T> {
|
|
144
|
-
options = options || {};
|
|
145
|
-
if (!record) {
|
|
146
|
-
throw new Error("insert should be called with data");
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
let { sql, parameters } = this.getUpsertQuery(record, options);
|
|
150
|
-
sql += " RETURNING " + (options && options.return && Array.isArray(options.return) ? options.return.map(pgUtils.quoteFieldName).join(',') : '*');
|
|
151
|
-
|
|
152
|
-
let result = await this.query(sql, parameters, { logger: options.logger });
|
|
153
|
-
|
|
154
|
-
if (options.return && options.return.length == 0) {
|
|
155
|
-
return <T>{};
|
|
156
|
-
}
|
|
157
|
-
return result[0];
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
async delete(conditions: { [k: string]: any }, options?: UpdateDeleteOption): Promise<number> {
|
|
161
|
-
let { sql, parameters } = this.getDeleteQuery(conditions, options);
|
|
162
|
-
sql = "WITH __RESULT as ( " + sql + " RETURNING 1) SELECT SUM(1) FROM __RESULT";
|
|
163
|
-
let res = await this.query(sql, parameters, options);
|
|
164
|
-
return res[0].sum;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
async deleteOne(conditions: { [k: string]: any }, options?: UpdateDeleteOption): Promise<number> {
|
|
168
|
-
let affected = await this.delete(conditions, options);
|
|
169
|
-
if (affected > 1) {
|
|
170
|
-
throw new Error('More then one record has been deleted!');
|
|
171
|
-
}
|
|
172
|
-
return affected;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
async deleteAndGet(conditions: { [k: string]: any }, options?: UpdateDeleteOption & Return): Promise<any[]> {
|
|
176
|
-
options = options || {};
|
|
177
|
-
let { sql, parameters } = this.getDeleteQuery(conditions, options);
|
|
178
|
-
sql += " RETURNING " + (options && options.return && Array.isArray(options.return) ? options.return.map(pgUtils.quoteFieldName).join(',') : '*');
|
|
179
|
-
return this.query(sql, parameters);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
async deleteAndGetOne(conditions: { [k: string]: any }, options?: UpdateDeleteOption & Return): Promise<any> {
|
|
183
|
-
let result = await this.deleteAndGet(conditions, options);
|
|
184
|
-
if (result.length > 1) {
|
|
185
|
-
throw new Error('More then one record has been deleted!');
|
|
186
|
-
}
|
|
187
|
-
return result[0];
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// async deleteAll(options?:UpdateDeleteOption):Promise<number> {
|
|
191
|
-
// let sql = util.format("DELETE FROM %s ", this.qualifiedName);
|
|
192
|
-
// sql = "WITH __RESULT as ( " + sql + " RETURNING 1) SELECT SUM(1) FROM __RESULT";
|
|
193
|
-
// let res = await this.query(sql, {logger:options.logger});
|
|
194
|
-
// return res[0].sum;
|
|
195
|
-
// }
|
|
196
|
-
|
|
197
|
-
async truncate(options?: TruncateOptions): Promise<void> {
|
|
198
|
-
let sql = `TRUNCATE ${this.qualifiedName}`;
|
|
199
|
-
if (options && options.restartIdentity) {
|
|
200
|
-
sql += ' RESTART IDENTITY';
|
|
201
|
-
}
|
|
202
|
-
if (options && options.cascade) {
|
|
203
|
-
sql += ' CASCADE';
|
|
204
|
-
}
|
|
205
|
-
await this.query(sql, undefined, options);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
async find(conditions: { [k: string]: any }, options?: QueryOptions): Promise<T[]>
|
|
209
|
-
async find(conditions: { [k: string]: any }, options?: QueryOptions & Stream): Promise<stream.Readable>
|
|
210
|
-
async find(conditions: { [k: string]: any }, options?: any): Promise<any> {
|
|
211
|
-
options = options || {};
|
|
212
|
-
options.skipUndefined = options.skipUndefined === true || (options.skipUndefined === undefined && this.db.config.skipUndefined && ['all', 'select'].includes(this.db.config.skipUndefined));
|
|
213
|
-
let where = _.isEmpty(conditions) ? {
|
|
214
|
-
where: "",
|
|
215
|
-
params: undefined
|
|
216
|
-
} : generateWhere(conditions, this.fieldTypes, this.qualifiedName, 0, options.skipUndefined);
|
|
217
|
-
let sql = `SELECT ${pgUtils.processQueryFields(options)} FROM ${this.qualifiedName} ${where.where} ${pgUtils.processQueryOptions<T>(options, this)}`;
|
|
218
|
-
return options.stream ? this.queryAsStream(sql, where.params, options) : this.query(sql, where.params, options);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
async findWhere(where: string, params: any[] | {}, options?: QueryOptions): Promise<T[]>
|
|
223
|
-
async findWhere(where: string, params: any[] | {}, options?: QueryOptions & Stream): Promise<stream.Readable>
|
|
224
|
-
async findWhere(where: string, params: any, options?: any): Promise<any> {
|
|
225
|
-
options = options || {};
|
|
226
|
-
let sql = `SELECT ${pgUtils.processQueryFields(options)} FROM ${this.qualifiedName} WHERE ${where} ${pgUtils.processQueryOptions<T>(options, this)}`;
|
|
227
|
-
return options.stream ? this.queryAsStream(sql, params, options) : this.query(sql, params, options);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
public async findAll(options?: QueryOptions): Promise<T[]>
|
|
231
|
-
public async findAll(options?: QueryOptions & Stream): Promise<stream.Readable>
|
|
232
|
-
public async findAll(options?: any): Promise<any> {
|
|
233
|
-
options = options || {};
|
|
234
|
-
let sql = `SELECT ${pgUtils.processQueryFields(options)} FROM ${this.qualifiedName} ${pgUtils.processQueryOptions<T>(options, this)}`;
|
|
235
|
-
return options.stream ? this.queryAsStream(sql, undefined, options) : this.query(sql, null, options);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
async findOne(conditions: Record<string, any>, options?: QueryOptions): Promise<T> {
|
|
239
|
-
let res = await this.find(conditions, options);
|
|
240
|
-
if (res.length > 1) {
|
|
241
|
-
let logger = (options && options.logger || this.getLogger(false));
|
|
242
|
-
let error = new Error('More then one rows exists');
|
|
243
|
-
pgUtils.logError(logger, { error, sql: this.qualifiedName, params: conditions, connection: this.db.connection });
|
|
244
|
-
throw error;
|
|
245
|
-
}
|
|
246
|
-
return res[0];
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
async findFirst(conditions: Record<string, any>, options?: QueryOptions): Promise<T> {
|
|
250
|
-
options = options || {};
|
|
251
|
-
options.limit = 1;
|
|
252
|
-
let res = await this.find(conditions, options);
|
|
253
|
-
return res[0];
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
async count(conditions?: Record<string, any>, options?: CountOption): Promise<number> {
|
|
258
|
-
options = options || {};
|
|
259
|
-
options.skipUndefined = options.skipUndefined === true || (options.skipUndefined === undefined && this.db.config.skipUndefined && ['all', 'select'].includes(this.db.config.skipUndefined));
|
|
260
|
-
|
|
261
|
-
let where = _.isEmpty(conditions) ? {
|
|
262
|
-
where: " ",
|
|
263
|
-
params: undefined
|
|
264
|
-
} : generateWhere(conditions!, this.fieldTypes, this.qualifiedName, 0, options.skipUndefined);
|
|
265
|
-
let sql = `SELECT COUNT(*) c FROM ${this.qualifiedName} ${where.where}`;
|
|
266
|
-
return (await this.queryOneField(sql, where.params));
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
async findOneFieldOnly(conditions: Record<string, any>, field: string, options?: QueryOptions): Promise<any> {
|
|
270
|
-
options = options || {};
|
|
271
|
-
options.fields = [field];
|
|
272
|
-
let res = await this.findOne(conditions, options);
|
|
273
|
-
return res ? res[field] : null;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
private getInsertQuery(records: T[]) {
|
|
278
|
-
let columnsMap = {};
|
|
279
|
-
records.forEach(rec => {
|
|
280
|
-
for (let field in <Object>rec) {
|
|
281
|
-
columnsMap[field] = true;
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
let columns = Object.keys(columnsMap);
|
|
285
|
-
let sql = `INSERT INTO ${this.qualifiedName} (${columns.map(pgUtils.quoteFieldName).join(", ")}) VALUES\n`;
|
|
286
|
-
let parameters: string[] = [];
|
|
287
|
-
let placeholders = [];
|
|
288
|
-
|
|
289
|
-
for (let i = 0, seed = 0; i < records.length; i++) {
|
|
290
|
-
placeholders.push('(' + columns.map(c => "$" + (++seed)).join(', ') + ')');
|
|
291
|
-
parameters.push(...columns.map(c => pgUtils.transformInsertUpdateParams(records[i][c], this.fieldTypes[c])));
|
|
292
|
-
}
|
|
293
|
-
sql += placeholders.join(",\n");
|
|
294
|
-
|
|
295
|
-
return { sql, parameters };
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
protected getUpdateSetSnippet(fields: { [k: string]: any }, parameters?: any[]): { snippet: string, parameters: any[] } {
|
|
300
|
-
let params = parameters || [];
|
|
301
|
-
let f: string[] = [];
|
|
302
|
-
let seed = params.length;
|
|
303
|
-
|
|
304
|
-
_.each(fields, (value, fieldName) => {
|
|
305
|
-
if (value === undefined) return;
|
|
306
|
-
|
|
307
|
-
f.push(`${pgUtils.quoteFieldName(fieldName)} = $${(++seed)}`);
|
|
308
|
-
params.push(pgUtils.transformInsertUpdateParams(value, this.fieldTypes[fieldName]));
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
return { snippet: f.join(', '), parameters: params };
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
protected getUpdateQuery(conditions: { [k: string]: any }, fields: { [k: string]: any }, options?: UpdateDeleteOption): { sql: string, parameters: any[] } {
|
|
315
|
-
options = options || {};
|
|
316
|
-
options.skipUndefined = options.skipUndefined === true || (options.skipUndefined === undefined && this.db.config.skipUndefined === 'all');
|
|
317
|
-
|
|
318
|
-
let hasConditions = true;
|
|
319
|
-
|
|
320
|
-
if (_.isEmpty(fields)) {
|
|
321
|
-
throw new Error('Missing fields for update');
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
let { snippet, parameters } = this.getUpdateSetSnippet(fields);
|
|
325
|
-
let sql = `UPDATE ${this.qualifiedName} SET ${snippet}`;
|
|
326
|
-
|
|
327
|
-
if (!hasConditions || !_.isEmpty(conditions)) {
|
|
328
|
-
let parsedWhere = generateWhere(conditions, this.fieldTypes, this.qualifiedName, parameters.length, options.skipUndefined);
|
|
329
|
-
sql += parsedWhere.where;
|
|
330
|
-
parameters = parameters.concat(parsedWhere.params);
|
|
331
|
-
}
|
|
332
|
-
return { sql, parameters };
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
protected getUpsertQuery(record: T, options?: UpsertOption): { sql: string, parameters: any[] } {
|
|
336
|
-
options = options || {};
|
|
337
|
-
|
|
338
|
-
if (_.isEmpty(record)) {
|
|
339
|
-
throw new Error('Missing fields for upsert');
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
let insert = this.getInsertQuery([record]);
|
|
343
|
-
let { snippet, parameters } = this.getUpdateSetSnippet(record, insert.parameters);
|
|
344
|
-
let sql = insert.sql;
|
|
345
|
-
|
|
346
|
-
if (options.columns) {
|
|
347
|
-
sql += ` ON CONFLICT (${options.columns.map(c => pgUtils.quoteFieldName(c)).join(', ')}) DO UPDATE SET ${snippet}`;
|
|
348
|
-
} else {
|
|
349
|
-
let constraint = pgUtils.quoteFieldName(options.constraint || this.pkey);
|
|
350
|
-
sql += ` ON CONFLICT ON CONSTRAINT ${constraint} DO UPDATE SET ${snippet}`;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
return { sql, parameters };
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
protected getDeleteQuery(conditions: { [k: string]: any }, options?: UpdateDeleteOption): { sql: string, parameters: any[] } {
|
|
357
|
-
options = options || {};
|
|
358
|
-
options.skipUndefined = options.skipUndefined === true || (options.skipUndefined === undefined && this.db.config.skipUndefined === 'all');
|
|
359
|
-
|
|
360
|
-
let sql = `DELETE FROM ${this.qualifiedName} `;
|
|
361
|
-
|
|
362
|
-
let parsedWhere;
|
|
363
|
-
if (!_.isEmpty(conditions)) {
|
|
364
|
-
parsedWhere = generateWhere(conditions, this.fieldTypes, this.qualifiedName, 0, options.skipUndefined);
|
|
365
|
-
sql += parsedWhere.where;
|
|
366
|
-
}
|
|
367
|
-
return { sql, parameters: parsedWhere && parsedWhere.params || [] }
|
|
368
|
-
}
|
|
369
|
-
}
|
package/src/pgTableInterface.ts
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { IQueryAble, QueryOptions } from "./queryAbleInterface";
|
|
2
|
-
import { PgDb, FieldType } from "./pgDb";
|
|
3
|
-
import { IPgDb } from "./pgDbInterface";
|
|
4
|
-
import { IPgSchema } from "./pgSchemaInterface";
|
|
5
|
-
import { PgDbLogger } from "./pgDbLogger"
|
|
6
|
-
import * as _ from 'lodash';
|
|
7
|
-
import * as stream from "stream";
|
|
8
|
-
|
|
9
|
-
const util = require('util');
|
|
10
|
-
|
|
11
|
-
export interface InsertOption {
|
|
12
|
-
logger?: PgDbLogger;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface Return {
|
|
16
|
-
return?: string[] | '*';
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface UpdateDeleteOption {
|
|
20
|
-
skipUndefined?: boolean;
|
|
21
|
-
logger?: PgDbLogger;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface UpsertOption {
|
|
25
|
-
constraint?: string,
|
|
26
|
-
columns?: string[],
|
|
27
|
-
logger?: PgDbLogger;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface CountOption {
|
|
31
|
-
skipUndefined?: boolean;
|
|
32
|
-
logger?: PgDbLogger;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface Stream {
|
|
36
|
-
stream: true;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface TruncateOptions {
|
|
40
|
-
restartIdentity?: boolean,
|
|
41
|
-
cascade?: boolean,
|
|
42
|
-
logger?: PgDbLogger;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface IPgTable<T> extends IQueryAble {
|
|
46
|
-
qualifiedName: string;
|
|
47
|
-
pkey: string;
|
|
48
|
-
db: IPgDb;
|
|
49
|
-
fieldTypes: { [index: string]: FieldType }; //written directly
|
|
50
|
-
|
|
51
|
-
toString: () => String
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* If you dont want to use the result set the options.return to false
|
|
55
|
-
* by default it is true. Also can set it to the fields that need to be returned,
|
|
56
|
-
* e.g.:
|
|
57
|
-
*
|
|
58
|
-
* let res = await table.insert([{username:'anonymous'},{username:'anonymous2'}], {return:['id']})
|
|
59
|
-
* res; // [{id:1},{id:2}]
|
|
60
|
-
*
|
|
61
|
-
* let res = await table.insert({username:'anonymous'}, {return:false})
|
|
62
|
-
* res; // void
|
|
63
|
-
*
|
|
64
|
-
* let res = await table.insert({username:'anonymous'})
|
|
65
|
-
* res; // {id:1, name:'anonymous', created:'...'}
|
|
66
|
-
*
|
|
67
|
-
*/
|
|
68
|
-
insert(records: T[], options?: InsertOption): Promise<number>
|
|
69
|
-
insert(records: T, options?: InsertOption): Promise<number>
|
|
70
|
-
insert(records: any, options?: any): Promise<any>
|
|
71
|
-
|
|
72
|
-
insertAndGet(records: T[], options?: InsertOption & Return): Promise<T[]>
|
|
73
|
-
insertAndGet(records: T, options?: InsertOption & Return): Promise<T>
|
|
74
|
-
insertAndGet(records: any, options?: InsertOption & Return): Promise<any>
|
|
75
|
-
|
|
76
|
-
updateOne(conditions: { [k: string]: any }, fields: { [k: string]: any }, options?: UpdateDeleteOption): Promise<number>
|
|
77
|
-
|
|
78
|
-
updateAndGetOne(conditions: { [k: string]: any }, fields: { [k: string]: any }, options?: UpdateDeleteOption & Return): Promise<T>
|
|
79
|
-
|
|
80
|
-
update(conditions: { [k: string]: any }, fields: { [k: string]: any }, options?: UpdateDeleteOption): Promise<number>
|
|
81
|
-
|
|
82
|
-
updateAndGet(conditions: { [k: string]: any }, fields: { [k: string]: any }, options?: UpdateDeleteOption & Return): Promise<T[]>
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* columnsOrConstraintName is by default the primary key
|
|
86
|
-
*/
|
|
87
|
-
upsert(record: T, options?: UpsertOption): Promise<number>
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* columnsOrConstraintName is by default the primary key
|
|
91
|
-
*/
|
|
92
|
-
upsertAndGet(record: T, options?: UpsertOption & Return): Promise<T>
|
|
93
|
-
|
|
94
|
-
delete(conditions: { [k: string]: any }, options?: UpdateDeleteOption): Promise<number>
|
|
95
|
-
|
|
96
|
-
deleteOne(conditions: { [k: string]: any }, options?: UpdateDeleteOption): Promise<number>
|
|
97
|
-
|
|
98
|
-
deleteAndGet(conditions: { [k: string]: any }, options?: UpdateDeleteOption & Return): Promise<any[]>
|
|
99
|
-
|
|
100
|
-
deleteAndGetOne(conditions: { [k: string]: any }, options?: UpdateDeleteOption & Return): Promise<any>
|
|
101
|
-
|
|
102
|
-
// async deleteAll(options?:UpdateDeleteOption):Promise<number> {
|
|
103
|
-
// let sql = util.format("DELETE FROM %s ", this.qualifiedName);
|
|
104
|
-
// sql = "WITH __RESULT as ( " + sql + " RETURNING 1) SELECT SUM(1) FROM __RESULT";
|
|
105
|
-
// let res = await this.query(sql, {logger:options.logger});
|
|
106
|
-
// return res[0].sum;
|
|
107
|
-
// }
|
|
108
|
-
|
|
109
|
-
truncate(options?: TruncateOptions): Promise<void>
|
|
110
|
-
|
|
111
|
-
find(conditions: { [k: string]: any }, options?: QueryOptions): Promise<T[]>
|
|
112
|
-
find(conditions: { [k: string]: any }, options?: QueryOptions & Stream): Promise<stream.Readable>
|
|
113
|
-
find(conditions: { [k: string]: any }, options?: any): Promise<any>
|
|
114
|
-
|
|
115
|
-
findWhere(where: string, params: any[] | {}, options?: QueryOptions): Promise<T[]>
|
|
116
|
-
findWhere(where: string, params: any[] | {}, options?: QueryOptions & Stream): Promise<stream.Readable>
|
|
117
|
-
findWhere(where: string, params: any, options?: any): Promise<any>
|
|
118
|
-
|
|
119
|
-
findAll(options?: QueryOptions): Promise<T[]>
|
|
120
|
-
findAll(options?: QueryOptions & Stream): Promise<stream.Readable>
|
|
121
|
-
findAll(options?: any): Promise<any>
|
|
122
|
-
|
|
123
|
-
findOne(conditions, options?: QueryOptions): Promise<T>
|
|
124
|
-
|
|
125
|
-
findFirst(conditions, options?: QueryOptions): Promise<T>
|
|
126
|
-
|
|
127
|
-
count(conditions?: {}, options?: CountOption): Promise<number>
|
|
128
|
-
|
|
129
|
-
findOneFieldOnly(conditions, field: string, options?: QueryOptions): Promise<any>
|
|
130
|
-
|
|
131
|
-
}
|