@oino-ts/db 0.0.11

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.
Files changed (48) hide show
  1. package/README.md +222 -0
  2. package/dist/cjs/OINODb.js +27 -0
  3. package/dist/cjs/OINODbApi.js +270 -0
  4. package/dist/cjs/OINODbConfig.js +86 -0
  5. package/dist/cjs/OINODbDataField.js +354 -0
  6. package/dist/cjs/OINODbDataModel.js +279 -0
  7. package/dist/cjs/OINODbDataSet.js +139 -0
  8. package/dist/cjs/OINODbFactory.js +563 -0
  9. package/dist/cjs/OINODbModelSet.js +267 -0
  10. package/dist/cjs/OINODbParams.js +280 -0
  11. package/dist/cjs/OINODbRequestParams.js +280 -0
  12. package/dist/cjs/OINODbSwagger.js +201 -0
  13. package/dist/cjs/index.js +51 -0
  14. package/dist/esm/OINODb.js +23 -0
  15. package/dist/esm/OINODbApi.js +265 -0
  16. package/dist/esm/OINODbConfig.js +82 -0
  17. package/dist/esm/OINODbDataField.js +345 -0
  18. package/dist/esm/OINODbDataModel.js +275 -0
  19. package/dist/esm/OINODbDataSet.js +134 -0
  20. package/dist/esm/OINODbFactory.js +559 -0
  21. package/dist/esm/OINODbModelSet.js +263 -0
  22. package/dist/esm/OINODbRequestParams.js +274 -0
  23. package/dist/esm/OINODbSwagger.js +197 -0
  24. package/dist/esm/index.js +17 -0
  25. package/dist/types/OINODb.d.ts +75 -0
  26. package/dist/types/OINODbApi.d.ts +57 -0
  27. package/dist/types/OINODbConfig.d.ts +52 -0
  28. package/dist/types/OINODbDataField.d.ts +202 -0
  29. package/dist/types/OINODbDataModel.d.ts +108 -0
  30. package/dist/types/OINODbDataSet.d.ts +95 -0
  31. package/dist/types/OINODbFactory.d.ts +99 -0
  32. package/dist/types/OINODbModelSet.d.ts +50 -0
  33. package/dist/types/OINODbRequestParams.d.ts +130 -0
  34. package/dist/types/OINODbSwagger.d.ts +25 -0
  35. package/dist/types/index.d.ts +103 -0
  36. package/package.json +35 -0
  37. package/src/OINODb.ts +98 -0
  38. package/src/OINODbApi.test.ts +243 -0
  39. package/src/OINODbApi.ts +270 -0
  40. package/src/OINODbConfig.ts +92 -0
  41. package/src/OINODbDataField.ts +372 -0
  42. package/src/OINODbDataModel.ts +290 -0
  43. package/src/OINODbDataSet.ts +170 -0
  44. package/src/OINODbFactory.ts +570 -0
  45. package/src/OINODbModelSet.ts +286 -0
  46. package/src/OINODbRequestParams.ts +281 -0
  47. package/src/OINODbSwagger.ts +209 -0
  48. package/src/index.ts +116 -0
