Merge pull request #3444 from Budibase/fix/sql-invalid-cols
Disallow _id, _rev and tableId fields for SQL tables
This commit is contained in:
commit
ddcc94c772
|
@ -8,6 +8,8 @@
|
||||||
export let onConfirm = undefined
|
export let onConfirm = undefined
|
||||||
|
|
||||||
$: icon = selectIcon(type)
|
$: icon = selectIcon(type)
|
||||||
|
// if newlines used, convert them to different elements
|
||||||
|
$: split = message.split("\n")
|
||||||
|
|
||||||
function selectIcon(alertType) {
|
function selectIcon(alertType) {
|
||||||
switch (alertType) {
|
switch (alertType) {
|
||||||
|
@ -33,7 +35,9 @@
|
||||||
<use xlink:href="#spectrum-icon-18-{icon}" />
|
<use xlink:href="#spectrum-icon-18-{icon}" />
|
||||||
</svg>
|
</svg>
|
||||||
<div class="spectrum-InLineAlert-header">{header}</div>
|
<div class="spectrum-InLineAlert-header">{header}</div>
|
||||||
<div class="spectrum-InLineAlert-content">{message}</div>
|
{#each split as splitMsg}
|
||||||
|
<div class="spectrum-InLineAlert-content">{splitMsg}</div>
|
||||||
|
{/each}
|
||||||
{#if onConfirm}
|
{#if onConfirm}
|
||||||
<div class="spectrum-InLineAlert-footer">
|
<div class="spectrum-InLineAlert-footer">
|
||||||
<Button secondary on:click={onConfirm}>OK</Button>
|
<Button secondary on:click={onConfirm}>OK</Button>
|
||||||
|
|
|
@ -7,7 +7,7 @@ const {
|
||||||
BudibaseInternalDB,
|
BudibaseInternalDB,
|
||||||
getTableParams,
|
getTableParams,
|
||||||
} = require("../../db/utils")
|
} = require("../../db/utils")
|
||||||
const { BuildSchemaErrors } = require("../../constants")
|
const { BuildSchemaErrors, InvalidColumns } = require("../../constants")
|
||||||
const { integrations } = require("../../integrations")
|
const { integrations } = require("../../integrations")
|
||||||
const { getDatasourceAndQuery } = require("./row/utils")
|
const { getDatasourceAndQuery } = require("./row/utils")
|
||||||
|
|
||||||
|
@ -152,6 +152,23 @@ exports.query = async function (ctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getErrorTables(errors, errorType) {
|
||||||
|
return Object.entries(errors)
|
||||||
|
.filter(entry => entry[1] === errorType)
|
||||||
|
.map(([name]) => name)
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateError(error, newError, tables) {
|
||||||
|
if (!error) {
|
||||||
|
error = ""
|
||||||
|
}
|
||||||
|
if (error.length > 0) {
|
||||||
|
error += "\n"
|
||||||
|
}
|
||||||
|
error += `${newError} ${tables.join(", ")}`
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
|
||||||
const buildSchemaHelper = async datasource => {
|
const buildSchemaHelper = async datasource => {
|
||||||
const Connector = integrations[datasource.source]
|
const Connector = integrations[datasource.source]
|
||||||
|
|
||||||
|
@ -176,12 +193,23 @@ const buildSchemaHelper = async datasource => {
|
||||||
const errors = connector.schemaErrors
|
const errors = connector.schemaErrors
|
||||||
let error = null
|
let error = null
|
||||||
if (errors && Object.keys(errors).length > 0) {
|
if (errors && Object.keys(errors).length > 0) {
|
||||||
const noKeyTables = Object.entries(errors)
|
const noKey = getErrorTables(errors, BuildSchemaErrors.NO_KEY)
|
||||||
.filter(entry => entry[1] === BuildSchemaErrors.NO_KEY)
|
const invalidCol = getErrorTables(errors, BuildSchemaErrors.INVALID_COLUMN)
|
||||||
.map(([name]) => name)
|
if (noKey.length) {
|
||||||
error = `No primary key constraint found for the following: ${noKeyTables.join(
|
error = updateError(
|
||||||
", "
|
error,
|
||||||
)}`
|
"No primary key constraint found for the following:",
|
||||||
|
noKey
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (invalidCol.length) {
|
||||||
|
const invalidCols = Object.values(InvalidColumns).join(", ")
|
||||||
|
error = updateError(
|
||||||
|
error,
|
||||||
|
`Cannot use columns ${invalidCols} found in following:`,
|
||||||
|
invalidCol
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return { tables: connector.tables, error }
|
return { tables: connector.tables, error }
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,8 +163,15 @@ exports.MetadataTypes = {
|
||||||
AUTOMATION_TEST_HISTORY: "automationTestHistory",
|
AUTOMATION_TEST_HISTORY: "automationTestHistory",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.InvalidColumns = {
|
||||||
|
ID: "_id",
|
||||||
|
REV: "_rev",
|
||||||
|
TABLE_ID: "tableId",
|
||||||
|
}
|
||||||
|
|
||||||
exports.BuildSchemaErrors = {
|
exports.BuildSchemaErrors = {
|
||||||
NO_KEY: "no_key",
|
NO_KEY: "no_key",
|
||||||
|
INVALID_COLUMN: "invalid_column",
|
||||||
}
|
}
|
||||||
|
|
||||||
// pass through the list from the auth/core lib
|
// pass through the list from the auth/core lib
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { SqlQuery } from "../definitions/datasource"
|
||||||
import { Datasource, Table } from "../definitions/common"
|
import { Datasource, Table } from "../definitions/common"
|
||||||
import { SourceNames } from "../definitions/datasource"
|
import { SourceNames } from "../definitions/datasource"
|
||||||
const { DocumentTypes, SEPARATOR } = require("../db/utils")
|
const { DocumentTypes, SEPARATOR } = require("../db/utils")
|
||||||
const { FieldTypes, BuildSchemaErrors } = require("../constants")
|
const { FieldTypes, BuildSchemaErrors, InvalidColumns } = require("../constants")
|
||||||
|
|
||||||
const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`
|
const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`
|
||||||
const ROW_ID_REGEX = /^\[.*]$/g
|
const ROW_ID_REGEX = /^\[.*]$/g
|
||||||
|
@ -161,13 +161,18 @@ export function finaliseExternalTables(
|
||||||
tables: { [key: string]: any },
|
tables: { [key: string]: any },
|
||||||
entities: { [key: string]: any }
|
entities: { [key: string]: any }
|
||||||
) {
|
) {
|
||||||
|
const invalidColumns = Object.values(InvalidColumns)
|
||||||
const finalTables: { [key: string]: any } = {}
|
const finalTables: { [key: string]: any } = {}
|
||||||
const errors: { [key: string]: string } = {}
|
const errors: { [key: string]: string } = {}
|
||||||
for (let [name, table] of Object.entries(tables)) {
|
for (let [name, table] of Object.entries(tables)) {
|
||||||
|
const schemaFields = Object.keys(table.schema)
|
||||||
// make sure every table has a key
|
// make sure every table has a key
|
||||||
if (table.primary == null || table.primary.length === 0) {
|
if (table.primary == null || table.primary.length === 0) {
|
||||||
errors[name] = BuildSchemaErrors.NO_KEY
|
errors[name] = BuildSchemaErrors.NO_KEY
|
||||||
continue
|
continue
|
||||||
|
} else if (schemaFields.find(field => invalidColumns.includes(field))) {
|
||||||
|
errors[name] = BuildSchemaErrors.INVALID_COLUMN
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
// make sure all previous props have been added back
|
// make sure all previous props have been added back
|
||||||
finalTables[name] = copyExistingPropsOver(name, table, entities)
|
finalTables[name] = copyExistingPropsOver(name, table, entities)
|
||||||
|
|
Loading…
Reference in New Issue