Adding first pass of attachments updating.
This commit is contained in:
parent
33e31fe2e4
commit
a2d12ef0a6
|
@ -32,7 +32,7 @@ const checkInitialised = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function init(opts: PouchOptions) {
|
export async function init(opts?: PouchOptions) {
|
||||||
PouchDB = pouch.getPouch(opts)
|
PouchDB = pouch.getPouch(opts)
|
||||||
initialised = true
|
initialised = true
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ export async function init(opts: PouchOptions) {
|
||||||
// NOTE: THIS IS A DANGEROUS FUNCTION - USE WITH CAUTION
|
// NOTE: THIS IS A DANGEROUS FUNCTION - USE WITH CAUTION
|
||||||
// this function is prone to leaks, should only be used
|
// this function is prone to leaks, should only be used
|
||||||
// in situations that using the function doWithDB does not work
|
// in situations that using the function doWithDB does not work
|
||||||
export async function dangerousGetDB(dbName: string, opts: any) {
|
export async function dangerousGetDB(dbName: string, opts?: any) {
|
||||||
checkInitialised()
|
checkInitialised()
|
||||||
if (env.isTest()) {
|
if (env.isTest()) {
|
||||||
dbList.add(dbName)
|
dbList.add(dbName)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { ATTACHMENT_DIR as attachmentDir } from "../../constants"
|
import { ATTACHMENT_DIR as attachmentDir } from "../../../constants"
|
||||||
export const DB_EXPORT_FILE = "db.txt"
|
export const DB_EXPORT_FILE = "db.txt"
|
||||||
export const ATTACHMENT_DIR = attachmentDir
|
export const ATTACHMENT_DIR = attachmentDir
|
||||||
export const GLOBAL_DB_EXPORT_FILE = "global.txt"
|
export const GLOBAL_DB_EXPORT_FILE = "global.txt"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { db as dbCore } from "@budibase/backend-core"
|
import { db as dbCore } from "@budibase/backend-core"
|
||||||
|
import { TABLE_ROW_PREFIX } from "../../../db/utils"
|
||||||
import { budibaseTempDir } from "../../../utilities/budibaseDir"
|
import { budibaseTempDir } from "../../../utilities/budibaseDir"
|
||||||
import { DB_EXPORT_FILE, ATTACHMENT_DIR } from "./constants"
|
import { DB_EXPORT_FILE, ATTACHMENT_DIR } from "./constants"
|
||||||
import { uploadDirectory } from "../../../utilities/fileSystem/utilities"
|
import { uploadDirectory } from "../../../utilities/fileSystem/utilities"
|
||||||
|
@ -6,7 +7,7 @@ import { ObjectStoreBuckets, FieldTypes } from "../../../constants"
|
||||||
import { join } from "path"
|
import { join } from "path"
|
||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
import sdk from "../../"
|
import sdk from "../../"
|
||||||
import { CouchFindOptions, Row } from "@budibase/types"
|
import { CouchFindOptions, RowAttachment } from "@budibase/types"
|
||||||
const uuid = require("uuid/v4")
|
const uuid = require("uuid/v4")
|
||||||
const tar = require("tar")
|
const tar = require("tar")
|
||||||
|
|
||||||
|
@ -18,6 +19,63 @@ type TemplateType = {
|
||||||
key?: string
|
key?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateAttachmentColumns(
|
||||||
|
prodAppId: string,
|
||||||
|
db: PouchDB.Database
|
||||||
|
) {
|
||||||
|
// iterate through attachment documents and update them
|
||||||
|
const tables = await sdk.tables.getAllInternalTables(db)
|
||||||
|
for (let table of tables) {
|
||||||
|
const attachmentCols: string[] = []
|
||||||
|
for (let [key, column] of Object.entries(table.schema)) {
|
||||||
|
if (column.type === FieldTypes.ATTACHMENT) {
|
||||||
|
attachmentCols.push(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// no attachment columns, nothing to do
|
||||||
|
if (attachmentCols.length === 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// use the CouchDB Mango query API to lookup rows that have attachments
|
||||||
|
const params: CouchFindOptions = {
|
||||||
|
selector: {
|
||||||
|
_id: {
|
||||||
|
$regex: `^${TABLE_ROW_PREFIX}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
attachmentCols.forEach(col => (params.selector[col] = { $exists: true }))
|
||||||
|
const { rows } = await dbCore.directCouchFind(db.name, params)
|
||||||
|
for (let row of rows) {
|
||||||
|
for (let column of attachmentCols) {
|
||||||
|
if (!Array.isArray(row[column])) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
row[column] = row[column].map((attachment: RowAttachment) => {
|
||||||
|
// URL looks like: /prod-budi-app-assets/appId/attachments/file.csv
|
||||||
|
const urlParts = attachment.url.split("/")
|
||||||
|
// drop the first empty element
|
||||||
|
urlParts.shift()
|
||||||
|
// get the prefix
|
||||||
|
const prefix = urlParts.shift()
|
||||||
|
// remove the app ID
|
||||||
|
urlParts.shift()
|
||||||
|
// add new app ID
|
||||||
|
urlParts.unshift(prodAppId)
|
||||||
|
const key = urlParts.join("/")
|
||||||
|
return {
|
||||||
|
...attachment,
|
||||||
|
key,
|
||||||
|
url: `/${prefix}/${key}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// write back the updated attachments
|
||||||
|
await db.bulkDocs(rows)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function manages temporary template files which are stored by Koa.
|
* This function manages temporary template files which are stored by Koa.
|
||||||
* @param {Object} template The template object retrieved from the Koa context object.
|
* @param {Object} template The template object retrieved from the Koa context object.
|
||||||
|
@ -67,28 +125,6 @@ export async function importApp(
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
throw "Error loading database dump from template."
|
throw "Error loading database dump from template."
|
||||||
}
|
}
|
||||||
// iterate through attachment documents and update them
|
await updateAttachmentColumns(prodAppId, db)
|
||||||
const tables = await sdk.tables.getAllInternalTables(db)
|
|
||||||
for (let table of tables) {
|
|
||||||
const attachmentCols: string[] = []
|
|
||||||
for (let [key, column] of Object.entries(table.schema)) {
|
|
||||||
if (column.type === FieldTypes.ATTACHMENT) {
|
|
||||||
attachmentCols.push(key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// no attachment columns, nothing to do
|
|
||||||
if (attachmentCols.length === 0) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// use the CouchDB Mango query API to lookup rows that have attachments
|
|
||||||
const params: CouchFindOptions = { selector: {} }
|
|
||||||
attachmentCols.forEach(col => (params.selector[col] = { $exists: true }))
|
|
||||||
const { rows } = await dbCore.directCouchFind(db.name, params)
|
|
||||||
for (let row of rows) {
|
|
||||||
// TODO:
|
|
||||||
}
|
|
||||||
// write back the updated attachments
|
|
||||||
await db.bulkDocs(rows)
|
|
||||||
}
|
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,14 @@ export enum FieldType {
|
||||||
INTERNAL = "internal",
|
INTERNAL = "internal",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RowAttachment {
|
||||||
|
size: number
|
||||||
|
name: string
|
||||||
|
url: string
|
||||||
|
extension: string
|
||||||
|
key: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface Row extends Document {
|
export interface Row extends Document {
|
||||||
type?: string
|
type?: string
|
||||||
tableId?: string
|
tableId?: string
|
||||||
|
|
Loading…
Reference in New Issue