Found some issues with relationship columns being doubled up, this isn't validated client side, best to make sure it doesn't happen server-side (can really break your data structure if columns overwrite each other).

This commit is contained in:
mike12345567 2021-02-25 12:06:13 +00:00
parent 8d496a49b4
commit a311002632
2 changed files with 39 additions and 10 deletions

View File

@ -89,16 +89,20 @@ exports.save = async function(ctx) {
} }
// update linked rows // update linked rows
const linkResp = await linkRows.updateLinks({ try {
appId, const linkResp = await linkRows.updateLinks({
eventType: oldTable appId,
? linkRows.EventType.TABLE_UPDATED eventType: oldTable
: linkRows.EventType.TABLE_SAVE, ? linkRows.EventType.TABLE_UPDATED
table: tableToSave, : linkRows.EventType.TABLE_SAVE,
oldTable: oldTable, table: tableToSave,
}) oldTable: oldTable,
if (linkResp != null && linkResp._rev) { })
tableToSave._rev = linkResp._rev if (linkResp != null && linkResp._rev) {
tableToSave._rev = linkResp._rev
}
} catch (err) {
ctx.throw(400, err)
} }
// don't perform any updates until relationships have been // don't perform any updates until relationships have been

View File

@ -3,6 +3,7 @@ const { IncludeDocs, getLinkDocuments } = require("./linkUtils")
const { generateLinkID } = require("../utils") const { generateLinkID } = require("../utils")
const Sentry = require("@sentry/node") const Sentry = require("@sentry/node")
const { FieldTypes } = require("../../constants") const { FieldTypes } = require("../../constants")
const { isEqual } = require("lodash")
/** /**
* Creates a new link document structure which can be put to the database. It is important to * Creates a new link document structure which can be put to the database. It is important to
@ -113,6 +114,23 @@ class LinkController {
}) })
} }
/**
* Makes sure the passed in table schema contains valid relationship structures.
*/
validateTable(table) {
const usedAlready = []
for (let schema of Object.values(table.schema)) {
if (schema.type !== FieldTypes.LINK) {
continue
}
const unique = schema.tableId + schema.fieldName
if (usedAlready.indexOf(unique) !== -1) {
throw "Cannot re-use the linked column name for a linked table."
}
usedAlready.push(unique)
}
}
// all operations here will assume that the table // all operations here will assume that the table
// this operation is related to has linked rows // this operation is related to has linked rows
/** /**
@ -246,6 +264,8 @@ class LinkController {
*/ */
async tableSaved() { async tableSaved() {
const table = await this.table() const table = await this.table()
// validate the table first
this.validateTable(table)
const schema = table.schema const schema = table.schema
for (let fieldName of Object.keys(schema)) { for (let fieldName of Object.keys(schema)) {
const field = schema[fieldName] const field = schema[fieldName]
@ -269,6 +289,11 @@ class LinkController {
if (field.autocolumn) { if (field.autocolumn) {
linkConfig.autocolumn = field.autocolumn linkConfig.autocolumn = field.autocolumn
} }
// check the linked table to make sure we aren't overwriting an existing column
const existingSchema = linkedTable.schema[field.fieldName]
if (existingSchema != null && !isEqual(existingSchema, linkConfig)) {
throw "Cannot overwrite existing column."
}
// create the link field in the other table // create the link field in the other table
linkedTable.schema[field.fieldName] = linkConfig linkedTable.schema[field.fieldName] = linkConfig
const response = await this._db.put(linkedTable) const response = await this._db.put(linkedTable)