From 955b9a4d630fc23d41070b66eb31bc8d0abc9120 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Wed, 25 May 2022 09:26:10 +0100 Subject: [PATCH 1/3] Export app without rows --- .../components/start/ExportAppModal.svelte | 16 ++++++++++ .../pages/builder/portal/apps/index.svelte | 11 +++++-- packages/server/src/api/controllers/backup.js | 6 ++-- packages/server/src/db/utils.js | 1 + .../server/src/utilities/fileSystem/index.js | 30 ++++++++++++++----- 5 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 packages/builder/src/components/start/ExportAppModal.svelte diff --git a/packages/builder/src/components/start/ExportAppModal.svelte b/packages/builder/src/components/start/ExportAppModal.svelte new file mode 100644 index 0000000000..19f86b12d8 --- /dev/null +++ b/packages/builder/src/components/start/ExportAppModal.svelte @@ -0,0 +1,16 @@ + + + + + diff --git a/packages/builder/src/pages/builder/portal/apps/index.svelte b/packages/builder/src/pages/builder/portal/apps/index.svelte index a25e7e2c6a..494cf0df92 100644 --- a/packages/builder/src/pages/builder/portal/apps/index.svelte +++ b/packages/builder/src/pages/builder/portal/apps/index.svelte @@ -18,6 +18,7 @@ import CreateAppModal from "components/start/CreateAppModal.svelte" import UpdateAppModal from "components/start/UpdateAppModal.svelte" import ChooseIconModal from "components/start/ChooseIconModal.svelte" + import ExportAppModal from "components/start/ExportAppModal.svelte" import { store, automationStore } from "builderStore" import { API } from "api" @@ -38,6 +39,7 @@ let updatingModal let deletionModal let unpublishModal + let exportModal let iconModal let creatingApp = false let loaded = $apps?.length || $templates?.length @@ -198,9 +200,8 @@ } const exportApp = app => { - const id = app.deployed ? app.prodId : app.devId - const appName = encodeURIComponent(app.name) - window.location = `/api/backups/export?appId=${id}&appname=${appName}` + exportModal.show() + selectedApp = app } const unpublishApp = app => { @@ -434,6 +435,10 @@ + + + + { return fs.createReadStream(path) } +exports.defineFilter = includeRows => { + if (includeRows) { + return doc => + !( + doc._id.includes(USER_METDATA_PREFIX) || + doc._id.includes(LINK_USER_METADATA_PREFIX) + ) + } else if (!includeRows) { + return doc => + !( + doc._id.includes(USER_METDATA_PREFIX) || + doc._id.includes(LINK_USER_METADATA_PREFIX) || + doc._id.includes(TABLE_ROW_PREFIX) + ) + } +} + /** * Local utility to back up the database state for an app, excluding global user * data or user relationships. @@ -116,14 +134,10 @@ exports.apiFileReturn = contents => { * @param {object} config Config to send to export DB * @returns {*} either a string or a stream of the backup */ -const backupAppData = async (appId, config) => { +const backupAppData = async (appId, config, noRows) => { return await exports.exportDB(appId, { ...config, - filter: doc => - !( - doc._id.includes(USER_METDATA_PREFIX) || - doc._id.includes(LINK_USER_METADATA_PREFIX) - ), + filter: exports.defineFilter(noRows), }) } @@ -142,8 +156,8 @@ exports.performBackup = async (appId, backupName) => { * @param {string} appId The ID of the app which is to be backed up. * @returns {*} a readable stream of the backup which is written in real time */ -exports.streamBackup = async appId => { - return await backupAppData(appId, { stream: true }) +exports.streamBackup = async (appId, includeRows) => { + return await backupAppData(appId, { stream: true }, includeRows) } /** From af5c1a7e1f080e4f3746d5478c862dc139ff2fc2 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Wed, 25 May 2022 15:06:41 +0100 Subject: [PATCH 2/3] change variable to reflect negation --- packages/server/src/utilities/fileSystem/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/src/utilities/fileSystem/index.js b/packages/server/src/utilities/fileSystem/index.js index 3666d09794..bbfeb5b627 100644 --- a/packages/server/src/utilities/fileSystem/index.js +++ b/packages/server/src/utilities/fileSystem/index.js @@ -134,10 +134,10 @@ exports.defineFilter = includeRows => { * @param {object} config Config to send to export DB * @returns {*} either a string or a stream of the backup */ -const backupAppData = async (appId, config, noRows) => { +const backupAppData = async (appId, config, includeRows) => { return await exports.exportDB(appId, { ...config, - filter: exports.defineFilter(noRows), + filter: exports.defineFilter(includeRows), }) } From bd737cc1ca05af741120c1a59511a1271e465b1a Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jun 2022 15:17:14 +0100 Subject: [PATCH 3/3] negate export button --- .../src/components/start/ExportAppModal.svelte | 6 +++--- packages/server/src/api/controllers/backup.js | 6 +++--- .../server/src/utilities/fileSystem/index.js | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/builder/src/components/start/ExportAppModal.svelte b/packages/builder/src/components/start/ExportAppModal.svelte index 19f86b12d8..05a42dfa4a 100644 --- a/packages/builder/src/components/start/ExportAppModal.svelte +++ b/packages/builder/src/components/start/ExportAppModal.svelte @@ -2,15 +2,15 @@ import { ModalContent, Toggle } from "@budibase/bbui" export let app - let includeRows = true + let excludeRows = false const exportApp = () => { const id = app.deployed ? app.prodId : app.devId const appName = encodeURIComponent(app.name) - window.location = `/api/backups/export?appId=${id}&appname=${appName}&includeRows=${includeRows}` + window.location = `/api/backups/export?appId=${id}&appname=${appName}&excludeRows=${excludeRows}` } - + diff --git a/packages/server/src/api/controllers/backup.js b/packages/server/src/api/controllers/backup.js index 586100918d..0ebf01176e 100644 --- a/packages/server/src/api/controllers/backup.js +++ b/packages/server/src/api/controllers/backup.js @@ -1,11 +1,11 @@ const { streamBackup } = require("../../utilities/fileSystem") exports.exportAppDump = async function (ctx) { - let { appId, includeRows } = ctx.query + let { appId, excludeRows } = ctx.query const appName = decodeURI(ctx.query.appname) - includeRows = includeRows === "true" + excludeRows = excludeRows === "true" const backupIdentifier = `${appName}-export-${new Date().getTime()}.txt` ctx.attachment(backupIdentifier) - ctx.body = await streamBackup(appId, includeRows) + ctx.body = await streamBackup(appId, excludeRows) } diff --git a/packages/server/src/utilities/fileSystem/index.js b/packages/server/src/utilities/fileSystem/index.js index bbfeb5b627..ed1cb1923a 100644 --- a/packages/server/src/utilities/fileSystem/index.js +++ b/packages/server/src/utilities/fileSystem/index.js @@ -110,20 +110,20 @@ exports.apiFileReturn = contents => { return fs.createReadStream(path) } -exports.defineFilter = includeRows => { - if (includeRows) { - return doc => - !( - doc._id.includes(USER_METDATA_PREFIX) || - doc._id.includes(LINK_USER_METADATA_PREFIX) - ) - } else if (!includeRows) { +exports.defineFilter = excludeRows => { + if (excludeRows) { return doc => !( doc._id.includes(USER_METDATA_PREFIX) || doc._id.includes(LINK_USER_METADATA_PREFIX) || doc._id.includes(TABLE_ROW_PREFIX) ) + } else if (!excludeRows) { + return doc => + !( + doc._id.includes(USER_METDATA_PREFIX) || + doc._id.includes(LINK_USER_METADATA_PREFIX) + ) } }