@oino-ts/db 0.17.1 → 0.17.2
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 +9 -0
- package/dist/esm/OINODbApi.js +9 -0
- package/dist/types/OINODbApi.d.ts +1 -0
- package/package.json +37 -37
- package/src/OINODb.ts +321 -321
- package/src/OINODbApi.test.ts +492 -492
- package/src/OINODbApi.ts +611 -602
- package/src/OINODbConfig.ts +98 -98
- package/src/OINODbDataField.ts +403 -403
- package/src/OINODbDataModel.ts +291 -291
- package/src/OINODbFactory.ts +68 -68
- package/src/OINODbModelSet.ts +351 -351
- package/src/OINODbParser.ts +447 -447
- package/src/OINODbSqlParams.ts +592 -592
- package/src/OINODbSwagger.ts +208 -208
- package/src/index.ts +120 -120
package/src/OINODb.ts
CHANGED
|
@@ -1,321 +1,321 @@
|
|
|
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 { OINODbParams, OINODbApi, OINODataCell, OINO_ERROR_PREFIX, OINODataRow, OINODB_EMPTY_ROW, OINOResult, OINOLog } from "./index.js"
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Base class for database abstraction, implementing methods for connecting, making queries and parsing/formatting data
|
|
11
|
-
* between SQL and serialization formats.
|
|
12
|
-
*
|
|
13
|
-
*/
|
|
14
|
-
export abstract class OINODb {
|
|
15
|
-
|
|
16
|
-
protected _params:OINODbParams
|
|
17
|
-
|
|
18
|
-
/** Name of the database */
|
|
19
|
-
readonly name:string
|
|
20
|
-
|
|
21
|
-
isConnected:boolean = false
|
|
22
|
-
isValidated:boolean = false
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Constructor for `OINODb`.
|
|
26
|
-
* @param params database parameters
|
|
27
|
-
*/
|
|
28
|
-
constructor(params:OINODbParams) {
|
|
29
|
-
this._params = { ...params } // make a shallow copy of params so that changes to them do not affect the original object
|
|
30
|
-
this.name = this._params.database
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Connect to database.
|
|
35
|
-
*
|
|
36
|
-
*/
|
|
37
|
-
abstract connect(): Promise<OINOResult>
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Validate connection to database is working.
|
|
41
|
-
*
|
|
42
|
-
*/
|
|
43
|
-
abstract validate(): Promise<OINOResult>
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Print a table name using database specific SQL escaping.
|
|
47
|
-
*
|
|
48
|
-
* @param sqlTable name of the table
|
|
49
|
-
*
|
|
50
|
-
*/
|
|
51
|
-
abstract printSqlTablename(sqlTable:string): string
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Print a column name with correct SQL escaping.
|
|
55
|
-
*
|
|
56
|
-
* @param sqlColumn name of the column
|
|
57
|
-
*
|
|
58
|
-
*/
|
|
59
|
-
abstract printSqlColumnname(sqlColumn:string): string
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Print a single data value from serialization using the context of the native data
|
|
63
|
-
* type with the correct SQL escaping.
|
|
64
|
-
*
|
|
65
|
-
* @param cellValue data from sql results
|
|
66
|
-
* @param sqlType native type name for table column
|
|
67
|
-
*
|
|
68
|
-
*/
|
|
69
|
-
abstract printCellAsSqlValue(cellValue:OINODataCell, sqlType: string): string
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Print a single string value as valid sql literal
|
|
73
|
-
*
|
|
74
|
-
* @param sqlString string value
|
|
75
|
-
*
|
|
76
|
-
*/
|
|
77
|
-
abstract printSqlString(sqlString:string): string
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Parse a single SQL result value for serialization using the context of the native data
|
|
81
|
-
* type.
|
|
82
|
-
*
|
|
83
|
-
* @param sqlValue data from serialization
|
|
84
|
-
* @param sqlType native type name for table column
|
|
85
|
-
*
|
|
86
|
-
*/
|
|
87
|
-
abstract parseSqlValueAsCell(sqlValue:OINODataCell, sqlType: string): OINODataCell
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Execute a select operation.
|
|
91
|
-
*
|
|
92
|
-
* @param sql SQL statement.
|
|
93
|
-
*
|
|
94
|
-
*/
|
|
95
|
-
abstract sqlSelect(sql:string): Promise<OINODbDataSet>
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Execute other sql operations.
|
|
99
|
-
*
|
|
100
|
-
* @param sql SQL statement.
|
|
101
|
-
*
|
|
102
|
-
*/
|
|
103
|
-
abstract sqlExec(sql:string): Promise<OINODbDataSet>
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Initialize a data model by getting the SQL schema and populating OINODbDataFields of
|
|
107
|
-
* the model.
|
|
108
|
-
*
|
|
109
|
-
* @param api api which data model to initialize.
|
|
110
|
-
*
|
|
111
|
-
*/
|
|
112
|
-
abstract initializeApiDatamodel(api:OINODbApi): Promise<void>
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Print SQL select statement with DB specific formatting.
|
|
116
|
-
*
|
|
117
|
-
* @param tableName - The name of the table to select from.
|
|
118
|
-
* @param columnNames - The columns to be selected.
|
|
119
|
-
* @param whereCondition - The WHERE clause to filter the results.
|
|
120
|
-
* @param orderCondition - The ORDER BY clause to sort the results.
|
|
121
|
-
* @param limitCondition - The LIMIT clause to limit the number of results.
|
|
122
|
-
* @param groupByCondition - The GROUP BY clause to group the results.
|
|
123
|
-
*
|
|
124
|
-
*/
|
|
125
|
-
printSqlSelect(tableName:string, columnNames:string, whereCondition:string, orderCondition:string, limitCondition:string, groupByCondition: string): string {
|
|
126
|
-
let result:string = "SELECT " + columnNames + " FROM " + tableName;
|
|
127
|
-
if (whereCondition != "") {
|
|
128
|
-
result += " WHERE " + whereCondition
|
|
129
|
-
}
|
|
130
|
-
if (groupByCondition != "") {
|
|
131
|
-
result += " GROUP BY " + groupByCondition
|
|
132
|
-
}
|
|
133
|
-
if (orderCondition != "") {
|
|
134
|
-
result += " ORDER BY " + orderCondition
|
|
135
|
-
}
|
|
136
|
-
if (limitCondition != "") {
|
|
137
|
-
result += " LIMIT " + limitCondition
|
|
138
|
-
}
|
|
139
|
-
result += ";"
|
|
140
|
-
return result;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Base class for SQL results that can be asynchronously iterated (but
|
|
146
|
-
* not necessarity rewinded). Idea is to handle database specific mechanisms
|
|
147
|
-
* for returning and formatting conventions in the database specific
|
|
148
|
-
* implementation. Data might be in memory or streamed in chunks and
|
|
149
|
-
* `OINODbDataSet` will serve it out consistently.
|
|
150
|
-
*
|
|
151
|
-
*/
|
|
152
|
-
|
|
153
|
-
export abstract class OINODbDataSet {
|
|
154
|
-
private _data: unknown;
|
|
155
|
-
|
|
156
|
-
/** Error messages */
|
|
157
|
-
readonly messages: string[];
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Constructor for `OINODbDataSet`.
|
|
161
|
-
*
|
|
162
|
-
* @param data internal database specific data type (constructor will throw if invalid)
|
|
163
|
-
* @param messages error messages from SQL-query
|
|
164
|
-
*
|
|
165
|
-
*/
|
|
166
|
-
constructor(data: unknown, messages: string[] = []) {
|
|
167
|
-
this._data = data;
|
|
168
|
-
this.messages = messages;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Is data set empty.
|
|
173
|
-
*
|
|
174
|
-
*/
|
|
175
|
-
abstract isEmpty(): boolean;
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Is there no more content, i.e. either dataset is empty or we have moved beyond last line
|
|
179
|
-
*
|
|
180
|
-
*/
|
|
181
|
-
abstract isEof(): boolean;
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Attempts to moves dataset to the next row, possibly waiting for more data to become available. Returns !isEof().
|
|
185
|
-
*
|
|
186
|
-
*/
|
|
187
|
-
abstract next(): Promise<boolean>;
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Gets current row of data.
|
|
191
|
-
*
|
|
192
|
-
*/
|
|
193
|
-
abstract getRow(): OINODataRow;
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Gets all rows of data.
|
|
197
|
-
*
|
|
198
|
-
* NOTE: This is left abstract instead of just using `getRow()` so that DB implementations can hopefully optimize not duplicating data *
|
|
199
|
-
*/
|
|
200
|
-
abstract getAllRows(): Promise<OINODataRow[]>;
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Checks if the messages contain errors.
|
|
204
|
-
*
|
|
205
|
-
*/
|
|
206
|
-
hasErrors(): boolean {
|
|
207
|
-
for (let i = 0; i < this.messages.length; i++) {
|
|
208
|
-
if (this.messages[i].startsWith(OINO_ERROR_PREFIX)) {
|
|
209
|
-
return true;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
return false;
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Checks if the messages contain errors.
|
|
216
|
-
*
|
|
217
|
-
*/
|
|
218
|
-
getFirstError(): string {
|
|
219
|
-
for (let i = 0; i < this.messages.length; i++) {
|
|
220
|
-
if (this.messages[i].startsWith(OINO_ERROR_PREFIX)) {
|
|
221
|
-
return this.messages[i];
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
return "";
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Generic in memory implementation of a data set where data is an array of rows. Used
|
|
230
|
-
* by BunSqlite and automated testing. Can be rewinded.
|
|
231
|
-
*
|
|
232
|
-
*/
|
|
233
|
-
|
|
234
|
-
export class OINODbMemoryDataSet extends OINODbDataSet {
|
|
235
|
-
private _rows: OINODataRow[];
|
|
236
|
-
private _currentRow: number;
|
|
237
|
-
private _eof: boolean;
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Constructor of `OINODbMemoryDataSet`.
|
|
241
|
-
*
|
|
242
|
-
* @param data data as OINODataRow[] (constructor will throw if invalid)
|
|
243
|
-
* @param errors error messages from SQL-query
|
|
244
|
-
*
|
|
245
|
-
*/
|
|
246
|
-
constructor(data: unknown, errors: string[] = []) {
|
|
247
|
-
super(data, errors);
|
|
248
|
-
if ((data == null) || !(Array.isArray(data))) {
|
|
249
|
-
throw new Error(OINO_ERROR_PREFIX + ": Data needs to be compatible with OINORow[]!"); // TODO: maybe check all rows
|
|
250
|
-
}
|
|
251
|
-
this._rows = data as OINODataRow[];
|
|
252
|
-
if (this.isEmpty()) {
|
|
253
|
-
this._currentRow = -1;
|
|
254
|
-
this._eof = true;
|
|
255
|
-
} else {
|
|
256
|
-
this._currentRow = 0;
|
|
257
|
-
this._eof = false;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Is data set empty.
|
|
263
|
-
*
|
|
264
|
-
*/
|
|
265
|
-
isEmpty(): boolean {
|
|
266
|
-
return (this._rows.length == 0);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Is there no more content, i.e. either dataset is empty or we have moved beyond last line
|
|
271
|
-
*
|
|
272
|
-
*/
|
|
273
|
-
isEof(): boolean {
|
|
274
|
-
return (this._eof);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Attempts to moves dataset to the next row, possibly waiting for more data to become available. Returns !isEof().
|
|
279
|
-
*
|
|
280
|
-
*/
|
|
281
|
-
async next(): Promise<boolean> {
|
|
282
|
-
if (this._currentRow < this._rows.length - 1) {
|
|
283
|
-
this._currentRow = this._currentRow + 1;
|
|
284
|
-
} else {
|
|
285
|
-
this._eof = true;
|
|
286
|
-
}
|
|
287
|
-
return Promise.resolve(!this._eof);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Gets current row of data.
|
|
292
|
-
*
|
|
293
|
-
*/
|
|
294
|
-
getRow(): OINODataRow {
|
|
295
|
-
if ((this._currentRow >= 0) && (this._currentRow < this._rows.length)) {
|
|
296
|
-
return this._rows[this._currentRow];
|
|
297
|
-
} else {
|
|
298
|
-
return OINODB_EMPTY_ROW;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Gets all rows of data.
|
|
304
|
-
*
|
|
305
|
-
*/
|
|
306
|
-
async getAllRows(): Promise<OINODataRow[]> {
|
|
307
|
-
return this._rows // at the moment theres no result streaming, so we can just return the rows
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Rewinds data set to the first row, returns !isEof().
|
|
312
|
-
*
|
|
313
|
-
*/
|
|
314
|
-
first(): boolean {
|
|
315
|
-
this._currentRow = 0;
|
|
316
|
-
this._eof = this._rows.length == 0;
|
|
317
|
-
return !this._eof;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
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 { OINODbParams, OINODbApi, OINODataCell, OINO_ERROR_PREFIX, OINODataRow, OINODB_EMPTY_ROW, OINOResult, OINOLog } from "./index.js"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Base class for database abstraction, implementing methods for connecting, making queries and parsing/formatting data
|
|
11
|
+
* between SQL and serialization formats.
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
export abstract class OINODb {
|
|
15
|
+
|
|
16
|
+
protected _params:OINODbParams
|
|
17
|
+
|
|
18
|
+
/** Name of the database */
|
|
19
|
+
readonly name:string
|
|
20
|
+
|
|
21
|
+
isConnected:boolean = false
|
|
22
|
+
isValidated:boolean = false
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Constructor for `OINODb`.
|
|
26
|
+
* @param params database parameters
|
|
27
|
+
*/
|
|
28
|
+
constructor(params:OINODbParams) {
|
|
29
|
+
this._params = { ...params } // make a shallow copy of params so that changes to them do not affect the original object
|
|
30
|
+
this.name = this._params.database
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Connect to database.
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
abstract connect(): Promise<OINOResult>
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Validate connection to database is working.
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
43
|
+
abstract validate(): Promise<OINOResult>
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Print a table name using database specific SQL escaping.
|
|
47
|
+
*
|
|
48
|
+
* @param sqlTable name of the table
|
|
49
|
+
*
|
|
50
|
+
*/
|
|
51
|
+
abstract printSqlTablename(sqlTable:string): string
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Print a column name with correct SQL escaping.
|
|
55
|
+
*
|
|
56
|
+
* @param sqlColumn name of the column
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
abstract printSqlColumnname(sqlColumn:string): string
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Print a single data value from serialization using the context of the native data
|
|
63
|
+
* type with the correct SQL escaping.
|
|
64
|
+
*
|
|
65
|
+
* @param cellValue data from sql results
|
|
66
|
+
* @param sqlType native type name for table column
|
|
67
|
+
*
|
|
68
|
+
*/
|
|
69
|
+
abstract printCellAsSqlValue(cellValue:OINODataCell, sqlType: string): string
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Print a single string value as valid sql literal
|
|
73
|
+
*
|
|
74
|
+
* @param sqlString string value
|
|
75
|
+
*
|
|
76
|
+
*/
|
|
77
|
+
abstract printSqlString(sqlString:string): string
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Parse a single SQL result value for serialization using the context of the native data
|
|
81
|
+
* type.
|
|
82
|
+
*
|
|
83
|
+
* @param sqlValue data from serialization
|
|
84
|
+
* @param sqlType native type name for table column
|
|
85
|
+
*
|
|
86
|
+
*/
|
|
87
|
+
abstract parseSqlValueAsCell(sqlValue:OINODataCell, sqlType: string): OINODataCell
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Execute a select operation.
|
|
91
|
+
*
|
|
92
|
+
* @param sql SQL statement.
|
|
93
|
+
*
|
|
94
|
+
*/
|
|
95
|
+
abstract sqlSelect(sql:string): Promise<OINODbDataSet>
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Execute other sql operations.
|
|
99
|
+
*
|
|
100
|
+
* @param sql SQL statement.
|
|
101
|
+
*
|
|
102
|
+
*/
|
|
103
|
+
abstract sqlExec(sql:string): Promise<OINODbDataSet>
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Initialize a data model by getting the SQL schema and populating OINODbDataFields of
|
|
107
|
+
* the model.
|
|
108
|
+
*
|
|
109
|
+
* @param api api which data model to initialize.
|
|
110
|
+
*
|
|
111
|
+
*/
|
|
112
|
+
abstract initializeApiDatamodel(api:OINODbApi): Promise<void>
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Print SQL select statement with DB specific formatting.
|
|
116
|
+
*
|
|
117
|
+
* @param tableName - The name of the table to select from.
|
|
118
|
+
* @param columnNames - The columns to be selected.
|
|
119
|
+
* @param whereCondition - The WHERE clause to filter the results.
|
|
120
|
+
* @param orderCondition - The ORDER BY clause to sort the results.
|
|
121
|
+
* @param limitCondition - The LIMIT clause to limit the number of results.
|
|
122
|
+
* @param groupByCondition - The GROUP BY clause to group the results.
|
|
123
|
+
*
|
|
124
|
+
*/
|
|
125
|
+
printSqlSelect(tableName:string, columnNames:string, whereCondition:string, orderCondition:string, limitCondition:string, groupByCondition: string): string {
|
|
126
|
+
let result:string = "SELECT " + columnNames + " FROM " + tableName;
|
|
127
|
+
if (whereCondition != "") {
|
|
128
|
+
result += " WHERE " + whereCondition
|
|
129
|
+
}
|
|
130
|
+
if (groupByCondition != "") {
|
|
131
|
+
result += " GROUP BY " + groupByCondition
|
|
132
|
+
}
|
|
133
|
+
if (orderCondition != "") {
|
|
134
|
+
result += " ORDER BY " + orderCondition
|
|
135
|
+
}
|
|
136
|
+
if (limitCondition != "") {
|
|
137
|
+
result += " LIMIT " + limitCondition
|
|
138
|
+
}
|
|
139
|
+
result += ";"
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Base class for SQL results that can be asynchronously iterated (but
|
|
146
|
+
* not necessarity rewinded). Idea is to handle database specific mechanisms
|
|
147
|
+
* for returning and formatting conventions in the database specific
|
|
148
|
+
* implementation. Data might be in memory or streamed in chunks and
|
|
149
|
+
* `OINODbDataSet` will serve it out consistently.
|
|
150
|
+
*
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
export abstract class OINODbDataSet {
|
|
154
|
+
private _data: unknown;
|
|
155
|
+
|
|
156
|
+
/** Error messages */
|
|
157
|
+
readonly messages: string[];
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Constructor for `OINODbDataSet`.
|
|
161
|
+
*
|
|
162
|
+
* @param data internal database specific data type (constructor will throw if invalid)
|
|
163
|
+
* @param messages error messages from SQL-query
|
|
164
|
+
*
|
|
165
|
+
*/
|
|
166
|
+
constructor(data: unknown, messages: string[] = []) {
|
|
167
|
+
this._data = data;
|
|
168
|
+
this.messages = messages;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Is data set empty.
|
|
173
|
+
*
|
|
174
|
+
*/
|
|
175
|
+
abstract isEmpty(): boolean;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Is there no more content, i.e. either dataset is empty or we have moved beyond last line
|
|
179
|
+
*
|
|
180
|
+
*/
|
|
181
|
+
abstract isEof(): boolean;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Attempts to moves dataset to the next row, possibly waiting for more data to become available. Returns !isEof().
|
|
185
|
+
*
|
|
186
|
+
*/
|
|
187
|
+
abstract next(): Promise<boolean>;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Gets current row of data.
|
|
191
|
+
*
|
|
192
|
+
*/
|
|
193
|
+
abstract getRow(): OINODataRow;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Gets all rows of data.
|
|
197
|
+
*
|
|
198
|
+
* NOTE: This is left abstract instead of just using `getRow()` so that DB implementations can hopefully optimize not duplicating data *
|
|
199
|
+
*/
|
|
200
|
+
abstract getAllRows(): Promise<OINODataRow[]>;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Checks if the messages contain errors.
|
|
204
|
+
*
|
|
205
|
+
*/
|
|
206
|
+
hasErrors(): boolean {
|
|
207
|
+
for (let i = 0; i < this.messages.length; i++) {
|
|
208
|
+
if (this.messages[i].startsWith(OINO_ERROR_PREFIX)) {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Checks if the messages contain errors.
|
|
216
|
+
*
|
|
217
|
+
*/
|
|
218
|
+
getFirstError(): string {
|
|
219
|
+
for (let i = 0; i < this.messages.length; i++) {
|
|
220
|
+
if (this.messages[i].startsWith(OINO_ERROR_PREFIX)) {
|
|
221
|
+
return this.messages[i];
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return "";
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Generic in memory implementation of a data set where data is an array of rows. Used
|
|
230
|
+
* by BunSqlite and automated testing. Can be rewinded.
|
|
231
|
+
*
|
|
232
|
+
*/
|
|
233
|
+
|
|
234
|
+
export class OINODbMemoryDataSet extends OINODbDataSet {
|
|
235
|
+
private _rows: OINODataRow[];
|
|
236
|
+
private _currentRow: number;
|
|
237
|
+
private _eof: boolean;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Constructor of `OINODbMemoryDataSet`.
|
|
241
|
+
*
|
|
242
|
+
* @param data data as OINODataRow[] (constructor will throw if invalid)
|
|
243
|
+
* @param errors error messages from SQL-query
|
|
244
|
+
*
|
|
245
|
+
*/
|
|
246
|
+
constructor(data: unknown, errors: string[] = []) {
|
|
247
|
+
super(data, errors);
|
|
248
|
+
if ((data == null) || !(Array.isArray(data))) {
|
|
249
|
+
throw new Error(OINO_ERROR_PREFIX + ": Data needs to be compatible with OINORow[]!"); // TODO: maybe check all rows
|
|
250
|
+
}
|
|
251
|
+
this._rows = data as OINODataRow[];
|
|
252
|
+
if (this.isEmpty()) {
|
|
253
|
+
this._currentRow = -1;
|
|
254
|
+
this._eof = true;
|
|
255
|
+
} else {
|
|
256
|
+
this._currentRow = 0;
|
|
257
|
+
this._eof = false;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Is data set empty.
|
|
263
|
+
*
|
|
264
|
+
*/
|
|
265
|
+
isEmpty(): boolean {
|
|
266
|
+
return (this._rows.length == 0);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Is there no more content, i.e. either dataset is empty or we have moved beyond last line
|
|
271
|
+
*
|
|
272
|
+
*/
|
|
273
|
+
isEof(): boolean {
|
|
274
|
+
return (this._eof);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Attempts to moves dataset to the next row, possibly waiting for more data to become available. Returns !isEof().
|
|
279
|
+
*
|
|
280
|
+
*/
|
|
281
|
+
async next(): Promise<boolean> {
|
|
282
|
+
if (this._currentRow < this._rows.length - 1) {
|
|
283
|
+
this._currentRow = this._currentRow + 1;
|
|
284
|
+
} else {
|
|
285
|
+
this._eof = true;
|
|
286
|
+
}
|
|
287
|
+
return Promise.resolve(!this._eof);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Gets current row of data.
|
|
292
|
+
*
|
|
293
|
+
*/
|
|
294
|
+
getRow(): OINODataRow {
|
|
295
|
+
if ((this._currentRow >= 0) && (this._currentRow < this._rows.length)) {
|
|
296
|
+
return this._rows[this._currentRow];
|
|
297
|
+
} else {
|
|
298
|
+
return OINODB_EMPTY_ROW;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Gets all rows of data.
|
|
304
|
+
*
|
|
305
|
+
*/
|
|
306
|
+
async getAllRows(): Promise<OINODataRow[]> {
|
|
307
|
+
return this._rows // at the moment theres no result streaming, so we can just return the rows
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Rewinds data set to the first row, returns !isEof().
|
|
312
|
+
*
|
|
313
|
+
*/
|
|
314
|
+
first(): boolean {
|
|
315
|
+
this._currentRow = 0;
|
|
316
|
+
this._eof = this._rows.length == 0;
|
|
317
|
+
return !this._eof;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
|