Merge pull request #6059 from Budibase/feat/dont-export-app-rows
Allow export of app without rows
This commit is contained in:
commit
5bd5d7df1b
|
@ -0,0 +1,16 @@
|
|||
<script>
|
||||
import { ModalContent, Toggle } from "@budibase/bbui"
|
||||
|
||||
export let app
|
||||
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}&excludeRows=${excludeRows}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<ModalContent title={"Export"} confirmText={"Export"} onConfirm={exportApp}>
|
||||
<Toggle text="Exclude Rows" bind:value={excludeRows} />
|
||||
</ModalContent>
|
|
@ -17,6 +17,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"
|
||||
|
@ -37,6 +38,7 @@
|
|||
let updatingModal
|
||||
let deletionModal
|
||||
let unpublishModal
|
||||
let exportModal
|
||||
let iconModal
|
||||
let creatingApp = false
|
||||
let loaded = $apps?.length || $templates?.length
|
||||
|
@ -200,9 +202,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 => {
|
||||
|
@ -457,6 +458,10 @@
|
|||
<UpdateAppModal app={selectedApp} />
|
||||
</Modal>
|
||||
|
||||
<Modal bind:this={exportModal} padding={false} width="600px">
|
||||
<ExportAppModal app={selectedApp} />
|
||||
</Modal>
|
||||
|
||||
<ConfirmDialog
|
||||
bind:this={deletionModal}
|
||||
title="Confirm deletion"
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
const { streamBackup } = require("../../utilities/fileSystem")
|
||||
|
||||
exports.exportAppDump = async function (ctx) {
|
||||
const { appId } = ctx.query
|
||||
let { appId, excludeRows } = ctx.query
|
||||
const appName = decodeURI(ctx.query.appname)
|
||||
excludeRows = excludeRows === "true"
|
||||
const backupIdentifier = `${appName}-export-${new Date().getTime()}.txt`
|
||||
ctx.attachment(backupIdentifier)
|
||||
ctx.body = await streamBackup(appId)
|
||||
|
||||
ctx.body = await streamBackup(appId, excludeRows)
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ exports.isDevAppID = isDevAppID
|
|||
exports.isProdAppID = isProdAppID
|
||||
exports.USER_METDATA_PREFIX = `${DocumentTypes.ROW}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}`
|
||||
exports.LINK_USER_METADATA_PREFIX = `${DocumentTypes.LINK}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}`
|
||||
exports.TABLE_ROW_PREFIX = `${DocumentTypes.ROW}${SEPARATOR}${DocumentTypes.TABLE}`
|
||||
exports.ViewNames = ViewNames
|
||||
exports.InternalTables = InternalTables
|
||||
exports.DocumentTypes = DocumentTypes
|
||||
|
|
|
@ -21,6 +21,7 @@ const env = require("../../environment")
|
|||
const {
|
||||
USER_METDATA_PREFIX,
|
||||
LINK_USER_METADATA_PREFIX,
|
||||
TABLE_ROW_PREFIX,
|
||||
} = require("../../db/utils")
|
||||
const MemoryStream = require("memorystream")
|
||||
const { getAppId } = require("@budibase/backend-core/context")
|
||||
|
@ -109,6 +110,23 @@ exports.apiFileReturn = contents => {
|
|||
return fs.createReadStream(path)
|
||||
}
|
||||
|
||||
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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, includeRows) => {
|
||||
return await exports.exportDB(appId, {
|
||||
...config,
|
||||
filter: doc =>
|
||||
!(
|
||||
doc._id.includes(USER_METDATA_PREFIX) ||
|
||||
doc._id.includes(LINK_USER_METADATA_PREFIX)
|
||||
),
|
||||
filter: exports.defineFilter(includeRows),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue