Remove ctx from export rows (search not implemented)
This commit is contained in:
parent
1bd8bdf84c
commit
90bf4655ea
|
@ -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,
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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[]
|
||||||
) {
|
) {
|
||||||
|
|
Loading…
Reference in New Issue