@oino-ts/db 0.12.2 → 0.13.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.
@@ -280,14 +280,18 @@ class OINOBlobDataField extends OINODbDataField {
280
280
  *
281
281
  */
282
282
  serializeCell(cellVal) {
283
+ // console.log("OINOBlobDataField.serializeCell: cellVal", cellVal, typeof(cellVal))
283
284
  if ((cellVal === null) || (cellVal === undefined)) {
284
285
  return cellVal;
285
286
  }
287
+ else if (cellVal instanceof Buffer) {
288
+ return cellVal.toString('base64');
289
+ }
286
290
  else if (cellVal instanceof Uint8Array) {
287
291
  return Buffer.from(cellVal).toString('base64');
288
292
  }
289
293
  else {
290
- return cellVal.toString();
294
+ return this.db.parseSqlValueAsCell(cellVal, this.sqlType)?.toString();
291
295
  }
292
296
  }
293
297
  /**
@@ -63,7 +63,7 @@ class OINODbModelSet {
63
63
  }
64
64
  let value = f.serializeCell(row[i]);
65
65
  if (value === undefined) {
66
- index_js_1.OINOLog.info("@oino-ts/db", "OINODbModelSet", "_writeRowJson", "Undefined value skipped", { field_name: f.name });
66
+ // skip undefined values
67
67
  }
68
68
  else if (value === null) {
69
69
  json_row += "," + index_js_1.OINOStr.encode(f.name, index_js_1.OINOContentType.json) + ":null";
@@ -229,6 +229,32 @@ class OINODbModelSet {
229
229
  }
230
230
  return result;
231
231
  }
232
+ _exportRow(row) {
233
+ // console.log("OINODbModelSet._exportRow: row=" + row)
234
+ const model = this.datamodel;
235
+ const fields = model.fields;
236
+ let row_id_seed = model.getRowPrimarykeyValues(row).join(' ');
237
+ let primary_key_values = [];
238
+ let result = {};
239
+ for (let i = 0; i < fields.length; i++) {
240
+ const f = fields[i];
241
+ if (this.sqlParams?.select?.isSelected(f) === false) {
242
+ continue;
243
+ }
244
+ let value = f.db.parseSqlValueAsCell(row[i], f.sqlType); // retain original value without serialization
245
+ if (value === undefined) {
246
+ // skip undefined values
247
+ }
248
+ else if (value === null) { // differentiate null and undefined
249
+ result[f.name] = null;
250
+ }
251
+ else {
252
+ result[f.name] = value;
253
+ }
254
+ }
255
+ result[index_js_1.OINODbConfig.OINODB_ID_FIELD] = index_js_1.OINODbConfig.printOINOId(primary_key_values);
256
+ return result;
257
+ }
232
258
  /**
233
259
  * Serialize model set in the given format.
234
260
  *
@@ -276,5 +302,19 @@ class OINODbModelSet {
276
302
  }
277
303
  return result;
278
304
  }
305
+ /**
306
+ * Export all rows as a record with OINOId as key and object with row cells as values.
307
+ *
308
+ */
309
+ async exportAsRecord() {
310
+ const result = {};
311
+ while (!this.dataset.isEof()) {
312
+ const row_data = this.dataset.getRow();
313
+ const row_export = this._exportRow(row_data);
314
+ result[row_export[index_js_1.OINODbConfig.OINODB_ID_FIELD]] = row_export;
315
+ await this.dataset.next();
316
+ }
317
+ return result;
318
+ }
279
319
  }
280
320
  exports.OINODbModelSet = OINODbModelSet;
