@oino-ts/db 0.0.16 → 0.0.18
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/README.md +7 -42
- package/dist/cjs/OINODb.js +26 -0
- package/dist/cjs/OINODbApi.js +18 -12
- package/dist/cjs/OINODbDataField.js +11 -2
- package/dist/cjs/OINODbDataModel.js +8 -13
- package/dist/cjs/OINODbFactory.js +0 -356
- package/dist/cjs/OINODbModelSet.js +6 -4
- package/dist/cjs/OINODbRequestParams.js +38 -23
- package/dist/cjs/OINODbSqlParams.js +336 -0
- package/dist/cjs/index.js +6 -6
- package/dist/esm/OINODb.js +26 -0
- package/dist/esm/OINODbApi.js +19 -13
- package/dist/esm/OINODbDataField.js +11 -2
- package/dist/esm/OINODbDataModel.js +8 -13
- package/dist/esm/OINODbFactory.js +1 -357
- package/dist/esm/OINODbModelSet.js +6 -4
- package/dist/esm/OINODbRequestParams.js +38 -23
- package/dist/esm/OINODbSqlParams.js +330 -0
- package/dist/esm/index.js +1 -1
- package/dist/types/OINODb.d.ts +11 -0
- package/dist/types/OINODbApi.d.ts +2 -2
- package/dist/types/OINODbFactory.d.ts +1 -29
- package/dist/types/OINODbRequestParams.d.ts +3 -2
- package/dist/types/OINODbSqlParams.d.ts +147 -0
- package/dist/types/index.d.ts +4 -2
- package/package.json +2 -2
- package/src/OINODb.ts +27 -0
- package/src/OINODbApi.test.ts +184 -46
- package/src/OINODbApi.ts +20 -15
- package/src/OINODbDataField.ts +11 -3
- package/src/OINODbDataModel.ts +8 -13
- package/src/OINODbFactory.ts +1 -358
- package/src/OINODbModelSet.ts +6 -4
- package/src/{OINODbRequestParams.ts → OINODbSqlParams.ts} +39 -21
- package/src/index.ts +4 -2
package/src/OINODbApi.test.ts
CHANGED
|
@@ -6,15 +6,19 @@
|
|
|
6
6
|
|
|
7
7
|
import { expect, test } from "bun:test";
|
|
8
8
|
|
|
9
|
-
import { OINODbApi, OINODbApiParams, OINOContentType, OINODataRow, OINODbDataField, OINOStringDataField, OINODb, OINODbFactory, OINODbParams, OINODbMemoryDataSet, OINODbModelSet, OINOBenchmark, OINOConsoleLog, OINORequestParams, OINODbSqlFilter, OINODbConfig, OINODbSqlOrder, OINOLogLevel, OINOLog } from "./index.js";
|
|
9
|
+
import { OINODbApi, OINODbApiParams, OINOContentType, OINODataRow, OINODbDataField, OINOStringDataField, OINODb, OINODbFactory, OINODbParams, OINODbMemoryDataSet, OINODbModelSet, OINOBenchmark, OINOConsoleLog, OINORequestParams, OINODbSqlFilter, OINODbConfig, OINODbSqlOrder, OINOLogLevel, OINOLog, OINODbSqlLimit, OINODbApiResult, OINODbSqlComparison, OINONumberDataField, OINODatetimeDataField } from "./index.js";
|
|
10
10
|
|
|
11
11
|
import { OINODbBunSqlite } from "@oino-ts/db-bunsqlite"
|
|
12
12
|
import { OINODbPostgresql } from "@oino-ts/db-postgresql"
|
|
13
13
|
import { OINODbMariadb } from "@oino-ts/db-mariadb"
|
|
14
14
|
import { OINODbMsSql } from "@oino-ts/db-mssql"
|
|
15
15
|
|
|
16
|
+
const OINODB_POSTGRESQL_TOKEN = process.env.OINODB_POSTGRESQL_TOKEN || console.error("OINODB_POSTGRESQL_TOKEN not set")
|
|
17
|
+
const OINODB_MARIADB_TOKEN = process.env.OINODB_MARIADB_TOKEN || console.error("OINODB_MARIADB_TOKEN not set")
|
|
18
|
+
const OINOCLOUD_POC_DB_TOKEN = process.env.OINOCLOUD_POC_DB_TOKEN || console.error("OINOCLOUD_POC_DB_TOKEN not set")
|
|
16
19
|
|
|
17
|
-
type
|
|
20
|
+
type OINOTestParams = {
|
|
21
|
+
name: string
|
|
18
22
|
apiParams: OINODbApiParams
|
|
19
23
|
requestParams: OINORequestParams
|
|
20
24
|
postRow: OINODataRow
|
|
@@ -23,45 +27,78 @@ type OINOTestApiParams = {
|
|
|
23
27
|
|
|
24
28
|
const dbs:OINODbParams[] = [
|
|
25
29
|
{ type: "OINODbBunSqlite", url:"file://../localDb/northwind.sqlite", database: "Northwind" },
|
|
26
|
-
{ type: "OINODbPostgresql", url: "localhost", database: "Northwind", port:5432, user: "node", password:
|
|
27
|
-
{ type: "OINODbMariadb", url: "127.0.0.1", database: "Northwind", port:6543, user: "node", password:
|
|
28
|
-
{ type: "OINODbMsSql", url: "oinocloud-poc-db-srv.database.windows.net", database: "Northwind", port:1433, user: "oinocloud-poc-db-srv-admin", password:
|
|
30
|
+
{ type: "OINODbPostgresql", url: "localhost", database: "Northwind", port:5432, user: "node", password: OINODB_POSTGRESQL_TOKEN },
|
|
31
|
+
{ type: "OINODbMariadb", url: "127.0.0.1", database: "Northwind", port:6543, user: "node", password: OINODB_MARIADB_TOKEN },
|
|
32
|
+
{ type: "OINODbMsSql", url: "oinocloud-poc-db-srv.database.windows.net", database: "Northwind", port:1433, user: "oinocloud-poc-db-srv-admin", password: OINOCLOUD_POC_DB_TOKEN }
|
|
29
33
|
]
|
|
30
34
|
|
|
31
|
-
const api_tests:
|
|
35
|
+
const api_tests:OINOTestParams[] = [
|
|
32
36
|
{
|
|
37
|
+
name: "API",
|
|
33
38
|
apiParams: { tableName: "Orders" },
|
|
34
39
|
requestParams: {
|
|
35
|
-
sqlParams: { filter: OINODbSqlFilter.parse("(ShipPostalCode)-like(0502%)"), order: OINODbSqlOrder.parse("ShipPostalCode desc") }
|
|
40
|
+
sqlParams: { filter: OINODbSqlFilter.parse("(ShipPostalCode)-like(0502%)"), order: OINODbSqlOrder.parse("ShipPostalCode desc,Freight asc"), limit: OINODbSqlLimit.parse("5 page 2") }
|
|
36
41
|
},
|
|
37
42
|
postRow: [30000,"CACTU",1,new Date("2024-04-05"),new Date("2024-04-06"),new Date("2024-04-07"),2,"184.75","a'b\"c%d_e\tf\rg\nh\\i","Garden House Crowther Way","Cowes","British Isles","PO31 7PJ","UK"],
|
|
38
43
|
putRow: [30000,"CACTU",1,new Date("2023-04-05"),new Date("2023-04-06"),new Date("2023-04-07"),2,"847.51","k'l\"m%n_o\tp\rq\nr\\s","59 rue de l'Abbaye","Cowes2","Western Europe","PO31 8PJ","UK"]
|
|
39
44
|
},
|
|
40
45
|
{
|
|
46
|
+
name: "API",
|
|
41
47
|
apiParams: { tableName: "Products", failOnOversizedValues: true },
|
|
42
48
|
requestParams: {
|
|
43
|
-
sqlParams: { filter: OINODbSqlFilter.parse("(UnitsInStock)-le(5)"), order: OINODbSqlOrder.parse("UnitsInStock asc,UnitPrice asc") }
|
|
49
|
+
sqlParams: { filter: OINODbSqlFilter.parse("(UnitsInStock)-le(5)"), order: OINODbSqlOrder.parse("UnitsInStock asc,UnitPrice asc"), limit: OINODbSqlLimit.parse("7") }
|
|
44
50
|
},
|
|
45
51
|
postRow: [99, "Umeshu", 1, 1, "500 ml", 12.99, 2, 0, 20, 0],
|
|
46
52
|
putRow: [99, "Umeshu", 1, 1, undefined, 24.99, 3, 0, 20, 0]
|
|
47
53
|
},
|
|
48
54
|
{
|
|
55
|
+
name: "API",
|
|
49
56
|
apiParams: { tableName: "Employees", hashidKey: "12345678901234567890123456789012", hashidStaticIds:true },
|
|
50
57
|
requestParams: {
|
|
51
|
-
sqlParams: { filter: OINODbSqlFilter.parse("(TitleOfCourtesy)-eq(Ms.)"), order: OINODbSqlOrder.parse("LastName asc") }
|
|
58
|
+
sqlParams: { filter: OINODbSqlFilter.parse("(TitleOfCourtesy)-eq(Ms.)"), order: OINODbSqlOrder.parse("LastName asc"), limit: OINODbSqlLimit.parse("5") }
|
|
52
59
|
},
|
|
53
60
|
postRow: [99, "LastName", "FirstName", "Title", "TitleOfCourtesy", new Date("2024-04-06"), new Date("2024-04-07"), "Address", "City", "Region", 12345, "EU", "123 456 7890", "9876", Buffer.from("0001020304", "hex"), "Line1\nLine2", 1, "http://accweb/emmployees/lastnamefirstname.bmp"],
|
|
54
61
|
putRow: [99, "LastName2", "FirstName2", null, "TitleOfCourtesy2", new Date("2023-04-06"), new Date("2023-04-07"), "Address2", "City2", "Region2", 54321, "EU2", "234 567 8901", "8765", Buffer.from("0506070809", "hex"), "Line3\nLine4", 1, "http://accweb/emmployees/lastnamefirstname.bmp"],
|
|
55
62
|
},
|
|
56
63
|
{
|
|
64
|
+
name: "API",
|
|
57
65
|
apiParams: { tableName: "OrderDetails" },
|
|
58
66
|
requestParams: {
|
|
59
|
-
sqlParams: { filter: OINODbSqlFilter.parse("(Quantity)-gt(100)"), order: OINODbSqlOrder.parse("Quantity desc") }
|
|
67
|
+
sqlParams: { filter: OINODbSqlFilter.parse("(Quantity)-gt(100)"), order: OINODbSqlOrder.parse("Quantity desc,UnitPrice asc"), limit: OINODbSqlLimit.parse("5 page 2") }
|
|
60
68
|
},
|
|
61
69
|
postRow: [10249,77,12.34,56,0],
|
|
62
70
|
putRow: [10249,77,23.45,67,0]
|
|
63
71
|
}
|
|
72
|
+
]
|
|
64
73
|
|
|
74
|
+
const owasp_tests:OINOTestParams[] = [
|
|
75
|
+
{
|
|
76
|
+
name: "OWASP 1",
|
|
77
|
+
apiParams: { tableName: "Products", failOnOversizedValues: true },
|
|
78
|
+
requestParams: {
|
|
79
|
+
sqlParams: { filter: OINODbSqlFilter.parse("(1)-eq(1)") }
|
|
80
|
+
},
|
|
81
|
+
postRow: [99, "' FOO", 1, 1],
|
|
82
|
+
putRow: [99, "; FOO", 1, 1]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "OWASP 2",
|
|
86
|
+
apiParams: { tableName: "Products", failOnOversizedValues: true },
|
|
87
|
+
requestParams: {
|
|
88
|
+
sqlParams: { order: OINODbSqlOrder.parse("1 asc") }
|
|
89
|
+
},
|
|
90
|
+
postRow: [99, "' FOO", 1, 1],
|
|
91
|
+
putRow: [99, "; FOO", 1, 1]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "OWASP 3",
|
|
95
|
+
apiParams: { tableName: "Products", failOnOversizedValues: true },
|
|
96
|
+
requestParams: {
|
|
97
|
+
sqlParams: { filter: OINODbSqlFilter.parse("(ProductID)-eq(FOO)") }
|
|
98
|
+
},
|
|
99
|
+
postRow: [99, "\" FOO", 1, 1],
|
|
100
|
+
putRow: [99, "\\ FOO", 1, 1]
|
|
101
|
+
}
|
|
65
102
|
]
|
|
66
103
|
|
|
67
104
|
Math.random()
|
|
@@ -89,50 +126,54 @@ function encodeResult(o:any|undefined):string {
|
|
|
89
126
|
})
|
|
90
127
|
}
|
|
91
128
|
|
|
92
|
-
export async function OINOTestApi(dbParams:OINODbParams,
|
|
129
|
+
export async function OINOTestApi(dbParams:OINODbParams, testParams: OINOTestParams) {
|
|
93
130
|
// OINOLog.info("OINOTestApi", {dbParams:dbParams, apiDataset:apiDataset})
|
|
94
131
|
const db:OINODb = await OINODbFactory.createDb( dbParams )
|
|
95
|
-
const api:OINODbApi = await OINODbFactory.createApi(db,
|
|
132
|
+
const api:OINODbApi = await OINODbFactory.createApi(db, testParams.apiParams)
|
|
96
133
|
|
|
97
|
-
const post_dataset:OINODbMemoryDataSet = new OINODbMemoryDataSet([
|
|
134
|
+
const post_dataset:OINODbMemoryDataSet = new OINODbMemoryDataSet([testParams.postRow])
|
|
98
135
|
const post_modelset:OINODbModelSet = new OINODbModelSet(api.datamodel, post_dataset)
|
|
99
136
|
|
|
100
|
-
const put_dataset:OINODbMemoryDataSet = new OINODbMemoryDataSet([
|
|
137
|
+
const put_dataset:OINODbMemoryDataSet = new OINODbMemoryDataSet([testParams.putRow])
|
|
101
138
|
const put_modelset:OINODbModelSet = new OINODbModelSet(api.datamodel, put_dataset)
|
|
102
139
|
|
|
103
140
|
// const new_row_id:string = OINODbConfig.printOINOId(post_modelset.datamodel.getRowPrimarykeyValues(apiDataset.postRow))
|
|
104
|
-
const new_row_id:string = OINODbConfig.printOINOId(post_modelset.datamodel.getRowPrimarykeyValues(
|
|
141
|
+
const new_row_id:string = OINODbConfig.printOINOId(post_modelset.datamodel.getRowPrimarykeyValues(testParams.postRow, true))
|
|
105
142
|
// OINOLog.debug("OINOTestApi", {new_row_id:new_row_id})
|
|
106
143
|
|
|
107
144
|
const empty_params:OINORequestParams = { sqlParams: {}}
|
|
108
|
-
const request_params:OINORequestParams = Object.assign({},
|
|
145
|
+
const request_params:OINORequestParams = Object.assign({}, testParams.requestParams)
|
|
109
146
|
request_params.sqlParams = {}
|
|
110
147
|
const request_params_with_filters:OINORequestParams = Object.assign({}, request_params)
|
|
111
|
-
request_params_with_filters.sqlParams =
|
|
148
|
+
request_params_with_filters.sqlParams = testParams.requestParams.sqlParams
|
|
112
149
|
// OINOLog.debug("OINOTestApi", {request_params:request_params, request_params_with_filters:request_params_with_filters})
|
|
113
150
|
|
|
151
|
+
let target_name:string = ""
|
|
152
|
+
if (testParams.name) {
|
|
153
|
+
target_name = "[" + testParams.name + "]"
|
|
154
|
+
}
|
|
114
155
|
const target_db:string = "[" + dbParams.type + "]"
|
|
115
|
-
let target_table:string = "[" +
|
|
156
|
+
let target_table:string = "[" + testParams.apiParams.tableName + "]"
|
|
116
157
|
let target_group:string = "[SCHEMA]"
|
|
117
158
|
|
|
118
159
|
// test("dummy", () => {
|
|
119
160
|
// expect({foo:"h\\i"}).toMatchSnapshot()
|
|
120
161
|
// })
|
|
121
162
|
|
|
122
|
-
test(target_db + target_table + target_group + " public properties", async () => {
|
|
123
|
-
expect(api.datamodel.printFieldPublicPropertiesJson()).toMatchSnapshot()
|
|
163
|
+
test(target_name + target_db + target_table + target_group + " public properties", async () => {
|
|
164
|
+
expect(api.datamodel.printFieldPublicPropertiesJson()).toMatchSnapshot("SCHEMA")
|
|
124
165
|
})
|
|
125
166
|
|
|
126
167
|
target_group = "[HTTP GET]"
|
|
127
|
-
test(target_db + target_table + target_group + " select *", async () => {
|
|
168
|
+
test(target_name + target_db + target_table + target_group + " select *", async () => {
|
|
128
169
|
expect(encodeData(await (await api.doRequest("GET", "", "", empty_params)).data?.writeString())).toMatchSnapshot("GET JSON")
|
|
129
170
|
})
|
|
130
171
|
|
|
131
|
-
test(target_db + target_table + target_group + " select *", async () => {
|
|
172
|
+
test(target_name + target_db + target_table + target_group + " select *", async () => {
|
|
132
173
|
expect(encodeData(await (await api.doRequest("GET", "", "", empty_params)).data?.writeString(OINOContentType.csv))).toMatchSnapshot("GET CSV")
|
|
133
174
|
})
|
|
134
175
|
|
|
135
|
-
test(target_db + target_table + target_group + " select * with filter", async () => {
|
|
176
|
+
test(target_name + target_db + target_table + target_group + " select * with filter", async () => {
|
|
136
177
|
expect(encodeData(await (await api.doRequest("GET", "", "", request_params_with_filters)).data?.writeString())).toMatchSnapshot("GET JSON FILTER")
|
|
137
178
|
})
|
|
138
179
|
|
|
@@ -143,25 +184,25 @@ export async function OINOTestApi(dbParams:OINODbParams, apiDataset: OINOTestApi
|
|
|
143
184
|
target_group = "[HTTP POST]"
|
|
144
185
|
const post_body_json:string = await post_modelset.writeString(OINOContentType.json)
|
|
145
186
|
// OINOLog.info("HTTP POST json", {post_body_json:post_body_json})
|
|
146
|
-
test(target_db + target_table + target_group + " insert with id", async () => {
|
|
187
|
+
test(target_name + target_db + target_table + target_group + " insert with id", async () => {
|
|
147
188
|
expect(encodeResult((await api.doRequest("POST", new_row_id, post_body_json, empty_params)))).toMatchSnapshot("POST")
|
|
148
189
|
})
|
|
149
|
-
test(target_db + target_table + target_group + " insert", async () => {
|
|
190
|
+
test(target_name + target_db + target_table + target_group + " insert", async () => {
|
|
150
191
|
expect(encodeResult((await api.doRequest("POST", "", post_body_json, empty_params)))).toMatchSnapshot("POST")
|
|
151
192
|
expect(encodeData(await (await api.doRequest("GET", new_row_id, "", empty_params)).data?.writeString())).toMatchSnapshot("GET JSON")
|
|
152
193
|
expect(encodeData(await (await api.doRequest("GET", new_row_id, "", empty_params)).data?.writeString(OINOContentType.csv))).toMatchSnapshot("GET CSV")
|
|
153
194
|
})
|
|
154
|
-
test(target_db + target_table + target_group + " insert no data", async () => {
|
|
155
|
-
expect(encodeResult((await api.doRequest("POST", "", "", empty_params)))).toMatchSnapshot("POST")
|
|
195
|
+
test(target_name + target_db + target_table + target_group + " insert no data", async () => {
|
|
196
|
+
expect(encodeResult((await api.doRequest("POST", "", "{}", empty_params)))).toMatchSnapshot("POST")
|
|
156
197
|
})
|
|
157
|
-
test(target_db + target_table + target_group + " insert duplicate", async () => {
|
|
198
|
+
test(target_name + target_db + target_table + target_group + " insert duplicate", async () => {
|
|
158
199
|
expect(encodeResult((await api.doRequest("POST", "", post_body_json, empty_params)))).toMatchSnapshot("POST")
|
|
159
200
|
})
|
|
160
201
|
|
|
161
202
|
target_group = "[HTTP PUT]"
|
|
162
203
|
const put_body_json = await put_modelset.writeString(OINOContentType.json)
|
|
163
204
|
// OINOLog.info("HTTP PUT JSON", {put_body_json:put_body_json})
|
|
164
|
-
test(target_db + target_table + target_group + " update JSON", async () => {
|
|
205
|
+
test(target_name + target_db + target_table + target_group + " update JSON", async () => {
|
|
165
206
|
request_params.requestType = OINOContentType.json
|
|
166
207
|
expect(encodeResult((await api.doRequest("PUT", new_row_id, post_body_json, empty_params)))).toMatchSnapshot("PUT JSON reset")
|
|
167
208
|
expect(encodeResult((await api.doRequest("PUT", new_row_id, put_body_json, request_params)))).toMatchSnapshot("PUT JSON")
|
|
@@ -171,7 +212,7 @@ export async function OINOTestApi(dbParams:OINODbParams, apiDataset: OINOTestApi
|
|
|
171
212
|
put_dataset.first()
|
|
172
213
|
const put_body_csv = await put_modelset.writeString(OINOContentType.csv)
|
|
173
214
|
// OINOLog.info("HTTP PUT csv", {put_body_csv:put_body_csv})
|
|
174
|
-
test(target_db + target_table + target_group + " update CSV", async () => {
|
|
215
|
+
test(target_name + target_db + target_table + target_group + " update CSV", async () => {
|
|
175
216
|
request_params.requestType = OINOContentType.csv
|
|
176
217
|
expect(encodeResult((await api.doRequest("PUT", new_row_id, post_body_json, empty_params)))).toMatchSnapshot("PUT CSV reset")
|
|
177
218
|
expect(encodeResult((await api.doRequest("PUT", new_row_id, put_body_csv, request_params)))).toMatchSnapshot("PUT CSV")
|
|
@@ -183,7 +224,7 @@ export async function OINOTestApi(dbParams:OINODbParams, apiDataset: OINOTestApi
|
|
|
183
224
|
const multipart_boundary = put_body_formdata.substring(0, put_body_formdata.indexOf('\r'))
|
|
184
225
|
put_body_formdata = put_body_formdata.replaceAll(multipart_boundary, "---------OINO999999999")
|
|
185
226
|
// OINOLog.info("HTTP PUT FORMDATA", {put_body_formdata:put_body_formdata})
|
|
186
|
-
test(target_db + target_table + target_group + " update FORMDATA", async () => {
|
|
227
|
+
test(target_name + target_db + target_table + target_group + " update FORMDATA", async () => {
|
|
187
228
|
request_params.requestType = OINOContentType.formdata
|
|
188
229
|
request_params.multipartBoundary = "---------OINO999999999"
|
|
189
230
|
expect(encodeResult(await (await api.doRequest("PUT", new_row_id, post_body_json, empty_params)))).toMatchSnapshot("PUT FORMDATA reset")
|
|
@@ -195,7 +236,7 @@ export async function OINOTestApi(dbParams:OINODbParams, apiDataset: OINOTestApi
|
|
|
195
236
|
put_dataset.first()
|
|
196
237
|
const put_body_urlencode = await put_modelset.writeString(OINOContentType.urlencode)
|
|
197
238
|
// OINOLog.info("HTTP PUT URLENCODE", {put_body_urlencode:put_body_urlencode})
|
|
198
|
-
test(target_db + target_table + target_group + " update URLENCODE", async () => {
|
|
239
|
+
test(target_name + target_db + target_table + target_group + " update URLENCODE", async () => {
|
|
199
240
|
request_params.requestType = OINOContentType.urlencode
|
|
200
241
|
request_params.multipartBoundary = undefined // for some reason this needs reset here so previous test value settings does not leak
|
|
201
242
|
expect(encodeResult((await api.doRequest("PUT", new_row_id, post_body_json, empty_params)))).toMatchSnapshot("PUT URLENCODE reset")
|
|
@@ -203,49 +244,133 @@ export async function OINOTestApi(dbParams:OINODbParams, apiDataset: OINOTestApi
|
|
|
203
244
|
expect(encodeData(await (await api.doRequest("GET", new_row_id, "", empty_params)).data?.writeString(OINOContentType.urlencode))).toMatchSnapshot("GET URLENCODE")
|
|
204
245
|
})
|
|
205
246
|
|
|
206
|
-
test(target_db + target_table + target_group + " update no data", async () => {
|
|
207
|
-
expect(encodeResult((await api.doRequest("PUT", new_row_id, "", empty_params)))).toMatchSnapshot("PUT")
|
|
247
|
+
test(target_name + target_db + target_table + target_group + " update no data", async () => {
|
|
248
|
+
expect(encodeResult((await api.doRequest("PUT", new_row_id, "{}", empty_params)))).toMatchSnapshot("PUT")
|
|
208
249
|
})
|
|
209
250
|
|
|
210
251
|
const primary_keys:OINODbDataField[] = api.datamodel.filterFields((field:OINODbDataField) => { return field.fieldParams.isPrimaryKey })
|
|
211
252
|
if (primary_keys.length != 1) {
|
|
212
|
-
OINOLog.info("HTTP PUT table " +
|
|
253
|
+
OINOLog.info("HTTP PUT table " + testParams.apiParams.tableName + " does not have an individual primary key so 'invalid null' and 'oversized data' tests are skipped")
|
|
213
254
|
} else {
|
|
214
255
|
const id_field:string = primary_keys[0].name
|
|
215
256
|
const notnull_fields:OINODbDataField[] = api.datamodel.filterFields((field:OINODbDataField) => { return (field.fieldParams.isPrimaryKey == false) && (field.fieldParams.isNotNull == true) })
|
|
216
257
|
if (notnull_fields.length > 0) {
|
|
217
258
|
const invalid_null_value = "[{\"" + id_field + "\":\"" + new_row_id + "\",\"" + notnull_fields[0].name + "\":null}]"
|
|
218
|
-
test(target_db + target_table + target_group + " update with invalid null value", async () => {
|
|
219
|
-
expect(encodeResult((await api.doRequest("PUT", new_row_id, invalid_null_value, empty_params)))).toMatchSnapshot("PUT")
|
|
259
|
+
test(target_name + target_db + target_table + target_group + " update with invalid null value", async () => {
|
|
260
|
+
expect(encodeResult((await api.doRequest("PUT", new_row_id, invalid_null_value, empty_params)))).toMatchSnapshot("PUT invalid null")
|
|
220
261
|
})
|
|
221
262
|
}
|
|
222
263
|
const maxsize_fields:OINODbDataField[] = api.datamodel.filterFields((field:OINODbDataField) => { return (field instanceof OINOStringDataField) && (field.fieldParams.isPrimaryKey == false) && (field.maxLength > 0) })
|
|
223
264
|
if (maxsize_fields.length > 0) {
|
|
224
265
|
const oversized_value = "[{\"" + id_field + "\":\"" + new_row_id + "\",\"" + maxsize_fields[0].name + "\":\"" + "".padEnd(maxsize_fields[0].maxLength+1, "z") + "\"}]"
|
|
225
|
-
test(target_db + target_table + target_group + " update with oversized data", async () => {
|
|
226
|
-
expect(encodeResult((await api.doRequest("PUT", new_row_id, oversized_value, empty_params)))).toMatchSnapshot("PUT")
|
|
266
|
+
test(target_name + target_db + target_table + target_group + " update with oversized data", async () => {
|
|
267
|
+
expect(encodeResult((await api.doRequest("PUT", new_row_id, oversized_value, empty_params)))).toMatchSnapshot("PUT oversized value")
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
const numeric_fields:OINODbDataField[] = api.datamodel.filterFields((field:OINODbDataField) => { return (field instanceof OINONumberDataField) && (field.fieldParams.isPrimaryKey == false) })
|
|
271
|
+
if (numeric_fields.length > 0) {
|
|
272
|
+
const nan_value = "[{\"" + id_field + "\":\"" + new_row_id + "\",\"" + numeric_fields[0].name + "\":\"" + "; FOO" + "\"}]"
|
|
273
|
+
OINOLog.debug("HTTP PUT NAN-value", {nan_value:nan_value})
|
|
274
|
+
test(target_name + target_db + target_table + target_group + " update NAN-value", async () => {
|
|
275
|
+
expect(encodeResult((await api.doRequest("PUT", new_row_id, nan_value, empty_params)))).toMatchSnapshot("PUT NAN-value")
|
|
276
|
+
})
|
|
277
|
+
}
|
|
278
|
+
const date_fields:OINODbDataField[] = api.datamodel.filterFields((field:OINODbDataField) => { return (field instanceof OINODatetimeDataField) && (field.fieldParams.isPrimaryKey == false) })
|
|
279
|
+
if (date_fields.length > 0) {
|
|
280
|
+
const non_date = "[{\"" + id_field + "\":\"" + new_row_id + "\",\"" + date_fields[0].name + "\":\"" + "; FOO" + "\"}]"
|
|
281
|
+
OINOLog.debug("HTTP PUT invalid date value", {non_date:non_date})
|
|
282
|
+
test(target_name + target_db + target_table + target_group + " update invalid date value", async () => {
|
|
283
|
+
expect(encodeResult((await api.doRequest("PUT", new_row_id, non_date, empty_params)))).toMatchSnapshot("PUT invalid date value")
|
|
227
284
|
})
|
|
228
285
|
}
|
|
229
286
|
}
|
|
230
287
|
|
|
231
288
|
target_group = "[HTTP DELETE]"
|
|
232
|
-
test(target_db + target_table + target_group + " remove", async () => {
|
|
289
|
+
test(target_name + target_db + target_table + target_group + " remove", async () => {
|
|
233
290
|
expect(encodeResult((await api.doRequest("DELETE", new_row_id, "", empty_params)))).toMatchSnapshot("DELETE")
|
|
234
291
|
expect(encodeData(await (await api.doRequest("GET", new_row_id, "", empty_params)).data?.writeString())).toMatchSnapshot("GET JSON")
|
|
235
292
|
})
|
|
236
293
|
}
|
|
237
294
|
|
|
295
|
+
export async function OINOTestOwasp(dbParams:OINODbParams, testParams: OINOTestParams) {
|
|
296
|
+
// OINOLog.info("OINOTestOwasp", {dbParams:dbParams, apiDataset:testParams})
|
|
297
|
+
const db:OINODb = await OINODbFactory.createDb( dbParams )
|
|
298
|
+
const api:OINODbApi = await OINODbFactory.createApi(db, testParams.apiParams)
|
|
299
|
+
|
|
300
|
+
const post_dataset:OINODbMemoryDataSet = new OINODbMemoryDataSet([testParams.postRow])
|
|
301
|
+
const post_modelset:OINODbModelSet = new OINODbModelSet(api.datamodel, post_dataset)
|
|
302
|
+
|
|
303
|
+
const put_dataset:OINODbMemoryDataSet = new OINODbMemoryDataSet([testParams.putRow])
|
|
304
|
+
const put_modelset:OINODbModelSet = new OINODbModelSet(api.datamodel, put_dataset)
|
|
305
|
+
|
|
306
|
+
const new_row_id:string = OINODbConfig.printOINOId(post_modelset.datamodel.getRowPrimarykeyValues(testParams.postRow, true))
|
|
307
|
+
// OINOLog.debug("OINOTestOwasp", {new_row_id:new_row_id})
|
|
308
|
+
|
|
309
|
+
const empty_params:OINORequestParams = { sqlParams: {}}
|
|
310
|
+
const request_params:OINORequestParams = Object.assign({}, testParams.requestParams)
|
|
311
|
+
request_params.sqlParams = {}
|
|
312
|
+
const request_params_with_filters:OINORequestParams = Object.assign({}, request_params)
|
|
313
|
+
request_params_with_filters.sqlParams = testParams.requestParams.sqlParams
|
|
314
|
+
// OINOLog.debug("OINOTestOwasp", {request_params:request_params, request_params_with_filters:request_params_with_filters})
|
|
315
|
+
|
|
316
|
+
let target_name:string = ""
|
|
317
|
+
if (testParams.name) {
|
|
318
|
+
target_name = "[" + testParams.name + "]"
|
|
319
|
+
}
|
|
320
|
+
const target_db:string = "[" + dbParams.type + "]"
|
|
321
|
+
let target_table:string = "[" + testParams.apiParams.tableName + "]"
|
|
322
|
+
|
|
323
|
+
let target_group = "[OWASP GET]"
|
|
324
|
+
test(target_name + target_db + target_table + target_group + " GET with filter", async () => {
|
|
325
|
+
const get_res:OINODbApiResult = await api.doRequest("GET", "", "", request_params_with_filters)
|
|
326
|
+
if (get_res.success) {
|
|
327
|
+
expect(encodeData(await get_res.data?.writeString())).toMatchSnapshot("OWASP GET DATA")
|
|
328
|
+
} else {
|
|
329
|
+
expect(encodeResult(get_res)).toMatchSnapshot("OWASP GET RESULT")
|
|
330
|
+
}
|
|
331
|
+
})
|
|
332
|
+
target_group = "[OWASP POST]"
|
|
333
|
+
test(target_name + target_db + target_table + target_group + " POST", async () => {
|
|
334
|
+
const post_body_json:string = await post_modelset.writeString(OINOContentType.json)
|
|
335
|
+
const post_res:OINODbApiResult = await api.doRequest("POST", "", post_body_json, request_params)
|
|
336
|
+
expect(encodeResult(post_res)).toMatchSnapshot("OWASP POST RESULT")
|
|
337
|
+
expect(encodeData(await (await api.doRequest("GET", new_row_id, "", empty_params)).data?.writeString())).toMatchSnapshot("POST JSON")
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
target_group = "[OWASP PUT]"
|
|
341
|
+
test(target_name + target_db + target_table + target_group + " PUT", async () => {
|
|
342
|
+
const put_body_json:string = await put_modelset.writeString(OINOContentType.json)
|
|
343
|
+
const post_res:OINODbApiResult = await api.doRequest("PUT", new_row_id, put_body_json, request_params)
|
|
344
|
+
expect(encodeResult(post_res)).toMatchSnapshot("OWASP PUT RESULT")
|
|
345
|
+
expect(encodeData(await (await api.doRequest("GET", new_row_id, "", empty_params)).data?.writeString())).toMatchSnapshot("PUT JSON")
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
target_group = "[OWASP DELETE]"
|
|
349
|
+
test(target_name + target_db + target_table + target_group + " DELETE", async () => {
|
|
350
|
+
expect(encodeResult((await api.doRequest("DELETE", new_row_id, "", empty_params)))).toMatchSnapshot("DELETE")
|
|
351
|
+
expect(encodeData(await (await api.doRequest("GET", new_row_id, "", empty_params)).data?.writeString())).toMatchSnapshot("DELETE JSON")
|
|
352
|
+
})
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
|
|
238
356
|
for (let db of dbs) {
|
|
239
357
|
for (let api_test of api_tests) {
|
|
240
358
|
await OINOTestApi(db, api_test)
|
|
241
359
|
}
|
|
242
360
|
}
|
|
243
361
|
|
|
362
|
+
for (let db of dbs) {
|
|
363
|
+
for (let owasp_test of owasp_tests) {
|
|
364
|
+
await OINOTestOwasp(db, owasp_test)
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
|
|
244
369
|
const snapshot_file = Bun.file("./node_modules/@oino-ts/db/src/__snapshots__/OINODbApi.test.ts.snap")
|
|
245
370
|
await Bun.write("./node_modules/@oino-ts/db/src/__snapshots__/OINODbApi.test.ts.snap.js", snapshot_file) // copy snapshots as .js so require works (note! if run with --update-snapshots, it's still the old file)
|
|
246
371
|
const snapshots = require("./__snapshots__/OINODbApi.test.ts.snap.js")
|
|
247
372
|
|
|
248
|
-
const
|
|
373
|
+
const api_crosschecks:string[] = [
|
|
249
374
|
"[HTTP GET] select *: GET JSON 1",
|
|
250
375
|
"[HTTP POST] insert: GET JSON 1",
|
|
251
376
|
"[HTTP POST] insert: GET CSV 1",
|
|
@@ -255,14 +380,27 @@ const crosscheck_tests:string[] = [
|
|
|
255
380
|
"[HTTP PUT] update URLENCODE: GET URLENCODE 1"
|
|
256
381
|
]
|
|
257
382
|
|
|
383
|
+
const owasp_crosschecks:string[] = [
|
|
384
|
+
"[OWASP POST] POST: POST JSON 1",
|
|
385
|
+
"[OWASP PUT] PUT: OWASP PUT RESULT 1"
|
|
386
|
+
]
|
|
387
|
+
|
|
258
388
|
for (let i=0; i<dbs.length-1; i++) {
|
|
259
389
|
const db1:string = dbs[i].type
|
|
260
390
|
const db2:string = dbs[i+1].type
|
|
261
|
-
for (let
|
|
262
|
-
const table_name =
|
|
263
|
-
for (let
|
|
264
|
-
test("cross check {" + db1 + "} and {" + db2 + "} table {" + table_name + "} snapshots on {" +
|
|
265
|
-
expect(snapshots["[" + db1 + "][" + table_name + "]" +
|
|
391
|
+
for (let api_test of api_tests) {
|
|
392
|
+
const table_name = api_test.apiParams.tableName
|
|
393
|
+
for (let crosscheck of api_crosschecks) {
|
|
394
|
+
test("cross check {" + db1 + "} and {" + db2 + "} table {" + table_name + "} snapshots on {" + crosscheck + "}", () => {
|
|
395
|
+
expect(snapshots["[" + api_test.name + "][" + db1 + "][" + table_name + "]" + crosscheck]).toMatch(snapshots["[" + api_test.name + "][" + db2 + "][" + table_name + "]" + crosscheck])
|
|
396
|
+
})
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
for (let owasp_test of owasp_tests) {
|
|
400
|
+
const table_name = owasp_test.apiParams.tableName
|
|
401
|
+
for (let crosscheck of owasp_crosschecks) {
|
|
402
|
+
test("cross check {" + db1 + "} and {" + db2 + "} table {" + table_name + "} snapshots on {" + crosscheck + "}", () => {
|
|
403
|
+
expect(snapshots["[" + owasp_test.name + "][" + db1 + "][" + table_name + "]" + crosscheck]).toMatch(snapshots["[" + owasp_test.name + "][" + db2 + "][" + table_name + "]" + crosscheck])
|
|
266
404
|
})
|
|
267
405
|
}
|
|
268
406
|
}
|
package/src/OINODbApi.ts
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { OINODbApiParams, OINODb, OINODbDataSet, OINODbDataModel, OINODbDataField, OINOStringDataField, OINO_ERROR_PREFIX, OINO_WARNING_PREFIX, OINO_INFO_PREFIX, OINODataRow, OINODataCell, OINODbModelSet, OINOBenchmark, OINODbFactory, OINODbApiRequestParams, OINOLog, OINODbConfig, OINOHttpResult, OINOHtmlTemplate, OINONumberDataField
|
|
7
|
+
import { OINODbApiParams, OINODb, OINODbDataSet, OINODbDataModel, OINODbDataField, OINOStringDataField, OINO_ERROR_PREFIX, OINO_WARNING_PREFIX, OINO_INFO_PREFIX, OINODataRow, OINODataCell, OINODbModelSet, OINOBenchmark, OINODbFactory, OINODbApiRequestParams, OINOLog, OINODbConfig, OINOHttpResult, OINOHtmlTemplate, OINONumberDataField } from "./index.js"
|
|
8
8
|
import { OINOResult } from "@oino-ts/types";
|
|
9
9
|
import { OINOHashid } from "@oino-ts/hashid"
|
|
10
|
+
import { OINOParser } from "@oino-ts/types";
|
|
10
11
|
|
|
11
12
|
const API_EMPTY_PARAMS:OINODbApiRequestParams = { sqlParams: {} }
|
|
12
13
|
|
|
@@ -41,7 +42,7 @@ export class OINODbApiResult extends OINOResult {
|
|
|
41
42
|
* @param headers Headers to include in the response
|
|
42
43
|
*
|
|
43
44
|
*/
|
|
44
|
-
async
|
|
45
|
+
async getResponse(headers:Record<string, string> = {}):Promise<Response> {
|
|
45
46
|
let response:Response|null = null
|
|
46
47
|
if (this.success && this.data) {
|
|
47
48
|
const body = await this.data.writeString(this.params.responseType)
|
|
@@ -93,11 +94,13 @@ export class OINODbHtmlTemplate extends OINOHtmlTemplate {
|
|
|
93
94
|
for (let i=0; i<datamodel.fields.length; i++) {
|
|
94
95
|
const f:OINODbDataField = datamodel.fields[i]
|
|
95
96
|
let value:string|null|undefined = f.serializeCell(row[i])
|
|
96
|
-
if (f.fieldParams.isPrimaryKey) {
|
|
97
|
+
if (f.fieldParams.isPrimaryKey || f.fieldParams.isForeignKey) {
|
|
97
98
|
if (value && (f instanceof OINONumberDataField) && (datamodel.api.hashid)) {
|
|
98
99
|
value = datamodel.api.hashid.encode(value, f.name + " " + row_id_seed)
|
|
99
100
|
}
|
|
100
|
-
|
|
101
|
+
if (f.fieldParams.isPrimaryKey) {
|
|
102
|
+
primary_key_values.push(value || "")
|
|
103
|
+
}
|
|
101
104
|
}
|
|
102
105
|
// OINOLog.debug("renderFromDbData replace field value", {field:f.name, value:value })
|
|
103
106
|
this.setVariableFromValue(f.name, value || "")
|
|
@@ -193,9 +196,10 @@ export class OINODbApi {
|
|
|
193
196
|
}
|
|
194
197
|
|
|
195
198
|
private async _doGet(result:OINODbApiResult, id:string, params:OINODbApiRequestParams):Promise<void> {
|
|
196
|
-
|
|
197
|
-
// OINOLog.debug("OINODbApi.doGet sql", {sql:sql})
|
|
199
|
+
let sql:string = ""
|
|
198
200
|
try {
|
|
201
|
+
sql = this.datamodel.printSqlSelect(id, params.sqlParams || {})
|
|
202
|
+
// OINOLog.debug("OINODbApi.doGet sql", {sql:sql})
|
|
199
203
|
const sql_res:OINODbDataSet = await this.db.sqlSelect(sql)
|
|
200
204
|
// OINOLog.debug("OINODbApi.doGet sql_res", {sql_res:sql_res})
|
|
201
205
|
if (sql_res.hasErrors()) {
|
|
@@ -291,20 +295,21 @@ export class OINODbApi {
|
|
|
291
295
|
* @param params HTTP URL parameters as key-value-pairs
|
|
292
296
|
*
|
|
293
297
|
*/
|
|
294
|
-
async doRequest(method:string, id: string, body:string|OINODataRow[]|any, params:OINODbApiRequestParams = API_EMPTY_PARAMS):Promise<OINODbApiResult> {
|
|
298
|
+
async doRequest(method:string, id: string, body:string|OINODataRow[]|Buffer|any, params:OINODbApiRequestParams = API_EMPTY_PARAMS):Promise<OINODbApiResult> {
|
|
295
299
|
OINOBenchmark.start("OINODbApi", "doRequest")
|
|
296
300
|
// OINOLog.debug("OINODbApi.doRequest enter", {method:method, id:id, body:body, params:params})
|
|
297
301
|
let result:OINODbApiResult = new OINODbApiResult(params)
|
|
298
302
|
let rows:OINODataRow[] = []
|
|
299
303
|
if ((method == "POST") || (method == "PUT")) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
304
|
+
try {
|
|
305
|
+
if (Array.isArray(body)) {
|
|
306
|
+
rows = body as OINODataRow[]
|
|
307
|
+
} else {
|
|
308
|
+
rows = OINOParser.createRows(this.datamodel, body, params)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
} catch (e:any) {
|
|
312
|
+
result.setError(400, "Invalid data: " + e.message, "DoRequest")
|
|
308
313
|
}
|
|
309
314
|
// OINOLog.debug("OINODbApi.doRequest - OINODataRow rows", {rows:rows})
|
|
310
315
|
}
|
package/src/OINODbDataField.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { OINODbDataFieldParams, OINODataCell, OINODb } from "./index.js";
|
|
7
|
+
import { OINODbDataFieldParams, OINODataCell, OINODb, OINOLog, OINO_ERROR_PREFIX } from "./index.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Base class for a column of data responsible for appropriatelly serializing/deserializing the data.
|
|
@@ -62,6 +62,9 @@ export class OINODbDataField {
|
|
|
62
62
|
if (this.fieldParams.isPrimaryKey) {
|
|
63
63
|
params += "PK ";
|
|
64
64
|
}
|
|
65
|
+
if (this.fieldParams.isForeignKey) {
|
|
66
|
+
params += "FK ";
|
|
67
|
+
}
|
|
65
68
|
if (this.fieldParams.isAutoInc) {
|
|
66
69
|
params += "AUTOINC ";
|
|
67
70
|
}
|
|
@@ -253,7 +256,12 @@ export class OINONumberDataField extends OINODbDataField {
|
|
|
253
256
|
} else if ((value === "") || (value === null)) {
|
|
254
257
|
return null
|
|
255
258
|
} else {
|
|
256
|
-
|
|
259
|
+
const result:number = parseFloat(value)
|
|
260
|
+
if (isNaN(result)) {
|
|
261
|
+
OINOLog.error("OINODbSqlFilter.toSql: Invalid value!", {value:value})
|
|
262
|
+
throw new Error(OINO_ERROR_PREFIX + ": OINONumberDataField.deserializeCell - Invalid value '" + value + "'") // incorrectly formatted data could be a security risk, abort processing
|
|
263
|
+
}
|
|
264
|
+
return result
|
|
257
265
|
}
|
|
258
266
|
}
|
|
259
267
|
}
|
|
@@ -305,7 +313,7 @@ export class OINOBlobDataField extends OINODbDataField {
|
|
|
305
313
|
*/
|
|
306
314
|
deserializeCell(value: string|null|undefined): OINODataCell {
|
|
307
315
|
if (value == null) {
|
|
308
|
-
return
|
|
316
|
+
return Buffer.alloc(0)
|
|
309
317
|
|
|
310
318
|
} else {
|
|
311
319
|
return Buffer.from(value, 'base64') // Blob-field data is base64 encoded and converted internally to UInt8Array / Buffer
|
package/src/OINODbDataModel.ts
CHANGED
|
@@ -231,25 +231,20 @@ export class OINODbDataModel {
|
|
|
231
231
|
*
|
|
232
232
|
*/
|
|
233
233
|
printSqlSelect(id: string, params:OINODbSqlParams): string {
|
|
234
|
-
|
|
235
|
-
const filter_sql = params.filter?.toSql(this) || ""
|
|
234
|
+
const column_names = this._printSqlColumnNames()
|
|
236
235
|
const order_sql = params.order?.toSql(this) || ""
|
|
237
236
|
const limit_sql = params.limit?.toSql(this) || ""
|
|
238
|
-
|
|
237
|
+
const filter_sql = params.filter?.toSql(this) || ""
|
|
238
|
+
let where_sql = ""
|
|
239
|
+
// OINOLog.debug("OINODbDataModel.printSqlSelect", {id:id, select_sql:result, filter_sql:filter_sql, order_sql:order_sql})
|
|
239
240
|
if ((id != null) && (id != "") && (filter_sql != "")) {
|
|
240
|
-
|
|
241
|
+
where_sql = this._printSqlPrimaryKeyCondition(id) + " AND " + filter_sql
|
|
241
242
|
} else if ((id != null) && (id != "")) {
|
|
242
|
-
|
|
243
|
+
where_sql = this._printSqlPrimaryKeyCondition(id)
|
|
243
244
|
} else if (filter_sql != "") {
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
if (order_sql) {
|
|
247
|
-
result += "\nORDER BY " + order_sql
|
|
248
|
-
}
|
|
249
|
-
if (limit_sql) {
|
|
250
|
-
result += "\nLIMIT " + limit_sql
|
|
245
|
+
where_sql = filter_sql
|
|
251
246
|
}
|
|
252
|
-
result
|
|
247
|
+
const result = this.api.db.printSqlSelect(this.api.params.tableName, column_names, where_sql, order_sql, limit_sql)
|
|
253
248
|
// OINOLog.debug("OINODbDataModel.printSqlSelect", {result:result})
|
|
254
249
|
return result;
|
|
255
250
|
}
|