@oino-ts/db 0.0.12 → 0.0.14
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/OINODbApi.js +13 -11
- package/dist/cjs/OINODbDataField.js +5 -2
- package/dist/cjs/OINODbFactory.js +10 -3
- package/dist/esm/OINODbApi.js +13 -11
- package/dist/esm/OINODbDataField.js +5 -2
- package/dist/esm/OINODbFactory.js +9 -2
- package/dist/types/OINODbApi.d.ts +1 -1
- package/dist/types/OINODbFactory.d.ts +1 -2
- package/dist/types/index.d.ts +7 -1
- package/package.json +2 -2
- package/src/OINODbApi.test.ts +1 -1
- package/src/OINODbApi.ts +15 -12
- package/src/OINODbDataField.ts +5 -3
- package/src/OINODbFactory.ts +9 -2
- package/src/index.ts +7 -1
package/dist/cjs/OINODbApi.js
CHANGED
|
@@ -65,11 +65,18 @@ class OINODbHtmlTemplate extends index_js_1.OINOHtmlTemplate {
|
|
|
65
65
|
*
|
|
66
66
|
*/
|
|
67
67
|
renderFromDbData(modelset) {
|
|
68
|
+
index_js_1.OINOBenchmark.start("OINOHtmlTemplate", "renderFromDbData");
|
|
68
69
|
let html = "";
|
|
69
70
|
const dataset = modelset.dataset;
|
|
70
71
|
const datamodel = modelset.datamodel;
|
|
72
|
+
const api = modelset.datamodel.api;
|
|
73
|
+
const modified_index = datamodel.findFieldIndexByName(api.params.cacheModifiedField || "");
|
|
74
|
+
let last_modified = this.modified;
|
|
71
75
|
while (!dataset.isEof()) {
|
|
72
76
|
const row = dataset.getRow();
|
|
77
|
+
if (modified_index >= 0) {
|
|
78
|
+
last_modified = Math.max(last_modified, new Date(row[modified_index]).getTime());
|
|
79
|
+
}
|
|
73
80
|
let row_id_seed = datamodel.getRowPrimarykeyValues(row).join(' ');
|
|
74
81
|
let primary_key_values = [];
|
|
75
82
|
let html_row = this.template.replaceAll('###' + index_js_1.OINODbConfig.OINODB_ID_FIELD + '###', '###createHtmlFromData_temporary_oinoid###');
|
|
@@ -82,6 +89,7 @@ class OINODbHtmlTemplate extends index_js_1.OINOHtmlTemplate {
|
|
|
82
89
|
}
|
|
83
90
|
primary_key_values.push(value || "");
|
|
84
91
|
}
|
|
92
|
+
// OINOLog.debug("renderFromDbData replace field value", {field:f.name, value:value })
|
|
85
93
|
html_row = html_row.replaceAll('###' + f.name + '###', index_js_1.OINOStr.encode(value, index_js_1.OINOContentType.html));
|
|
86
94
|
}
|
|
87
95
|
html_row = html_row.replaceAll('###createHtmlFromData_temporary_oinoid###', index_js_1.OINOStr.encode(index_js_1.OINODbConfig.printOINOId(primary_key_values), index_js_1.OINOContentType.html));
|
|
@@ -89,6 +97,8 @@ class OINODbHtmlTemplate extends index_js_1.OINOHtmlTemplate {
|
|
|
89
97
|
dataset.next();
|
|
90
98
|
}
|
|
91
99
|
const result = new index_js_1.OINOHttpResult(html);
|
|
100
|
+
result.lastModified = last_modified;
|
|
101
|
+
index_js_1.OINOBenchmark.end("OINOHtmlTemplate", "renderFromDbData");
|
|
92
102
|
return result;
|
|
93
103
|
}
|
|
94
104
|
}
|
|
@@ -123,7 +133,7 @@ class OINODbApi {
|
|
|
123
133
|
this.params = params;
|
|
124
134
|
this.datamodel = new index_js_1.OINODbDataModel(this);
|
|
125
135
|
if (this.params.hashidKey) {
|
|
126
|
-
this.hashid = new hashid_1.OINOHashid(this.params.hashidKey, this.db.name, this.params.hashidLength, this.params.
|
|
136
|
+
this.hashid = new hashid_1.OINOHashid(this.params.hashidKey, this.db.name, this.params.hashidLength, this.params.hashidStaticIds);
|
|
127
137
|
}
|
|
128
138
|
else {
|
|
129
139
|
this.hashid = null;
|
|
@@ -163,7 +173,6 @@ class OINODbApi {
|
|
|
163
173
|
//logDebug("OINODbApi.validateHttpValues", {result:result})
|
|
164
174
|
}
|
|
165
175
|
async _doGet(result, id, params) {
|
|
166
|
-
index_js_1.OINOBenchmark.start("doGet");
|
|
167
176
|
const sql = this.datamodel.printSqlSelect(id, params.sqlParams || {});
|
|
168
177
|
// OINOLog.debug("OINODbApi.doGet sql", {sql:sql})
|
|
169
178
|
try {
|
|
@@ -181,10 +190,8 @@ class OINODbApi {
|
|
|
181
190
|
result.setError(500, "Unhandled exception in doGet: " + e.message, "DoGet");
|
|
182
191
|
result.addDebug("OINO GET SQL [" + sql + "]", "DoGet");
|
|
183
192
|
}
|
|
184
|
-
index_js_1.OINOBenchmark.end("doGet");
|
|
185
193
|
}
|
|
186
194
|
async _doPost(result, rows) {
|
|
187
|
-
index_js_1.OINOBenchmark.start("doPost");
|
|
188
195
|
let sql = "";
|
|
189
196
|
try {
|
|
190
197
|
let i = 0;
|
|
@@ -215,10 +222,8 @@ class OINODbApi {
|
|
|
215
222
|
result.setError(500, "Unhandled exception in doPost: " + e.message, "DoPost");
|
|
216
223
|
result.addDebug("OINO POST SQL [" + sql + "]", "DoPost");
|
|
217
224
|
}
|
|
218
|
-
index_js_1.OINOBenchmark.end("doPost");
|
|
219
225
|
}
|
|
220
226
|
async _doPut(result, id, row) {
|
|
221
|
-
index_js_1.OINOBenchmark.start("doPut");
|
|
222
227
|
let sql = "";
|
|
223
228
|
try {
|
|
224
229
|
this._validateRowValues(result, row, false);
|
|
@@ -238,10 +243,8 @@ class OINODbApi {
|
|
|
238
243
|
result.setError(500, "Unhandled exception: " + e.message, "DoPut");
|
|
239
244
|
result.addDebug("OINO POST SQL [" + sql + "]", "DoPut");
|
|
240
245
|
}
|
|
241
|
-
index_js_1.OINOBenchmark.end("doPut");
|
|
242
246
|
}
|
|
243
247
|
async _doDelete(result, id) {
|
|
244
|
-
index_js_1.OINOBenchmark.start("doDelete");
|
|
245
248
|
let sql = "";
|
|
246
249
|
try {
|
|
247
250
|
sql = this.datamodel.printSqlDelete(id);
|
|
@@ -258,7 +261,6 @@ class OINODbApi {
|
|
|
258
261
|
result.setError(500, "Unhandled exception: " + e.message, "DoDelete");
|
|
259
262
|
result.addDebug("OINO DELETE SQL [" + sql + "]", "DoDelete");
|
|
260
263
|
}
|
|
261
|
-
index_js_1.OINOBenchmark.end("doDelete");
|
|
262
264
|
}
|
|
263
265
|
/**
|
|
264
266
|
* Method for handlind a HTTP REST request with GET, POST, PUT, DELETE corresponding to
|
|
@@ -271,7 +273,7 @@ class OINODbApi {
|
|
|
271
273
|
*
|
|
272
274
|
*/
|
|
273
275
|
async doRequest(method, id, body, params = API_EMPTY_PARAMS) {
|
|
274
|
-
index_js_1.OINOBenchmark.start("doRequest");
|
|
276
|
+
index_js_1.OINOBenchmark.start("OINODbApi", "doRequest");
|
|
275
277
|
// OINOLog.debug("OINODbApi.doRequest enter", {method:method, id:id, body:body, params:params})
|
|
276
278
|
let result = new OINODbApiResult(params);
|
|
277
279
|
let rows = [];
|
|
@@ -339,7 +341,7 @@ class OINODbApi {
|
|
|
339
341
|
else {
|
|
340
342
|
result.setError(405, "Unsupported HTTP method '" + method + "'", "DoRequest");
|
|
341
343
|
}
|
|
342
|
-
index_js_1.OINOBenchmark.end("doRequest");
|
|
344
|
+
index_js_1.OINOBenchmark.end("OINODbApi", "doRequest", method);
|
|
343
345
|
return result;
|
|
344
346
|
}
|
|
345
347
|
}
|
|
@@ -235,8 +235,11 @@ class OINONumberDataField extends OINODbDataField {
|
|
|
235
235
|
*
|
|
236
236
|
*/
|
|
237
237
|
deserializeCell(value) {
|
|
238
|
-
if (
|
|
239
|
-
return
|
|
238
|
+
if (value === undefined) {
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
else if ((value === "") || (value === null)) {
|
|
242
|
+
return null;
|
|
240
243
|
}
|
|
241
244
|
else {
|
|
242
245
|
return Number.parseFloat(value);
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.OINODbFactory = void 0;
|
|
9
|
-
const OINOResult_js_1 = require("../../types/src/OINOResult.js");
|
|
10
9
|
const index_js_1 = require("./index.js");
|
|
11
10
|
/**
|
|
12
11
|
* Static factory class for easily creating things based on data
|
|
@@ -101,6 +100,14 @@ class OINODbFactory {
|
|
|
101
100
|
if (result.responseType === undefined) {
|
|
102
101
|
result.responseType = index_js_1.OINOContentType.json;
|
|
103
102
|
}
|
|
103
|
+
const last_modified = request.headers.get("if-modified-since");
|
|
104
|
+
if (last_modified) {
|
|
105
|
+
result.lastModified = new Date(last_modified).getTime();
|
|
106
|
+
}
|
|
107
|
+
const etags = request.headers.get("if-none-match")?.split(',').map(e => e.trim());
|
|
108
|
+
if (etags) {
|
|
109
|
+
result.etags = etags;
|
|
110
|
+
}
|
|
104
111
|
// OINOLog.debug("createParamsFromRequest", {params:result})
|
|
105
112
|
return result;
|
|
106
113
|
}
|
|
@@ -135,7 +142,7 @@ class OINODbFactory {
|
|
|
135
142
|
html += html_row + "\r\n";
|
|
136
143
|
dataset.next();
|
|
137
144
|
}
|
|
138
|
-
const result = new
|
|
145
|
+
const result = new index_js_1.OINOHttpResult(html);
|
|
139
146
|
return result;
|
|
140
147
|
}
|
|
141
148
|
/**
|
|
@@ -172,7 +179,7 @@ class OINODbFactory {
|
|
|
172
179
|
html = html.replaceAll('###messages###', "<ul>" + messages + "</ul>");
|
|
173
180
|
}
|
|
174
181
|
html = html.replace(/###[^#]*###/g, "");
|
|
175
|
-
const http_result = new
|
|
182
|
+
const http_result = new index_js_1.OINOHttpResult(html);
|
|
176
183
|
return http_result;
|
|
177
184
|
}
|
|
178
185
|
static _findCsvLineEnd(csvData, start) {
|
package/dist/esm/OINODbApi.js
CHANGED
|
@@ -61,11 +61,18 @@ export class OINODbHtmlTemplate extends OINOHtmlTemplate {
|
|
|
61
61
|
*
|
|
62
62
|
*/
|
|
63
63
|
renderFromDbData(modelset) {
|
|
64
|
+
OINOBenchmark.start("OINOHtmlTemplate", "renderFromDbData");
|
|
64
65
|
let html = "";
|
|
65
66
|
const dataset = modelset.dataset;
|
|
66
67
|
const datamodel = modelset.datamodel;
|
|
68
|
+
const api = modelset.datamodel.api;
|
|
69
|
+
const modified_index = datamodel.findFieldIndexByName(api.params.cacheModifiedField || "");
|
|
70
|
+
let last_modified = this.modified;
|
|
67
71
|
while (!dataset.isEof()) {
|
|
68
72
|
const row = dataset.getRow();
|
|
73
|
+
if (modified_index >= 0) {
|
|
74
|
+
last_modified = Math.max(last_modified, new Date(row[modified_index]).getTime());
|
|
75
|
+
}
|
|
69
76
|
let row_id_seed = datamodel.getRowPrimarykeyValues(row).join(' ');
|
|
70
77
|
let primary_key_values = [];
|
|
71
78
|
let html_row = this.template.replaceAll('###' + OINODbConfig.OINODB_ID_FIELD + '###', '###createHtmlFromData_temporary_oinoid###');
|
|
@@ -78,6 +85,7 @@ export class OINODbHtmlTemplate extends OINOHtmlTemplate {
|
|
|
78
85
|
}
|
|
79
86
|
primary_key_values.push(value || "");
|
|
80
87
|
}
|
|
88
|
+
// OINOLog.debug("renderFromDbData replace field value", {field:f.name, value:value })
|
|
81
89
|
html_row = html_row.replaceAll('###' + f.name + '###', OINOStr.encode(value, OINOContentType.html));
|
|
82
90
|
}
|
|
83
91
|
html_row = html_row.replaceAll('###createHtmlFromData_temporary_oinoid###', OINOStr.encode(OINODbConfig.printOINOId(primary_key_values), OINOContentType.html));
|
|
@@ -85,6 +93,8 @@ export class OINODbHtmlTemplate extends OINOHtmlTemplate {
|
|
|
85
93
|
dataset.next();
|
|
86
94
|
}
|
|
87
95
|
const result = new OINOHttpResult(html);
|
|
96
|
+
result.lastModified = last_modified;
|
|
97
|
+
OINOBenchmark.end("OINOHtmlTemplate", "renderFromDbData");
|
|
88
98
|
return result;
|
|
89
99
|
}
|
|
90
100
|
}
|
|
@@ -118,7 +128,7 @@ export class OINODbApi {
|
|
|
118
128
|
this.params = params;
|
|
119
129
|
this.datamodel = new OINODbDataModel(this);
|
|
120
130
|
if (this.params.hashidKey) {
|
|
121
|
-
this.hashid = new OINOHashid(this.params.hashidKey, this.db.name, this.params.hashidLength, this.params.
|
|
131
|
+
this.hashid = new OINOHashid(this.params.hashidKey, this.db.name, this.params.hashidLength, this.params.hashidStaticIds);
|
|
122
132
|
}
|
|
123
133
|
else {
|
|
124
134
|
this.hashid = null;
|
|
@@ -158,7 +168,6 @@ export class OINODbApi {
|
|
|
158
168
|
//logDebug("OINODbApi.validateHttpValues", {result:result})
|
|
159
169
|
}
|
|
160
170
|
async _doGet(result, id, params) {
|
|
161
|
-
OINOBenchmark.start("doGet");
|
|
162
171
|
const sql = this.datamodel.printSqlSelect(id, params.sqlParams || {});
|
|
163
172
|
// OINOLog.debug("OINODbApi.doGet sql", {sql:sql})
|
|
164
173
|
try {
|
|
@@ -176,10 +185,8 @@ export class OINODbApi {
|
|
|
176
185
|
result.setError(500, "Unhandled exception in doGet: " + e.message, "DoGet");
|
|
177
186
|
result.addDebug("OINO GET SQL [" + sql + "]", "DoGet");
|
|
178
187
|
}
|
|
179
|
-
OINOBenchmark.end("doGet");
|
|
180
188
|
}
|
|
181
189
|
async _doPost(result, rows) {
|
|
182
|
-
OINOBenchmark.start("doPost");
|
|
183
190
|
let sql = "";
|
|
184
191
|
try {
|
|
185
192
|
let i = 0;
|
|
@@ -210,10 +217,8 @@ export class OINODbApi {
|
|
|
210
217
|
result.setError(500, "Unhandled exception in doPost: " + e.message, "DoPost");
|
|
211
218
|
result.addDebug("OINO POST SQL [" + sql + "]", "DoPost");
|
|
212
219
|
}
|
|
213
|
-
OINOBenchmark.end("doPost");
|
|
214
220
|
}
|
|
215
221
|
async _doPut(result, id, row) {
|
|
216
|
-
OINOBenchmark.start("doPut");
|
|
217
222
|
let sql = "";
|
|
218
223
|
try {
|
|
219
224
|
this._validateRowValues(result, row, false);
|
|
@@ -233,10 +238,8 @@ export class OINODbApi {
|
|
|
233
238
|
result.setError(500, "Unhandled exception: " + e.message, "DoPut");
|
|
234
239
|
result.addDebug("OINO POST SQL [" + sql + "]", "DoPut");
|
|
235
240
|
}
|
|
236
|
-
OINOBenchmark.end("doPut");
|
|
237
241
|
}
|
|
238
242
|
async _doDelete(result, id) {
|
|
239
|
-
OINOBenchmark.start("doDelete");
|
|
240
243
|
let sql = "";
|
|
241
244
|
try {
|
|
242
245
|
sql = this.datamodel.printSqlDelete(id);
|
|
@@ -253,7 +256,6 @@ export class OINODbApi {
|
|
|
253
256
|
result.setError(500, "Unhandled exception: " + e.message, "DoDelete");
|
|
254
257
|
result.addDebug("OINO DELETE SQL [" + sql + "]", "DoDelete");
|
|
255
258
|
}
|
|
256
|
-
OINOBenchmark.end("doDelete");
|
|
257
259
|
}
|
|
258
260
|
/**
|
|
259
261
|
* Method for handlind a HTTP REST request with GET, POST, PUT, DELETE corresponding to
|
|
@@ -266,7 +268,7 @@ export class OINODbApi {
|
|
|
266
268
|
*
|
|
267
269
|
*/
|
|
268
270
|
async doRequest(method, id, body, params = API_EMPTY_PARAMS) {
|
|
269
|
-
OINOBenchmark.start("doRequest");
|
|
271
|
+
OINOBenchmark.start("OINODbApi", "doRequest");
|
|
270
272
|
// OINOLog.debug("OINODbApi.doRequest enter", {method:method, id:id, body:body, params:params})
|
|
271
273
|
let result = new OINODbApiResult(params);
|
|
272
274
|
let rows = [];
|
|
@@ -334,7 +336,7 @@ export class OINODbApi {
|
|
|
334
336
|
else {
|
|
335
337
|
result.setError(405, "Unsupported HTTP method '" + method + "'", "DoRequest");
|
|
336
338
|
}
|
|
337
|
-
OINOBenchmark.end("doRequest");
|
|
339
|
+
OINOBenchmark.end("OINODbApi", "doRequest", method);
|
|
338
340
|
return result;
|
|
339
341
|
}
|
|
340
342
|
}
|
|
@@ -229,8 +229,11 @@ export class OINONumberDataField extends OINODbDataField {
|
|
|
229
229
|
*
|
|
230
230
|
*/
|
|
231
231
|
deserializeCell(value) {
|
|
232
|
-
if (
|
|
233
|
-
return
|
|
232
|
+
if (value === undefined) {
|
|
233
|
+
return undefined;
|
|
234
|
+
}
|
|
235
|
+
else if ((value === "") || (value === null)) {
|
|
236
|
+
return null;
|
|
234
237
|
}
|
|
235
238
|
else {
|
|
236
239
|
return Number.parseFloat(value);
|
|
@@ -3,8 +3,7 @@
|
|
|
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 { OINOHttpResult } from "
|
|
7
|
-
import { OINODbApi, OINOContentType, OINODbSqlFilter, OINOStr, OINODbConfig, OINONumberDataField, OINODbSqlOrder, OINODbSqlLimit, OINO_ERROR_PREFIX, OINO_WARNING_PREFIX, OINO_INFO_PREFIX, OINO_DEBUG_PREFIX, OINOLog } from "./index.js";
|
|
6
|
+
import { OINOHttpResult, OINODbApi, OINOContentType, OINODbSqlFilter, OINOStr, OINODbConfig, OINONumberDataField, OINODbSqlOrder, OINODbSqlLimit, OINO_ERROR_PREFIX, OINO_WARNING_PREFIX, OINO_INFO_PREFIX, OINO_DEBUG_PREFIX, OINOLog } from "./index.js";
|
|
8
7
|
/**
|
|
9
8
|
* Static factory class for easily creating things based on data
|
|
10
9
|
*
|
|
@@ -98,6 +97,14 @@ export class OINODbFactory {
|
|
|
98
97
|
if (result.responseType === undefined) {
|
|
99
98
|
result.responseType = OINOContentType.json;
|
|
100
99
|
}
|
|
100
|
+
const last_modified = request.headers.get("if-modified-since");
|
|
101
|
+
if (last_modified) {
|
|
102
|
+
result.lastModified = new Date(last_modified).getTime();
|
|
103
|
+
}
|
|
104
|
+
const etags = request.headers.get("if-none-match")?.split(',').map(e => e.trim());
|
|
105
|
+
if (etags) {
|
|
106
|
+
result.etags = etags;
|
|
107
|
+
}
|
|
101
108
|
// OINOLog.debug("createParamsFromRequest", {params:result})
|
|
102
109
|
return result;
|
|
103
110
|
}
|
|
@@ -25,7 +25,7 @@ export declare class OINODbApiResult extends OINOResult {
|
|
|
25
25
|
* @param headers Headers to include in the response
|
|
26
26
|
*
|
|
27
27
|
*/
|
|
28
|
-
getResponse(headers?:
|
|
28
|
+
getResponse(headers?: Record<string, string>): Response;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Specialized HTML template that can render ´OINODbApiResult´.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { OINOHttpResult } from "
|
|
2
|
-
import { OINODbApi, OINODbApiParams, OINODbParams, OINODbDataModel, OINODb, OINODataRow, OINODbConstructor, OINODbApiRequestParams, OINODbModelSet, OINOResult } from "./index.js";
|
|
1
|
+
import { OINOHttpResult, OINODbApi, OINODbApiParams, OINODbParams, OINODbDataModel, OINODb, OINODataRow, OINODbConstructor, OINODbApiRequestParams, OINODbModelSet, OINOResult } from "./index.js";
|
|
3
2
|
/**
|
|
4
3
|
* Static factory class for easily creating things based on data
|
|
5
4
|
*
|
package/dist/types/index.d.ts
CHANGED
|
@@ -35,7 +35,9 @@ export type OINODbApiParams = {
|
|
|
35
35
|
/** Set (minimum) length (12-32 chars) of the hashids */
|
|
36
36
|
hashidLength?: number;
|
|
37
37
|
/** Make hashids static per row/table */
|
|
38
|
-
|
|
38
|
+
hashidStaticIds?: boolean;
|
|
39
|
+
/** Name of field that has the modified field */
|
|
40
|
+
cacheModifiedField?: string;
|
|
39
41
|
};
|
|
40
42
|
/**
|
|
41
43
|
* Database class (constructor) type
|
|
@@ -88,6 +90,10 @@ export type OINODbApiRequestParams = {
|
|
|
88
90
|
responseType?: OINOContentType;
|
|
89
91
|
/** Multipart boundary token */
|
|
90
92
|
multipartBoundary?: string;
|
|
93
|
+
/** Request last-modified value */
|
|
94
|
+
lastModified?: number;
|
|
95
|
+
/** Request etag values */
|
|
96
|
+
etags?: string[];
|
|
91
97
|
/** SQL parameters */
|
|
92
98
|
sqlParams?: OINODbSqlParams;
|
|
93
99
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oino-ts/db",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "OINO TS library package for publishing an SQL database tables as a REST API.",
|
|
5
5
|
"author": "Matias Kiviniemi (pragmatta)",
|
|
6
6
|
"license": "MPL-2.0",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"types": "./dist/types/index.d.ts",
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@types/node": "^20.14.10",
|
|
23
|
-
"@oino-ts/types": "0.0.
|
|
23
|
+
"@oino-ts/types": "0.0.14"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/bun": "latest",
|
package/src/OINODbApi.test.ts
CHANGED
|
@@ -192,7 +192,7 @@ const apis:OINOTestApiParams[] = [
|
|
|
192
192
|
putRow: [99, "Umeshu", 1, 1, undefined, 24.99, 3, 0, 20, 0]
|
|
193
193
|
},
|
|
194
194
|
{
|
|
195
|
-
apiParams: { tableName: "Employees", hashidKey: "12345678901234567890123456789012" },
|
|
195
|
+
apiParams: { tableName: "Employees", hashidKey: "12345678901234567890123456789012", hashidStaticIds:true },
|
|
196
196
|
requestParams: {
|
|
197
197
|
sqlParams: { filter: OINODbSqlFilter.parse("(TitleOfCourtesy)-eq(Ms.)"), order: OINODbSqlOrder.parse("LastName asc") }
|
|
198
198
|
},
|
package/src/OINODbApi.ts
CHANGED
|
@@ -41,7 +41,7 @@ export class OINODbApiResult extends OINOResult {
|
|
|
41
41
|
* @param headers Headers to include in the response
|
|
42
42
|
*
|
|
43
43
|
*/
|
|
44
|
-
getResponse(headers:
|
|
44
|
+
getResponse(headers:Record<string, string> = {}):Response {
|
|
45
45
|
let response:Response|null = null
|
|
46
46
|
if (this.success && this.data) {
|
|
47
47
|
response = new Response(this.data.writeString(this.params.responseType), {status:this.statusCode, statusText: this.statusMessage, headers: headers })
|
|
@@ -68,11 +68,19 @@ export class OINODbHtmlTemplate extends OINOHtmlTemplate {
|
|
|
68
68
|
*
|
|
69
69
|
*/
|
|
70
70
|
renderFromDbData(modelset:OINODbModelSet):OINOHttpResult {
|
|
71
|
+
OINOBenchmark.start("OINOHtmlTemplate", "renderFromDbData")
|
|
71
72
|
let html:string = ""
|
|
72
73
|
const dataset:OINODbDataSet|undefined = modelset.dataset
|
|
73
74
|
const datamodel:OINODbDataModel = modelset.datamodel
|
|
75
|
+
const api:OINODbApi = modelset.datamodel.api
|
|
76
|
+
const modified_index = datamodel.findFieldIndexByName(api.params.cacheModifiedField || "")
|
|
77
|
+
let last_modified:number = this.modified
|
|
78
|
+
|
|
74
79
|
while (!dataset.isEof()) {
|
|
75
80
|
const row:OINODataRow = dataset.getRow()
|
|
81
|
+
if (modified_index >= 0) {
|
|
82
|
+
last_modified = Math.max(last_modified, new Date(row[modified_index] as Date).getTime())
|
|
83
|
+
}
|
|
76
84
|
let row_id_seed:string = datamodel.getRowPrimarykeyValues(row).join(' ')
|
|
77
85
|
let primary_key_values:string[] = []
|
|
78
86
|
let html_row:string = this.template.replaceAll('###' + OINODbConfig.OINODB_ID_FIELD + '###', '###createHtmlFromData_temporary_oinoid###')
|
|
@@ -85,6 +93,7 @@ export class OINODbHtmlTemplate extends OINOHtmlTemplate {
|
|
|
85
93
|
}
|
|
86
94
|
primary_key_values.push(value || "")
|
|
87
95
|
}
|
|
96
|
+
// OINOLog.debug("renderFromDbData replace field value", {field:f.name, value:value })
|
|
88
97
|
html_row = html_row.replaceAll('###' + f.name + '###', OINOStr.encode(value, OINOContentType.html))
|
|
89
98
|
}
|
|
90
99
|
html_row = html_row.replaceAll('###createHtmlFromData_temporary_oinoid###', OINOStr.encode(OINODbConfig.printOINOId(primary_key_values), OINOContentType.html))
|
|
@@ -92,6 +101,8 @@ export class OINODbHtmlTemplate extends OINOHtmlTemplate {
|
|
|
92
101
|
dataset.next()
|
|
93
102
|
}
|
|
94
103
|
const result:OINOHttpResult = new OINOHttpResult(html)
|
|
104
|
+
result.lastModified = last_modified
|
|
105
|
+
OINOBenchmark.end("OINOHtmlTemplate", "renderFromDbData")
|
|
95
106
|
return result
|
|
96
107
|
}
|
|
97
108
|
|
|
@@ -132,7 +143,7 @@ export class OINODbApi {
|
|
|
132
143
|
this.params = params
|
|
133
144
|
this.datamodel = new OINODbDataModel(this)
|
|
134
145
|
if (this.params.hashidKey) {
|
|
135
|
-
this.hashid = new OINOHashid(this.params.hashidKey, this.db.name, this.params.hashidLength, this.params.
|
|
146
|
+
this.hashid = new OINOHashid(this.params.hashidKey, this.db.name, this.params.hashidLength, this.params.hashidStaticIds)
|
|
136
147
|
} else {
|
|
137
148
|
this.hashid = null
|
|
138
149
|
}
|
|
@@ -173,7 +184,6 @@ export class OINODbApi {
|
|
|
173
184
|
}
|
|
174
185
|
|
|
175
186
|
private async _doGet(result:OINODbApiResult, id:string, params:OINODbApiRequestParams):Promise<void> {
|
|
176
|
-
OINOBenchmark.start("doGet")
|
|
177
187
|
const sql:string = this.datamodel.printSqlSelect(id, params.sqlParams || {})
|
|
178
188
|
// OINOLog.debug("OINODbApi.doGet sql", {sql:sql})
|
|
179
189
|
try {
|
|
@@ -189,11 +199,9 @@ export class OINODbApi {
|
|
|
189
199
|
result.setError(500, "Unhandled exception in doGet: " + e.message, "DoGet")
|
|
190
200
|
result.addDebug("OINO GET SQL [" + sql + "]", "DoGet")
|
|
191
201
|
}
|
|
192
|
-
OINOBenchmark.end("doGet")
|
|
193
202
|
}
|
|
194
203
|
|
|
195
204
|
private async _doPost(result:OINODbApiResult, rows:OINODataRow[]):Promise<void> {
|
|
196
|
-
OINOBenchmark.start("doPost")
|
|
197
205
|
let sql:string = ""
|
|
198
206
|
try {
|
|
199
207
|
let i:number = 0
|
|
@@ -223,11 +231,9 @@ export class OINODbApi {
|
|
|
223
231
|
result.setError(500, "Unhandled exception in doPost: " + e.message, "DoPost")
|
|
224
232
|
result.addDebug("OINO POST SQL [" + sql + "]", "DoPost")
|
|
225
233
|
}
|
|
226
|
-
OINOBenchmark.end("doPost")
|
|
227
234
|
}
|
|
228
235
|
|
|
229
236
|
private async _doPut(result:OINODbApiResult, id:string, row:OINODataRow):Promise<void> {
|
|
230
|
-
OINOBenchmark.start("doPut")
|
|
231
237
|
let sql:string = ""
|
|
232
238
|
try {
|
|
233
239
|
this._validateRowValues(result, row, false)
|
|
@@ -246,11 +252,9 @@ export class OINODbApi {
|
|
|
246
252
|
result.setError(500, "Unhandled exception: " + e.message, "DoPut")
|
|
247
253
|
result.addDebug("OINO POST SQL [" + sql + "]", "DoPut")
|
|
248
254
|
}
|
|
249
|
-
OINOBenchmark.end("doPut")
|
|
250
255
|
}
|
|
251
256
|
|
|
252
257
|
private async _doDelete(result:OINODbApiResult, id:string):Promise<void> {
|
|
253
|
-
OINOBenchmark.start("doDelete")
|
|
254
258
|
let sql:string = ""
|
|
255
259
|
try {
|
|
256
260
|
sql = this.datamodel.printSqlDelete(id)
|
|
@@ -266,7 +270,6 @@ export class OINODbApi {
|
|
|
266
270
|
result.setError(500, "Unhandled exception: " + e.message, "DoDelete")
|
|
267
271
|
result.addDebug("OINO DELETE SQL [" + sql + "]", "DoDelete")
|
|
268
272
|
}
|
|
269
|
-
OINOBenchmark.end("doDelete")
|
|
270
273
|
}
|
|
271
274
|
|
|
272
275
|
/**
|
|
@@ -280,7 +283,7 @@ export class OINODbApi {
|
|
|
280
283
|
*
|
|
281
284
|
*/
|
|
282
285
|
async doRequest(method:string, id: string, body:string|OINODataRow[]|any, params:OINODbApiRequestParams = API_EMPTY_PARAMS):Promise<OINODbApiResult> {
|
|
283
|
-
OINOBenchmark.start("doRequest")
|
|
286
|
+
OINOBenchmark.start("OINODbApi", "doRequest")
|
|
284
287
|
// OINOLog.debug("OINODbApi.doRequest enter", {method:method, id:id, body:body, params:params})
|
|
285
288
|
let result:OINODbApiResult = new OINODbApiResult(params)
|
|
286
289
|
let rows:OINODataRow[] = []
|
|
@@ -345,7 +348,7 @@ export class OINODbApi {
|
|
|
345
348
|
} else {
|
|
346
349
|
result.setError(405, "Unsupported HTTP method '" + method + "'", "DoRequest")
|
|
347
350
|
}
|
|
348
|
-
OINOBenchmark.end("doRequest")
|
|
351
|
+
OINOBenchmark.end("OINODbApi", "doRequest", method)
|
|
349
352
|
return result
|
|
350
353
|
}
|
|
351
354
|
}
|
package/src/OINODbDataField.ts
CHANGED
|
@@ -248,10 +248,12 @@ export class OINONumberDataField extends OINODbDataField {
|
|
|
248
248
|
*
|
|
249
249
|
*/
|
|
250
250
|
deserializeCell(value: string|null|undefined): OINODataCell {
|
|
251
|
-
if (
|
|
252
|
-
return
|
|
251
|
+
if (value === undefined) {
|
|
252
|
+
return undefined
|
|
253
|
+
} else if ((value === "") || (value === null)) {
|
|
254
|
+
return null
|
|
253
255
|
} else {
|
|
254
|
-
return Number.parseFloat(value)
|
|
256
|
+
return Number.parseFloat(value)
|
|
255
257
|
}
|
|
256
258
|
}
|
|
257
259
|
}
|
package/src/OINODbFactory.ts
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { OINOHttpResult } from "
|
|
8
|
-
import { OINODbApi, OINODbApiParams, OINODbParams, OINOContentType, OINODbDataModel, OINODbDataField, OINODb, OINODataRow, OINODbConstructor, OINODbApiRequestParams, OINODbSqlFilter, OINOStr, OINOBlobDataField, OINODbApiResult, OINODbDataSet, OINODbModelSet, OINODbConfig, OINONumberDataField, OINODataCell, OINODbSqlOrder, OINODbSqlLimit, OINO_ERROR_PREFIX, OINO_WARNING_PREFIX, OINO_INFO_PREFIX, OINO_DEBUG_PREFIX, OINOLog, OINODbSqlParams, OINOResult } from "./index.js"
|
|
7
|
+
import { OINOHttpResult, OINODbApi, OINODbApiParams, OINODbParams, OINOContentType, OINODbDataModel, OINODbDataField, OINODb, OINODataRow, OINODbConstructor, OINODbApiRequestParams, OINODbSqlFilter, OINOStr, OINOBlobDataField, OINODbApiResult, OINODbDataSet, OINODbModelSet, OINODbConfig, OINONumberDataField, OINODataCell, OINODbSqlOrder, OINODbSqlLimit, OINO_ERROR_PREFIX, OINO_WARNING_PREFIX, OINO_INFO_PREFIX, OINO_DEBUG_PREFIX, OINOLog, OINODbSqlParams, OINOResult } from "./index.js"
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Static factory class for easily creating things based on data
|
|
@@ -106,6 +105,14 @@ export class OINODbFactory {
|
|
|
106
105
|
if (result.responseType === undefined) {
|
|
107
106
|
result.responseType = OINOContentType.json
|
|
108
107
|
}
|
|
108
|
+
const last_modified = request.headers.get("if-modified-since")
|
|
109
|
+
if (last_modified) {
|
|
110
|
+
result.lastModified = new Date(last_modified).getTime()
|
|
111
|
+
}
|
|
112
|
+
const etags = request.headers.get("if-none-match")?.split(',').map(e => e.trim())
|
|
113
|
+
if (etags) {
|
|
114
|
+
result.etags = etags
|
|
115
|
+
}
|
|
109
116
|
|
|
110
117
|
// OINOLog.debug("createParamsFromRequest", {params:result})
|
|
111
118
|
return result
|
package/src/index.ts
CHANGED
|
@@ -39,7 +39,9 @@ export type OINODbApiParams = {
|
|
|
39
39
|
/** Set (minimum) length (12-32 chars) of the hashids */
|
|
40
40
|
hashidLength?:number,
|
|
41
41
|
/** Make hashids static per row/table */
|
|
42
|
-
|
|
42
|
+
hashidStaticIds?: boolean,
|
|
43
|
+
/** Name of field that has the modified field */
|
|
44
|
+
cacheModifiedField?:string
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
/**
|
|
@@ -98,6 +100,10 @@ export type OINODbApiRequestParams = {
|
|
|
98
100
|
responseType?:OINOContentType
|
|
99
101
|
/** Multipart boundary token */
|
|
100
102
|
multipartBoundary?:string
|
|
103
|
+
/** Request last-modified value */
|
|
104
|
+
lastModified?:number
|
|
105
|
+
/** Request etag values */
|
|
106
|
+
etags?:string[]
|
|
101
107
|
/** SQL parameters */
|
|
102
108
|
sqlParams?:OINODbSqlParams
|
|
103
109
|
}
|