@@ -273,14 +273,18 @@ export class OINOBlobDataField extends OINODbDataField {
273
273
  *
274
274
  */
275
275
  serializeCell(cellVal) {
276
+ // console.log("OINOBlobDataField.serializeCell: cellVal", cellVal, typeof(cellVal))
276
277
  if ((cellVal === null) || (cellVal === undefined)) {
277
278
  return cellVal;
278
279
  }
280
+ else if (cellVal instanceof Buffer) {
281
+ return cellVal.toString('base64');
282
+ }
279
283
  else if (cellVal instanceof Uint8Array) {
280
284
  return Buffer.from(cellVal).toString('base64');
281
285
  }
282
286
  else {
283
- return cellVal.toString();
287
+ return this.db.parseSqlValueAsCell(cellVal, this.sqlType)?.toString();
284
288
  }
285
289
  }
286
290
  /**
@@ -60,7 +60,7 @@ export class OINODbModelSet {
60
60
  }
61
61
  let value = f.serializeCell(row[i]);
62
62
  if (value === undefined) {
63
- OINOLog.info("@oino-ts/db", "OINODbModelSet", "_writeRowJson", "Undefined value skipped", { field_name: f.name });
63
+ // skip undefined values
64
64
  }
65
65
  else if (value === null) {
66
66
  json_row += "," + OINOStr.encode(f.name, OINOContentType.json) + ":null";
@@ -226,6 +226,32 @@ export class OINODbModelSet {
226
226
  }
227
227
  return result;
228
228
  }
229
+ _exportRow(row) {
230
+ // console.log("OINODbModelSet._exportRow: row=" + row)
231
+ const model = this.datamodel;
232
+ const fields = model.fields;
233
+ let row_id_seed = model.getRowPrimarykeyValues(row).join(' ');
234
+ let primary_key_values = [];
235
+ let result = {};
236
+ for (let i = 0; i < fields.length; i++) {
237
+ const f = fields[i];
238
+ if (this.sqlParams?.select?.isSelected(f) === false) {
239
+ continue;
240
+ }
241
+ let value = f.db.parseSqlValueAsCell(row[i], f.sqlType); // retain original value without serialization
242
+ if (value === undefined) {
243
+ // skip undefined values
244
+ }
245
+ else if (value === null) { // differentiate null and undefined
246
+ result[f.name] = null;
247
+ }
248
+ else {
249
+ result[f.name] = value;
250
+ }
251
+ }
252
+ result[OINODbConfig.OINODB_ID_FIELD] = OINODbConfig.printOINOId(primary_key_values);
253
+ return result;
254
+ }
229
255
  /**
230
256
  * Serialize model set in the given format.
231
257
  *
@@ -273,4 +299,18 @@ export class OINODbModelSet {
273
299
  }
274
300
  return result;
275
301
  }
302
+ /**
303
+ * Export all rows as a record with OINOId as key and object with row cells as values.
304
+ *
305
+ */
306
+ async exportAsRecord() {
307
+ const result = {};
308
+ while (!this.dataset.isEof()) {
309
+ const row_data = this.dataset.getRow();
310
+ const row_export = this._exportRow(row_data);
311
+ result[row_export[OINODbConfig.OINODB_ID_FIELD]] = row_export;
312
+ await this.dataset.next();
313
+ }
314
+ return result;
315
+ }
276
316
  }
