allow execution of external connector queries from button clicks
This commit is contained in:
parent
d27a264c96
commit
755fa0ac4a
|
@ -1,7 +1,6 @@
|
||||||
import { writable, get } from "svelte/store"
|
import { writable, get } from "svelte/store"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import api from "../api"
|
import api from "../api"
|
||||||
import { backendUiStore } from ".."
|
|
||||||
|
|
||||||
const INITIAL_BACKEND_UI_STATE = {
|
const INITIAL_BACKEND_UI_STATE = {
|
||||||
tables: [],
|
tables: [],
|
||||||
|
@ -63,6 +62,7 @@ export const getBackendUiStore = () => {
|
||||||
select: async datasourceId => {
|
select: async datasourceId => {
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
state.selectedDatasourceId = datasourceId
|
state.selectedDatasourceId = datasourceId
|
||||||
|
state.selectedQueryId = null
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -123,6 +123,7 @@ export const getBackendUiStore = () => {
|
||||||
queries: {
|
queries: {
|
||||||
select: queryId =>
|
select: queryId =>
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
|
state.selectedDatasourceId = null
|
||||||
state.selectedQueryId = queryId
|
state.selectedQueryId = queryId
|
||||||
return state
|
return state
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -6,21 +6,13 @@
|
||||||
import Table from "./Table.svelte"
|
import Table from "./Table.svelte"
|
||||||
import CreateQueryButton from "components/backend/DataTable/buttons/CreateQueryButton.svelte"
|
import CreateQueryButton from "components/backend/DataTable/buttons/CreateQueryButton.svelte"
|
||||||
|
|
||||||
export let datasourceId
|
export let datasource
|
||||||
export let query = {}
|
export let query = {}
|
||||||
|
|
||||||
let data = []
|
let data = []
|
||||||
let loading = false
|
let loading = false
|
||||||
let error = false
|
let error = false
|
||||||
|
|
||||||
$: datasourceId = $params.selectedDatasource
|
|
||||||
// TODO: refactor
|
|
||||||
// $: query = $backendUiStore.datasources.find(
|
|
||||||
// ds => ds._id === $params.selectedDatasource
|
|
||||||
// ).queries[$params.query]
|
|
||||||
$: title = query.name
|
|
||||||
$: schema = query.schema
|
|
||||||
|
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
try {
|
try {
|
||||||
loading = true
|
loading = true
|
||||||
|
@ -46,8 +38,8 @@
|
||||||
{#if error}
|
{#if error}
|
||||||
<div class="errors">{error}</div>
|
<div class="errors">{error}</div>
|
||||||
{/if}
|
{/if}
|
||||||
<Table {title} {schema} {data} {loading}>
|
<Table title={query.name} schema={query.schema} {data} {loading}>
|
||||||
<CreateQueryButton {query} />
|
<CreateQueryButton {query} {datasource} />
|
||||||
</Table>
|
</Table>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -236,6 +236,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ag-filter) {
|
:global(.ag-filter) {
|
||||||
|
background: var(--background);
|
||||||
padding: var(--spacing-s);
|
padding: var(--spacing-s);
|
||||||
outline: none;
|
outline: none;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
import CreateEditQuery from "components/backend/DataTable/modals/CreateEditQuery.svelte"
|
import CreateEditQuery from "components/backend/DataTable/modals/CreateEditQuery.svelte"
|
||||||
|
|
||||||
export let datasource
|
export let datasource
|
||||||
|
export let query = {}
|
||||||
|
|
||||||
let modal
|
let modal
|
||||||
let query = {}
|
|
||||||
let fields = []
|
let fields = []
|
||||||
|
|
||||||
async function saveQuery() {
|
async function saveQuery() {
|
||||||
|
@ -30,14 +30,12 @@
|
||||||
notifier.danger(`Error creating query. ${err.message}`)
|
notifier.danger(`Error creating query. ${err.message}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: console.log(query)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Button text small on:click={modal.show}>
|
<Button text small on:click={modal.show}>
|
||||||
<Icon name="filter" />
|
<Icon name="filter" />
|
||||||
{query ? 'Edit' : 'Create'} Query
|
{$backendUiStore.selectedQueryId ? 'Edit' : 'Create'} Query
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Modal bind:this={modal}>
|
<Modal bind:this={modal}>
|
||||||
|
@ -45,7 +43,7 @@
|
||||||
confirmText="Save"
|
confirmText="Save"
|
||||||
cancelText="Cancel"
|
cancelText="Cancel"
|
||||||
onConfirm={saveQuery}
|
onConfirm={saveQuery}
|
||||||
title="Create New Query">
|
title={query ? 'Edit Query' : 'Create New Query'}>
|
||||||
<CreateEditQuery {datasource} bind:query />
|
<CreateEditQuery {datasource} bind:query />
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
export let query
|
export let query
|
||||||
export let fields = []
|
export let fields = []
|
||||||
|
|
||||||
|
console.log(query)
|
||||||
|
|
||||||
let config = {}
|
let config = {}
|
||||||
let queryType
|
let queryType
|
||||||
let previewTab = "PREVIEW"
|
let previewTab = "PREVIEW"
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
import { Modal, Switcher } from "@budibase/bbui"
|
import { Modal, Switcher } from "@budibase/bbui"
|
||||||
import NavItem from "components/common/NavItem.svelte"
|
import NavItem from "components/common/NavItem.svelte"
|
||||||
|
|
||||||
let modal
|
|
||||||
|
|
||||||
$: selectedView =
|
$: selectedView =
|
||||||
$backendUiStore.selectedView && $backendUiStore.selectedView.name
|
$backendUiStore.selectedView && $backendUiStore.selectedView.name
|
||||||
|
|
||||||
|
@ -34,12 +32,6 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $backendUiStore.selectedDatabase && $backendUiStore.selectedDatabase._id}
|
{#if $backendUiStore.selectedDatabase && $backendUiStore.selectedDatabase._id}
|
||||||
<div class="title">
|
|
||||||
<i
|
|
||||||
data-cy="new-datasource"
|
|
||||||
on:click={modal.show}
|
|
||||||
class="ri-add-circle-fill" />
|
|
||||||
</div>
|
|
||||||
<div class="hierarchy-items-container">
|
<div class="hierarchy-items-container">
|
||||||
{#each $backendUiStore.datasources as datasource, idx}
|
{#each $backendUiStore.datasources as datasource, idx}
|
||||||
<NavItem
|
<NavItem
|
||||||
|
@ -64,23 +56,3 @@
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<Modal bind:this={modal}>
|
|
||||||
<CreateDatasourceModal />
|
|
||||||
</Modal>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.title {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title i {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
.title i:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--blue);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -2,14 +2,11 @@
|
||||||
import { goto } from "@sveltech/routify"
|
import { goto } from "@sveltech/routify"
|
||||||
import { backendUiStore } from "builderStore"
|
import { backendUiStore } from "builderStore"
|
||||||
import { TableNames } from "constants"
|
import { TableNames } from "constants"
|
||||||
import CreateTableModal from "./modals/CreateTableModal.svelte"
|
|
||||||
import EditTablePopover from "./popovers/EditTablePopover.svelte"
|
import EditTablePopover from "./popovers/EditTablePopover.svelte"
|
||||||
import EditViewPopover from "./popovers/EditViewPopover.svelte"
|
import EditViewPopover from "./popovers/EditViewPopover.svelte"
|
||||||
import { Modal, Switcher } from "@budibase/bbui"
|
import { Switcher } from "@budibase/bbui"
|
||||||
import NavItem from "components/common/NavItem.svelte"
|
import NavItem from "components/common/NavItem.svelte"
|
||||||
|
|
||||||
let modal
|
|
||||||
|
|
||||||
$: selectedView =
|
$: selectedView =
|
||||||
$backendUiStore.selectedView && $backendUiStore.selectedView.name
|
$backendUiStore.selectedView && $backendUiStore.selectedView.name
|
||||||
|
|
||||||
|
@ -35,9 +32,6 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $backendUiStore.selectedDatabase && $backendUiStore.selectedDatabase._id}
|
{#if $backendUiStore.selectedDatabase && $backendUiStore.selectedDatabase._id}
|
||||||
<div class="title">
|
|
||||||
<i data-cy="new-table" on:click={modal.show} class="ri-add-circle-fill" />
|
|
||||||
</div>
|
|
||||||
<div class="hierarchy-items-container">
|
<div class="hierarchy-items-container">
|
||||||
{#each $backendUiStore.tables as table, idx}
|
{#each $backendUiStore.tables as table, idx}
|
||||||
<NavItem
|
<NavItem
|
||||||
|
@ -64,27 +58,3 @@
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<Modal bind:this={modal}>
|
|
||||||
<CreateTableModal />
|
|
||||||
</Modal>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.title {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.title h1 {
|
|
||||||
font-size: var(--font-size-m);
|
|
||||||
font-weight: 500;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.title i {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
.title i:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--blue);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
tables: $backendUiStore.tables,
|
tables: $backendUiStore.tables,
|
||||||
})
|
})
|
||||||
|
|
||||||
// just wraps binding in {{ ... }}
|
|
||||||
const toBindingExpression = bindingPath => `{{ ${bindingPath} }}`
|
|
||||||
|
|
||||||
const tableFields = tableId => {
|
const tableFields = tableId => {
|
||||||
const table = $backendUiStore.tables.find(m => m._id === tableId)
|
const table = $backendUiStore.tables.find(m => m._id === tableId)
|
||||||
|
|
||||||
|
@ -63,12 +60,4 @@
|
||||||
grid-column-start: 2;
|
grid-column-start: 2;
|
||||||
grid-column-end: 6;
|
grid-column-end: 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cannot-use {
|
|
||||||
color: var(--red);
|
|
||||||
font-size: var(--font-size-s);
|
|
||||||
text-align: center;
|
|
||||||
width: 70%;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -42,8 +42,6 @@
|
||||||
typeof tableInfo === "string" ? tableInfo : tableInfo.tableId
|
typeof tableInfo === "string" ? tableInfo : tableInfo.tableId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(parameters)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<script>
|
||||||
|
import { Select, Label, Spacer } from "@budibase/bbui"
|
||||||
|
import { backendUiStore } from "builderStore"
|
||||||
|
|
||||||
|
export let parameters
|
||||||
|
|
||||||
|
$: datasource = $backendUiStore.datasources.find(
|
||||||
|
ds => ds._id === parameters.datasourceId
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="root">
|
||||||
|
<Label size="m" color="dark">Datasource</Label>
|
||||||
|
<Select secondary bind:value={parameters.datasourceId}>
|
||||||
|
<option value="" />
|
||||||
|
{#each $backendUiStore.datasources as datasource}
|
||||||
|
<option value={datasource._id}>{datasource.name}</option>
|
||||||
|
{/each}
|
||||||
|
</Select>
|
||||||
|
|
||||||
|
<Spacer medium />
|
||||||
|
|
||||||
|
{#if parameters.datasourceId}
|
||||||
|
<Label size="m" color="dark">Query</Label>
|
||||||
|
<Select secondary bind:value={parameters.queryId}>
|
||||||
|
<option value="" />
|
||||||
|
{#each Object.keys(datasource.queries) as query}
|
||||||
|
<option value={query}>{datasource.queries[query].name}</option>
|
||||||
|
{/each}
|
||||||
|
</Select>
|
||||||
|
{/if}
|
||||||
|
</div>
|
|
@ -1,6 +1,7 @@
|
||||||
import NavigateTo from "./NavigateTo.svelte"
|
import NavigateTo from "./NavigateTo.svelte"
|
||||||
import SaveRow from "./SaveRow.svelte"
|
import SaveRow from "./SaveRow.svelte"
|
||||||
import DeleteRow from "./DeleteRow.svelte"
|
import DeleteRow from "./DeleteRow.svelte"
|
||||||
|
import ExecuteQuery from "./ExecuteQuery.svelte"
|
||||||
|
|
||||||
// defines what actions are available, when adding a new one
|
// defines what actions are available, when adding a new one
|
||||||
// the component is the setup panel for the action
|
// the component is the setup panel for the action
|
||||||
|
@ -20,4 +21,8 @@ export default [
|
||||||
name: "Navigate To",
|
name: "Navigate To",
|
||||||
component: NavigateTo,
|
component: NavigateTo,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Execute Query",
|
||||||
|
component: ExecuteQuery,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
import { Switcher } from "@budibase/bbui"
|
import { params } from "@sveltech/routify"
|
||||||
|
import { Switcher, Modal } from "@budibase/bbui"
|
||||||
import TableNavigator from "components/backend/TableNavigator/TableNavigator.svelte"
|
import TableNavigator from "components/backend/TableNavigator/TableNavigator.svelte"
|
||||||
import DatasourceNavigator from "components/backend/DatasourceNavigator/DatasourceNavigator.svelte"
|
import DatasourceNavigator from "components/backend/DatasourceNavigator/DatasourceNavigator.svelte"
|
||||||
|
import CreateDatasourceModal from "components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte"
|
||||||
|
import CreateTableModal from "components/backend/TableNavigator/modals/CreateTableModal.svelte"
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{
|
{
|
||||||
|
@ -14,17 +17,31 @@
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
let tab = "table"
|
let tab = $params.selectedDatasource ? "datasource" : "table"
|
||||||
|
|
||||||
|
let modal
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- routify:options index=0 -->
|
<!-- routify:options index=0 -->
|
||||||
<div class="root">
|
<div class="root">
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<Switcher headings={tabs} bind:value={tab}>
|
<Switcher headings={tabs} bind:value={tab}>
|
||||||
|
<div class="title">
|
||||||
|
<i
|
||||||
|
data-cy={`new-${tab}`}
|
||||||
|
class="ri-add-circle-fill"
|
||||||
|
on:click={modal.show} />
|
||||||
|
</div>
|
||||||
{#if tab === 'table'}
|
{#if tab === 'table'}
|
||||||
<TableNavigator />
|
<TableNavigator />
|
||||||
|
<Modal bind:this={modal}>
|
||||||
|
<CreateTableModal />
|
||||||
|
</Modal>
|
||||||
{:else if tab === 'datasource'}
|
{:else if tab === 'datasource'}
|
||||||
<DatasourceNavigator />
|
<DatasourceNavigator />
|
||||||
|
<Modal bind:this={modal}>
|
||||||
|
<CreateDatasourceModal />
|
||||||
|
</Modal>
|
||||||
{/if}
|
{/if}
|
||||||
</Switcher>
|
</Switcher>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,6 +57,7 @@
|
||||||
grid-template-columns: 260px minmax(0, 1fr);
|
grid-template-columns: 260px minmax(0, 1fr);
|
||||||
background: var(--grey-2);
|
background: var(--grey-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
padding: var(--spacing-l) 40px;
|
padding: var(--spacing-l) 40px;
|
||||||
|
@ -50,6 +68,7 @@
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
gap: var(--spacing-l);
|
gap: var(--spacing-l);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav {
|
.nav {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
background: var(--background);
|
background: var(--background);
|
||||||
|
@ -59,5 +78,18 @@
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
gap: var(--spacing-l);
|
gap: var(--spacing-l);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 20px;
|
||||||
|
position: absolute;
|
||||||
|
top: var(--spacing-l);
|
||||||
|
right: var(--spacing-xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
i:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--blue);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -10,6 +10,6 @@
|
||||||
$: query = datasource && datasource.queries[$params.query]
|
$: query = datasource && datasource.queries[$params.query]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $backendUiStore.selectedDatabase._id && datasource}
|
{#if $backendUiStore.selectedDatabase._id && datasource && query}
|
||||||
<ExternalDataSourceTable {query} datasourceId={datasource._id} />
|
<ExternalDataSourceTable {query} {datasource} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
margin-bottom: var(--spacing-s);
|
margin-bottom: var(--spacing-s);
|
||||||
}
|
}
|
||||||
section {
|
section {
|
||||||
background: white;
|
background: var(--background);
|
||||||
border-radius: var(--border-radius-m);
|
border-radius: var(--border-radius-m);
|
||||||
padding: var(--spacing-xl);
|
padding: var(--spacing-xl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,3 +9,14 @@ export const fetchQueryData = async ({ datasourceId, queryId }) => {
|
||||||
})
|
})
|
||||||
return response.rows
|
return response.rows
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a query against an external data connector.
|
||||||
|
*/
|
||||||
|
export const executeQuery = async ({ datasourceId, queryId }) => {
|
||||||
|
const response = await API.post({
|
||||||
|
url: `/api/datasources/${datasourceId}/queries/${queryId}`,
|
||||||
|
// body: params,
|
||||||
|
})
|
||||||
|
return response.rows
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { enrichDataBinding } from "./enrichDataBinding"
|
import { enrichDataBinding, enrichDataBindings } from "./enrichDataBinding"
|
||||||
import { routeStore } from "../store"
|
import { routeStore } from "../store"
|
||||||
import { saveRow, deleteRow } from "../api"
|
import { saveRow, deleteRow, executeQuery } from "../api"
|
||||||
|
|
||||||
const saveRowHandler = async (action, context) => {
|
const saveRowHandler = async (action, context) => {
|
||||||
let draft = context[`${action.parameters.contextPath}_draft`]
|
let draft = context[`${action.parameters.contextPath}_draft`]
|
||||||
|
@ -25,10 +25,27 @@ const navigationHandler = action => {
|
||||||
routeStore.actions.navigate(action.parameters.url)
|
routeStore.actions.navigate(action.parameters.url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const queryExecutionHandler = async (action, context) => {
|
||||||
|
const { datasourceId, queryId, params } = action.parameters
|
||||||
|
console.log(context)
|
||||||
|
// TODO: allow context based bindings for query params
|
||||||
|
// const enrichedQueryParameters = enrichDataBindings(params, context)
|
||||||
|
|
||||||
|
// console.log({
|
||||||
|
// action,
|
||||||
|
// context,
|
||||||
|
// // enrichedQueryParameters,
|
||||||
|
// datasourceId,
|
||||||
|
// // queryId
|
||||||
|
// })
|
||||||
|
await executeQuery({ datasourceId, queryId })
|
||||||
|
}
|
||||||
|
|
||||||
const handlerMap = {
|
const handlerMap = {
|
||||||
["Save Row"]: saveRowHandler,
|
["Save Row"]: saveRowHandler,
|
||||||
["Delete Row"]: deleteRowHandler,
|
["Delete Row"]: deleteRowHandler,
|
||||||
["Navigate To"]: navigationHandler,
|
["Navigate To"]: navigationHandler,
|
||||||
|
["Execute Query"]: queryExecutionHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -115,7 +115,7 @@ exports.previewQuery = async function(ctx) {
|
||||||
ctx.body = await new Integration(config, query).query()
|
ctx.body = await new Integration(config, query).query()
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.executeQuery = async function(ctx) {
|
exports.fetchQuery = async function(ctx) {
|
||||||
const db = new CouchDB(ctx.user.appId)
|
const db = new CouchDB(ctx.user.appId)
|
||||||
|
|
||||||
const datasource = await db.get(ctx.params.datasourceId)
|
const datasource = await db.get(ctx.params.datasourceId)
|
||||||
|
@ -139,3 +139,28 @@ exports.executeQuery = async function(ctx) {
|
||||||
rows,
|
rows,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.executeQuery = async function(ctx) {
|
||||||
|
const db = new CouchDB(ctx.user.appId)
|
||||||
|
|
||||||
|
const datasource = await db.get(ctx.params.datasourceId)
|
||||||
|
|
||||||
|
const query = datasource.queries[ctx.params.queryId]
|
||||||
|
|
||||||
|
const Integration = integrations[datasource.source]
|
||||||
|
|
||||||
|
if (!Integration) {
|
||||||
|
ctx.throw(400, "Integration type does not exist.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: allow the ability to POST parameters down when executing the query
|
||||||
|
// const customParams = ctx.request.body
|
||||||
|
|
||||||
|
const response = await new Integration(
|
||||||
|
datasource.config,
|
||||||
|
query.queryString
|
||||||
|
).query()
|
||||||
|
|
||||||
|
ctx.body = response
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,11 @@ router
|
||||||
datasourceController.previewQuery
|
datasourceController.previewQuery
|
||||||
)
|
)
|
||||||
.get(
|
.get(
|
||||||
|
"/api/datasources/:datasourceId/queries/:queryId",
|
||||||
|
authorized(BUILDER),
|
||||||
|
datasourceController.fetchQuery
|
||||||
|
)
|
||||||
|
.post(
|
||||||
"/api/datasources/:datasourceId/queries/:queryId",
|
"/api/datasources/:datasourceId/queries/:queryId",
|
||||||
authorized(BUILDER),
|
authorized(BUILDER),
|
||||||
datasourceController.executeQuery
|
datasourceController.executeQuery
|
||||||
|
|
Loading…
Reference in New Issue