@budibase/server 1.1.22 → 1.1.25-alpha.0
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/builder/assets/{index.5c0ce502.css → index.25c094f3.css} +2 -2
- package/builder/assets/index.6980613e.js +979 -0
- package/builder/assets/{vendor.7f11b0ca.js → vendor.b0c43a06.js} +1 -1
- package/builder/index.html +3 -3
- package/coverage/clover.xml +158 -149
- package/coverage/coverage-final.json +1 -1
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
- package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
- package/coverage/lcov-report/api/controllers/component.js.html +1 -1
- package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +1 -1
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
- package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
- package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
- package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.html +1 -1
- package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/role.js.html +1 -1
- package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/index.html +18 -18
- package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +94 -49
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
- package/coverage/lcov-report/api/controllers/script.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
- package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +1 -1
- package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
- package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/routes/auth.js.html +1 -1
- package/coverage/lcov-report/api/routes/automation.js.html +1 -1
- package/coverage/lcov-report/api/routes/backup.js.html +1 -1
- package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
- package/coverage/lcov-report/api/routes/component.js.html +1 -1
- package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
- package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
- package/coverage/lcov-report/api/routes/dev.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +1 -1
- package/coverage/lcov-report/api/routes/integration.js.html +1 -1
- package/coverage/lcov-report/api/routes/layout.js.html +1 -1
- package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
- package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
- package/coverage/lcov-report/api/routes/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +1 -1
- package/coverage/lcov-report/api/routes/role.js.html +1 -1
- package/coverage/lcov-report/api/routes/routing.js.html +1 -1
- package/coverage/lcov-report/api/routes/screen.js.html +1 -1
- package/coverage/lcov-report/api/routes/script.js.html +1 -1
- package/coverage/lcov-report/api/routes/table.js.html +1 -1
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +1 -1
- package/coverage/lcov-report/api/routes/utils/index.html +1 -1
- package/coverage/lcov-report/api/routes/utils/validators.js.html +1 -1
- package/coverage/lcov-report/api/routes/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +1 -1
- package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
- package/coverage/lcov-report/automations/bullboard.js.html +1 -1
- package/coverage/lcov-report/automations/index.html +1 -1
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
- package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
- package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +1 -1
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
- package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
- package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
- package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
- package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/triggers.js.html +1 -1
- package/coverage/lcov-report/constants/index.html +1 -1
- package/coverage/lcov-report/constants/index.js.html +1 -1
- package/coverage/lcov-report/constants/layouts.js.html +1 -1
- package/coverage/lcov-report/constants/screens.js.html +1 -1
- package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
- package/coverage/lcov-report/db/index.html +1 -1
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
- package/coverage/lcov-report/db/newid.js.html +1 -1
- package/coverage/lcov-report/db/utils.js.html +1 -1
- package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
- package/coverage/lcov-report/events/index.html +1 -1
- package/coverage/lcov-report/events/index.js.html +1 -1
- package/coverage/lcov-report/events/utils.js.html +1 -1
- package/coverage/lcov-report/index.html +18 -18
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
- package/coverage/lcov-report/middleware/builder.js.html +1 -1
- package/coverage/lcov-report/middleware/currentapp.js.html +1 -1
- package/coverage/lcov-report/middleware/index.html +1 -1
- package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
- package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
- package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/utils.js.html +1 -1
- package/coverage/lcov-report/threads/automation.js.html +1 -1
- package/coverage/lcov-report/threads/index.html +1 -1
- package/coverage/lcov-report/threads/query.js.html +1 -1
- package/coverage/lcov-report/threads/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
- package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
- package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
- package/coverage/lcov-report/utilities/global.js.html +1 -1
- package/coverage/lcov-report/utilities/index.html +1 -1
- package/coverage/lcov-report/utilities/index.js.html +1 -1
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
- package/coverage/lcov-report/utilities/queue/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
- package/coverage/lcov-report/utilities/security.js.html +1 -1
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
- package/coverage/lcov-report/utilities/users.js.html +1 -1
- package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
- package/coverage/lcov.info +307 -288
- package/dist/api/controllers/row/internalSearch.js +30 -16
- package/dist/integrations/base/sql.js +43 -14
- package/dist/package.json +8 -8
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/index.js +5 -7
- package/package.json +9 -9
- package/src/api/controllers/row/internalSearch.js +35 -20
- package/src/definitions/datasource.ts +3 -0
- package/src/integrations/base/sql.ts +44 -13
- package/src/integrations/tests/sql.spec.js +50 -4
- package/src/utilities/fileSystem/index.js +6 -12
- package/builder/assets/index.2709af96.js +0 -979
|
@@ -99,21 +99,18 @@ exports.apiFileReturn = contents => {
|
|
|
99
99
|
return fs.createReadStream(path);
|
|
100
100
|
};
|
|
101
101
|
exports.defineFilter = excludeRows => {
|
|
102
|
+
const ids = [USER_METDATA_PREFIX, LINK_USER_METADATA_PREFIX];
|
|
102
103
|
if (excludeRows) {
|
|
103
|
-
|
|
104
|
-
doc._id.includes(LINK_USER_METADATA_PREFIX) ||
|
|
105
|
-
doc._id.includes(TABLE_ROW_PREFIX));
|
|
106
|
-
}
|
|
107
|
-
else if (!excludeRows) {
|
|
108
|
-
return doc => !(doc._id.includes(USER_METDATA_PREFIX) ||
|
|
109
|
-
doc._id.includes(LINK_USER_METADATA_PREFIX));
|
|
104
|
+
ids.push(TABLE_ROW_PREFIX);
|
|
110
105
|
}
|
|
106
|
+
return doc => !ids.map(key => doc._id.includes(key)).reduce((prev, curr) => prev || curr);
|
|
111
107
|
};
|
|
112
108
|
/**
|
|
113
109
|
* Local utility to back up the database state for an app, excluding global user
|
|
114
110
|
* data or user relationships.
|
|
115
111
|
* @param {string} appId The app to backup
|
|
116
112
|
* @param {object} config Config to send to export DB
|
|
113
|
+
* @param {boolean} includeRows Flag to state whether the export should include data.
|
|
117
114
|
* @returns {*} either a string or a stream of the backup
|
|
118
115
|
*/
|
|
119
116
|
const backupAppData = (appId, config, includeRows) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -131,6 +128,7 @@ exports.performBackup = (appId, backupName) => __awaiter(void 0, void 0, void 0,
|
|
|
131
128
|
/**
|
|
132
129
|
* Streams a backup of the database state for an app
|
|
133
130
|
* @param {string} appId The ID of the app which is to be backed up.
|
|
131
|
+
* @param {boolean} includeRows Flag to state whether the export should include data.
|
|
134
132
|
* @returns {*} a readable stream of the backup which is written in real time
|
|
135
133
|
*/
|
|
136
134
|
exports.streamBackup = (appId, includeRows) => __awaiter(void 0, void 0, void 0, function* () {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.25-alpha.0",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -77,11 +77,11 @@
|
|
|
77
77
|
"license": "GPL-3.0",
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"@apidevtools/swagger-parser": "10.0.3",
|
|
80
|
-
"@budibase/backend-core": "^1.1.
|
|
81
|
-
"@budibase/client": "^1.1.
|
|
82
|
-
"@budibase/pro": "1.1.
|
|
83
|
-
"@budibase/string-templates": "^1.1.
|
|
84
|
-
"@budibase/types": "^1.1.
|
|
80
|
+
"@budibase/backend-core": "^1.1.25-alpha.0",
|
|
81
|
+
"@budibase/client": "^1.1.25-alpha.0",
|
|
82
|
+
"@budibase/pro": "1.1.24",
|
|
83
|
+
"@budibase/string-templates": "^1.1.25-alpha.0",
|
|
84
|
+
"@budibase/types": "^1.1.25-alpha.0",
|
|
85
85
|
"@bull-board/api": "3.7.0",
|
|
86
86
|
"@bull-board/koa": "3.9.4",
|
|
87
87
|
"@elastic/elasticsearch": "7.10.0",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"koa-send": "5.0.0",
|
|
119
119
|
"koa-session": "5.12.0",
|
|
120
120
|
"koa-static": "5.0.0",
|
|
121
|
-
"koa2-ratelimit": "1.1.
|
|
121
|
+
"koa2-ratelimit": "1.1.1",
|
|
122
122
|
"lodash": "4.17.21",
|
|
123
123
|
"memorystream": "0.3.1",
|
|
124
124
|
"mongodb": "3.6.3",
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
"redis": "4",
|
|
138
138
|
"server-destroy": "1.0.1",
|
|
139
139
|
"snowflake-promise": "^4.5.0",
|
|
140
|
-
"svelte": "3.
|
|
140
|
+
"svelte": "3.49.0",
|
|
141
141
|
"swagger-parser": "10.0.3",
|
|
142
142
|
"to-json-schema": "0.2.5",
|
|
143
143
|
"uuid": "3.3.2",
|
|
@@ -195,5 +195,5 @@
|
|
|
195
195
|
"optionalDependencies": {
|
|
196
196
|
"oracledb": "5.3.0"
|
|
197
197
|
},
|
|
198
|
-
"gitHead": "
|
|
198
|
+
"gitHead": "dd0b07d7c9e04583d9e46af1f8d39896767bc9b6"
|
|
199
199
|
}
|
|
@@ -19,6 +19,7 @@ class QueryBuilder {
|
|
|
19
19
|
empty: {},
|
|
20
20
|
notEmpty: {},
|
|
21
21
|
oneOf: {},
|
|
22
|
+
contains: {},
|
|
22
23
|
...base,
|
|
23
24
|
}
|
|
24
25
|
this.limit = 50
|
|
@@ -119,6 +120,11 @@ class QueryBuilder {
|
|
|
119
120
|
return this
|
|
120
121
|
}
|
|
121
122
|
|
|
123
|
+
addContains(key, value) {
|
|
124
|
+
this.query.contains[key] = value
|
|
125
|
+
return this
|
|
126
|
+
}
|
|
127
|
+
|
|
122
128
|
/**
|
|
123
129
|
* Preprocesses a value before going into a lucene search.
|
|
124
130
|
* Transforms strings to lowercase and wraps strings and bools in quotes.
|
|
@@ -164,6 +170,31 @@ class QueryBuilder {
|
|
|
164
170
|
return `${key}:${builder.preprocess(value, allPreProcessingOpts)}`
|
|
165
171
|
}
|
|
166
172
|
|
|
173
|
+
const contains = (key, value) => {
|
|
174
|
+
if (!value && value !== 0) {
|
|
175
|
+
return null
|
|
176
|
+
}
|
|
177
|
+
return `${key}:${builder.preprocess(value, { escape: true })}`
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const oneOf = (key, value) => {
|
|
181
|
+
if (!Array.isArray(value)) {
|
|
182
|
+
if (typeof value === "string") {
|
|
183
|
+
value = value.split(",")
|
|
184
|
+
} else {
|
|
185
|
+
return ""
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
let orStatement = `${builder.preprocess(value[0], allPreProcessingOpts)}`
|
|
189
|
+
for (let i = 1; i < value.length; i++) {
|
|
190
|
+
orStatement += ` OR ${builder.preprocess(
|
|
191
|
+
value[i],
|
|
192
|
+
allPreProcessingOpts
|
|
193
|
+
)}`
|
|
194
|
+
}
|
|
195
|
+
return `${key}:(${orStatement})`
|
|
196
|
+
}
|
|
197
|
+
|
|
167
198
|
function build(structure, queryFn) {
|
|
168
199
|
for (let [key, value] of Object.entries(structure)) {
|
|
169
200
|
key = builder.preprocess(key.replace(/ /g, "_"), {
|
|
@@ -239,26 +270,10 @@ class QueryBuilder {
|
|
|
239
270
|
build(this.query.notEmpty, key => `${key}:["" TO *]`)
|
|
240
271
|
}
|
|
241
272
|
if (this.query.oneOf) {
|
|
242
|
-
build(this.query.oneOf,
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
} else {
|
|
247
|
-
return ""
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
let orStatement = `${builder.preprocess(
|
|
251
|
-
value[0],
|
|
252
|
-
allPreProcessingOpts
|
|
253
|
-
)}`
|
|
254
|
-
for (let i = 1; i < value.length; i++) {
|
|
255
|
-
orStatement += ` OR ${builder.preprocess(
|
|
256
|
-
value[i],
|
|
257
|
-
allPreProcessingOpts
|
|
258
|
-
)}`
|
|
259
|
-
}
|
|
260
|
-
return `${key}:(${orStatement})`
|
|
261
|
-
})
|
|
273
|
+
build(this.query.oneOf, oneOf)
|
|
274
|
+
}
|
|
275
|
+
if (this.query.contains) {
|
|
276
|
+
build(this.query.contains, contains)
|
|
262
277
|
}
|
|
263
278
|
// make sure table ID is always added as an AND
|
|
264
279
|
if (tableId) {
|
|
@@ -142,6 +142,21 @@ class InternalBuilder {
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
+
|
|
146
|
+
const like = (key: string, value: any) => {
|
|
147
|
+
const fnc = allOr ? "orWhere" : "where"
|
|
148
|
+
// postgres supports ilike, nothing else does
|
|
149
|
+
if (this.client === SqlClients.POSTGRES) {
|
|
150
|
+
query = query[fnc](key, "ilike", `%${value}%`)
|
|
151
|
+
} else {
|
|
152
|
+
const rawFnc = `${fnc}Raw`
|
|
153
|
+
// @ts-ignore
|
|
154
|
+
query = query[rawFnc](`LOWER(${likeKey(this.client, key)}) LIKE ?`, [
|
|
155
|
+
`%${value}%`,
|
|
156
|
+
])
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
145
160
|
if (!filters) {
|
|
146
161
|
return query
|
|
147
162
|
}
|
|
@@ -168,19 +183,7 @@ class InternalBuilder {
|
|
|
168
183
|
})
|
|
169
184
|
}
|
|
170
185
|
if (filters.fuzzy) {
|
|
171
|
-
iterate(filters.fuzzy,
|
|
172
|
-
const fnc = allOr ? "orWhere" : "where"
|
|
173
|
-
// postgres supports ilike, nothing else does
|
|
174
|
-
if (this.client === SqlClients.POSTGRES) {
|
|
175
|
-
query = query[fnc](key, "ilike", `%${value}%`)
|
|
176
|
-
} else {
|
|
177
|
-
const rawFnc = `${fnc}Raw`
|
|
178
|
-
// @ts-ignore
|
|
179
|
-
query = query[rawFnc](`LOWER(${likeKey(this.client, key)}) LIKE ?`, [
|
|
180
|
-
`%${value}%`,
|
|
181
|
-
])
|
|
182
|
-
}
|
|
183
|
-
})
|
|
186
|
+
iterate(filters.fuzzy, like)
|
|
184
187
|
}
|
|
185
188
|
if (filters.range) {
|
|
186
189
|
iterate(filters.range, (key, value) => {
|
|
@@ -223,6 +226,34 @@ class InternalBuilder {
|
|
|
223
226
|
query = query[fnc](key)
|
|
224
227
|
})
|
|
225
228
|
}
|
|
229
|
+
if (filters.contains) {
|
|
230
|
+
const fnc = allOr ? "orWhere" : "where"
|
|
231
|
+
const rawFnc = `${fnc}Raw`
|
|
232
|
+
if (this.client === SqlClients.POSTGRES) {
|
|
233
|
+
iterate(filters.contains, (key: string, value: any) => {
|
|
234
|
+
const fieldNames = key.split(/\./g)
|
|
235
|
+
const tableName = fieldNames[0]
|
|
236
|
+
const columnName = fieldNames[1]
|
|
237
|
+
if (typeof value === "string") {
|
|
238
|
+
value = `"${value}"`
|
|
239
|
+
}
|
|
240
|
+
// @ts-ignore
|
|
241
|
+
query = query[rawFnc](
|
|
242
|
+
`"${tableName}"."${columnName}"::jsonb @> '[${value}]'`
|
|
243
|
+
)
|
|
244
|
+
})
|
|
245
|
+
} else if (this.client === SqlClients.MY_SQL) {
|
|
246
|
+
iterate(filters.contains, (key: string, value: any) => {
|
|
247
|
+
if (typeof value === "string") {
|
|
248
|
+
value = `"${value}"`
|
|
249
|
+
}
|
|
250
|
+
// @ts-ignore
|
|
251
|
+
query = query[rawFnc](`JSON_CONTAINS(${key}, '${value}')`)
|
|
252
|
+
})
|
|
253
|
+
} else {
|
|
254
|
+
iterate(filters.contains, like)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
226
257
|
return query
|
|
227
258
|
}
|
|
228
259
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const Sql = require("../base/sql")
|
|
2
|
+
const { SqlClients } = require("../utils")
|
|
2
3
|
|
|
3
4
|
const TABLE_NAME = "test"
|
|
4
5
|
|
|
@@ -46,7 +47,7 @@ function generateDeleteJson(table = TABLE_NAME, filters = {}) {
|
|
|
46
47
|
|
|
47
48
|
describe("SQL query builder", () => {
|
|
48
49
|
const limit = 500
|
|
49
|
-
const client =
|
|
50
|
+
const client = SqlClients.POSTGRES
|
|
50
51
|
let sql
|
|
51
52
|
|
|
52
53
|
beforeEach(() => {
|
|
@@ -173,15 +174,15 @@ describe("SQL query builder", () => {
|
|
|
173
174
|
})
|
|
174
175
|
|
|
175
176
|
it("should work with MS-SQL", () => {
|
|
176
|
-
const query = new Sql(
|
|
177
|
+
const query = new Sql(SqlClients.MS_SQL, 10)._query(generateReadJson())
|
|
177
178
|
expect(query).toEqual({
|
|
178
179
|
bindings: [10],
|
|
179
180
|
sql: `select * from (select top (@p0) * from [${TABLE_NAME}]) as [${TABLE_NAME}]`
|
|
180
181
|
})
|
|
181
182
|
})
|
|
182
183
|
|
|
183
|
-
it("should work with
|
|
184
|
-
const query = new Sql(
|
|
184
|
+
it("should work with MySQL", () => {
|
|
185
|
+
const query = new Sql(SqlClients.MY_SQL, 10)._query(generateReadJson())
|
|
185
186
|
expect(query).toEqual({
|
|
186
187
|
bindings: [10],
|
|
187
188
|
sql: `select * from (select * from \`${TABLE_NAME}\` limit ?) as \`${TABLE_NAME}\``
|
|
@@ -238,4 +239,49 @@ describe("SQL query builder", () => {
|
|
|
238
239
|
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."property" > $1 limit $2) as "${TABLE_NAME}"`
|
|
239
240
|
})
|
|
240
241
|
})
|
|
242
|
+
|
|
243
|
+
it("should use like expression for MS-SQL when filter is contains", () => {
|
|
244
|
+
const query = new Sql(SqlClients.MS_SQL, 10)._query(generateReadJson({
|
|
245
|
+
filters: {
|
|
246
|
+
contains: {
|
|
247
|
+
age: 20,
|
|
248
|
+
name: "John"
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}))
|
|
252
|
+
expect(query).toEqual({
|
|
253
|
+
bindings: [10, "%20%", "%John%"],
|
|
254
|
+
sql: `select * from (select top (@p0) * from [${TABLE_NAME}] where LOWER(${TABLE_NAME}.age) LIKE @p1 and LOWER(${TABLE_NAME}.name) LIKE @p2) as [${TABLE_NAME}]`
|
|
255
|
+
})
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it("should use JSON_CONTAINS expression for MySQL when filter is contains", () => {
|
|
259
|
+
const query = new Sql(SqlClients.MY_SQL, 10)._query(generateReadJson({
|
|
260
|
+
filters: {
|
|
261
|
+
contains: {
|
|
262
|
+
age: 20,
|
|
263
|
+
name: "John"
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}))
|
|
267
|
+
expect(query).toEqual({
|
|
268
|
+
bindings: [10],
|
|
269
|
+
sql: `select * from (select * from \`${TABLE_NAME}\` where JSON_CONTAINS(${TABLE_NAME}.age, '20') and JSON_CONTAINS(${TABLE_NAME}.name, '"John"') limit ?) as \`${TABLE_NAME}\``
|
|
270
|
+
})
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
it("should use jsonb operator expression for PostgreSQL when filter is contains", () => {
|
|
274
|
+
const query = new Sql(SqlClients.POSTGRES, 10)._query(generateReadJson({
|
|
275
|
+
filters: {
|
|
276
|
+
contains: {
|
|
277
|
+
age: 20,
|
|
278
|
+
name: "John"
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}))
|
|
282
|
+
expect(query).toEqual({
|
|
283
|
+
bindings: [10],
|
|
284
|
+
sql: `select * from (select * from \"${TABLE_NAME}\" where \"${TABLE_NAME}\".\"age\"::jsonb @> '[20]' and \"${TABLE_NAME}\".\"name\"::jsonb @> '["John"]' limit $1) as \"${TABLE_NAME}\"`
|
|
285
|
+
})
|
|
286
|
+
})
|
|
241
287
|
})
|
|
@@ -111,20 +111,12 @@ exports.apiFileReturn = contents => {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
exports.defineFilter = excludeRows => {
|
|
114
|
+
const ids = [USER_METDATA_PREFIX, LINK_USER_METADATA_PREFIX]
|
|
114
115
|
if (excludeRows) {
|
|
115
|
-
|
|
116
|
-
!(
|
|
117
|
-
doc._id.includes(USER_METDATA_PREFIX) ||
|
|
118
|
-
doc._id.includes(LINK_USER_METADATA_PREFIX) ||
|
|
119
|
-
doc._id.includes(TABLE_ROW_PREFIX)
|
|
120
|
-
)
|
|
121
|
-
} else if (!excludeRows) {
|
|
122
|
-
return doc =>
|
|
123
|
-
!(
|
|
124
|
-
doc._id.includes(USER_METDATA_PREFIX) ||
|
|
125
|
-
doc._id.includes(LINK_USER_METADATA_PREFIX)
|
|
126
|
-
)
|
|
116
|
+
ids.push(TABLE_ROW_PREFIX)
|
|
127
117
|
}
|
|
118
|
+
return doc =>
|
|
119
|
+
!ids.map(key => doc._id.includes(key)).reduce((prev, curr) => prev || curr)
|
|
128
120
|
}
|
|
129
121
|
|
|
130
122
|
/**
|
|
@@ -132,6 +124,7 @@ exports.defineFilter = excludeRows => {
|
|
|
132
124
|
* data or user relationships.
|
|
133
125
|
* @param {string} appId The app to backup
|
|
134
126
|
* @param {object} config Config to send to export DB
|
|
127
|
+
* @param {boolean} includeRows Flag to state whether the export should include data.
|
|
135
128
|
* @returns {*} either a string or a stream of the backup
|
|
136
129
|
*/
|
|
137
130
|
const backupAppData = async (appId, config, includeRows) => {
|
|
@@ -154,6 +147,7 @@ exports.performBackup = async (appId, backupName) => {
|
|
|
154
147
|
/**
|
|
155
148
|
* Streams a backup of the database state for an app
|
|
156
149
|
* @param {string} appId The ID of the app which is to be backed up.
|
|
150
|
+
* @param {boolean} includeRows Flag to state whether the export should include data.
|
|
157
151
|
* @returns {*} a readable stream of the backup which is written in real time
|
|
158
152
|
*/
|
|
159
153
|
exports.streamBackup = async (appId, includeRows) => {
|