@oino-ts/db 0.21.2 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/cjs/OINODb.js +6 -144
  2. package/dist/cjs/OINODbApi.js +50 -318
  3. package/dist/cjs/OINODbConfig.js +10 -10
  4. package/dist/cjs/OINODbConstants.js +10 -0
  5. package/dist/cjs/OINODbDataField.js +28 -70
  6. package/dist/cjs/OINODbDataModel.js +30 -144
  7. package/dist/cjs/OINODbFactory.js +2 -2
  8. package/dist/cjs/OINODbModelSet.js +23 -23
  9. package/dist/cjs/OINODbQueryParams.js +201 -0
  10. package/dist/cjs/index.js +12 -41
  11. package/dist/esm/OINODb.js +6 -142
  12. package/dist/esm/OINODbApi.js +49 -314
  13. package/dist/esm/OINODbConstants.js +7 -0
  14. package/dist/esm/OINODbDataModel.js +31 -145
  15. package/dist/esm/OINODbFactory.js +1 -1
  16. package/dist/esm/OINODbQueryParams.js +194 -0
  17. package/dist/esm/index.js +4 -14
  18. package/dist/types/OINODb.d.ts +6 -173
  19. package/dist/types/OINODbApi.d.ts +18 -104
  20. package/dist/types/OINODbConstants.d.ts +23 -0
  21. package/dist/types/OINODbDataModel.d.ts +7 -61
  22. package/dist/types/OINODbFactory.d.ts +5 -2
  23. package/dist/types/OINODbQueryParams.d.ts +72 -0
  24. package/dist/types/index.d.ts +4 -108
  25. package/package.json +37 -37
  26. package/src/OINODb.ts +99 -348
  27. package/src/OINODbApi.test.ts +507 -498
  28. package/src/OINODbApi.ts +389 -667
  29. package/src/OINODbConstants.ts +32 -0
  30. package/src/OINODbDataModel.ts +191 -307
  31. package/src/OINODbFactory.ts +73 -68
  32. package/src/OINODbQueryParams.ts +203 -0
  33. package/src/index.ts +6 -118
  34. package/src/OINODbConfig.ts +0 -98
  35. package/src/OINODbDataField.ts +0 -405
  36. package/src/OINODbModelSet.ts +0 -353
  37. package/src/OINODbParser.ts +0 -438
  38. package/src/OINODbSqlParams.ts +0 -593
  39. package/src/OINODbSwagger.ts +0 -209
@@ -1,353 +0,0 @@
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
- import { OINOContentType, OINOStr, OINOLog } from "@oino-ts/common"
8
- import { OINODbDataSet, OINODbDataModel, OINODbDataField, OINODataRow, OINOBlobDataField, OINODbConfig, OINONumberDataField, OINOBooleanDataField, OINODataCell, OINODbSqlParams } from "./index.js";
9
-
10
- /**
11
- * Class for dataset based on a data model that can be serialized to
12
- * a supported format:
13
- * - JSON (application/json)
14
- * - CSV (text/csv)
15
- *
16
- */
17
- export class OINODbModelSet {
18
-
19
- /** Reference to datamodel */
20
- readonly datamodel: OINODbDataModel
21
-
22
- /** Reference to data set */
23
- readonly dataset: OINODbDataSet
24
-
25
- /** SQL parameters */
26
- readonly sqlParams?: OINODbSqlParams
27
-
28
- /** Collection of errors */
29
- errors: string[]
30
-
31
- /**
32
- * Constructor for `OINODbModelSet`.
33
- *
34
- * @param datamodel data model
35
- * @param dataset data set
36
- * @param sqlParams SQL parameters
37
- */
38
- constructor(datamodel: OINODbDataModel, dataset: OINODbDataSet, sqlParams?: OINODbSqlParams) {
39
- this.datamodel = datamodel
40
- this.dataset = dataset
41
- this.sqlParams = sqlParams
42
- this.errors = this.dataset.messages
43
- }
44
-
45
- private _encodeAndHashFieldValue(field:OINODbDataField, value:string|null, contentType:OINOContentType, primaryKeyValues:string[], rowIdSeed:string):string {
46
- let result:string
47
- if (field.fieldParams.isPrimaryKey || field.fieldParams.isForeignKey) {
48
- if (value && (field instanceof OINONumberDataField) && (this.datamodel.api.hashid) && ((this.sqlParams?.aggregate === undefined) || (this.sqlParams.aggregate.isAggregated(field) == false))) {
49
- value = this.datamodel.api.hashid.encode(value, rowIdSeed)
50
- }
51
- if (field.fieldParams.isPrimaryKey) {
52
- primaryKeyValues.push(value || "")
53
- }
54
- }
55
- result = OINOStr.encode(value, contentType)
56
- return result
57
- }
58
-
59
- private _writeRowJson(row:OINODataRow):string {
60
- // console.log("OINODbModelSet._writeRowJson: row=" + row)
61
- const model:OINODbDataModel = this.datamodel
62
- const fields:OINODbDataField[] = model.fields
63
- let row_id_seed:string = model.getRowPrimarykeyValues(row).join(' ')
64
- let primary_key_values:string[] = []
65
- let json_row:string = ""
66
- for (let i=0; i<fields.length; i++) {
67
- const f = fields[i]
68
- if (this.sqlParams?.select?.isSelected(f) === false) {
69
- continue
70
- }
71
- let value:string|null|undefined = f.serializeCell(row[i])
72
- if (value === undefined) {
73
- // skip undefined values
74
-
75
- } else if (value === null) {
76
- json_row += "," + OINOStr.encode(f.name, OINOContentType.json) + ":null"
77
-
78
- } else {
79
-
80
- let is_hashed:boolean = (f.fieldParams.isPrimaryKey || f.fieldParams.isForeignKey) && (f instanceof OINONumberDataField) && (this.datamodel.api.hashid != null)
81
- let is_value = (f instanceof OINOBooleanDataField) || ((f instanceof OINONumberDataField) && !is_hashed)
82
- value = this._encodeAndHashFieldValue(f, value, OINOContentType.json, primary_key_values, f.name + " " + row_id_seed)
83
- if (is_value) {
84
- value = value.substring(1, value.length-1)
85
- }
86
- json_row += "," + OINOStr.encode(f.name, OINOContentType.json) + ":" + value
87
- }
88
- }
89
- json_row = OINOStr.encode(OINODbConfig.OINODB_ID_FIELD, OINOContentType.json) + ":" + OINOStr.encode(OINODbConfig.printOINOId(primary_key_values), OINOContentType.json) + json_row
90
- return "{" + json_row + "}"
91
- }
92
-
93
- private async _writeStringJson():Promise<string> {
94
- let result:string = ""
95
- while (!this.dataset.isEof()) {
96
- if (result != "") {
97
- result += ",\r\n"
98
- }
99
- const row:OINODataRow = this.dataset.getRow()
100
- result += this._writeRowJson(row)
101
- await this.dataset.next()
102
- }
103
- result = "[\r\n" + result + "\r\n]"
104
- return result
105
- }
106
-
107
- private _writeHeaderCsv():string {
108
- const model:OINODbDataModel = this.datamodel
109
- const fields:OINODbDataField[] = model.fields
110
- let csv_header:string = "\"" + OINODbConfig.OINODB_ID_FIELD + "\""
111
- for (let i=0; i<fields.length; i++) {
112
- if (this.sqlParams?.select?.isSelected(fields[i]) === false) {
113
- continue
114
- }
115
- csv_header += ",\"" + fields[i].name + "\""
116
- }
117
- return csv_header
118
- }
119
-
120
- private _writeRowCsv(row:OINODataRow):string {
121
- const model:OINODbDataModel = this.datamodel
122
- const fields:OINODbDataField[] = model.fields
123
- let row_id_seed:string = model.getRowPrimarykeyValues(row).join(' ')
124
- let primary_key_values:string[] = []
125
- let csv_row:string = ""
126
- for (let i=0; i<fields.length; i++) {
127
- const f = fields[i]
128
- if (this.sqlParams?.select?.isSelected(f) === false) {
129
- continue
130
- }
131
- let value:string|null|undefined = f.serializeCell(row[i])
132
- if (value == null) {
133
- csv_row += "," + OINOStr.encode(value, OINOContentType.csv) // either null or undefined
134
-
135
- } else {
136
- value = this._encodeAndHashFieldValue(f, value, OINOContentType.csv, primary_key_values, f.name + " " + row_id_seed)
137
- csv_row += "," + value
138
- }
139
- }
140
- csv_row = OINOStr.encode(OINODbConfig.printOINOId(primary_key_values), OINOContentType.csv) + csv_row
141
- return csv_row
142
- }
143
-
144
- private async _writeStringCsv():Promise<string> {
145
- let result:string = this._writeHeaderCsv()
146
- while (!this.dataset.isEof()) {
147
- if (result != "") {
148
- result += "\r\n"
149
- }
150
- const row:OINODataRow = this.dataset.getRow()
151
- result += this._writeRowCsv(row)
152
- await this.dataset.next()
153
- }
154
- return result
155
- }
156
-
157
- private _writeRowFormdataParameterBlock(blockName:string, blockValue:string|null, multipartBoundary:string):string {
158
- if (blockValue === null) {
159
- return multipartBoundary + "\r\n" + "Content-Disposition: form-data; name=\"" + blockName + "\"\r\n\r\n"
160
- } else {
161
- return multipartBoundary + "\r\n" + "Content-Disposition: form-data; name=\"" + blockName + "\"\r\n\r\n" + blockValue + "\r\n"
162
- }
163
- }
164
-
165
- private _writeRowFormdataFileBlock(blockName:string, blockValue:string, multipartBoundary:string):string {
166
- return multipartBoundary + "\r\n" + "Content-Disposition: form-data; name=\"" + blockName + "\"; filename=" + blockName + "\"\r\nContent-Type: application/octet-stream\r\nContent-Transfer-Encoding: BASE64\r\n\r\n" + blockValue + "\r\n"
167
- }
168
-
169
- private _writeRowFormdata(row:OINODataRow):string {
170
- const multipart_boundary:string = "---------OINOMultipartBoundary35424568" // this method is just used for test data generation and we want it to be static
171
- const model:OINODbDataModel = this.datamodel
172
- const fields:OINODbDataField[] = model.fields
173
- let row_id_seed:string = model.getRowPrimarykeyValues(row).join(' ')
174
- let primary_key_values:string[] = []
175
- let result:string = ""
176
- for (let i=0; i<fields.length; i++) {
177
- const f = fields[i]
178
- if (this.sqlParams?.select?.isSelected(f) === false) {
179
- continue
180
- }
181
- let value:string|null|undefined = f.serializeCell(row[i])
182
- let formdata_block:string = ""
183
- let is_file = (f instanceof OINOBlobDataField)
184
-
185
- if (value === undefined) {
186
- OINOLog.info("@oino-ts/db", "OINODbModelSet", "_writeRowFormdata", "Undefined value skipped", {field_name:f.name})
187
-
188
- } else if (value === null) {
189
- formdata_block = this._writeRowFormdataParameterBlock(fields[i].name, null, multipart_boundary)
190
-
191
- } else {
192
- value = this._encodeAndHashFieldValue(f, value, OINOContentType.formdata, primary_key_values, f.name + " " + row_id_seed)
193
- if (is_file) {
194
- formdata_block = this._writeRowFormdataFileBlock(f.name, value, multipart_boundary)
195
- } else {
196
- formdata_block = this._writeRowFormdataParameterBlock(fields[i].name, value, multipart_boundary)
197
- }
198
- }
199
-
200
- result += formdata_block
201
- }
202
- result = this._writeRowFormdataParameterBlock(OINODbConfig.OINODB_ID_FIELD, OINODbConfig.printOINOId(primary_key_values), multipart_boundary) + result
203
- return result
204
- }
205
-
206
- private _writeStringFormdata():string {
207
- const row:OINODataRow = this.dataset.getRow()
208
- let result:string = this._writeRowFormdata(row)
209
- return result
210
- }
211
-
212
-
213
- private _writeRowUrlencode(row:OINODataRow):string {
214
- const model:OINODbDataModel = this.datamodel
215
- const fields:OINODbDataField[] = model.fields
216
- let row_id_seed:string = model.getRowPrimarykeyValues(row).join(' ')
217
- let primary_key_values:string[] = []
218
- let urlencode_row:string = ""
219
- for (let i=0; i<fields.length; i++) {
220
- const f = fields[i]
221
- if (this.sqlParams?.select?.isSelected(f) === false) {
222
- continue
223
- }
224
- let value:string|null|undefined = f.serializeCell(row[i])
225
- if ((value === undefined)) { // || (value === null)) {
226
- // console.log("OINODbModelSet._writeRowUrlencode undefined field value:" + fields[i].name)
227
- } else {
228
- value = this._encodeAndHashFieldValue(f, value, OINOContentType.urlencode, primary_key_values, f.name + " " + row_id_seed)
229
- if (urlencode_row != "") {
230
- urlencode_row += "&"
231
- }
232
- urlencode_row += OINOStr.encode(f.name, OINOContentType.urlencode) + "=" + value
233
- }
234
- }
235
- urlencode_row = OINOStr.encode(OINODbConfig.OINODB_ID_FIELD, OINOContentType.urlencode) + "=" + OINOStr.encode(OINODbConfig.printOINOId(primary_key_values), OINOContentType.urlencode) + "&" + urlencode_row
236
- return urlencode_row
237
- }
238
-
239
- private async _writeStringUrlencode():Promise<string> {
240
- let result:string = ""
241
- let line_count = 0
242
- while (!this.dataset.isEof()) {
243
- const row:OINODataRow = this.dataset.getRow()
244
- result += this._writeRowUrlencode(row) + "\r\n"
245
- await this.dataset.next()
246
- line_count += 1
247
- }
248
- if (line_count > 1) {
249
- OINOLog.warning("@oino-ts/db", "OINODbModelSet", "_writeStringUrlencode", "Content type " + OINOContentType.urlencode + " does not officially support multiline content!", {})
250
- }
251
- return result
252
- }
253
-
254
- private _exportRow(row:OINODataRow):any {
255
- // console.log("OINODbModelSet._exportRow: row=" + row)
256
- const model:OINODbDataModel = this.datamodel
257
- const fields:OINODbDataField[] = model.fields
258
- let row_id_seed:string = model.getRowPrimarykeyValues(row).join(' ')
259
- let primary_key_values:string[] = []
260
- let result:any = {}
261
- for (let i=0; i<fields.length; i++) {
262
- const f = fields[i]
263
- if (f.fieldParams.isPrimaryKey) {
264
- primary_key_values.push(f.serializeCell(row[i]) || "")
265
- }
266
- if (this.sqlParams?.select?.isSelected(f) === false) {
267
- continue
268
- }
269
- let value:OINODataCell = f.db.parseSqlValueAsCell(row[i], f.sqlType) // retain original value without serialization
270
- if (value === undefined) {
271
- // skip undefined values
272
-
273
- } else if (value === null) { // differentiate null and undefined
274
- result[f.name] = null
275
-
276
- } else {
277
- result[f.name] = value
278
- }
279
- }
280
- result[OINODbConfig.OINODB_ID_FIELD] = OINODbConfig.printOINOId(primary_key_values)
281
- return result
282
- }
283
-
284
-
285
- /**
286
- * Serialize model set in the given format.
287
- *
288
- * @param [contentType=OINOContentType.json] serialization content type
289
- *
290
- */
291
- async writeString(contentType:OINOContentType = OINOContentType.json):Promise<string> {
292
- let result:string = ""
293
- if (contentType == OINOContentType.csv) {
294
- result += await this._writeStringCsv()
295
-
296
- } else if (contentType == OINOContentType.json) {
297
- result += await this._writeStringJson()
298
-
299
- } else if (contentType == OINOContentType.formdata) {
300
- result += await this._writeStringFormdata()
301
-
302
- } else if (contentType == OINOContentType.urlencode) {
303
- result += await this._writeStringUrlencode()
304
-
305
- } else {
306
- OINOLog.error("@oino-ts/db", "OINODbModelSet", "writeString", "Content type is only for input!", {contentType:contentType})
307
- }
308
- return result
309
- }
310
-
311
- /**
312
- * Get value of given field in the current row. Undefined if no rows,
313
- * field not found or value does not exist.
314
- *
315
- * @param fieldName name of the field
316
- * @param serialize serialize the value
317
- *
318
- */
319
- getValueByFieldName(fieldName:string, serialize:boolean = false):OINODataCell {
320
- let result:OINODataCell = undefined
321
- if (!this.dataset.isEof()) {
322
- const current_row:OINODataRow = this.dataset.getRow()
323
- const field_index:number = this.datamodel.findFieldIndexByName(fieldName)
324
- if (field_index >= 0) {
325
- result = current_row[field_index]
326
- if (serialize) {
327
- result = this.datamodel.fields[field_index].serializeCell(result)
328
- }
329
- }
330
- }
331
- return result
332
- }
333
-
334
- /**
335
- * Export all rows as a record with OINOId as key and object with row cells as values.
336
- *
337
- * @param idFieldName optional field name to use as key instead of OINOId
338
- */
339
-
340
- async exportAsRecord(idFieldName?:string):Promise<Record<string, any>> {
341
- const result:Record<string, any> = {}
342
- const row_id_field = idFieldName || OINODbConfig.OINODB_ID_FIELD
343
- while (!this.dataset.isEof()) {
344
- const row_data:OINODataRow = this.dataset.getRow()
345
- const row_export = this._exportRow(row_data)
346
- const row_id = row_export[row_id_field]
347
- result[row_id] = row_export
348
- await this.dataset.next()
349
- }
350
- return result
351
- }
352
-
353
- }