From 7a1212ff36f9df3cb3ab238e643a80905aa22bf0 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Tue, 12 Jan 2021 17:45:43 +0000 Subject: [PATCH] Add all CRUD ops to airtable integration --- .../builder/src/builderStore/store/backend.js | 8 +-- .../popovers/EditDatasourcePopover.svelte | 2 - .../popovers/EditQueryPopover.svelte | 2 +- .../DataBindingDrawer/index.svelte | 62 ------------------- .../[selectedDatasource]/[query]/index.svelte | 12 +++- .../server/src/api/controllers/datasource.js | 2 +- packages/server/src/api/controllers/query.js | 2 +- packages/server/src/api/routes/query.js | 6 +- packages/server/src/integrations/airtable.js | 61 ++++++++++++++---- .../server/src/integrations/elasticsearch.js | 19 +++++- packages/server/src/integrations/postgres.js | 61 ++++-------------- 11 files changed, 101 insertions(+), 136 deletions(-) delete mode 100644 packages/builder/src/components/userInterface/DataBindingDrawer/index.svelte diff --git a/packages/builder/src/builderStore/store/backend.js b/packages/builder/src/builderStore/store/backend.js index 0ada121790..f646c84d3d 100644 --- a/packages/builder/src/builderStore/store/backend.js +++ b/packages/builder/src/builderStore/store/backend.js @@ -139,13 +139,13 @@ export const getBackendUiStore = () => { state.selectedQueryId = queryId return state }), - delete: async queryId => { - await api.delete(`/api/queries/${queryId}`) + delete: async query => { + await api.delete(`/api/queries/${query._id}/${query._rev}`) store.update(state => { state.queries = state.queries.filter( - existing => existing._id !== queryId + existing => existing._id !== query._id ) - if (state.selectedQueryId === queryId) { + if (state.selectedQueryId === query._id) { state.selectedQueryId = null } diff --git a/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditDatasourcePopover.svelte b/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditDatasourcePopover.svelte index d72ca668b1..d76c8cdcd5 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditDatasourcePopover.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditDatasourcePopover.svelte @@ -25,9 +25,7 @@ } async function deleteDatasource() { - // TODO: update the store correctly await backendUiStore.actions.datasources.delete(datasource) - // await backendUiStore.actions.datasources.fetch() notifier.success("Datasource deleted") hideEditor() } diff --git a/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditQueryPopover.svelte b/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditQueryPopover.svelte index ccd48c2d9e..676458fd29 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditQueryPopover.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/popovers/EditQueryPopover.svelte @@ -24,7 +24,7 @@ } async function deleteQuery() { - await backendUiStore.actions.queries.delete(query._id) + await backendUiStore.actions.queries.delete(query) notifier.success("Query deleted") hideEditor() } diff --git a/packages/builder/src/components/userInterface/DataBindingDrawer/index.svelte b/packages/builder/src/components/userInterface/DataBindingDrawer/index.svelte deleted file mode 100644 index 023784b3f2..0000000000 --- a/packages/builder/src/components/userInterface/DataBindingDrawer/index.svelte +++ /dev/null @@ -1,62 +0,0 @@ - - -{#if query} - -
- -
-
-
{query.queryString}
- -
-
-{/if} - - diff --git a/packages/builder/src/pages/[application]/data/datasource/[selectedDatasource]/[query]/index.svelte b/packages/builder/src/pages/[application]/data/datasource/[selectedDatasource]/[query]/index.svelte index 137920b874..c10813076e 100644 --- a/packages/builder/src/pages/[application]/data/datasource/[selectedDatasource]/[query]/index.svelte +++ b/packages/builder/src/pages/[application]/data/datasource/[selectedDatasource]/[query]/index.svelte @@ -6,6 +6,17 @@ let query + async function fetchQueryConfig() { + try { + const response = await api.get(`/api/integrations/${datasource.source}`) + const json = await response.json() + config = json.query + } catch (err) { + notifier.danger("Error fetching datasource configuration options.") + console.error(err) + } + } + $: { if ($params.query !== "new") { query = $backendUiStore.queries.find(query => query._id === $params.query) @@ -15,7 +26,6 @@ datasourceId: $params.selectedDatasource, name: "New Query", parameters: [], - // TODO: set dynamically } } } diff --git a/packages/server/src/api/controllers/datasource.js b/packages/server/src/api/controllers/datasource.js index ba8cb589ef..7cd530121d 100644 --- a/packages/server/src/api/controllers/datasource.js +++ b/packages/server/src/api/controllers/datasource.js @@ -66,7 +66,7 @@ exports.destroy = async function(ctx) { await db.bulkDocs(rows.rows.map(row => ({ ...row.doc, _deleted: true }))) // delete the datasource - await db.remove(ctx.params.datasourceId) + await db.remove(ctx.params.datasourceId, ctx.params.revId) ctx.message = `Datasource deleted.` ctx.status = 200 diff --git a/packages/server/src/api/controllers/query.js b/packages/server/src/api/controllers/query.js index c1e0b879c0..d967c83d09 100644 --- a/packages/server/src/api/controllers/query.js +++ b/packages/server/src/api/controllers/query.js @@ -79,7 +79,7 @@ exports.execute = async function(ctx) { exports.destroy = async function(ctx) { const db = new CouchDB(ctx.user.appId) - await db.remove(ctx.params.queryId) + await db.remove(ctx.params.queryId, ctx.params.revId) ctx.message = `Query deleted.` ctx.status = 200 } diff --git a/packages/server/src/api/routes/query.js b/packages/server/src/api/routes/query.js index 0159064c4c..8d1526f1e2 100644 --- a/packages/server/src/api/routes/query.js +++ b/packages/server/src/api/routes/query.js @@ -65,6 +65,10 @@ router authorized(PermissionTypes.QUERY, PermissionLevels.WRITE), queryController.execute ) - .delete("/api/queries/:queryId", authorized(BUILDER), queryController.destroy) + .delete( + "/api/queries/:queryId/:revId", + authorized(BUILDER), + queryController.destroy + ) module.exports = router diff --git a/packages/server/src/integrations/airtable.js b/packages/server/src/integrations/airtable.js index 0d109e8b54..f21fc3e301 100644 --- a/packages/server/src/integrations/airtable.js +++ b/packages/server/src/integrations/airtable.js @@ -18,7 +18,15 @@ const SCHEMA = { required: true, }, }, - query: {}, + query: { + Custom: { + type: "fields", + custom: true, + }, + "Airtable Ids": { + type: "list", + }, + }, } class AirtableIntegration { @@ -27,17 +35,19 @@ class AirtableIntegration { this.client = new Airtable(config).base(config.base) } - // async create() { - - // } - - // async update() { - - // } - - // async delete() { - - // } + async create(record) { + try { + const records = await this.client(this.config.table).create([ + { + fields: record, + }, + ]) + return records + } catch (err) { + console.error("Error writing to airtable", err) + throw err + } + } async read() { const records = await this.client(this.config.table) @@ -45,6 +55,33 @@ class AirtableIntegration { .firstPage() return records.map(({ fields }) => fields) } + + async update(document) { + const { id, ...rest } = document + + try { + const records = await this.client(this.config.table).update([ + { + id, + fields: rest, + }, + ]) + return records + } catch (err) { + console.error("Error writing to airtable", err) + throw err + } + } + + async delete(id) { + try { + const records = await this.client(this.config.table).destroy([id]) + return records + } catch (err) { + console.error("Error writing to airtable", err) + throw err + } + } } module.exports = { diff --git a/packages/server/src/integrations/elasticsearch.js b/packages/server/src/integrations/elasticsearch.js index d4ac64d0e7..8e9e92be42 100644 --- a/packages/server/src/integrations/elasticsearch.js +++ b/packages/server/src/integrations/elasticsearch.js @@ -26,11 +26,26 @@ class ElasticSearchIntegration { this.client = new Client({ node: config.url }) } - async read() { + async create(document) { + try { + const result = await this.client.index({ + index: this.config.index, + body: JSON.parse(document), + }) + return [result] + } catch (err) { + console.error("Error writing to elasticsearch", err) + throw err + } finally { + await this.client.close() + } + } + + async read(query) { try { const result = await this.client.search({ index: this.config.index, - body: JSON.parse(this.config.query), + body: JSON.parse(query), }) return result.body.hits.hits.map(({ _source }) => _source) } catch (err) { diff --git a/packages/server/src/integrations/postgres.js b/packages/server/src/integrations/postgres.js index e7a0c4dab6..8b6ce6f618 100644 --- a/packages/server/src/integrations/postgres.js +++ b/packages/server/src/integrations/postgres.js @@ -32,41 +32,6 @@ const SCHEMA = { SQL: { type: "sql", }, - "Simple Query": { - type: "fields", - fields: { - table: { - type: "string", - }, - column: { - type: "string", - }, - condition: { - type: "options", - options: [ - { - name: "Equals", - value: "=", - }, - { - name: "Not Equals", - value: "!=", - }, - { - name: "Greater Than", - value: ">", - }, - { - name: "Less Than", - value: "<", - }, - ], - }, - value: { - type: "string", - }, - }, - }, }, } @@ -87,27 +52,25 @@ class PostgresIntegration { return this.client.connect() } - // async create() { - - // } + async create() { + const response = await this.client.query(this.queryString) + return response.rows + } async read() { const response = await this.client.query(this.queryString) return response.rows } - // async update() { + async update() { + const response = await this.client.query(this.queryString) + return response.rows + } - // } - - // async delete() { - - // } - - // async query() { - // const response = await this.client.query(this.queryString) - // return response.rows - // } + async delete() { + const response = await this.client.query(this.queryString) + return response.rows + } } module.exports = {