Remove ctx from export rows (search not implemented)

This commit is contained in:
Adria Navarro 2023-07-17 15:57:12 +02:00
parent 1bd8bdf84c
commit 90bf4655ea
5 changed files with 92 additions and 47 deletions

View File

@ -6,6 +6,8 @@ import { Ctx } from "@budibase/types"
import * as utils from "./utils" import * as utils from "./utils"
import { gridSocket } from "../../../websockets" import { gridSocket } from "../../../websockets"
import sdk from "../../../sdk" import sdk from "../../../sdk"
import * as exporters from "../view/exporters"
import { apiFileReturn } from "../../../utilities/fileSystem"
function pickApi(tableId: any) { function pickApi(tableId: any) {
if (isExternalTable(tableId)) { if (isExternalTable(tableId)) {
@ -164,7 +166,33 @@ export async function fetchEnrichedRow(ctx: any) {
export const exportRows = async (ctx: any) => { export const exportRows = async (ctx: any) => {
const tableId = utils.getTableId(ctx) const tableId = utils.getTableId(ctx)
ctx.body = await quotas.addQuery(() => sdk.rows.exportRows(tableId, ctx), {
datasourceId: tableId, const format = ctx.query.format
const { rows, columns, query } = ctx.request.body
if (typeof format !== "string" || !exporters.isFormat(format)) {
ctx.throw(
400,
`Format ${format} not valid. Valid values: ${Object.values(
exporters.Format
)}`
)
}
ctx.body = await quotas.addQuery(
async () => {
const { fileName, content } = await sdk.rows.exportRows({
tableId,
format,
rowIds: rows,
columns,
query,
}) })
ctx.attachment(fileName)
return apiFileReturn(content)
},
{
datasourceId: tableId,
}
)
} }

View File

@ -2,6 +2,7 @@ import { Ctx, SearchFilters } from "@budibase/types"
import { isExternalTable } from "../../../integrations/utils" import { isExternalTable } from "../../../integrations/utils"
import * as internal from "./search/internal" import * as internal from "./search/internal"
import * as external from "./search/external" import * as external from "./search/external"
import { Format } from "../../../api/controllers/view/exporters"
export interface SearchParams { export interface SearchParams {
tableId: string tableId: string
@ -31,8 +32,23 @@ export async function search(tableId: string, ctx: Ctx) {
return pickApi(tableId).search(ctx) return pickApi(tableId).search(ctx)
} }
export async function exportRows(tableId: string, ctx: Ctx) { export interface ExportRowsParams {
return pickApi(tableId).exportRows(ctx) tableId: string
format: Format
rowIds: string[]
columns: string[]
query: string
}
export interface ExportRowsResult {
fileName: string
content: string
}
export async function exportRows(
options: ExportRowsParams
): Promise<ExportRowsResult> {
return pickApi(options.tableId).exportRows(options)
} }
export async function fetch(tableId: string) { export async function fetch(tableId: string) {

View File

@ -14,6 +14,7 @@ import { breakExternalTableId } from "../../../../integrations/utils"
import { cleanExportRows } from "../utils" import { cleanExportRows } from "../utils"
import { apiFileReturn } from "../../../../utilities/fileSystem" import { apiFileReturn } from "../../../../utilities/fileSystem"
import { utils } from "@budibase/shared-core" import { utils } from "@budibase/shared-core"
import { ExportRowsParams, ExportRowsResult } from "../search"
export async function search(ctx: Ctx) { export async function search(ctx: Ctx) {
const tableId = ctx.params.tableId const tableId = ctx.params.tableId
@ -78,34 +79,30 @@ export async function search(ctx: Ctx) {
} }
} }
export async function exportRows(ctx: Ctx) { export async function exportRows(
const { datasourceId, tableName } = breakExternalTableId(ctx.params.tableId) options: ExportRowsParams
const format = ctx.query.format as string ): Promise<ExportRowsResult> {
const { columns } = ctx.request.body const { tableId, format, columns, rowIds } = options
const { datasourceId, tableName } = breakExternalTableId(tableId)
const datasource = await sdk.datasources.get(datasourceId!) const datasource = await sdk.datasources.get(datasourceId!)
if (!datasource || !datasource.entities) { if (!datasource || !datasource.entities) {
ctx.throw(400, "Datasource has not been configured for plus API.") throw ctx.throw(400, "Datasource has not been configured for plus API.")
} }
if (!exporters.isFormat(format)) { if (rowIds?.length) {
ctx.throw(
400,
`Format ${format} not valid. Valid values: ${Object.values(
exporters.Format
)}`
)
}
if (ctx.request.body.rows) {
ctx.request.body = { ctx.request.body = {
query: { query: {
oneOf: { oneOf: {
_id: ctx.request.body.rows.map((row: string) => { _id: rowIds.map((row: string) => {
const ids = JSON.parse( const ids = JSON.parse(
decodeURI(row).replace(/'/g, `"`).replace(/%2C/g, ",") decodeURI(row).replace(/'/g, `"`).replace(/%2C/g, ",")
) )
if (ids.length > 1) { if (ids.length > 1) {
ctx.throw(400, "Export data does not support composite keys.") throw ctx.throw(
400,
"Export data does not support composite keys."
)
} }
return ids[0] return ids[0]
}), }),
@ -131,14 +128,14 @@ export async function exportRows(ctx: Ctx) {
} }
if (!tableName) { if (!tableName) {
ctx.throw(400, "Could not find table name.") throw ctx.throw(400, "Could not find table name.")
} }
let schema = datasource.entities[tableName].schema const schema = datasource.entities[tableName].schema
let exportRows = cleanExportRows(rows, schema, format, columns) let exportRows = cleanExportRows(rows, schema, format, columns)
let headers = Object.keys(schema) let headers = Object.keys(schema)
let content let content: string
switch (format) { switch (format) {
case exporters.Format.CSV: case exporters.Format.CSV:
content = exporters.csv(headers, exportRows) content = exporters.csv(headers, exportRows)
@ -150,15 +147,14 @@ export async function exportRows(ctx: Ctx) {
content = exporters.jsonWithSchema(schema, exportRows) content = exporters.jsonWithSchema(schema, exportRows)
break break
default: default:
utils.unreachable(format) throw utils.unreachable(format)
break
} }
const filename = `export.${format}` const fileName = `export.${format}`
return {
// send down the file fileName,
ctx.attachment(filename) content,
return apiFileReturn(content) }
} }
export async function fetch(tableId: string) { export async function fetch(tableId: string) {

View File

@ -25,6 +25,7 @@ import {
getFromMemoryDoc, getFromMemoryDoc,
} from "../../../../api/controllers/view/utils" } from "../../../../api/controllers/view/utils"
import sdk from "../../../../sdk" import sdk from "../../../../sdk"
import { ExportRowsParams, ExportRowsResult } from "../search"
export async function search(ctx: Ctx) { export async function search(ctx: Ctx) {
const { tableId } = ctx.params const { tableId } = ctx.params
@ -67,15 +68,12 @@ export async function search(ctx: Ctx) {
return response return response
} }
export async function exportRows(ctx: Ctx) { export async function exportRows(
options: ExportRowsParams
): Promise<ExportRowsResult> {
const { tableId, format, rowIds, columns, query } = options
const db = context.getAppDB() const db = context.getAppDB()
const table = await db.get(ctx.params.tableId) const table = await db.get(tableId)
const rowIds = ctx.request.body.rows
let format = ctx.query.format
if (typeof format !== "string") {
ctx.throw(400, "Format parameter is not valid")
}
const { columns, query } = ctx.request.body
let result let result
if (rowIds) { if (rowIds) {
@ -109,14 +107,20 @@ export async function exportRows(ctx: Ctx) {
let exportRows = cleanExportRows(rows, schema, format, columns) let exportRows = cleanExportRows(rows, schema, format, columns)
if (format === Format.CSV) { if (format === Format.CSV) {
ctx.attachment("export.csv") return {
return apiFileReturn(csv(Object.keys(rows[0]), exportRows)) fileName: "export.csv",
content: csv(Object.keys(rows[0]), exportRows),
}
} else if (format === Format.JSON) { } else if (format === Format.JSON) {
ctx.attachment("export.json") return {
return apiFileReturn(json(exportRows)) fileName: "export.json",
content: json(exportRows),
}
} else if (format === Format.JSON_WITH_SCHEMA) { } else if (format === Format.JSON_WITH_SCHEMA) {
ctx.attachment("export.json") return {
return apiFileReturn(jsonWithSchema(schema, exportRows)) fileName: "export.json",
content: jsonWithSchema(schema, exportRows),
}
} else { } else {
throw "Format not recognised" throw "Format not recognised"
} }

View File

@ -1,3 +1,4 @@
import { TableSchema } from "@budibase/types"
import { FieldTypes } from "../../../constants" import { FieldTypes } from "../../../constants"
import { makeExternalQuery } from "../../../integrations/base/query" import { makeExternalQuery } from "../../../integrations/base/query"
import { Format } from "../../../api/controllers/view/exporters" import { Format } from "../../../api/controllers/view/exporters"
@ -11,7 +12,7 @@ export async function getDatasourceAndQuery(json: any) {
export function cleanExportRows( export function cleanExportRows(
rows: any[], rows: any[],
schema: any, schema: TableSchema,
format: string, format: string,
columns: string[] columns: string[]
) { ) {