switching between queries

This commit is contained in:
Martin McKeaveney 2021-01-06 12:28:51 +00:00
parent 0be3c722b8
commit 37ef32a173
20 changed files with 339 additions and 238 deletions

View File

@ -8,6 +8,7 @@ const INITIAL_BACKEND_UI_STATE = {
users: [], users: [],
roles: [], roles: [],
datasources: [], datasources: [],
queries: [],
selectedDatabase: {}, selectedDatabase: {},
selectedTable: {}, selectedTable: {},
draftTable: {}, draftTable: {},
@ -24,10 +25,13 @@ export const getBackendUiStore = () => {
const tables = await tablesResponse.json() const tables = await tablesResponse.json()
const datasourcesResponse = await api.get(`/api/datasources`) const datasourcesResponse = await api.get(`/api/datasources`)
const datasources = await datasourcesResponse.json() const datasources = await datasourcesResponse.json()
const queriesResponse = await api.get(`/api/queries`)
const queries = await queriesResponse.json()
store.update(state => { store.update(state => {
state.selectedDatabase = db state.selectedDatabase = db
state.tables = tables state.tables = tables
state.datasources = datasources state.datasources = datasources
state.queries = queries
return state return state
}) })
}, },
@ -98,35 +102,56 @@ export const getBackendUiStore = () => {
return state return state
}) })
}, },
saveQuery: async (datasourceId, query) => { },
const response = await api.post( queries: {
`/api/datasources/${datasourceId}/queries`, fetch: async () => {
query const response = await api.get(`/api/queries`)
)
const json = await response.json() const json = await response.json()
store.update(state => { store.update(state => {
const currentIdx = state.datasources.findIndex( state.queries = json
ds => ds._id === json._id return state
})
return json
},
save: async (datasourceId, query) => {
query.datasourceId = datasourceId
const response = await api.post(`/api/queries`, query)
const json = await response.json()
store.update(state => {
const currentIdx = state.queries.findIndex(
query => query._id === json._id
) )
if (currentIdx >= 0) { if (currentIdx >= 0) {
state.datasources.splice(currentIdx, 1, json) state.queries.splice(currentIdx, 1, json)
} else { } else {
state.datasources.push(json) state.queries.push(json)
} }
state.datasources = state.datasources state.queries = state.queries
state.selectedQueryId = json._id
return state return state
}) })
}, },
},
queries: {
select: queryId => select: queryId =>
store.update(state => { store.update(state => {
state.selectedDatasourceId = null state.selectedDatasourceId = null
state.selectedQueryId = queryId state.selectedQueryId = queryId
return state return state
}), }),
delete: async queryId => {
await api.delete(`/api/queries/${queryId}`)
store.update(state => {
state.datasources = state.queries.filter(
existing => existing._id !== queryId
)
if (state.selectedQueryId === queryId) {
state.selectedQueryId = null
}
return state
})
},
}, },
tables: { tables: {
fetch: async () => { fetch: async () => {

View File

@ -6,7 +6,6 @@
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 datasource
export let query = {} export let query = {}
let data = [] let data = []
@ -23,7 +22,6 @@
data = response.rows || [] data = response.rows || []
error = false error = false
} catch (err) { } catch (err) {
console.log(err)
error = `${query}: Query error. (${err.message}). This could be a problem with your datasource configuration.` error = `${query}: Query error. (${err.message}). This could be a problem with your datasource configuration.`
notifier.danger(error) notifier.danger(error)
} finally { } finally {
@ -32,14 +30,14 @@
} }
// Fetch rows for specified query // Fetch rows for specified query
$: fetchData() $: query && fetchData()
</script> </script>
{#if error} {#if error}
<div class="errors">{error}</div> <div class="errors">{error}</div>
{/if} {/if}
<Table title={query.name} schema={query.schema} {data} {loading}> <Table title={query.name} schema={query.schema} {data} {loading}>
<CreateQueryButton {query} {datasource} /> <CreateQueryButton {query} edit />
</Table> </Table>
<style> <style>

View File

@ -32,7 +32,7 @@ export async function fetchDataForView(view) {
} }
export async function fetchDataForQuery(datasourceId, queryId) { export async function fetchDataForQuery(datasourceId, queryId) {
const FETCH_QUERY_URL = `/api/datasources/${datasourceId}/queries/${queryId}` const FETCH_QUERY_URL = `/api/queries/${queryId}`
const response = await api.get(FETCH_QUERY_URL) const response = await api.get(FETCH_QUERY_URL)
const json = await response.json() const json = await response.json()

View File

@ -15,15 +15,15 @@
import EditIntegrationConfig from "../modals/EditIntegrationConfig.svelte" import EditIntegrationConfig from "../modals/EditIntegrationConfig.svelte"
import CreateEditQuery from "components/backend/DataTable/modals/CreateEditQuery.svelte" import CreateEditQuery from "components/backend/DataTable/modals/CreateEditQuery.svelte"
export let datasource
export let query = {} export let query = {}
export let edit
let modal let modal
let fields = [] let fields = []
async function saveQuery() { async function saveQuery() {
try { try {
await backendUiStore.actions.datasources.saveQuery(datasource._id, query) await backendUiStore.actions.queries.save(query.datasourceId, query)
notifier.success(`Query created successfully.`) notifier.success(`Query created successfully.`)
} catch (err) { } catch (err) {
console.error(err) console.error(err)
@ -35,7 +35,7 @@
<div> <div>
<Button text small on:click={modal.show}> <Button text small on:click={modal.show}>
<Icon name="filter" /> <Icon name="filter" />
{$backendUiStore.selectedQueryId ? 'Edit' : 'Create'} Query {edit ? 'Edit' : 'Create'} Query
</Button> </Button>
</div> </div>
<Modal bind:this={modal}> <Modal bind:this={modal}>
@ -43,7 +43,7 @@
confirmText="Save" confirmText="Save"
cancelText="Cancel" cancelText="Cancel"
onConfirm={saveQuery} onConfirm={saveQuery}
title={query ? 'Edit Query' : 'Create New Query'}> title={edit ? 'Edit Query' : 'Create New Query'}>
<CreateEditQuery {datasource} bind:query /> <CreateEditQuery bind:query />
</ModalContent> </ModalContent>
</Modal> </Modal>

View File

@ -27,17 +27,20 @@
}, },
] ]
export let datasource
export let query export let query
export let fields = [] export let fields = []
console.log(query)
let config = {} let config = {}
let queryType
let previewTab = "PREVIEW" let previewTab = "PREVIEW"
let preview let preview
$: datasource = $backendUiStore.datasources.find(
ds => ds._id === query.datasourceId
)
$: query.datasourceId =
query.datasourceId || $backendUiStore.selectedDatasourceId
$: query.schema = fields.reduce( $: query.schema = fields.reduce(
(acc, next) => ({ (acc, next) => ({
...acc, ...acc,
@ -72,9 +75,8 @@
async function previewQuery() { async function previewQuery() {
try { try {
const response = await api.post(`/api/datasources/queries/preview`, { const response = await api.post(`/api/queries/preview`, {
type: datasource.source, datasourceId: datasource._id,
config: datasource.config,
query: query.queryString, query: query.queryString,
}) })
const json = await response.json() const json = await response.json()
@ -101,18 +103,13 @@
<section> <section>
<div class="config"> <div class="config">
<h6>Datasource Type</h6>
<span>{datasource.source}</span>
<Spacer medium />
<Label extraSmall grey>Query Name</Label> <Label extraSmall grey>Query Name</Label>
<Input type="text" thin bind:value={query.name} /> <Input type="text" thin bind:value={query.name} />
<Spacer medium /> <Spacer medium />
<Label extraSmall grey>Query Type</Label> <Label extraSmall grey>Query Type</Label>
<Select secondary bind:value={queryType}> <Select secondary bind:value={query.queryType}>
<option value={''}>Select an option</option> <option value={''}>Select an option</option>
{#each Object.keys(config) as queryType} {#each Object.keys(config) as queryType}
<option value={queryType}>{queryType}</option> <option value={queryType}>{queryType}</option>
@ -121,7 +118,9 @@
<Spacer medium /> <Spacer medium />
<IntegrationQueryEditor {queryType} bind:query={query.queryString} /> <IntegrationQueryEditor
type={query.queryType}
bind:query={query.queryString} />
<Spacer small /> <Spacer small />

View File

@ -5,6 +5,7 @@
import { TableNames } from "constants" import { TableNames } from "constants"
import CreateDatasourceModal from "./modals/CreateDatasourceModal.svelte" import CreateDatasourceModal from "./modals/CreateDatasourceModal.svelte"
import EditDatasourcePopover from "./popovers/EditDatasourcePopover.svelte" import EditDatasourcePopover from "./popovers/EditDatasourcePopover.svelte"
import EditQueryPopover from "./popovers/EditQueryPopover.svelte"
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"
@ -18,6 +19,7 @@
} }
function onClickQuery(datasourceId, queryId) { function onClickQuery(datasourceId, queryId) {
console.log(backendUiStore.selectedQueryId, queryId)
if ($backendUiStore.selectedQueryId === queryId) { if ($backendUiStore.selectedQueryId === queryId) {
return return
} }
@ -28,6 +30,7 @@
onMount(() => { onMount(() => {
backendUiStore.actions.datasources.fetch() backendUiStore.actions.datasources.fetch()
backendUiStore.actions.queries.fetch()
}) })
</script> </script>
@ -42,15 +45,14 @@
on:click={() => selectDatasource(datasource)}> on:click={() => selectDatasource(datasource)}>
<EditDatasourcePopover {datasource} /> <EditDatasourcePopover {datasource} />
</NavItem> </NavItem>
{#each Object.keys(datasource.queries) as queryId} {#each $backendUiStore.queries.filter(query => query.datasourceId === datasource._id) as query}
<NavItem <NavItem
indentLevel={1} indentLevel={1}
icon="ri-eye-line" icon="ri-eye-line"
text={datasource.queries[queryId].name} text={query.name}
selected={$backendUiStore.selectedQueryId === queryId} selected={$backendUiStore.selectedQueryId === query._id}
on:click={() => onClickQuery(datasource._id, queryId)}> on:click={() => onClickQuery(datasource._id, query._id)}>
<!-- <EditViewPopover <EditQueryPopover {query} />
view={{ name: viewName, ...table.views[viewName] }} /> -->
</NavItem> </NavItem>
{/each} {/each}
{/each} {/each}

View File

@ -0,0 +1,85 @@
<script>
import { backendUiStore, store, allScreens } from "builderStore"
import { notifier } from "builderStore/store/notifications"
import { DropdownMenu, Button, Input } from "@budibase/bbui"
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import IntegrationConfigForm from "../TableIntegrationMenu//IntegrationConfigForm.svelte"
import { DropdownContainer, DropdownItem } from "components/common/Dropdowns"
export let query
let anchor
let dropdown
let confirmDeleteDialog
let error = ""
let willBeDeleted
function hideEditor() {
dropdown?.hide()
}
function showModal() {
hideEditor()
confirmDeleteDialog.show()
}
async function deleteQuery() {
await backendUiStore.actions.queries.delete(query._id)
notifier.success("Query deleted")
hideEditor()
}
</script>
<div on:click|stopPropagation>
<div bind:this={anchor} class="icon" on:click={dropdown.show}>
<i class="ri-more-line" />
</div>
<DropdownMenu align="left" {anchor} bind:this={dropdown}>
<DropdownContainer>
<DropdownItem
icon="ri-delete-bin-line"
title="Delete"
on:click={showModal}
data-cy="delete-datasource" />
</DropdownContainer>
</DropdownMenu>
</div>
<ConfirmDialog
bind:this={confirmDeleteDialog}
okText="Delete Query"
onOk={deleteQuery}
title="Confirm Deletion">
Are you sure you wish to delete this query?
This action cannot be undone.
</ConfirmDialog>
<style>
div.icon {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
div.icon i {
font-size: 16px;
}
.actions {
padding: var(--spacing-xl);
display: grid;
grid-gap: var(--spacing-xl);
min-width: 400px;
}
h5 {
margin: 0;
font-weight: 500;
}
footer {
display: flex;
justify-content: flex-end;
gap: var(--spacing-m);
}
</style>

View File

@ -1,17 +1,28 @@
<script> <script>
import { TextArea } from "@budibase/bbui" import { TextArea, Label, Input } from "@budibase/bbui"
import Editor from "./Editor.svelte" import Editor from "./Editor.svelte"
const CAPTURE_VAR_INSIDE_MUSTACHE = /{{([^}]+)}}/g
const QueryTypes = { const QueryTypes = {
SQL: "sql", SQL: "sql",
} }
export let queryType export let type
export let query export let query
$: console.log(query) // $: parameters = Array.from(
// query
// .matchAll(CAPTURE_VAR_INSIDE_MUSTACHE)
// .map(([_, paramName]) => paramName)
// )
</script> </script>
{#if queryType === QueryTypes.SQL} <!-- {#each parameters as param}
<Label grey extraSmall>{param}</Label>
<Input thin bind:value={query.params[param]} />
{/each} -->
{#if type === QueryTypes.SQL}
<Editor label="Query" bind:value={query} /> <Editor label="Query" bind:value={query} />
{/if} {/if}

View File

@ -24,7 +24,7 @@
<Label size="m" color="dark">Query</Label> <Label size="m" color="dark">Query</Label>
<Select secondary bind:value={parameters.queryId}> <Select secondary bind:value={parameters.queryId}>
<option value="" /> <option value="" />
{#each Object.keys(datasource.queries) as query} {#each $backendUiStore.queries.filter(query => query.datasourceId === datasource._id) as query}
<option value={query}>{datasource.queries[query].name}</option> <option value={query}>{datasource.queries[query].name}</option>
{/each} {/each}
</Select> </Select>

View File

@ -31,17 +31,13 @@
return [...acc, ...viewsArr] return [...acc, ...viewsArr]
}, []) }, [])
$: queries = $backendUiStore.datasources.reduce((acc, cur) => { $: queries = $backendUiStore.queries.map(query => ({
let queriesArr = Object.entries(cur.queries).map(([key, value]) => ({ label: query.name,
label: value.name, name: query.name,
name: value.name, ...query,
datasourceId: cur._id, schema: query.schema,
queryId: key,
schema: value.schema,
type: "query", type: "query",
})) }))
return [...acc, ...queriesArr]
}, [])
$: bindableProperties = fetchBindableProperties({ $: bindableProperties = fetchBindableProperties({
componentInstanceId: $store.selectedComponentId, componentInstanceId: $store.selectedComponentId,

View File

@ -3,13 +3,10 @@
import { backendUiStore } from "builderStore" import { backendUiStore } from "builderStore"
import ExternalDataSourceTable from "components/backend/DataTable/ExternalDataSourceTable.svelte" import ExternalDataSourceTable from "components/backend/DataTable/ExternalDataSourceTable.svelte"
// TODO: refactor $: query = $backendUiStore.queries.find(query => query._id === $params.query)
$: datasource = $backendUiStore.datasources.find( $: console.log("updated", query)
ds => ds._id === $params.selectedDatasource
)
$: query = datasource && datasource.queries[$params.query]
</script> </script>
{#if $backendUiStore.selectedDatabase._id && datasource && query} {#if $backendUiStore.selectedDatabase._id && query}
<ExternalDataSourceTable {query} {datasource} /> <ExternalDataSourceTable {query} />
{/if} {/if}

View File

@ -3,9 +3,9 @@ import API from "./api"
/** /**
* Fetches all rows from a query. * Fetches all rows from a query.
*/ */
export const fetchQueryData = async ({ datasourceId, queryId }) => { export const fetchQueryData = async ({ _id }) => {
const response = await API.get({ const response = await API.get({
url: `/api/datasources/${datasourceId}/queries/${queryId}`, url: `/api/queries/${_id}`,
}) })
return response.rows return response.rows
} }
@ -13,9 +13,9 @@ export const fetchQueryData = async ({ datasourceId, queryId }) => {
/** /**
* Executes a query against an external data connector. * Executes a query against an external data connector.
*/ */
export const executeQuery = async ({ datasourceId, queryId }) => { export const executeQuery = async ({ _id }) => {
const response = await API.post({ const response = await API.post({
url: `/api/datasources/${datasourceId}/queries/${queryId}`, url: `/api/queries/${_id}`,
// body: params, // body: params,
}) })
return response.rows return response.rows

View File

@ -1,11 +1,6 @@
const CouchDB = require("../../db") const CouchDB = require("../../db")
const bcrypt = require("../../utilities/bcrypt") const bcrypt = require("../../utilities/bcrypt")
const { const { generateDatasourceID, getDatasourceParams } = require("../../db/utils")
generateDatasourceID,
getDatasourceParams,
generateQueryID,
} = require("../../db/utils")
const { integrations } = require("../../integrations")
exports.fetch = async function(ctx) { exports.fetch = async function(ctx) {
const database = new CouchDB(ctx.user.appId) const database = new CouchDB(ctx.user.appId)
@ -30,7 +25,6 @@ exports.save = async function(ctx) {
const datasource = { const datasource = {
_id: generateDatasourceID(), _id: generateDatasourceID(),
type: "datasource", type: "datasource",
queries: {},
...ctx.request.body, ...ctx.request.body,
} }
@ -77,90 +71,3 @@ exports.find = async function(ctx) {
const datasource = await database.get(ctx.params.datasourceId) const datasource = await database.get(ctx.params.datasourceId)
ctx.body = datasource ctx.body = datasource
} }
exports.saveQuery = async function(ctx) {
const db = new CouchDB(ctx.user.appId)
const query = ctx.request.body
//
// {
// type: "",
// query: "",
// otherStuff: ""
// }
const datasource = await db.get(ctx.params.datasourceId)
const queryId = generateQueryID()
datasource.queries[queryId] = query
const response = await db.put(datasource)
datasource._rev = response.rev
ctx.body = datasource
ctx.message = `Query ${query.name} saved successfully.`
}
exports.previewQuery = async function(ctx) {
const { type, config, query } = ctx.request.body
const Integration = integrations[type]
if (!Integration) {
ctx.throw(400, "Integration type does not exist.")
return
}
ctx.body = await new Integration(config, query).query()
}
exports.fetchQuery = 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
}
const rows = await new Integration(
datasource.config,
query.queryString
).query()
ctx.body = {
schema: query.schema,
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
}

View File

@ -1,39 +1,128 @@
// const CouchDB = require("../../../db") const handlebars = require("handlebars")
// const { generateQueryID } = require("../../db/utils") const Joi = require("joi")
// const viewTemplate = require("./viewBuilder") const CouchDB = require("../../db")
const bcrypt = require("../../utilities/bcrypt")
const { generateQueryID, getQueryParams } = require("../../db/utils")
const { integrations } = require("../../integrations")
const joiValidator = require("../../middleware/joi-validator")
// exports.save = async ctx => { function generateQueryValidation() {
// const db = new CouchDB(ctx.user.appId) // prettier-ignore
// const { datasourceId, query } = ctx.request.body return joiValidator.body(Joi.object({
name: Joi.string().required(),
queryString: Joi.string().required(),
datasourceId: Joi.string().required(),
queryType: Joi.string().required(),
schema: Joi.object({}).required().unknown(true)
}))
}
// const datasource = await db.get(datasourceId) exports.fetch = async function(ctx) {
const db = new CouchDB(ctx.user.appId)
// const queryId = generateQueryID() const body = await db.allDocs(
getQueryParams(null, {
include_docs: true,
})
)
ctx.body = body.rows.map(row => row.doc)
}
// datasource.queries[queryId] = query exports.save = async function(ctx) {
const db = new CouchDB(ctx.user.appId)
const query = ctx.request.body
// const response = await db.put(datasource) //
// {
// ctx.body = query // type: "",
// ctx.message = `View ${viewToSave.name} saved successfully.` // query: "",
// otherStuff: ""
// } // }
// exports.destroy = async ctx => { if (!query._id) {
// const db = new CouchDB(ctx.user.appId) query._id = generateQueryID(query.datasourceId)
// const designDoc = await db.get("_design/database") }
// const viewName = decodeURI(ctx.params.viewName) const response = await db.put(query)
query._rev = response.rev
// const view = designDoc.views[viewName] ctx.body = query
ctx.message = `Query ${query.name} saved successfully.`
}
// delete designDoc.views[viewName] exports.preview = async function(ctx) {
const { query, datasourceId } = ctx.request.body
// await db.put(designDoc) const db = new CouchDB(ctx.user.appId)
// const table = await db.get(view.meta.tableId) const datasource = await db.get(datasourceId)
// delete table.views[viewName]
// await db.put(table)
// ctx.body = view const Integration = integrations[datasource.source]
// ctx.message = `View ${ctx.params.viewName} saved successfully.`
// } if (!Integration) {
ctx.throw(400, "Integration type does not exist.")
return
}
ctx.body = await new Integration(datasource.config, query).query()
}
exports.execute = 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 queryTemplate = handlebars.compile(query.queryString)
const response = await new Integration(
datasource.config,
queryTemplate({
// pass the params here from the UI and backend contexts
})
).query()
ctx.body = response
}
exports.fetchQuery = async function(ctx) {
const db = new CouchDB(ctx.user.appId)
const query = await db.get(ctx.params.queryId)
const datasource = await db.get(query.datasourceId)
const Integration = integrations[datasource.source]
if (!Integration) {
ctx.throw(400, "Integration type does not exist.")
return
}
const rows = await new Integration(
datasource.config,
query.queryString
).query()
ctx.body = {
schema: query.schema,
rows,
}
}
exports.destroy = async function(ctx) {
const db = new CouchDB(ctx.user.appId)
await db.destroy(ctx.params.queryId)
ctx.message = `Query deleted.`
ctx.status = 200
}

View File

@ -17,26 +17,26 @@ router
datasourceController.find datasourceController.find
) )
.post("/api/datasources", authorized(BUILDER), datasourceController.save) .post("/api/datasources", authorized(BUILDER), datasourceController.save)
.post( // .post(
"/api/datasources/:datasourceId/queries", // "/api/datasources/:datasourceId/queries",
authorized(BUILDER), // authorized(BUILDER),
datasourceController.saveQuery // datasourceController.saveQuery
) // )
.post( // .post(
"/api/datasources/queries/preview", // "/api/datasources/queries/preview",
authorized(BUILDER), // authorized(BUILDER),
datasourceController.previewQuery // datasourceController.previewQuery
) // )
.get( // .get(
"/api/datasources/:datasourceId/queries/:queryId", // "/api/datasources/:datasourceId/queries/:queryId",
authorized(BUILDER), // authorized(BUILDER),
datasourceController.fetchQuery // datasourceController.fetchQuery
) // )
.post( // .post(
"/api/datasources/:datasourceId/queries/:queryId", // "/api/datasources/:datasourceId/queries/:queryId",
authorized(BUILDER), // authorized(BUILDER),
datasourceController.executeQuery // datasourceController.executeQuery
) // )
.delete( .delete(
"/api/datasources/:datasourceId/:revId", "/api/datasources/:datasourceId/:revId",
authorized(BUILDER), authorized(BUILDER),

View File

@ -19,7 +19,7 @@ const routingRoutes = require("./routing")
const integrationRoutes = require("./integration") const integrationRoutes = require("./integration")
const permissionRoutes = require("./permission") const permissionRoutes = require("./permission")
const datasourceRoutes = require("./datasource") const datasourceRoutes = require("./datasource")
// const queryRoutes = require("./query") const queryRoutes = require("./query")
exports.mainRoutes = [ exports.mainRoutes = [
deployRoutes, deployRoutes,
@ -39,7 +39,7 @@ exports.mainRoutes = [
integrationRoutes, integrationRoutes,
permissionRoutes, permissionRoutes,
datasourceRoutes, datasourceRoutes,
// queryRoutes, queryRoutes,
// these need to be handled last as they still use /api/:tableId // these need to be handled last as they still use /api/:tableId
// this could be breaking as koa may recognise other routes as this // this could be breaking as koa may recognise other routes as this
tableRoutes, tableRoutes,

View File

@ -1,28 +1,17 @@
// const Router = require("@koa/router") const Router = require("@koa/router")
// const queryController = require("../controllers/query") const queryController = require("../controllers/query")
// const authorized = require("../../middleware/authorized") const authorized = require("../../middleware/authorized")
// const { BUILDER } = require("../../utilities/security/permissions") const { BUILDER } = require("../../utilities/security/permissions")
// const router = Router() const router = Router()
// // TODO: send down the datasource ID as well // TODO: sort out auth so apps have the right permissions
router
.get("/api/queries", authorized(BUILDER), queryController.fetch)
.get("/api/queries/:queryId", authorized(BUILDER), queryController.fetchQuery)
.post("/api/queries", authorized(BUILDER), queryController.save)
.post("/api/queries/preview", authorized(BUILDER), queryController.preview)
.post("/api/queries/:queryId", authorized(BUILDER), queryController.execute)
.delete("/api/queries/:queryId", authorized(BUILDER), queryController.destroy)
// router module.exports = router
// // .get("/api/queries", authorized(BUILDER), queryController.fetch)
// // .get(
// // "/api/datasources/:datasourceId/queries/:id",
// // authorized(PermissionTypes.TABLE, PermissionLevels.READ),
// // queryController.find
// // )
// .post(
// "/api/datasources/:datasourceId/queries",
// authorized(BUILDER),
// queryController.save
// )
// .delete(
// "/api/datasources/:datasourceId/queries/:queryId/:revId",
// authorized(BUILDER),
// queryController.destroy
// )
// module.exports = router

View File

@ -38,6 +38,6 @@ function replicateLocal() {
}) })
} }
// replicateLocal() replicateLocal()
module.exports = Pouch module.exports = Pouch

View File

@ -245,8 +245,10 @@ exports.getDatasourceParams = (datasourceId = null, otherProps = {}) => {
* Generates a new query ID. * Generates a new query ID.
* @returns {string} The new query ID which the query doc can be stored under. * @returns {string} The new query ID which the query doc can be stored under.
*/ */
exports.generateQueryID = () => { exports.generateQueryID = datasourceId => {
return `${DocumentTypes.QUERY}${SEPARATOR}${newid()}` return `${
DocumentTypes.QUERY
}${SEPARATOR}${datasourceId}${SEPARATOR}${newid()}`
} }
/** /**

View File

@ -14,6 +14,7 @@ const PermissionTypes = {
WEBHOOK: "webhook", WEBHOOK: "webhook",
BUILDER: "builder", BUILDER: "builder",
VIEW: "view", VIEW: "view",
QUERY: "query",
} }
function Permission(type, level) { function Permission(type, level) {