schema updates, custom fields

This commit is contained in:
Martin McKeaveney 2021-01-13 16:39:47 +00:00
parent 94ee5855a5
commit 01ff661f17
12 changed files with 170 additions and 124 deletions

View File

@ -8,7 +8,7 @@
{#each Object.keys(integration) as configKey}
<Input
thin
type={configKey.type}
type={integration[configKey].type}
label={configKey}
bind:value={integration[configKey]} />
<Spacer medium />

View File

@ -35,6 +35,7 @@
<Spacer medium />
{/each}
{#if schema.customisable}
<Spacer large />
<Label>Add Custom Field</Label>
{#each Object.keys(customSchema) as field}
<Label extraSmall grey>{field}</Label>
@ -54,7 +55,7 @@
<option value={"number"}>Number</option>
</Select>
</div>
<Button small thin primary on:click={addField}>Add Field</Button>
<Button small thin secondary on:click={addField}>Add Field</Button>
{/if}
</form>

View File

@ -32,8 +32,6 @@
},
]
const QueryVerb = ["create", "read", "update", "delete"]
export let query
export let fields = []
@ -128,25 +126,27 @@
<header>
<Heading small>{query.name}</Heading>
<div class="queryVerbs">
{#each QueryVerb as queryVerb}
<div
class="queryVerb"
class:selected={queryVerb === query.queryVerb}
on:click={() => {
query.queryVerb = queryVerb
}}>
{queryVerb}
</div>
{/each}
</div>
{#if config && query.queryVerb}
<Select thin secondary bind:value={query.queryType}>
<option value={''}>Select an option</option>
{#each Object.keys(config[query.queryVerb]) as queryType}
<option value={queryType}>{queryType}</option>
{#if config}
<div class="queryVerbs">
{#each Object.keys(config) as queryVerb}
<div
class="queryVerb"
class:selected={queryVerb === query.queryVerb}
on:click={() => {
query.queryVerb = queryVerb
}}>
{queryVerb}
</div>
{/each}
</Select>
</div>
{#if query.queryVerb}
<Select thin secondary bind:value={query.queryType}>
<option value={''}>Select an option</option>
{#each Object.keys(config[query.queryVerb]) as queryType}
<option value={queryType}>{queryType}</option>
{/each}
</Select>
{/if}
{/if}
</header>

View File

@ -14,7 +14,7 @@
export let schema
function updateQuery({ detail }) {
query.fields.sql = detail.value
query.fields[schema.type] = detail.value
}
</script>
@ -24,19 +24,21 @@
<Heading extraSmall black>Query</Heading>
<Spacer large />
{#if schema.type === QueryTypes.SQL}
<Editor
label="Query"
mode="sql"
on:change={updateQuery}
value={query.fields.sql} />
{:else if schema.type === QueryTypes.JSON}
<Spacer large />
<Editor
label="Query"
mode="json"
on:change={updateQuery}
value={query.fields.json} />
{:else if schema.type === QueryTypes.FIELDS}
<FieldsBuilder bind:fields={query.fields} {schema} />
{#if schema}
{#if schema.type === QueryTypes.SQL}
<Editor
label="Query"
mode="sql"
on:change={updateQuery}
value={query.fields.sql} />
{:else if schema.type === QueryTypes.JSON}
<Spacer large />
<Editor
label="Query"
mode="json"
on:change={updateQuery}
value={query.fields.json} />
{:else if schema.type === QueryTypes.FIELDS}
<FieldsBuilder bind:fields={query.fields} {schema} />
{/if}
{/if}

View File

@ -26,9 +26,7 @@
<IntegrationConfigForm integration={datasource.config} />
<Spacer medium />
<footer>
<Button primary wide disabled={false} on:click={saveDatasource}>
Save
</Button>
<Button blue wide on:click={saveDatasource}>Save</Button>
</footer>
</section>
{/if}

View File

@ -1,7 +1,12 @@
class Field {
constructor(type, defaultValue, required) {
this.type = type
this.default = defaultValue
this.required = required
}
exports.QUERY_TYPES = {
SQL: "sql",
JSON: "json",
FIELDS: "fields",
}
exports.FIELD_TYPES = {
STRING: "string",
NUMBER: "number",
PASSWORD: "password",
LIST: "list",
}

View File

@ -1,14 +1,15 @@
const Airtable = require("airtable")
const { FIELD_TYPES, QUERY_TYPES } = require("./Integration")
const SCHEMA = {
datasource: {
apiKey: {
type: "string",
type: FIELD_TYPES.STRING,
default: "enter api key",
required: true,
},
base: {
type: "string",
type: FIELD_TYPES.STRING,
default: "mybase",
required: true,
},
@ -20,7 +21,7 @@ const SCHEMA = {
customisable: true,
fields: {
table: {
type: "string",
type: FIELD_TYPES.STRING,
required: true,
},
},
@ -28,14 +29,14 @@ const SCHEMA = {
},
read: {
Table: {
type: "fields",
type: QUERY_TYPES.FIELDS,
fields: {
table: {
type: "string",
type: FIELD_TYPES.STRING,
required: true,
},
view: {
type: "string",
type: FIELD_TYPES.STRING,
required: true,
},
},
@ -43,11 +44,11 @@ const SCHEMA = {
},
update: {
Fields: {
type: "fields",
type: QUERY_TYPES.FIELDS,
customisable: true,
fields: {
id: {
type: "string",
type: FIELD_TYPES.STRING,
required: true,
},
},
@ -55,7 +56,7 @@ const SCHEMA = {
},
delete: {
"Airtable Ids": {
type: "list",
type: FIELD_TYPES.LIST,
},
},
},

View File

@ -1,53 +1,46 @@
const AWS = require("aws-sdk")
const { FIELD_TYPES, QUERY_TYPES } = require("./Integration")
const SCHEMA = {
datasource: {
table: {
type: "string",
required: true,
},
region: {
type: "string",
type: FIELD_TYPES.STRING,
required: true,
default: "us-east-1",
},
accessKeyId: {
type: "string",
type: FIELD_TYPES.PASSWORD,
required: true,
},
secretKey: {
type: "secretKey",
type: FIELD_TYPES.PASSWORD,
required: true,
default: 5432,
},
indexName: {
type: "string",
},
},
query: {
type: "fields",
fields: [
{
name: "Index",
key: "Index",
type: "string",
read: {
DynamoConfig: {
type: QUERY_TYPES.FIELDS,
fields: {
Table: {
type: FIELD_TYPES.STRING,
required: true,
},
Index: {
type: FIELD_TYPES.STRING,
},
KeyConditionExpression: {
type: FIELD_TYPES.STRING,
},
ExpressionAttributeNames: {
type: FIELD_TYPES.STRING,
},
ExpressionAttributeValues: {
type: FIELD_TYPES.STRING,
},
},
},
{
name: "Key Condition Expression",
key: "KeyConditionExpression",
type: "string",
},
{
name: "Attribute Names",
key: "ExpressionAttributeNames",
type: "string",
},
{
name: "Attribute Values",
key: "ExpressionAttributeValues",
type: "string",
},
],
},
},
}
@ -62,12 +55,12 @@ class DynamoDBIntegration {
AWS.config.update(this.config)
}
async read() {
async read(query) {
const response = await this.client.query({
TableName: this.config.table,
KeyConditionExpression: this.config.KeyConditionExpression,
ExpressionAttributeNames: this.config.ExpressionAttributeNames,
ExpressionAttributeValues: this.config.ExpressionAttributeValues,
TableName: query.Table,
KeyConditionExpression: query.KeyConditionExpression,
ExpressionAttributeNames: query.ExpressionAttributeNames,
ExpressionAttributeValues: query.ExpressionAttributeValues,
})
return response
}

View File

@ -26,11 +26,11 @@ class ElasticSearchIntegration {
this.client = new Client({ node: config.url })
}
async create(document) {
async create(query) {
try {
const result = await this.client.index({
index: this.config.index,
body: JSON.parse(document),
body: JSON.parse(query.json),
})
return [result]
} catch (err) {
@ -45,7 +45,7 @@ class ElasticSearchIntegration {
try {
const result = await this.client.search({
index: this.config.index,
body: JSON.parse(query),
body: JSON.parse(query.json),
})
return result.body.hits.hits.map(({ _source }) => _source)
} catch (err) {

View File

@ -1,28 +1,36 @@
const sqlServer = require("mssql")
const { FIELD_TYPES } = require("./Integration")
const SCHEMA = {
datasource: {
user: {
type: "string",
type: FIELD_TYPES.STRING,
required: true,
default: "localhost",
},
password: {
type: "password",
type: FIELD_TYPES.PASSWORD,
required: true,
},
server: {
type: "string",
type: FIELD_TYPES.STRING,
default: "localhost",
},
database: {
type: "string",
type: FIELD_TYPES.STRING,
default: "root",
},
},
query: {
sql: {
type: "sql",
create: {
SQL: {
type: "sql",
},
},
read: {
SQL: {
type: "sql",
},
},
},
}
@ -37,10 +45,21 @@ class SqlServerIntegration {
return await this.client.connect(this.config)
}
async read() {
async read(query) {
try {
await this.connect()
const response = await this.client.query(this.config.query)
const response = await this.client.query(query.sql)
return response.recordset
} catch (err) {
console.error("Error querying MS SQL Server", err)
throw err
}
}
async create(query) {
try {
await this.connect()
const response = await this.client.query(query.sql)
return response.recordset
} catch (err) {
console.error("Error querying MS SQL Server", err)

View File

@ -17,8 +17,15 @@ const SCHEMA = {
},
},
query: {
JSON: {
type: "json",
create: {
JSON: {
type: "json",
},
},
read: {
JSON: {
type: "json",
},
},
},
}
@ -27,23 +34,35 @@ class MongoIntegration {
constructor(config) {
this.config = config
this.client = new MongoClient(config.connectionString)
try {
this.config.query = JSON.parse(this.config.query)
} catch (err) {
this.config.query = {}
}
this.connect()
}
async connect() {
return this.client.connect()
}
async read() {
async create(query) {
try {
const mongoQuery = query.json ? JSON.parse(query.json) : {}
await this.connect()
const db = this.client.db(this.config.db)
const collection = db.collection(this.config.collection)
const result = await collection.find(this.config.query).toArray()
const result = await collection.insertOne(mongoQuery)
return result
} catch (err) {
console.error("Error querying mongodb", err)
throw err
} finally {
await this.client.close()
}
}
async read(query) {
try {
const mongoQuery = query.json ? JSON.parse(query.json) : {}
await this.connect()
const db = this.client.db(this.config.db)
const collection = db.collection(this.config.collection)
const result = await collection.find(mongoQuery).toArray()
return result
} catch (err) {
console.error("Error querying mongodb", err)

View File

@ -2,25 +2,33 @@ const AWS = require("aws-sdk")
const SCHEMA = {
datasource: {
bucket: {
type: "string",
required: true,
},
region: {
type: "string",
required: true,
default: "us-east-1",
},
accessKeyId: {
type: "string",
type: "password",
required: true,
},
secretAccessKey: {
type: "string",
type: "password",
required: true,
},
},
query: {},
query: {
read: {
Bucket: {
type: "fields",
fields: {
bucket: {
type: "string",
required: true,
},
},
},
},
},
}
class S3Integration {
@ -34,10 +42,10 @@ class S3Integration {
AWS.config.update(this.config)
}
async query() {
async read(query) {
const response = await this.client
.listObjects({
Bucket: this.config.bucket,
Bucket: query.bucket,
})
.promise()
return response.Contents