@oino-ts/db 0.21.2 → 1.0.1
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/dist/cjs/OINODb.js +6 -144
- package/dist/cjs/OINODbApi.js +50 -318
- package/dist/cjs/OINODbConfig.js +10 -10
- package/dist/cjs/OINODbConstants.js +10 -0
- package/dist/cjs/OINODbDataField.js +28 -70
- package/dist/cjs/OINODbDataModel.js +30 -144
- package/dist/cjs/OINODbFactory.js +2 -2
- package/dist/cjs/OINODbModelSet.js +23 -23
- package/dist/cjs/OINODbQueryParams.js +201 -0
- package/dist/cjs/index.js +12 -41
- package/dist/esm/OINODb.js +6 -142
- package/dist/esm/OINODbApi.js +49 -314
- package/dist/esm/OINODbConstants.js +7 -0
- package/dist/esm/OINODbDataModel.js +31 -145
- package/dist/esm/OINODbFactory.js +1 -1
- package/dist/esm/OINODbQueryParams.js +194 -0
- package/dist/esm/index.js +4 -14
- package/dist/types/OINODb.d.ts +6 -173
- package/dist/types/OINODbApi.d.ts +18 -104
- package/dist/types/OINODbConstants.d.ts +23 -0
- package/dist/types/OINODbDataModel.d.ts +7 -61
- package/dist/types/OINODbFactory.d.ts +5 -2
- package/dist/types/OINODbQueryParams.d.ts +72 -0
- package/dist/types/index.d.ts +4 -108
- package/package.json +37 -37
- package/src/OINODb.ts +99 -348
- package/src/OINODbApi.test.ts +507 -498
- package/src/OINODbApi.ts +389 -667
- package/src/OINODbConstants.ts +32 -0
- package/src/OINODbDataModel.ts +191 -307
- package/src/OINODbFactory.ts +73 -68
- package/src/OINODbQueryParams.ts +203 -0
- package/src/index.ts +6 -118
- package/src/OINODbConfig.ts +0 -98
- package/src/OINODbDataField.ts +0 -405
- package/src/OINODbModelSet.ts +0 -353
- package/src/OINODbParser.ts +0 -438
- package/src/OINODbSqlParams.ts +0 -593
- package/src/OINODbSwagger.ts +0 -209
|
@@ -21,7 +21,7 @@ class OINODbModelSet {
|
|
|
21
21
|
/** Reference to data set */
|
|
22
22
|
dataset;
|
|
23
23
|
/** SQL parameters */
|
|
24
|
-
|
|
24
|
+
queryParams;
|
|
25
25
|
/** Collection of errors */
|
|
26
26
|
errors;
|
|
27
27
|
/**
|
|
@@ -29,21 +29,21 @@ class OINODbModelSet {
|
|
|
29
29
|
*
|
|
30
30
|
* @param datamodel data model
|
|
31
31
|
* @param dataset data set
|
|
32
|
-
* @param
|
|
32
|
+
* @param queryParams SQL parameters
|
|
33
33
|
*/
|
|
34
|
-
constructor(datamodel, dataset,
|
|
34
|
+
constructor(datamodel, dataset, queryParams) {
|
|
35
35
|
this.datamodel = datamodel;
|
|
36
36
|
this.dataset = dataset;
|
|
37
|
-
this.
|
|
37
|
+
this.queryParams = queryParams;
|
|
38
38
|
this.errors = this.dataset.messages;
|
|
39
39
|
}
|
|
40
40
|
_encodeAndHashFieldValue(field, value, contentType, primaryKeyValues, rowIdSeed) {
|
|
41
41
|
let result;
|
|
42
|
-
if (field.fieldParams.
|
|
43
|
-
if (value && (field instanceof index_js_1.OINONumberDataField) && (this.datamodel.api.hashid) && ((this.
|
|
42
|
+
if (field.fieldParams.isDbPrimaryKey || field.fieldParams.isDbForeignKey) {
|
|
43
|
+
if (value && (field instanceof index_js_1.OINONumberDataField) && (this.datamodel.api.hashid) && ((this.queryParams?.aggregate === undefined) || (this.queryParams.aggregate.isAggregated(field.name) == false))) {
|
|
44
44
|
value = this.datamodel.api.hashid.encode(value, rowIdSeed);
|
|
45
45
|
}
|
|
46
|
-
if (field.fieldParams.
|
|
46
|
+
if (field.fieldParams.isDbPrimaryKey) {
|
|
47
47
|
primaryKeyValues.push(value || "");
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -59,7 +59,7 @@ class OINODbModelSet {
|
|
|
59
59
|
let json_row = "";
|
|
60
60
|
for (let i = 0; i < fields.length; i++) {
|
|
61
61
|
const f = fields[i];
|
|
62
|
-
if (this.
|
|
62
|
+
if ((this.queryParams?.select?.isSelected(f.name) === false) && (f.fieldParams.isDbPrimaryKey == false)) {
|
|
63
63
|
continue;
|
|
64
64
|
}
|
|
65
65
|
let value = f.serializeCell(row[i]);
|
|
@@ -70,7 +70,7 @@ class OINODbModelSet {
|
|
|
70
70
|
json_row += "," + common_1.OINOStr.encode(f.name, common_1.OINOContentType.json) + ":null";
|
|
71
71
|
}
|
|
72
72
|
else {
|
|
73
|
-
let is_hashed = (f.fieldParams.
|
|
73
|
+
let is_hashed = (f.fieldParams.isDbPrimaryKey || f.fieldParams.isDbForeignKey) && (f instanceof index_js_1.OINONumberDataField) && (this.datamodel.api.hashid != null);
|
|
74
74
|
let is_value = (f instanceof index_js_1.OINOBooleanDataField) || ((f instanceof index_js_1.OINONumberDataField) && !is_hashed);
|
|
75
75
|
value = this._encodeAndHashFieldValue(f, value, common_1.OINOContentType.json, primary_key_values, f.name + " " + row_id_seed);
|
|
76
76
|
if (is_value) {
|
|
@@ -79,7 +79,7 @@ class OINODbModelSet {
|
|
|
79
79
|
json_row += "," + common_1.OINOStr.encode(f.name, common_1.OINOContentType.json) + ":" + value;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
json_row = common_1.OINOStr.encode(
|
|
82
|
+
json_row = common_1.OINOStr.encode(common_1.OINOConfig.OINO_ID_FIELD, common_1.OINOContentType.json) + ":" + common_1.OINOStr.encode(common_1.OINOConfig.printOINOId(primary_key_values), common_1.OINOContentType.json) + json_row;
|
|
83
83
|
return "{" + json_row + "}";
|
|
84
84
|
}
|
|
85
85
|
async _writeStringJson() {
|
|
@@ -98,9 +98,9 @@ class OINODbModelSet {
|
|
|
98
98
|
_writeHeaderCsv() {
|
|
99
99
|
const model = this.datamodel;
|
|
100
100
|
const fields = model.fields;
|
|
101
|
-
let csv_header = "\"" +
|
|
101
|
+
let csv_header = "\"" + common_1.OINOConfig.OINO_ID_FIELD + "\"";
|
|
102
102
|
for (let i = 0; i < fields.length; i++) {
|
|
103
|
-
if (this.
|
|
103
|
+
if ((this.queryParams?.select?.isSelected(fields[i].name) === false) && (fields[i].fieldParams.isDbPrimaryKey == false)) {
|
|
104
104
|
continue;
|
|
105
105
|
}
|
|
106
106
|
csv_header += ",\"" + fields[i].name + "\"";
|
|
@@ -115,7 +115,7 @@ class OINODbModelSet {
|
|
|
115
115
|
let csv_row = "";
|
|
116
116
|
for (let i = 0; i < fields.length; i++) {
|
|
117
117
|
const f = fields[i];
|
|
118
|
-
if (this.
|
|
118
|
+
if ((this.queryParams?.select?.isSelected(f.name) === false) && (f.fieldParams.isDbPrimaryKey == false)) {
|
|
119
119
|
continue;
|
|
120
120
|
}
|
|
121
121
|
let value = f.serializeCell(row[i]);
|
|
@@ -127,7 +127,7 @@ class OINODbModelSet {
|
|
|
127
127
|
csv_row += "," + value;
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
-
csv_row = common_1.OINOStr.encode(
|
|
130
|
+
csv_row = common_1.OINOStr.encode(common_1.OINOConfig.printOINOId(primary_key_values), common_1.OINOContentType.csv) + csv_row;
|
|
131
131
|
return csv_row;
|
|
132
132
|
}
|
|
133
133
|
async _writeStringCsv() {
|
|
@@ -162,7 +162,7 @@ class OINODbModelSet {
|
|
|
162
162
|
let result = "";
|
|
163
163
|
for (let i = 0; i < fields.length; i++) {
|
|
164
164
|
const f = fields[i];
|
|
165
|
-
if (this.
|
|
165
|
+
if ((this.queryParams?.select?.isSelected(f.name) === false) && (f.fieldParams.isDbPrimaryKey == false)) {
|
|
166
166
|
continue;
|
|
167
167
|
}
|
|
168
168
|
let value = f.serializeCell(row[i]);
|
|
@@ -185,7 +185,7 @@ class OINODbModelSet {
|
|
|
185
185
|
}
|
|
186
186
|
result += formdata_block;
|
|
187
187
|
}
|
|
188
|
-
result = this._writeRowFormdataParameterBlock(
|
|
188
|
+
result = this._writeRowFormdataParameterBlock(common_1.OINOConfig.OINO_ID_FIELD, common_1.OINOConfig.printOINOId(primary_key_values), multipart_boundary) + result;
|
|
189
189
|
return result;
|
|
190
190
|
}
|
|
191
191
|
_writeStringFormdata() {
|
|
@@ -201,7 +201,7 @@ class OINODbModelSet {
|
|
|
201
201
|
let urlencode_row = "";
|
|
202
202
|
for (let i = 0; i < fields.length; i++) {
|
|
203
203
|
const f = fields[i];
|
|
204
|
-
if (this.
|
|
204
|
+
if ((this.queryParams?.select?.isSelected(f.name) === false) && (f.fieldParams.isDbPrimaryKey == false)) {
|
|
205
205
|
continue;
|
|
206
206
|
}
|
|
207
207
|
let value = f.serializeCell(row[i]);
|
|
@@ -216,7 +216,7 @@ class OINODbModelSet {
|
|
|
216
216
|
urlencode_row += common_1.OINOStr.encode(f.name, common_1.OINOContentType.urlencode) + "=" + value;
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
|
-
urlencode_row = common_1.OINOStr.encode(
|
|
219
|
+
urlencode_row = common_1.OINOStr.encode(common_1.OINOConfig.OINO_ID_FIELD, common_1.OINOContentType.urlencode) + "=" + common_1.OINOStr.encode(common_1.OINOConfig.printOINOId(primary_key_values), common_1.OINOContentType.urlencode) + "&" + urlencode_row;
|
|
220
220
|
return urlencode_row;
|
|
221
221
|
}
|
|
222
222
|
async _writeStringUrlencode() {
|
|
@@ -242,13 +242,13 @@ class OINODbModelSet {
|
|
|
242
242
|
let result = {};
|
|
243
243
|
for (let i = 0; i < fields.length; i++) {
|
|
244
244
|
const f = fields[i];
|
|
245
|
-
if (f.fieldParams.
|
|
245
|
+
if (f.fieldParams.isDbPrimaryKey) {
|
|
246
246
|
primary_key_values.push(f.serializeCell(row[i]) || "");
|
|
247
247
|
}
|
|
248
|
-
if (this.
|
|
248
|
+
if ((this.queryParams?.select?.isSelected(f.name) === false) && (f.fieldParams.isDbPrimaryKey == false)) {
|
|
249
249
|
continue;
|
|
250
250
|
}
|
|
251
|
-
let value = f.
|
|
251
|
+
let value = f.datasource.parseValueAsCell(row[i], f.sqlType); // retain original value without serialization
|
|
252
252
|
if (value === undefined) {
|
|
253
253
|
// skip undefined values
|
|
254
254
|
}
|
|
@@ -259,7 +259,7 @@ class OINODbModelSet {
|
|
|
259
259
|
result[f.name] = value;
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
|
-
result[
|
|
262
|
+
result[common_1.OINOConfig.OINO_ID_FIELD] = common_1.OINOConfig.printOINOId(primary_key_values);
|
|
263
263
|
return result;
|
|
264
264
|
}
|
|
265
265
|
/**
|
|
@@ -316,7 +316,7 @@ class OINODbModelSet {
|
|
|
316
316
|
*/
|
|
317
317
|
async exportAsRecord(idFieldName) {
|
|
318
318
|
const result = {};
|
|
319
|
-
const row_id_field = idFieldName ||
|
|
319
|
+
const row_id_field = idFieldName || common_1.OINOConfig.OINO_ID_FIELD;
|
|
320
320
|
while (!this.dataset.isEof()) {
|
|
321
321
|
const row_data = this.dataset.getRow();
|
|
322
322
|
const row_export = this._exportRow(row_data);
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.OINODbQueryAggregate = exports.OINODbQueryLimit = exports.OINODbQueryOrder = exports.OINODbQueryFilter = void 0;
|
|
9
|
+
const common_1 = require("@oino-ts/common");
|
|
10
|
+
/**
|
|
11
|
+
* Class for recursively parsing of filters and printing them as SQL conditions.
|
|
12
|
+
* Supports three types of statements
|
|
13
|
+
* - comparison: (field)-lt|le|eq|ge|gt|like(value)
|
|
14
|
+
* - negation: -not(filter)
|
|
15
|
+
* - conjunction/disjunction: (filter)-and|or(filter)
|
|
16
|
+
* Supported conditions are comparisons (<, <=, =, >=, >) and substring match (LIKE).
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
class OINODbQueryFilter extends common_1.OINOQueryFilter {
|
|
20
|
+
static operatorToSql(filter) {
|
|
21
|
+
switch (filter.operator) {
|
|
22
|
+
case "and": return " AND ";
|
|
23
|
+
case "or": return " OR ";
|
|
24
|
+
case "not": return "NOT ";
|
|
25
|
+
case "lt": return " < ";
|
|
26
|
+
case "le": return " <= ";
|
|
27
|
+
case "eq": return " = ";
|
|
28
|
+
case "ne": return " != ";
|
|
29
|
+
case "ge": return " >= ";
|
|
30
|
+
case "gt": return " > ";
|
|
31
|
+
case "like": return " LIKE ";
|
|
32
|
+
case "isnull": return " IS NULL";
|
|
33
|
+
case "isNotNull": return " IS NOT NULL";
|
|
34
|
+
}
|
|
35
|
+
return " ";
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Print filter as SQL condition based on the datamodel of the API.
|
|
39
|
+
*
|
|
40
|
+
* @param dataModel data model (and database) to use for formatting of values
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
43
|
+
static printSql(filter, dataModel) {
|
|
44
|
+
if (filter.isEmpty()) {
|
|
45
|
+
return "";
|
|
46
|
+
}
|
|
47
|
+
let result = "";
|
|
48
|
+
let field = null;
|
|
49
|
+
if (filter.leftSide instanceof common_1.OINOQueryFilter) {
|
|
50
|
+
result += OINODbQueryFilter.printSql(filter.leftSide, dataModel);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
field = dataModel.findFieldByName(filter.leftSide);
|
|
54
|
+
if (!field) {
|
|
55
|
+
common_1.OINOLog.error("@oino-ts/db", "OINODbQueryFilter", "toSql", "Invalid field!", { field: filter.leftSide });
|
|
56
|
+
throw new Error(common_1.OINO_ERROR_PREFIX + ": OINODbQueryFilter.toSql - Invalid field '" + filter.leftSide + "'"); // invalid field name could be a security risk, stop processing
|
|
57
|
+
}
|
|
58
|
+
result += dataModel.api.datasource.printColumnName(field.name);
|
|
59
|
+
}
|
|
60
|
+
result += OINODbQueryFilter.operatorToSql(filter);
|
|
61
|
+
if (filter.rightSide instanceof common_1.OINOQueryFilter) {
|
|
62
|
+
result += OINODbQueryFilter.printSql(filter.rightSide, dataModel);
|
|
63
|
+
}
|
|
64
|
+
else if (filter.operator == common_1.OINOQueryNullCheck.isnull || filter.operator == common_1.OINOQueryNullCheck.isNotNull) {
|
|
65
|
+
// nothing to do, IS NULL and IS NOT NULL do not have a right side
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const value = field.deserializeCell(filter.rightSide);
|
|
69
|
+
if ((value == null) || (value === "")) {
|
|
70
|
+
common_1.OINOLog.error("@oino-ts/db", "OINODbQueryFilter", "toSql", "Invalid value!", { value: value });
|
|
71
|
+
throw new Error(common_1.OINO_ERROR_PREFIX + ": OINODbQueryFilter.toSql - Invalid value '" + value + "'"); // invalid value could be a security risk, stop processing
|
|
72
|
+
}
|
|
73
|
+
result += field.printCellAsValue(value);
|
|
74
|
+
}
|
|
75
|
+
result = "(" + result + ")";
|
|
76
|
+
common_1.OINOLog.debug("@oino-ts/db", "OINODbQueryFilter", "toSql", "Result", { sql: result });
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.OINODbQueryFilter = OINODbQueryFilter;
|
|
81
|
+
/**
|
|
82
|
+
* Class for ordering select results on a number of columns.
|
|
83
|
+
*
|
|
84
|
+
*/
|
|
85
|
+
class OINODbQueryOrder extends common_1.OINOQueryOrder {
|
|
86
|
+
/**
|
|
87
|
+
* Print order as SQL condition based on the datamodel of the API.
|
|
88
|
+
*
|
|
89
|
+
* @param order order instance
|
|
90
|
+
* @param dataModel data model (and database) to use for formatting of values
|
|
91
|
+
*
|
|
92
|
+
*/
|
|
93
|
+
static printSql(order, dataModel) {
|
|
94
|
+
if (order.isEmpty()) {
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
97
|
+
let result = "";
|
|
98
|
+
for (let i = 0; i < order.columns.length; i++) {
|
|
99
|
+
const field = dataModel.findFieldByName(order.columns[i]);
|
|
100
|
+
if (!field) {
|
|
101
|
+
common_1.OINOLog.error("@oino-ts/db", "OINODbQueryOrder", "toSql", "Invalid field!", { field: order.columns[i] });
|
|
102
|
+
throw new Error(common_1.OINO_ERROR_PREFIX + ": OINODbQueryOrder.toSql - Invalid field '" + order.columns[i] + "'"); // invalid field name could be a security risk, stop processing
|
|
103
|
+
}
|
|
104
|
+
if (result) {
|
|
105
|
+
result += ",";
|
|
106
|
+
}
|
|
107
|
+
result += dataModel.api.datasource.printColumnName(field.name) + " ";
|
|
108
|
+
if (order.descending[i]) {
|
|
109
|
+
result += "DESC";
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
result += "ASC";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
common_1.OINOLog.debug("@oino-ts/db", "OINODbQueryOrder", "toSql", "Result", { sql: result });
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.OINODbQueryOrder = OINODbQueryOrder;
|
|
120
|
+
/**
|
|
121
|
+
* Class for limiting the number of results.
|
|
122
|
+
*
|
|
123
|
+
*/
|
|
124
|
+
class OINODbQueryLimit extends common_1.OINOQueryLimit {
|
|
125
|
+
/**
|
|
126
|
+
* Print order as SQL condition based on the datamodel of the API.
|
|
127
|
+
*
|
|
128
|
+
* @param limit limit instance
|
|
129
|
+
* @param dataModel data model (and database) to use for formatting of values
|
|
130
|
+
*
|
|
131
|
+
*/
|
|
132
|
+
static printSql(limit, dataModel) {
|
|
133
|
+
if (limit.isEmpty()) {
|
|
134
|
+
return "";
|
|
135
|
+
}
|
|
136
|
+
let result = limit.limit.toString();
|
|
137
|
+
if (limit.page > 0) {
|
|
138
|
+
result += " OFFSET " + (limit.limit * (limit.page - 1) + 1).toString();
|
|
139
|
+
}
|
|
140
|
+
common_1.OINOLog.debug("@oino-ts/db", "OINODbQueryLimit", "toSql", "Result", { sql: result });
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.OINODbQueryLimit = OINODbQueryLimit;
|
|
145
|
+
/**
|
|
146
|
+
* Class for limiting the number of results.
|
|
147
|
+
*
|
|
148
|
+
*/
|
|
149
|
+
class OINODbQueryAggregate extends common_1.OINOQueryAggregate {
|
|
150
|
+
/**
|
|
151
|
+
* Print non-aggregated fields as SQL GROUP BY-condition based on the datamodel of the API.
|
|
152
|
+
*
|
|
153
|
+
* @param aggregate aggregate instance
|
|
154
|
+
* @param dataModel data model (and database) to use for formatting of values
|
|
155
|
+
* @param select what fields to select
|
|
156
|
+
*
|
|
157
|
+
*/
|
|
158
|
+
static printSql(aggregate, dataModel, select) {
|
|
159
|
+
if (aggregate.isEmpty()) {
|
|
160
|
+
return "";
|
|
161
|
+
}
|
|
162
|
+
let result = "";
|
|
163
|
+
for (let i = 0; i < dataModel.fields.length; i++) {
|
|
164
|
+
const f = dataModel.fields[i];
|
|
165
|
+
if ((select?.isSelected(f.name) || (f.fieldParams.isPrimaryKey == true)) && (aggregate.fields.includes(f.name) == false)) {
|
|
166
|
+
result += f.printColumnName() + ",";
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
result = result.substring(0, result.length - 1);
|
|
170
|
+
common_1.OINOLog.debug("@oino-ts/db", "OINODbQueryAggregate", "toSql", "Result", { sql: result });
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Print non-aggregated fields as SQL GROUP BY-condition based on the datamodel of the API.
|
|
175
|
+
*
|
|
176
|
+
* @param dataModel data model (and database) to use for formatting of values
|
|
177
|
+
* @param select what fields to select
|
|
178
|
+
*
|
|
179
|
+
*/
|
|
180
|
+
static printColumnNames(aggregate, dataModel, select) {
|
|
181
|
+
let result = "";
|
|
182
|
+
for (let i = 0; i < dataModel.fields.length; i++) {
|
|
183
|
+
const f = dataModel.fields[i];
|
|
184
|
+
if ((select?.isSelected(f.name) === false) && (f.fieldParams.isPrimaryKey == false)) { // if a field is not selected, we include an aggregated constant (min of const string) and correct fieldname instead so that dimensions of the data don't change, it does not need a group by but no unnecessary data is fetched
|
|
185
|
+
result += common_1.OINOQueryAggregateFunctions.min + "(" + f.datasource.printStringValue("") + ") as " + f.printColumnName() + ",";
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
const aggregate_index = aggregate.fields.indexOf(f.name);
|
|
189
|
+
const col_name = f.printColumnName();
|
|
190
|
+
if (aggregate_index >= 0) {
|
|
191
|
+
result += aggregate.functions[aggregate_index] + "(" + col_name + ") as " + col_name + ",";
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
result += col_name + ",";
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return result.substring(0, result.length - 1);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
exports.OINODbQueryAggregate = OINODbQueryAggregate;
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,47 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OINODB_UNDEFINED = exports.
|
|
4
|
-
var OINODbApi_js_1 = require("./OINODbApi.js");
|
|
5
|
-
Object.defineProperty(exports, "OINODbApiResult", { enumerable: true, get: function () { return OINODbApi_js_1.OINODbApiResult; } });
|
|
6
|
-
Object.defineProperty(exports, "OINODbHtmlTemplate", { enumerable: true, get: function () { return OINODbApi_js_1.OINODbHtmlTemplate; } });
|
|
7
|
-
Object.defineProperty(exports, "OINODbApi", { enumerable: true, get: function () { return OINODbApi_js_1.OINODbApi; } });
|
|
8
|
-
Object.defineProperty(exports, "OINODbApiRequest", { enumerable: true, get: function () { return OINODbApi_js_1.OINODbApiRequest; } });
|
|
9
|
-
var OINODbDataModel_js_1 = require("./OINODbDataModel.js");
|
|
10
|
-
Object.defineProperty(exports, "OINODbDataModel", { enumerable: true, get: function () { return OINODbDataModel_js_1.OINODbDataModel; } });
|
|
11
|
-
var OINODbModelSet_js_1 = require("./OINODbModelSet.js");
|
|
12
|
-
Object.defineProperty(exports, "OINODbModelSet", { enumerable: true, get: function () { return OINODbModelSet_js_1.OINODbModelSet; } });
|
|
13
|
-
var OINODbDataField_js_1 = require("./OINODbDataField.js");
|
|
14
|
-
Object.defineProperty(exports, "OINODbDataField", { enumerable: true, get: function () { return OINODbDataField_js_1.OINODbDataField; } });
|
|
15
|
-
Object.defineProperty(exports, "OINOBooleanDataField", { enumerable: true, get: function () { return OINODbDataField_js_1.OINOBooleanDataField; } });
|
|
16
|
-
Object.defineProperty(exports, "OINONumberDataField", { enumerable: true, get: function () { return OINODbDataField_js_1.OINONumberDataField; } });
|
|
17
|
-
Object.defineProperty(exports, "OINOStringDataField", { enumerable: true, get: function () { return OINODbDataField_js_1.OINOStringDataField; } });
|
|
18
|
-
Object.defineProperty(exports, "OINOBlobDataField", { enumerable: true, get: function () { return OINODbDataField_js_1.OINOBlobDataField; } });
|
|
19
|
-
Object.defineProperty(exports, "OINODatetimeDataField", { enumerable: true, get: function () { return OINODbDataField_js_1.OINODatetimeDataField; } });
|
|
3
|
+
exports.OINODB_UNDEFINED = exports.OINODbQueryAggregate = exports.OINODbQueryLimit = exports.OINODbQueryOrder = exports.OINODbQueryFilter = exports.OINODbApi = exports.OINODbFactory = exports.OINODbDataModel = exports.OINODb = void 0;
|
|
20
4
|
var OINODb_js_1 = require("./OINODb.js");
|
|
21
|
-
Object.defineProperty(exports, "OINODbDataSet", { enumerable: true, get: function () { return OINODb_js_1.OINODbDataSet; } });
|
|
22
|
-
Object.defineProperty(exports, "OINODbMemoryDataSet", { enumerable: true, get: function () { return OINODb_js_1.OINODbMemoryDataSet; } });
|
|
23
5
|
Object.defineProperty(exports, "OINODb", { enumerable: true, get: function () { return OINODb_js_1.OINODb; } });
|
|
24
|
-
var
|
|
25
|
-
Object.defineProperty(exports, "
|
|
26
|
-
Object.defineProperty(exports, "OINODbSqlOrder", { enumerable: true, get: function () { return OINODbSqlParams_js_1.OINODbSqlOrder; } });
|
|
27
|
-
Object.defineProperty(exports, "OINODbSqlComparison", { enumerable: true, get: function () { return OINODbSqlParams_js_1.OINODbSqlComparison; } });
|
|
28
|
-
Object.defineProperty(exports, "OINODbSqlLimit", { enumerable: true, get: function () { return OINODbSqlParams_js_1.OINODbSqlLimit; } });
|
|
29
|
-
Object.defineProperty(exports, "OINODbSqlBooleanOperation", { enumerable: true, get: function () { return OINODbSqlParams_js_1.OINODbSqlBooleanOperation; } });
|
|
30
|
-
Object.defineProperty(exports, "OINODbSqlAggregate", { enumerable: true, get: function () { return OINODbSqlParams_js_1.OINODbSqlAggregate; } });
|
|
31
|
-
Object.defineProperty(exports, "OINODbSqlAggregateFunctions", { enumerable: true, get: function () { return OINODbSqlParams_js_1.OINODbSqlAggregateFunctions; } });
|
|
32
|
-
Object.defineProperty(exports, "OINODbSqlSelect", { enumerable: true, get: function () { return OINODbSqlParams_js_1.OINODbSqlSelect; } });
|
|
33
|
-
Object.defineProperty(exports, "OINODbSqlNullCheck", { enumerable: true, get: function () { return OINODbSqlParams_js_1.OINODbSqlNullCheck; } });
|
|
34
|
-
var OINODbConfig_js_1 = require("./OINODbConfig.js");
|
|
35
|
-
Object.defineProperty(exports, "OINODbConfig", { enumerable: true, get: function () { return OINODbConfig_js_1.OINODbConfig; } });
|
|
6
|
+
var OINODbDataModel_js_1 = require("./OINODbDataModel.js");
|
|
7
|
+
Object.defineProperty(exports, "OINODbDataModel", { enumerable: true, get: function () { return OINODbDataModel_js_1.OINODbDataModel; } });
|
|
36
8
|
var OINODbFactory_js_1 = require("./OINODbFactory.js");
|
|
37
9
|
Object.defineProperty(exports, "OINODbFactory", { enumerable: true, get: function () { return OINODbFactory_js_1.OINODbFactory; } });
|
|
38
|
-
var
|
|
39
|
-
Object.defineProperty(exports, "
|
|
40
|
-
var
|
|
41
|
-
Object.defineProperty(exports, "
|
|
42
|
-
|
|
43
|
-
exports.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
exports.OINODB_UNDEFINED = ""; // original idea was to have a defined literal that get's swapped back to undefined, but current implementation just leaves it out at serialization (so value does not matter)
|
|
10
|
+
var OINODbApi_js_1 = require("./OINODbApi.js");
|
|
11
|
+
Object.defineProperty(exports, "OINODbApi", { enumerable: true, get: function () { return OINODbApi_js_1.OINODbApi; } });
|
|
12
|
+
var OINODbQueryParams_js_1 = require("./OINODbQueryParams.js");
|
|
13
|
+
Object.defineProperty(exports, "OINODbQueryFilter", { enumerable: true, get: function () { return OINODbQueryParams_js_1.OINODbQueryFilter; } });
|
|
14
|
+
Object.defineProperty(exports, "OINODbQueryOrder", { enumerable: true, get: function () { return OINODbQueryParams_js_1.OINODbQueryOrder; } });
|
|
15
|
+
Object.defineProperty(exports, "OINODbQueryLimit", { enumerable: true, get: function () { return OINODbQueryParams_js_1.OINODbQueryLimit; } });
|
|
16
|
+
Object.defineProperty(exports, "OINODbQueryAggregate", { enumerable: true, get: function () { return OINODbQueryParams_js_1.OINODbQueryAggregate; } });
|
|
17
|
+
var OINODbConstants_js_1 = require("./OINODbConstants.js");
|
|
18
|
+
Object.defineProperty(exports, "OINODB_UNDEFINED", { enumerable: true, get: function () { return OINODbConstants_js_1.OINODB_UNDEFINED; } });
|
package/dist/esm/OINODb.js
CHANGED
|
@@ -3,15 +3,14 @@
|
|
|
3
3
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
4
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import { OINODB_EMPTY_ROW } from "./index.js";
|
|
6
|
+
import { OINODataSource } from "@oino-ts/common";
|
|
8
7
|
/**
|
|
9
8
|
* Base class for database abstraction, implementing methods for connecting, making queries and parsing/formatting data
|
|
10
9
|
* between SQL and serialization formats.
|
|
11
10
|
*
|
|
12
11
|
*/
|
|
13
|
-
export class OINODb {
|
|
14
|
-
|
|
12
|
+
export class OINODb extends OINODataSource {
|
|
13
|
+
dbParams;
|
|
15
14
|
/** Name of the database */
|
|
16
15
|
name;
|
|
17
16
|
isConnected = false;
|
|
@@ -21,8 +20,9 @@ export class OINODb {
|
|
|
21
20
|
* @param params database parameters
|
|
22
21
|
*/
|
|
23
22
|
constructor(params) {
|
|
24
|
-
|
|
25
|
-
this.
|
|
23
|
+
super();
|
|
24
|
+
this.dbParams = { ...params }; // make a shallow copy of params so that changes to them do not affect the original object
|
|
25
|
+
this.name = this.dbParams.database;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Print SQL select statement with DB specific formatting.
|
|
@@ -70,139 +70,3 @@ export class OINODb {
|
|
|
70
70
|
return result;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Base class for SQL results that can be asynchronously iterated (but
|
|
75
|
-
* not necessarity rewinded). Idea is to handle database specific mechanisms
|
|
76
|
-
* for returning and formatting conventions in the database specific
|
|
77
|
-
* implementation. Data might be in memory or streamed in chunks and
|
|
78
|
-
* `OINODbDataSet` will serve it out consistently.
|
|
79
|
-
*
|
|
80
|
-
*/
|
|
81
|
-
export class OINODbDataSet extends OINOResult {
|
|
82
|
-
_data;
|
|
83
|
-
/** Error messages */
|
|
84
|
-
messages;
|
|
85
|
-
/**
|
|
86
|
-
* Constructor for `OINODbDataSet`.
|
|
87
|
-
*
|
|
88
|
-
* @param data internal database specific data type (constructor will throw if invalid)
|
|
89
|
-
* @param messages error messages from SQL-query
|
|
90
|
-
*
|
|
91
|
-
*/
|
|
92
|
-
constructor(data, messages = []) {
|
|
93
|
-
super();
|
|
94
|
-
this._data = data;
|
|
95
|
-
this.messages = messages;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Checks if the messages contain errors.
|
|
99
|
-
*
|
|
100
|
-
*/
|
|
101
|
-
hasErrors() {
|
|
102
|
-
for (let i = 0; i < this.messages.length; i++) {
|
|
103
|
-
if (this.messages[i].startsWith(OINO_ERROR_PREFIX)) {
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Checks if the messages contain errors.
|
|
111
|
-
*
|
|
112
|
-
*/
|
|
113
|
-
getFirstError() {
|
|
114
|
-
for (let i = 0; i < this.messages.length; i++) {
|
|
115
|
-
if (this.messages[i].startsWith(OINO_ERROR_PREFIX)) {
|
|
116
|
-
return this.messages[i];
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return "";
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Generic in memory implementation of a data set where data is an array of rows. Used
|
|
124
|
-
* by BunSqlite and automated testing. Can be rewinded.
|
|
125
|
-
*
|
|
126
|
-
*/
|
|
127
|
-
export class OINODbMemoryDataSet extends OINODbDataSet {
|
|
128
|
-
_rows;
|
|
129
|
-
_currentRow;
|
|
130
|
-
_eof;
|
|
131
|
-
/**
|
|
132
|
-
* Constructor of `OINODbMemoryDataSet`.
|
|
133
|
-
*
|
|
134
|
-
* @param data data as OINODataRow[] (constructor will throw if invalid)
|
|
135
|
-
* @param errors error messages from SQL-query
|
|
136
|
-
*
|
|
137
|
-
*/
|
|
138
|
-
constructor(data, errors = []) {
|
|
139
|
-
super(data, errors);
|
|
140
|
-
if ((data == null) || !(Array.isArray(data))) {
|
|
141
|
-
throw new Error(OINO_ERROR_PREFIX + ": Data needs to be compatible with OINORow[]!"); // TODO: maybe check all rows
|
|
142
|
-
}
|
|
143
|
-
this._rows = data;
|
|
144
|
-
if (this.isEmpty()) {
|
|
145
|
-
this._currentRow = -1;
|
|
146
|
-
this._eof = true;
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
this._currentRow = 0;
|
|
150
|
-
this._eof = false;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Is data set empty.
|
|
155
|
-
*
|
|
156
|
-
*/
|
|
157
|
-
isEmpty() {
|
|
158
|
-
return (this._rows.length == 0);
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Is there no more content, i.e. either dataset is empty or we have moved beyond last line
|
|
162
|
-
*
|
|
163
|
-
*/
|
|
164
|
-
isEof() {
|
|
165
|
-
return (this._eof);
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Attempts to moves dataset to the next row, possibly waiting for more data to become available. Returns !isEof().
|
|
169
|
-
*
|
|
170
|
-
*/
|
|
171
|
-
async next() {
|
|
172
|
-
if (this._currentRow < this._rows.length - 1) {
|
|
173
|
-
this._currentRow = this._currentRow + 1;
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
this._eof = true;
|
|
177
|
-
}
|
|
178
|
-
return Promise.resolve(!this._eof);
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Gets current row of data.
|
|
182
|
-
*
|
|
183
|
-
*/
|
|
184
|
-
getRow() {
|
|
185
|
-
if ((this._currentRow >= 0) && (this._currentRow < this._rows.length)) {
|
|
186
|
-
return this._rows[this._currentRow];
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
return OINODB_EMPTY_ROW;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Gets all rows of data.
|
|
194
|
-
*
|
|
195
|
-
*/
|
|
196
|
-
async getAllRows() {
|
|
197
|
-
return this._rows; // at the moment theres no result streaming, so we can just return the rows
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Rewinds data set to the first row, returns !isEof().
|
|
201
|
-
*
|
|
202
|
-
*/
|
|
203
|
-
first() {
|
|
204
|
-
this._currentRow = 0;
|
|
205
|
-
this._eof = this._rows.length == 0;
|
|
206
|
-
return !this._eof;
|
|
207
|
-
}
|
|
208
|
-
}
|