@@ -35,6 +35,7 @@ export declare class OINODbModelSet {
35
35
  private _writeStringFormdata;
36
36
  private _writeRowUrlencode;
37
37
  private _writeStringUrlencode;
38
+ private _exportRow;
38
39
  /**
39
40
  * Serialize model set in the given format.
40
41
  *
@@ -51,4 +52,9 @@ export declare class OINODbModelSet {
51
52
  *
52
53
  */
53
54
  getValueByFieldName(fieldName: string, serialize?: boolean): OINODataCell;
55
+ /**
56
+ * Export all rows as a record with OINOId as key and object with row cells as values.
57
+ *
58
+ */
59
+ exportAsRecord(): Promise<Record<string, any>>;
54
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oino-ts/db",
3
- "version": "0.12.2",
3
+ "version": "0.13.1",
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",
@@ -19,11 +19,11 @@
19
19
  "module": "./dist/esm/index.js",
20
20
  "types": "./dist/types/index.d.ts",
21
21
  "dependencies": {
22
- "@oino-ts/common": "0.12.2",
22
+ "@oino-ts/common": "0.13.1",
23
23
  "oino-ts": "file:.."
24
24
  },
25
25
  "devDependencies": {
26
- "@oino-ts/types": "0.12.2",
26
+ "@oino-ts/types": "0.13.1",
27
27
  "@types/bun": "^1.1.14",
28
28
  "@types/node": "^20.14.10",
29
29
  "typescript": "~5.9.0"
@@ -108,6 +108,7 @@ const OWASP_TESTS:OINOTestParams[] = [
108
108
  const API_CROSSCHECKS:string[] = [
109
109
  "[HTTP GET] select *: GET JSON 1",
110
110
  "[HTTP GET] select * with template: GET HTML 1",
111
+ "[HTTP GET] select *: GET RECORD 1",
111
112
  "[HTTP POST] insert: GET JSON 1",
112
113
  "[HTTP POST] insert: GET CSV 1",
113
114
  "[HTTP PUT] update JSON: GET JSON 1",
@@ -127,6 +128,7 @@ const OWASP_CROSSCHECKS:string[] = [
127
128
  Math.random()
128
129
 
129
130
  OINOLog.setInstance(new OINOConsoleLog(OINOLogLevel.warning))
131
+ // OINOLog.setLogLevel(OINOLogLevel.debug, "@oino-ts/db-mssql", "OINODbMsSql", "printSqlSelect")
130
132
  OINODbFactory.registerDb("OINODbBunSqlite", OINODbBunSqlite)
131
133
  OINODbFactory.registerDb("OINODbPostgresql", OINODbPostgresql)
132
134
  OINODbFactory.registerDb("OINODbMariadb", OINODbMariadb)
@@ -218,6 +220,10 @@ export async function OINOTestApi(dbParams:OINODbParams, testParams: OINOTestPar
218
220
  expect(encodeData(await (await api.doRequest("GET", "", "", empty_params)).data?.writeString(OINOContentType.csv))).toMatchSnapshot("GET CSV")
219
221
  })
220
222
 
223
+ await test(target_name + target_db + target_table + target_group + " select *", async () => {
224
+ expect(encodeData(JSON.stringify(await (await api.doRequest("GET", "", "", empty_params)).data?.exportAsRecord()))).toMatchSnapshot("GET RECORD")
225
+ })
226
+
221
227
  await test(target_name + target_db + target_table + target_group + " select * with template", async () => {
222
228
  const template = createApiTemplate(api)
223
229
  const api_result:OINODbApiResult = await api.doRequest("GET", "", "", empty_params)
@@ -228,6 +234,7 @@ export async function OINOTestApi(dbParams:OINODbParams, testParams: OINOTestPar
228
234
  await test(target_name + target_db + target_table + target_group + " select * with filter", async () => {
229
235
  expect(encodeData(await (await api.doRequest("GET", "", "", request_params_with_filters)).data?.writeString())).toMatchSnapshot("GET JSON FILTER")
230
236
  })
237
+
231
238
 
232
239
  // remove filter so it does not affect rest of the tests
233
240
  request_params.sqlParams.filter = undefined
@@ -292,14 +292,18 @@ export class OINOBlobDataField extends OINODbDataField {
292
292
  *
293
293
  */
294
294
  serializeCell(cellVal: OINODataCell):string|null|undefined {
295
+ // console.log("OINOBlobDataField.serializeCell: cellVal", cellVal, typeof(cellVal))
295
296
  if ((cellVal === null) || (cellVal === undefined)) {
296
297
  return cellVal
297
298
 
299
+ } else if (cellVal instanceof Buffer) {
300
+ return cellVal.toString('base64')
301
+
298
302
  } else if (cellVal instanceof Uint8Array) {
299
- return Buffer.from(cellVal as Uint8Array).toString('base64')
303
+ return Buffer.from(cellVal).toString('base64')
300
304
 
301
305
  } else {
302
- return cellVal.toString()
306
+ return this.db.parseSqlValueAsCell(cellVal, this.sqlType)?.toString()
303
307
  }
304
308
  }
305
309
 
@@ -69,7 +69,7 @@ export class OINODbModelSet {
69
69
  }
70
70
  let value:string|null|undefined = f.serializeCell(row[i])
71
71
  if (value === undefined) {
72
- OINOLog.info("@oino-ts/db", "OINODbModelSet", "_writeRowJson", "Undefined value skipped", {field_name:f.name})
72
+ // skip undefined values
73
73
 
74
74
  } else if (value === null) {
75
75
  json_row += "," + OINOStr.encode(f.name, OINOContentType.json) + ":null"
@@ -247,6 +247,34 @@ export class OINODbModelSet {
247
247
  return result
248
248
  }
249
249
 
250
+ private _exportRow(row:OINODataRow):any {
251
+ // console.log("OINODbModelSet._exportRow: row=" + row)
252
+ const model:OINODbDataModel = this.datamodel
253
+ const fields:OINODbDataField[] = model.fields
254
+ let row_id_seed:string = model.getRowPrimarykeyValues(row).join(' ')
255
+ let primary_key_values:string[] = []
256
+ let result:any = {}
257
+ for (let i=0; i<fields.length; i++) {
258
+ const f = fields[i]
259
+ if (this.sqlParams?.select?.isSelected(f) === false) {
260
+ continue
261
+ }
262
+ let value:OINODataCell = f.db.parseSqlValueAsCell(row[i], f.sqlType) // retain original value without serialization
263
+ if (value === undefined) {
264
+ // skip undefined values
265
+
266
+ } else if (value === null) { // differentiate null and undefined
267
+ result[f.name] = null
268
+
269
+ } else {
270
+ result[f.name] = value
271
+ }
272
+ }
273
+ result[OINODbConfig.OINODB_ID_FIELD] = OINODbConfig.printOINOId(primary_key_values)
274
+ return result
275
+ }
276
+
277
+
250
278
  /**
251
279
  * Serialize model set in the given format.
252
280
  *
@@ -295,5 +323,21 @@ export class OINODbModelSet {
295
323
  }
296
324
  return result
297
325
  }
298
- }
299
326
 
327
+ /**
328
+ * Export all rows as a record with OINOId as key and object with row cells as values.
329
+ *
330
+ */
331
+
332
+ async exportAsRecord():Promise<Record<string, any>> {
333
+ const result:Record<string, any> = {}
334
+ while (!this.dataset.isEof()) {
335
+ const row_data:OINODataRow = this.dataset.getRow()
336
+ const row_export = this._exportRow(row_data)
337
+ result[row_export[OINODbConfig.OINODB_ID_FIELD]] = row_export
338
+ await this.dataset.next()
339
+ }
340
+ return result
341
+ }
342
+
343
+ }