@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.
@@ -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.hashidRandomIds);
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 (!value) {
239
- return 0;
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 OINOResult_js_1.OINOHttpResult(html);
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 OINOResult_js_1.OINOHttpResult(html);
182
+ const http_result = new index_js_1.OINOHttpResult(html);
176
183
  return http_result;
177
184
  }
178
185
  static _findCsvLineEnd(csvData, start) {
@@ -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.hashidRandomIds);
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 (!value) {
233
- return 0;
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 "../../types/src/OINOResult.js";
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?: HeadersInit): Response;
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 "../../types/src/OINOResult.js";
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
  *
@@ -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
- hashidRandomIds?: boolean;
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.12",
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.12"
23
+ "@oino-ts/types": "0.0.14"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/bun": "latest",
@@ -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:HeadersInit = {}):Response {
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.hashidRandomIds)
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
  }
@@ -248,10 +248,12 @@ export class OINONumberDataField extends OINODbDataField {
248
248
  *
249
249
  */
250
250
  deserializeCell(value: string|null|undefined): OINODataCell {
251
- if (!value) {
252
- return 0
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
  }
@@ -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 "../../types/src/OINOResult.js"
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
- hashidRandomIds?: boolean
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
  }