Adding schema validation and API endpoint to data sources for query.

This commit is contained in:
mike12345567 2021-06-04 14:53:49 +01:00
parent 9f50d2d329
commit 091b537e2d
4 changed files with 70 additions and 8 deletions

View File

@ -64,7 +64,17 @@ exports.find = async function (ctx) {
// dynamic query functionality
exports.query = async function (ctx) {
const queryJson = ctx.request.body
const datasourceId = queryJson.endpoint.datasourceId
const database = new CouchDB(ctx.appId)
const datasource = await database.get(datasourceId)
const source = integrations[datasource.source]
// query is the opinionated function
if (source.query) {
ctx.body = await source.query(queryJson)
} else {
ctx.throw(400, "Datasource does not support query.")
}
}
// TODO: merge endpoint with main datasource endpoint

View File

@ -8,7 +8,7 @@ const {
PermissionTypes,
} = require("@budibase/auth/permissions")
const Joi = require("joi")
const { FieldTypes } = require("../../constants")
const { FieldTypes, DataSourceOperation, SortDirection } = require("../../constants")
const router = Router()
@ -31,6 +31,35 @@ function generatePlusDatasourceSchema() {
}).unknown(true))
}
function generateQueryDatasourceSchema() {
// prettier-ignore
return joiValidator.body(Joi.object({
endpoint: Joi.object({
datasourceId: Joi.string().required(),
operation: Joi.string().required().valid(...Object.values(DataSourceOperation)),
entityId: Joi.string().required(),
}).required(),
resource: Joi.object({
fields: Joi.array().items(Joi.string()).optional(),
}).optional(),
body: Joi.object().optional(),
sort: Joi.object().optional(),
filters: Joi.object({
string: Joi.object().optional(),
range: Joi.object().optional(),
equal: Joi.object().optional(),
notEqual: Joi.object().optional(),
empty: Joi.object().optional(),
notEmpty: Joi.object().optional(),
}).optional(),
paginate: Joi.object({
page: Joi.string().alphanum().optional(),
limit: Joi.number().optional(),
}).optional(),
}))
}
router
.get("/api/datasources", authorized(BUILDER), datasourceController.fetch)
.get(
@ -40,9 +69,16 @@ router
)
.post(
"/api/datasources/plus",
authorized(PermissionTypes.TABLE, PermissionLevels.READ),
generatePlusDatasourceSchema(),
datasourceController.plus
)
.post(
"/api/datasources/query",
authorized(PermissionTypes.TABLE, PermissionLevels.READ),
generateQueryDatasourceSchema(),
datasourceController.query
)
.post("/api/datasources", authorized(BUILDER), datasourceController.save)
.delete(
"/api/datasources/:datasourceId/:revId",

View File

@ -31,6 +31,19 @@ exports.AuthTypes = {
EXTERNAL: "external",
}
exports.DataSourceOperation = {
CREATE: "CREATE",
READ: "READ",
UPDATE: "UPDATE",
DELETE: "DELETE",
}
exports.SortDirection = {
ASCENDING: "ASCENDING",
DESCENDING: "DESCENDING",
}
exports.USERS_TABLE_SCHEMA = {
_id: "ta_users",
type: "table",

View File

@ -1,4 +1,7 @@
const { Operation, SortDirection } = require("./constants")
const {
DataSourceOperation,
SortDirection,
} = require("../../constants")
const BASE_LIMIT = 5000
@ -113,20 +116,20 @@ class SqlQueryBuilder {
const knex = require("knex")({ client: this._client })
let query
switch (this._operation(json)) {
case Operation.CREATE:
case DataSourceOperation.CREATE:
query = buildCreate(knex, json)
break
case Operation.READ:
case DataSourceOperation.READ:
query = buildRead(knex, json, this._limit)
break
case Operation.UPDATE:
case DataSourceOperation.UPDATE:
query = buildUpdate(knex, json)
break
case Operation.DELETE:
case DataSourceOperation.DELETE:
query = buildDelete(knex, json)
break
default:
throw `Operation ${operation} type is not supported by SQL query builder`
throw `Operation type is not supported by SQL query builder`
}
return query.toSQL().toNative()
}