Merge branch 'feature/opinionated-sql' of github.com:Budibase/budibase into feature/opinionated-sql

This commit is contained in:
mike12345567 2021-06-17 14:42:41 +01:00
commit 1014260ad5
25 changed files with 166 additions and 136 deletions

View File

@ -2,9 +2,11 @@ import { store } from "./index"
import { get as svelteGet } from "svelte/store"
import { removeCookie, Cookies } from "./cookies"
const apiCall =
method =>
async (url, body, headers = { "Content-Type": "application/json" }) => {
const apiCall = method => async (
url,
body,
headers = { "Content-Type": "application/json" }
) => {
headers["x-budibase-app-id"] = svelteGet(store).appId
const json = headers["Content-Type"] === "application/json"
const resp = await fetch(url, {

View File

@ -100,8 +100,7 @@ const automationActions = store => ({
},
deleteAutomationBlock: block => {
store.update(state => {
const idx =
state.selectedAutomation.automation.definition.steps.findIndex(
const idx = state.selectedAutomation.automation.definition.steps.findIndex(
x => x.id === block.id
)
state.selectedAutomation.deleteBlock(block.id)

View File

@ -53,7 +53,9 @@
bind:hideAutocolumns
{loading}
>
{#if isInternal}
<CreateColumnButton />
{/if}
{#if schema && Object.keys(schema).length > 0}
{#if !isUsersTable}
<CreateRowButton

View File

@ -9,7 +9,11 @@
import CreateEditRow from "./modals/CreateEditRow.svelte"
import CreateEditUser from "./modals/CreateEditUser.svelte"
import CreateEditColumn from "./modals/CreateEditColumn.svelte"
import { TableNames, UNEDITABLE_USER_FIELDS, BUDIBASE_INTERNAL_DB } from "constants"
import {
TableNames,
UNEDITABLE_USER_FIELDS,
BUDIBASE_INTERNAL_DB,
} from "constants"
import RoleCell from "./cells/RoleCell.svelte"
export let schema = {}

View File

@ -15,9 +15,6 @@
}
function onClickQuery(query) {
if ($queries.selected === query._id) {
return
}
queries.select(query)
$goto(`./datasource/${query.datasourceId}/${query._id}`)
}

View File

@ -59,7 +59,9 @@
<section>
<Heading size="XS">Columns</Heading>
<ul>
{#each context.filter( context => context.readableBinding.match(searchRgx) ) as { readableBinding }}
{#each context.filter(context =>
context.readableBinding.match(searchRgx)
) as { readableBinding }}
<li
on:click={() => {
value = addToText(value, getCaretPosition(), readableBinding)
@ -75,7 +77,9 @@
<section>
<Heading size="XS">Components</Heading>
<ul>
{#each instance.filter( instance => instance.readableBinding.match(searchRgx) ) as { readableBinding }}
{#each instance.filter(instance =>
instance.readableBinding.match(searchRgx)
) as { readableBinding }}
<li on:click={() => addToText(readableBinding)}>
{readableBinding}
</li>

View File

@ -49,7 +49,9 @@
<div class="section">
{#each categories as [categoryName, bindings]}
<Heading size="XS">{categoryName}</Heading>
{#each bindings.filter( binding => binding.label.match(searchRgx) ) as binding}
{#each bindings.filter(binding =>
binding.label.match(searchRgx)
) as binding}
<div
class="binding"
on:click={() => {

View File

@ -103,9 +103,8 @@
}
function fetchQueryDefinition(query) {
const source = $datasources.list.find(
ds => ds._id === query.datasourceId
).source
const source = $datasources.list.find(ds => ds._id === query.datasourceId)
.source
return $integrations[source].query[query.queryVerb]
}
</script>

View File

@ -18,9 +18,8 @@
)
function fetchQueryDefinition(query) {
const source = $datasources.list.find(
ds => ds._id === query.datasourceId
).source
const source = $datasources.list.find(ds => ds._id === query.datasourceId)
.source
return $integrations[source].query[query.queryVerb]
}
</script>

View File

@ -1,12 +1,7 @@
<script>
import { goto, beforeUrlChange } from "@roxi/routify"
import { Button, Heading, Body, Divider, Layout } from "@budibase/bbui"
import {
datasources,
integrations,
queries,
tables,
} from "stores/backend"
import { datasources, integrations, queries, tables } from "stores/backend"
import { notifications } from "@budibase/bbui"
import IntegrationConfigForm from "components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte"
import ICONS from "components/backend/DatasourceNavigator/icons"
@ -100,11 +95,16 @@
>
</div>
<Body>
This datasource can determine tables automatically. Budibase can fetch your tables directly from the database and you can use them without having to write any queries at all.
This datasource can determine tables automatically. Budibase can fetch
your tables directly from the database and you can use them without
having to write any queries at all.
</Body>
<div class="query-list">
{#each Object.keys(datasource.entities) as entity}
<div class="query-list-item" on:click={() => onClickTable(datasource.entities[entity])}>
<div
class="query-list-item"
on:click={() => onClickTable(datasource.entities[entity])}
>
<p class="query-name">{entity}</p>
<p>Primary Key: {datasource.entities[entity].primary}</p>
<p></p>

View File

@ -3,8 +3,6 @@
import CreateTableModal from "components/backend/TableNavigator/modals/CreateTableModal.svelte"
let modal
</script>
<Modal bind:this={modal}>
@ -12,14 +10,9 @@
</Modal>
<Layout>
<Heading>
Budibase Internal DB
</Heading>
<Body>
Stuff about the internal table
</Body>
<Heading>Budibase Internal DB</Heading>
<div>
<Button cta on:click={modal.show}>Create new table</Button>
</div>
</Layout>

View File

@ -1,5 +1,5 @@
import { writable } from "svelte/store"
import { queries } from "./"
import { queries, tables, views } from "./"
import api from "../../builderStore/api"
export const INITIAL_DATASOURCE_VALUES = {
@ -26,7 +26,12 @@ export function createDatasourcesStore() {
},
select: async datasourceId => {
update(state => ({ ...state, selected: datasourceId }))
queries.update(state => ({ ...state, selected: null }))
queries.unselect()
tables.unselect()
views.unselect()
},
unselect: () => {
update(state => ({ ...state, selected: null }))
},
updateSchema: async datasource => {
let url = `/api/datasources/${datasource._id}/schema`

View File

@ -55,10 +55,6 @@ export function createQueriesStore() {
},
select: query => {
update(state => ({ ...state, selected: query._id }))
datasources.update(state => ({
...state,
selected: query.datasourceId,
}))
tables.update(state => ({
...state,
selected: null,
@ -66,10 +62,6 @@ export function createQueriesStore() {
},
unselect: () => {
update(state => ({ ...state, selected: null }))
datasources.update(state => ({
...state,
selected: null,
}))
},
delete: async query => {
const response = await api.delete(

View File

@ -1,5 +1,5 @@
import { writable, get } from "svelte/store"
import { views, queries } from "./"
import { views, queries, datasources } from "./"
import { cloneDeep } from "lodash/fp"
import api from "builderStore/api"
@ -25,8 +25,9 @@ export function createTablesStore() {
selected: table,
draft: cloneDeep(table),
}))
views.select({ name: table._id })
views.unselect()
queries.unselect()
datasources.unselect()
}
}
@ -70,6 +71,12 @@ export function createTablesStore() {
update,
fetch,
select,
unselect: () => {
update(state => ({
...state,
selected: null,
}))
},
save,
init: async () => {
const response = await api.get("/api/tables")

View File

@ -9,7 +9,8 @@ export const SOME_QUERY = {
queryVerb: "read",
schema: {},
name: "Speakers",
_id: "query_datasource_04b003a7b4a8428eadd3bb2f7eae0255_bcb8ffc6fcbc484e8d63121fc0bf986f",
_id:
"query_datasource_04b003a7b4a8428eadd3bb2f7eae0255_bcb8ffc6fcbc484e8d63121fc0bf986f",
_rev: "2-941f8699eb0adf995f8bd59c99203b26",
readable: true,
}
@ -74,7 +75,8 @@ export const SAVE_QUERY_RESPONSE = {
},
},
name: "Speakers",
_id: "query_datasource_04b003a7b4a8428eadd3bb2f7eae0255_bcb8ffc6fcbc484e8d63121fc0bf986f",
_id:
"query_datasource_04b003a7b4a8428eadd3bb2f7eae0255_bcb8ffc6fcbc484e8d63121fc0bf986f",
_rev: "3-5a64adef494b1e9c793dc91b51ce73c6",
readable: true,
}

View File

@ -1,5 +1,5 @@
import { writable, get } from "svelte/store"
import { tables } from "./"
import { tables, datasources, queries } from "./"
import api from "builderStore/api"
export function createViewsStore() {
@ -10,11 +10,20 @@ export function createViewsStore() {
return {
subscribe,
update,
select: async view => {
update(state => ({
...state,
selected: view,
}))
queries.unselect()
datasources.unselect()
},
unselect: () => {
update(state => ({
...state,
selected: null,
}))
},
delete: async view => {
await api.delete(`/api/views/${view}`)

View File

@ -2,7 +2,8 @@ const { Client } = require("@elastic/elasticsearch")
const { QUERY_TYPES, FIELD_TYPES } = require("./Integration")
const SCHEMA = {
docs: "https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html",
docs:
"https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html",
description:
"Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.",
friendlyName: "ElasticSearch",

View File

@ -14,9 +14,7 @@ const WEBHOOK_ENDPOINTS = new RegExp(
["webhooks/trigger", "webhooks/schema"].join("|")
)
module.exports =
(permType, permLevel = null) =>
async (ctx, next) => {
module.exports = (permType, permLevel = null) => async (ctx, next) => {
// webhooks don't need authentication, each webhook unique
if (WEBHOOK_ENDPOINTS.test(ctx.request.url)) {
return next()

View File

@ -1,5 +1,9 @@
const { getAppId, setCookie, getCookie, clearCookie } =
require("@budibase/auth").utils
const {
getAppId,
setCookie,
getCookie,
clearCookie,
} = require("@budibase/auth").utils
const { Cookies } = require("@budibase/auth").constants
const { getRole } = require("@budibase/auth/roles")
const { getGlobalSelf } = require("../utilities/workerRequests")

View File

@ -90,9 +90,7 @@ const numericalConstraint = (constraint, error) => value => {
return null
}
const inclusionConstraint =
(options = []) =>
value => {
const inclusionConstraint = (options = []) => value => {
if (value == null || value === "") {
return null
}

View File

@ -5,8 +5,15 @@ const authPkg = require("@budibase/auth")
const GLOBAL_DB = authPkg.StaticDatabases.GLOBAL.name
exports.sendEmail = async ctx => {
const { groupId, email, userId, purpose, contents, from, subject } =
ctx.request.body
const {
groupId,
email,
userId,
purpose,
contents,
from,
subject,
} = ctx.request.body
let user
if (userId) {
const db = new CouchDB(GLOBAL_DB)

View File

@ -1,6 +1,9 @@
const CouchDB = require("../../../db")
const { getGroupParams, generateGroupID, StaticDatabases } =
require("@budibase/auth").db
const {
getGroupParams,
generateGroupID,
StaticDatabases,
} = require("@budibase/auth").db
const GLOBAL_DB = StaticDatabases.GLOBAL.name

View File

@ -1,6 +1,9 @@
const CouchDB = require("../../../db")
const { generateGlobalUserID, getGlobalUserParams, StaticDatabases } =
require("@budibase/auth").db
const {
generateGlobalUserID,
getGlobalUserParams,
StaticDatabases,
} = require("@budibase/auth").db
const { hash, getGlobalUserByEmail } = require("@budibase/auth").utils
const { UserStatus, EmailTemplatePurpose } = require("../../../constants")
const { checkInviteCode } = require("../../../utilities/redis")