@@ -0,0 +1,265 @@
1
+ /*
2
+ * This Source Code Form is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
+ */
6
+ import { OINODbDataModel, OINOStringDataField, OINO_ERROR_PREFIX, OINODbModelSet, OINOBenchmark, OINODbFactory, OINOLog, OINOResult } from "./index.js";
7
+ import { OINOHashid } from "@oino-ts/hashid";
8
+ /**
9
+ * OINO API request result object with returned data and/or http status code/message and
10
+ * error / warning messages.
11
+ *
12
+ */
13
+ export class OINODbApiResult extends OINOResult {
14
+ /** Returned data if any */
15
+ data;
16
+ /**
17
+ * Constructor of OINODbApiResult.
18
+ *
19
+ * @param data result data
20
+ *
21
+ */
22
+ constructor(data) {
23
+ super();
24
+ this.data = data;
25
+ }
26
+ }
27
+ /**
28
+ * API class with method to process HTTP REST requests.
29
+ *
30
+ */
31
+ export class OINODbApi {
32
+ /** API database reference */
33
+ db;
34
+ /** API datamodel */
35
+ datamodel;
36
+ /** API parameters */
37
+ params;
38
+ /** API hashid */
39
+ hashid;
40
+ /**
41
+ * Constructor of API object.
42
+ * NOTE! OINODb.initDatamodel must be called if created manually instead of the factory.
43
+ *
44
+ * @param db database for the API
45
+ * @param params parameters for the API
46
+ *
47
+ */
48
+ constructor(db, params) {
49
+ // OINOLog.debug("OINODbApi.constructor", {db:db, tableName:tableName, params:params})
50
+ if (!params.tableName) {
51
+ throw new Error(OINO_ERROR_PREFIX + ": OINODbApiParams needs to define a table name!");
52
+ }
53
+ this.db = db;
54
+ this.params = params;
55
+ this.datamodel = new OINODbDataModel(this);
56
+ if (this.params.hashidKey) {
57
+ this.hashid = new OINOHashid(this.params.hashidKey, this.db.name, this.params.hashidLength, this.params.hashidRandomIds);
58
+ }
59
+ else {
60
+ this.hashid = null;
61
+ }
62
+ }
63
+ _validateRowValues(httpResult, row, requirePrimaryKey) {
64
+ let field;
65
+ for (let i = 0; i < this.datamodel.fields.length; i++) {
66
+ field = this.datamodel.fields[i];
67
+ // OINOLog.debug("OINODbApi.validateHttpValues", {field:field})
68
+ const val = row[i];
69
+ // OINOLog.debug("OINODbApi.validateHttpValues", {val:val})
70
+ if ((val === null) && ((field.fieldParams.isNotNull) || (field.fieldParams.isPrimaryKey))) { // null is a valid SQL value except if it's not allowed
71
+ httpResult.setError(405, "Field '" + field.name + "' is not allowed to be NULL!", "ValidateRowValues");
72
+ }
73
+ else if ((val === undefined) && (requirePrimaryKey) && (field.fieldParams.isPrimaryKey) && (!field.fieldParams.isAutoInc)) {
74
+ httpResult.setError(405, "Primary key '" + field.name + "' is not autoinc and missing from the data!", "ValidateRowValues");
75
+ }
76
+ else if ((val !== undefined) && (this.params.failOnUpdateOnAutoinc) && (field.fieldParams.isAutoInc)) {
77
+ httpResult.setError(405, "Autoinc field '" + field.name + "' can't be updated!", "ValidateRowValues");
78
+ }
79
+ else {
80
+ if ((field instanceof OINOStringDataField) && ((field.maxLength > 0))) {
81
+ const str_val = val?.toString() || "";
82
+ // OINOLog.debug("OINODbApi.validateHttpValues", {f:str_field, val:val})
83
+ if (str_val.length > field.maxLength) {
84
+ if (this.params.failOnOversizedValues) {
85
+ httpResult.setError(405, "Field '" + field.name + "' length (" + str_val.length + ") exceeds maximum (" + field.maxLength + ") and can't be set!", "ValidateRowValues");
86
+ }
87
+ else {
88
+ httpResult.addWarning("Field '" + field.name + "' length (" + str_val.length + ") exceeds maximum (" + field.maxLength + ") and might truncate or fail.", "ValidateRowValues");
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ //logDebug("OINODbApi.validateHttpValues", {result:result})
95
+ }
96
+ async _doGet(result, id, params) {
97
+ OINOBenchmark.start("doGet");
98
+ const sql = this.datamodel.printSqlSelect(id, params.sqlParams);
99
+ // OINOLog.debug("OINODbApi.doGet sql", {sql:sql})
100
+ try {
101
+ const sql_res = await this.db.sqlSelect(sql);
102
+ // OINOLog.debug("OINODbApi.doGet sql_res", {sql_res:sql_res})
103
+ if (sql_res.hasErrors()) {
104
+ result.setError(500, sql_res.getFirstError(), "DoGet");
105
+ result.addDebug("OINO GET SQL [" + sql + "]", "DoPut");
106
+ }
107
+ else {
108
+ result.data = new OINODbModelSet(this.datamodel, sql_res);
109
+ }
110
+ }
111
+ catch (e) {
112
+ result.setError(500, "Unhandled exception in doGet: " + e.message, "DoGet");
113
+ result.addDebug("OINO GET SQL [" + sql + "]", "DoGet");
114
+ }
115
+ OINOBenchmark.end("doGet");
116
+ }
117
+ async _doPost(result, rows) {
118
+ OINOBenchmark.start("doPost");
119
+ let sql = "";
120
+ try {
121
+ let i = 0;
122
+ while (i < rows.length) {
123
+ this._validateRowValues(result, rows[i], this.params.failOnInsertWithoutKey || false);
124
+ if (result.success) {
125
+ sql += this.datamodel.printSqlInsert(rows[i]);
126
+ }
127
+ result.setOk(); // individual rows may fail and will just be messages in response similar to executing multiple sql statements
128
+ i++;
129
+ }
130
+ if (sql == "") {
131
+ result.setError(405, "No valid rows for POST!", "DoPost");
132
+ result.addDebug("OINO POST DATA [" + rows.join("|") + "]", "DoPost");
133
+ }
134
+ else {
135
+ // OINOLog.debug("OINODbApi.doPost sql", {sql:sql})
136
+ const sql_res = await this.db.sqlExec(sql);
137
+ // OINOLog.debug("OINODbApi.doPost sql_res", {sql_res:sql_res})
138
+ if (sql_res.hasErrors()) {
139
+ result.setError(500, sql_res.getFirstError(), "DoPost");
140
+ result.addDebug("OINO POST MESSAGES [" + sql_res.messages.join('|') + "]", "DoPost");
141
+ result.addDebug("OINO POST SQL [" + sql + "]", "DoPost");
142
+ }
143
+ }
144
+ }
145
+ catch (e) {
146
+ result.setError(500, "Unhandled exception in doPost: " + e.message, "DoPost");
147
+ result.addDebug("OINO POST SQL [" + sql + "]", "DoPost");
148
+ }
149
+ OINOBenchmark.end("doPost");
150
+ }
151
+ async _doPut(result, id, row) {
152
+ OINOBenchmark.start("doPut");
153
+ let sql = "";
154
+ try {
155
+ this._validateRowValues(result, row, false);
156
+ if (result.success) {
157
+ sql = this.datamodel.printSqlUpdate(id, row);
158
+ // OINOLog.debug("OINODbApi.doPut sql", {sql:sql})
159
+ const sql_res = await this.db.sqlExec(sql);
160
+ // OINOLog.debug("OINODbApi.doPut sql_res", {sql_res:sql_res})
161
+ if (sql_res.hasErrors()) {
162
+ result.setError(500, sql_res.getFirstError(), "DoPut");
163
+ result.addDebug("OINO PUT MESSAGES [" + sql_res.messages.join('|') + "]", "DoPut");
164
+ result.addDebug("OINO PUT SQL [" + sql + "]", "DoPut");
165
+ }
166
+ }
167
+ }
168
+ catch (e) {
169
+ result.setError(500, "Unhandled exception: " + e.message, "DoPut");
170
+ result.addDebug("OINO POST SQL [" + sql + "]", "DoPut");
171
+ }
172
+ OINOBenchmark.end("doPut");
173
+ }
174
+ async _doDelete(result, id) {
175
+ OINOBenchmark.start("doDelete");
176
+ let sql = "";
177
+ try {
178
+ sql = this.datamodel.printSqlDelete(id);
179
+ // OINOLog.debug("OINODbApi.doDelete sql", {sql:sql})
180
+ const sql_res = await this.db.sqlExec(sql);
181
+ // OINOLog.debug("OINODbApi.doDelete sql_res", {sql_res:sql_res})
182
+ if (sql_res.hasErrors()) {
183
+ result.setError(500, sql_res.getFirstError(), "DoDelete");
184
+ result.addDebug("OINO DELETE MESSAGES [" + sql_res.messages.join('|') + "]", "DoDelete");
185
+ result.addDebug("OINO DELETE SQL [" + sql + "]", "DoDelete");
186
+ }
187
+ }
188
+ catch (e) {
189
+ result.setError(500, "Unhandled exception: " + e.message, "DoDelete");
190
+ result.addDebug("OINO DELETE SQL [" + sql + "]", "DoDelete");
191
+ }
192
+ OINOBenchmark.end("doDelete");
193
+ }
194
+ /**
195
+ * Method for handlind a HTTP REST request with GET, POST, PUT, DELETE corresponding to
196
+ * SQL select, insert, update and delete.
197
+ *
198
+ * @param method HTTP verb (uppercase)
199
+ * @param id URL id of the REST request
200
+ * @param body HTTP body data as string
201
+ * @param params HTTP URL parameters as key-value-pairs
202
+ *
203
+ */
204
+ async doRequest(method, id, body, params) {
205
+ OINOBenchmark.start("doRequest");
206
+ let result = new OINODbApiResult();
207
+ OINOLog.debug("OINODbApi.doRequest enter", { method: method, id: id, body: body, searchParams: params });
208
+ if (method == "GET") {
209
+ await this._doGet(result, id, params);
210
+ }
211
+ else if (method == "PUT") {
212
+ const rows = OINODbFactory.createRows(this.datamodel, body, params);
213
+ if (!id) {
214
+ result.setError(400, "HTTP PUT method requires an URL ID for the row that is updated!", "DoRequest");
215
+ }
216
+ else if (rows.length != 1) {
217
+ result.setError(400, "HTTP PUT method requires exactly one row in the body data!", "DoRequest");
218
+ }
219
+ else {
220
+ try {
221
+ await this._doPut(result, id, rows[0]);
222
+ }
223
+ catch (e) {
224
+ result.setError(500, "Unhandled exception in HTTP PUT doRequest: " + e.message, "DoRequest");
225
+ }
226
+ }
227
+ }
228
+ else if (method == "POST") {
229
+ const rows = OINODbFactory.createRows(this.datamodel, body, params);
230
+ if (id) {
231
+ result.setError(400, "HTTP POST method must not have an URL ID as it does not target an existing row but creates a new one!", "DoRequest");
232
+ }
233
+ else if (rows.length == 0) {
234
+ result.setError(400, "HTTP POST method requires at least one row in the body data!", "DoRequest");
235
+ }
236
+ else {
237
+ try {
238
+ OINOLog.debug("OINODbApi.doRequest / POST", { rows: rows });
239
+ await this._doPost(result, rows);
240
+ }
241
+ catch (e) {
242
+ result.setError(500, "Unhandled exception in HTTP POST doRequest: " + e.message, "DoRequest");
243
+ }
244
+ }
245
+ }
246
+ else if (method == "DELETE") {
247
+ if (!id) {
248
+ result.setError(400, "HTTP DELETE method requires an id!", "DoRequest");
249
+ }
250
+ else {
251
+ try {
252
+ await this._doDelete(result, id);
253
+ }
254
+ catch (e) {
255
+ result.setError(500, "Unhandled exception in HTTP DELETE doRequest: " + e.message, "DoRequest");
256
+ }
257
+ }
258
+ }
259
+ else {
260
+ result.setError(405, "Unsupported HTTP method '" + method + "'", "DoRequest");
261
+ }
262
+ OINOBenchmark.end("doRequest");
263
+ return result;
264
+ }
265
+ }
@@ -0,0 +1,82 @@
1
+ /** Set the name of the OINO ID field (default \_OINOID\_) */
2
+ export class OINODbConfig {
3
+ /** Name of the synthetic OINO ID field */
4
+ static OINODB_ID_FIELD = "_OINOID_";
5
+ /** Private key separator of the synthetic OINO ID field */
6
+ static OINODB_ID_SEPARATOR = "_";
7
+ static OINODB_ID_SEPARATOR_ESCAPED = "%";
8
+ /** Name of the OINODbSqlFilter-parameter in request */
9
+ static OINODB_SQL_FILTER_PARAM = "oinosqlfilter";
10
+ /** Name of the OINODbSqlOrder-parameter in request */
11
+ static OINODB_SQL_ORDER_PARAM = "oinosqlorder";
12
+ /** Name of the OINODbSqlLimit-parameter in request */
13
+ static OINODB_SQL_LIMIT_PARAM = "oinosqllimit";
14
+ /**
15
+ * Set the name of the OINO ID field
16
+ * @param idField name of the OINO ID field
17
+ */
18
+ static setOinoIdField(idField) {
19
+ if (idField) {
20
+ OINODbConfig.OINODB_ID_FIELD = idField;
21
+ }
22
+ }
23
+ /**
24
+ * Set the separator character of the OINO ID field
25
+ * @param idSeparator character to use as separator of id parts
26
+ */
27
+ static setOinoIdSeparator(idSeparator) {
28
+ if (idSeparator && (idSeparator.length == 1)) {
29
+ OINODbConfig.OINODB_ID_SEPARATOR = idSeparator;
30
+ OINODbConfig.OINODB_ID_SEPARATOR_ESCAPED = '%' + idSeparator.charCodeAt(0).toString(16);
31
+ }
32
+ }
33
+ /**
34
+ * Print OINO ID for primary key values.
35
+ *
36
+ * @param primaryKeys an array of primary key values.
37
+ *
38
+ */
39
+ static printOINOId(primaryKeys) {
40
+ let result = "";
41
+ for (let i = 0; i < primaryKeys.length; i++) {
42
+ if (i > 0) {
43
+ result += OINODbConfig.OINODB_ID_SEPARATOR;
44
+ }
45
+ result += encodeURIComponent(primaryKeys[i]).replaceAll(OINODbConfig.OINODB_ID_SEPARATOR, OINODbConfig.OINODB_ID_SEPARATOR_ESCAPED);
46
+ }
47
+ return result;
48
+ }
49
+ /**
50
+ * Set the name of the OINODbSqlFilter-param field
51
+ *
52
+ * @param sqlFilterParam name of the http parameter with `OINODbSqlFilter` definition
53
+ *
54
+ */
55
+ static setOinoSqlFilterParam(sqlFilterParam) {
56
+ if (sqlFilterParam) {
57
+ OINODbConfig.OINODB_SQL_FILTER_PARAM = sqlFilterParam;
58
+ }
59
+ }
60
+ /**
61
+ * Set the name of the OINODbSqlOrder-param field
62
+ *
63
+ * @param sqlOrderParam name of the http parameter with `OINODbSqlOrder` definition
64
+ *
65
+ */
66
+ static setOinoSqlOrderParam(sqlOrderParam) {
67
+ if (sqlOrderParam) {
68
+ OINODbConfig.OINODB_SQL_ORDER_PARAM = sqlOrderParam;
69
+ }
70
+ }
71
+ /**
72
+ * Set the name of the OINODbSqlLimit-param field
73
+ *
74
+ * @param sqlLimitParam name of the http parameter with `OINODbSqlLimit` definition
75
+ *
76
+ */
77
+ static setOinoSqlLimitParam(sqlLimitParam) {
78
+ if (sqlLimitParam) {
79
+ OINODbConfig.OINODB_SQL_LIMIT_PARAM = sqlLimitParam;
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,345 @@
1
+ /*
2
+ * This Source Code Form is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
+ */
6
+ /**
7
+ * Base class for a column of data responsible for appropriatelly serializing/deserializing the data.
8
+ *
9
+ */
10
+ export class OINODbDataField {
11
+ /** OINODB reference*/
12
+ db;
13
+ /** Name of the field */
14
+ name;
15
+ /** Internal type of field*/
16
+ type;
17
+ /** SQL type of the field */
18
+ sqlType;
19
+ /** Maximum length of the field (or 0) */
20
+ maxLength;
21
+ /** Parameters for the field */
22
+ fieldParams;
23
+ /**
24
+ * Constructor for a data field
25
+ *
26
+ * @param db OINODb reference
27
+ * @param name name of the field
28
+ * @param type internal type of the field
29
+ * @param sqlType column type in database
30
+ * @param fieldParams parameters of the field
31
+ * @param maxLength maximum length of the field (or 0)
32
+ *
33
+ */
34
+ constructor(db, name, type, sqlType, fieldParams, maxLength = 0) {
35
+ this.db = db;
36
+ this.name = name;
37
+ this.type = type;
38
+ this.maxLength = maxLength;
39
+ this.sqlType = sqlType;
40
+ this.fieldParams = fieldParams;
41
+ // OINOLog.debug("OINODbDataField.constructor", {this:this})
42
+ }
43
+ /**
44
+ * Pring debug information for the field
45
+ *
46
+ * @param length length of the debug output (or 0 for as long as needed)
47
+ *
48
+ */
49
+ printColumnDebug(length = 0) {
50
+ let params = "";
51
+ if (this.fieldParams.isPrimaryKey) {
52
+ params += "PK ";
53
+ }
54
+ if (this.fieldParams.isAutoInc) {
55
+ params += "AUTOINC ";
56
+ }
57
+ if (this.fieldParams.isNotNull) {
58
+ params += "NOTNUL ";
59
+ }
60
+ if (params != "") {
61
+ params = "{" + params.trim() + "}";
62
+ }
63
+ if (this.maxLength > 0) {
64
+ params = this.sqlType + "(" + this.maxLength + ")" + params;
65
+ }
66
+ else {
67
+ params = this.sqlType + params;
68
+ }
69
+ const name_length = length - 2 - 1 - params.length;
70
+ let result = this.name;
71
+ if (length > 0) {
72
+ if (result.length > name_length) {
73
+ result = result.substring(0, name_length - 2) + "..";
74
+ }
75
+ result = (result + ":" + params).padEnd(length - 2, " ");
76
+ }
77
+ else {
78
+ result = this.type + ":" + result + ":" + params;
79
+ }
80
+ return "[" + result + "]";
81
+ }
82
+ /**
83
+ * Serialize cell value in the given content format.
84
+ *
85
+ * @param cellVal cell value
86
+ *
87
+ */
88
+ serializeCell(cellVal) {
89
+ cellVal = this.db.parseSqlValueAsCell(cellVal, this.sqlType);
90
+ if ((cellVal === null) || (cellVal === undefined)) {
91
+ return cellVal; // let content type encoder worry what to do with the value (so not force it to string)
92
+ }
93
+ else {
94
+ return cellVal.toString();
95
+ }
96
+ }
97
+ /**
98
+ * Parce cell value from string using field type specific formatting rules.
99
+ *
100
+ * @param value string value
101
+ *
102
+ */
103
+ deserializeCell(value) {
104
+ return value;
105
+ }
106
+ /**
107
+ * Print data cell (from deserialization) as SQL-string.
108
+ *
109
+ * @param cellVal cell value
110
+ *
111
+ */
112
+ printCellAsSqlValue(cellVal) {
113
+ return this.db.printCellAsSqlValue(cellVal, this.sqlType);
114
+ }
115
+ /**
116
+ * Print name of column as SQL.
117
+ *
118
+ */
119
+ printSqlColumnName() {
120
+ return this.db.printSqlColumnname(this.name);
121
+ }
122
+ }
123
+ /**
124
+ * Specialised class for a string column.
125
+ *
126
+ */
127
+ export class OINOStringDataField extends OINODbDataField {
128
+ /**
129
+ * Constructor for a string data field
130
+ *
131
+ * @param db OINODb reference
132
+ * @param name name of the field
133
+ * @param sqlType column type in database
134
+ * @param fieldParams parameters of the field
135
+ * @param maxLength maximum length of the field (or 0)
136
+ *
137
+ */
138
+ constructor(db, name, sqlType, fieldParams, maxLength) {
139
+ super(db, name, "string", sqlType, fieldParams, maxLength);
140
+ }
141
+ }
142
+ /**
143
+ * Specialised class for a boolean column.
144
+ *
145
+ */
146
+ export class OINOBooleanDataField extends OINODbDataField {
147
+ /**
148
+ * Constructor for a boolean data field
149
+ *
150
+ * @param db OINODb reference
151
+ * @param name name of the field
152
+ * @param sqlType column type in database
153
+ * @param fieldParams parameters of the field
154
+ *
155
+ */
156
+ constructor(db, name, sqlType, fieldParams) {
157
+ super(db, name, "boolean", sqlType, fieldParams);
158
+ }
159
+ /**
160
+ * Serialize cell value in the given content format.
161
+ *
162
+ * @param cellVal cell value
163
+ *
164
+ */
165
+ serializeCell(cellVal) {
166
+ const parsed_value = (this.db.parseSqlValueAsCell(cellVal, this.sqlType) || "").toString();
167
+ let result;
168
+ // console.log("OINOBooleanDataField.serializeCell: parsed_value=" + parsed_value)
169
+ if ((parsed_value == "") || (parsed_value.toLowerCase() == "false") || (parsed_value.match(/^0+$/))) {
170
+ result = "false";
171
+ }
172
+ else {
173
+ result = "true";
174
+ }
175
+ return result;
176
+ }
177
+ /**
178
+ * Parce cell value from string using field type specific formatting rules.
179
+ *
180
+ * @param value string value
181
+ *
182
+ */
183
+ deserializeCell(value) {
184
+ if (value == null || value == "" || value.toString().toLowerCase() == "false" || value == "0") { // TODO: testaa poistaa .toString()
185
+ return false;
186
+ }
187
+ else {
188
+ return true;
189
+ }
190
+ }
191
+ }
192
+ /**
193
+ * Specialised class for a number column.
194
+ *
195
+ */
196
+ export class OINONumberDataField extends OINODbDataField {
197
+ /**
198
+ * Constructor for a string data field
199
+ *
200
+ * @param db OINODb reference
201
+ * @param name name of the field
202
+ * @param sqlType column type in database
203
+ * @param fieldParams parameters of the field
204
+ *
205
+ */
206
+ constructor(db, name, sqlType, fieldParams) {
207
+ super(db, name, "number", sqlType, fieldParams);
208
+ }
209
+ /**
210
+ * Serialize cell value in the given content format.
211
+ *
212
+ * @param cellVal cell value
213
+ *
214
+ */
215
+ serializeCell(cellVal) {
216
+ let result;
217
+ if ((cellVal === null) || (cellVal === undefined) || (cellVal === "")) {
218
+ result = null;
219
+ }
220
+ else {
221
+ result = cellVal.toString();
222
+ }
223
+ return result;
224
+ }
225
+ /**
226
+ * Parce cell value from string using field type specific formatting rules.
227
+ *
228
+ * @param value string value
229
+ *
230
+ */
231
+ deserializeCell(value) {
232
+ if (!value) {
233
+ return 0;
234
+ }
235
+ else {
236
+ return Number.parseFloat(value);
237
+ }
238
+ }
239
+ }
240
+ /**
241
+ * Specialised class for a blob column.
242
+ *
243
+ */
244
+ export class OINOBlobDataField extends OINODbDataField {
245
+ /**
246
+ * Constructor for a blob data field
247
+ *
248
+ * @param db OINODb reference
249
+ * @param name name of the field
250
+ * @param sqlType column type in database
251
+ * @param fieldParams parameters of the field
252
+ * @param maxLength maximum length of the field (or 0)
253
+ *
254
+ */
255
+ constructor(db, name, sqlType, fieldParams, maxLength) {
256
+ super(db, name, "blob", sqlType, fieldParams, maxLength);
257
+ }
258
+ /**
259
+ * Serialize cell value in the given content format.
260
+ *
261
+ * @param cellVal cell value
262
+ *
263
+ */
264
+ serializeCell(cellVal) {
265
+ // OINOLog.debug("OINOBlobDataField.serializeCell", {cellVal:cellVal})
266
+ if ((cellVal === null) || (cellVal === undefined)) {
267
+ return cellVal;
268
+ }
269
+ else if (cellVal instanceof Uint8Array) {
270
+ return Buffer.from(cellVal).toString('base64');
271
+ }
272
+ else {
273
+ return cellVal.toString();
274
+ }
275
+ }
276
+ /**
277
+ * Parce cell value from string using field type specific formatting rules.
278
+ *
279
+ * @param value string value
280
+ *
281
+ */
282
+ deserializeCell(value) {
283
+ if (value == null) {
284
+ return new Buffer(0);
285
+ }
286
+ else {
287
+ return Buffer.from(value, 'base64'); // Blob-field data is base64 encoded and converted internally to UInt8Array / Buffer
288
+ }
289
+ }
290
+ }
291
+ /**
292
+ * Specialised class for a datetime column.
293
+ *
294
+ */
295
+ export class OINODatetimeDataField extends OINODbDataField {
296
+ /**
297
+ * Constructor for a string data field
298
+ *
299
+ * @param db OINODb reference
300
+ * @param name name of the field
301
+ * @param sqlType column type in database
302
+ * @param fieldParams parameters of the field
303
+ *
304
+ */
305
+ constructor(db, name, sqlType, fieldParams) {
306
+ super(db, name, "datetime", sqlType, fieldParams);
307
+ }
308
+ /**
309
+ * Serialize cell value in the given content format.
310
+ *
311
+ * @param cellVal cell value
312
+ *
313
+ */
314
+ serializeCell(cellVal) {
315
+ // OINOLog.debug("OINODatetimeDataField.serializeCell", {cellVal:cellVal, type:typeof(cellVal)})
316
+ if (typeof (cellVal) == "string") {
317
+ cellVal = this.db.parseSqlValueAsCell(cellVal, this.sqlType);
318
+ // OINOLog.debug("OINODatetimeDataField.serializeCell parsed", {cellVal:cellVal, type:typeof(cellVal)})
319
+ }
320
+ if ((cellVal === null) || (cellVal === undefined)) {
321
+ return cellVal;
322
+ }
323
+ else if (cellVal instanceof Date) {
324
+ return cellVal.toISOString();
325
+ }
326
+ else {
327
+ return cellVal.toString();
328
+ }
329
+ }
330
+ /**
331
+ * Parce cell value from string using field type specific formatting rules.
332
+ *
333
+ * @param value string value
334
+ *
335
+ */
336
+ deserializeCell(value) {
337
+ // OINOLog.debug("OINODatetimeDataField.deserializeCell", {strVal:strVal})
338
+ if ((value === null) || (value === undefined)) {
339
+ return value;
340
+ }
341
+ else {
342
+ return new Date(value);
343
+ }
344
+ }
345
+ }