Fix relationship types
This commit is contained in:
parent
c8ffa98844
commit
21e2d7ddbe
|
@ -5,8 +5,11 @@ import {
|
|||
FieldType,
|
||||
FilterType,
|
||||
IncludeRelationship,
|
||||
ManyToManyRelationshipFieldMetadata,
|
||||
OneToManyRelationshipFieldMetadata,
|
||||
Operation,
|
||||
PaginationJson,
|
||||
RelationshipFieldMetadata,
|
||||
RelationshipsJson,
|
||||
RelationshipType,
|
||||
Row,
|
||||
|
@ -254,12 +257,20 @@ function fixArrayTypes(row: Row, table: Table) {
|
|||
return row
|
||||
}
|
||||
|
||||
function isOneSide(field: FieldSchema) {
|
||||
function isOneSide(
|
||||
field: RelationshipFieldMetadata
|
||||
): field is OneToManyRelationshipFieldMetadata {
|
||||
return (
|
||||
field.relationshipType && field.relationshipType.split("-")[0] === "one"
|
||||
)
|
||||
}
|
||||
|
||||
function isManyToMany(
|
||||
field: RelationshipFieldMetadata
|
||||
): field is ManyToManyRelationshipFieldMetadata {
|
||||
return !!(field as ManyToManyRelationshipFieldMetadata).through
|
||||
}
|
||||
|
||||
function isEditableColumn(column: FieldSchema) {
|
||||
const isExternalAutoColumn =
|
||||
column.autocolumn &&
|
||||
|
@ -352,11 +363,11 @@ export class ExternalRequest<T extends Operation> {
|
|||
}
|
||||
}
|
||||
// many to many
|
||||
else if (field.through) {
|
||||
else if (isManyToMany(field)) {
|
||||
// we're not inserting a doc, will be a bunch of update calls
|
||||
const otherKey: string = field.throughFrom || linkTablePrimary
|
||||
const thisKey: string = field.throughTo || tablePrimary
|
||||
row[key].forEach((relationship: any) => {
|
||||
for (const relationship of row[key]) {
|
||||
manyRelationships.push({
|
||||
tableId: field.through || field.tableId,
|
||||
isUpdate: false,
|
||||
|
@ -365,14 +376,14 @@ export class ExternalRequest<T extends Operation> {
|
|||
// leave the ID for enrichment later
|
||||
[thisKey]: `{{ literal ${tablePrimary} }}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
// many to one
|
||||
else {
|
||||
const thisKey: string = "id"
|
||||
// @ts-ignore
|
||||
const otherKey: string = field.fieldName
|
||||
row[key].forEach((relationship: any) => {
|
||||
for (const relationship of row[key]) {
|
||||
manyRelationships.push({
|
||||
tableId: field.tableId,
|
||||
isUpdate: true,
|
||||
|
@ -381,7 +392,7 @@ export class ExternalRequest<T extends Operation> {
|
|||
// leave the ID for enrichment later
|
||||
[otherKey]: `{{ literal ${tablePrimary} }}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
// we return the relationships that may need to be created in the through table
|
||||
|
@ -551,20 +562,24 @@ export class ExternalRequest<T extends Operation> {
|
|||
}
|
||||
const definition: any = {
|
||||
// if no foreign key specified then use the name of the field in other table
|
||||
from: field.foreignKey || table.primary[0],
|
||||
from: (field as any).foreignKey || table.primary[0],
|
||||
to: field.fieldName,
|
||||
tableName: linkTableName,
|
||||
// need to specify where to put this back into
|
||||
column: fieldName,
|
||||
}
|
||||
if (field.through) {
|
||||
if ((field as ManyToManyRelationshipFieldMetadata).through) {
|
||||
const { tableName: throughTableName } = breakExternalTableId(
|
||||
field.through
|
||||
(field as ManyToManyRelationshipFieldMetadata).through
|
||||
)
|
||||
definition.through = throughTableName
|
||||
// don't support composite keys for relationships
|
||||
definition.from = field.throughTo || table.primary[0]
|
||||
definition.to = field.throughFrom || linkTable.primary[0]
|
||||
definition.from =
|
||||
(field as ManyToManyRelationshipFieldMetadata).throughTo ||
|
||||
table.primary[0]
|
||||
definition.to =
|
||||
(field as ManyToManyRelationshipFieldMetadata).throughFrom ||
|
||||
linkTable.primary[0]
|
||||
definition.fromPrimary = table.primary[0]
|
||||
definition.toPrimary = linkTable.primary[0]
|
||||
}
|
||||
|
@ -597,12 +612,15 @@ export class ExternalRequest<T extends Operation> {
|
|||
continue
|
||||
}
|
||||
const isMany = field.relationshipType === RelationshipType.MANY_TO_MANY
|
||||
const tableId = isMany ? field.through : field.tableId
|
||||
const tableId = isMany
|
||||
? (field as ManyToManyRelationshipFieldMetadata).through
|
||||
: field.tableId
|
||||
const { tableName: relatedTableName } = breakExternalTableId(tableId)
|
||||
// @ts-ignore
|
||||
const linkPrimaryKey = this.tables[relatedTableName].primary[0]
|
||||
const manyKey = field.throughTo || primaryKey
|
||||
const lookupField = isMany ? primaryKey : field.foreignKey
|
||||
const manyKey =
|
||||
(field as ManyToManyRelationshipFieldMetadata).throughTo || primaryKey
|
||||
const lookupField = isMany ? primaryKey : (field as any).foreignKey
|
||||
const fieldName = isMany ? manyKey : field.fieldName
|
||||
if (!lookupField || !row[lookupField]) {
|
||||
continue
|
||||
|
@ -617,7 +635,10 @@ export class ExternalRequest<T extends Operation> {
|
|||
})
|
||||
// this is the response from knex if no rows found
|
||||
const rows = !response[0].read ? response : []
|
||||
const storeTo = isMany ? field.throughFrom || linkPrimaryKey : fieldName
|
||||
const storeTo = isMany
|
||||
? (field as ManyToManyRelationshipFieldMetadata).throughFrom ||
|
||||
linkPrimaryKey
|
||||
: fieldName
|
||||
related[storeTo] = { rows, isMany, tableId }
|
||||
}
|
||||
return related
|
||||
|
|
|
@ -306,7 +306,8 @@ class OracleIntegration extends Sql implements DatasourcePlus {
|
|||
presence: false,
|
||||
},
|
||||
...this.internalConvertType(oracleColumn),
|
||||
}
|
||||
} as any // TODO
|
||||
|
||||
table.schema[columnName] = fieldSchema
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,13 @@ import { ObjectStoreBuckets } from "../../constants"
|
|||
import { context, db as dbCore, objectStore } from "@budibase/backend-core"
|
||||
import { InternalTables } from "../../db/utils"
|
||||
import { TYPE_TRANSFORM_MAP } from "./map"
|
||||
import { FieldSubtype, Row, RowAttachment, Table } from "@budibase/types"
|
||||
import {
|
||||
AutoColumnFieldMetadata,
|
||||
FieldSubtype,
|
||||
Row,
|
||||
RowAttachment,
|
||||
Table,
|
||||
} from "@budibase/types"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
import {
|
||||
processInputBBReferences,
|
||||
|
@ -71,7 +77,7 @@ export function processAutoColumn(
|
|||
continue
|
||||
}
|
||||
if (!schema.subtype) {
|
||||
schema = fixAutoColumnSubType(schema)
|
||||
schema = fixAutoColumnSubType(schema as AutoColumnFieldMetadata)
|
||||
}
|
||||
switch (schema.subtype) {
|
||||
case AutoFieldSubTypes.CREATED_BY:
|
||||
|
@ -94,8 +100,12 @@ export function processAutoColumn(
|
|||
break
|
||||
case AutoFieldSubTypes.AUTO_ID:
|
||||
if (creating) {
|
||||
schema.lastID = !schema.lastID ? BASE_AUTO_ID : schema.lastID + 1
|
||||
row[key] = schema.lastID
|
||||
const safeSchema = schema as AutoColumnFieldMetadata
|
||||
|
||||
safeSchema.lastID = !safeSchema.lastID
|
||||
? BASE_AUTO_ID
|
||||
: safeSchema.lastID + 1
|
||||
row[key] = safeSchema.lastID
|
||||
}
|
||||
break
|
||||
}
|
||||
|
|
|
@ -15,22 +15,33 @@ export interface UIFieldMetadata {
|
|||
icon?: string
|
||||
}
|
||||
|
||||
interface ManyToManyRelationshipFieldMetadata {
|
||||
interface BaseRelationshipFieldMetadata extends BaseFieldSchema {
|
||||
type: FieldType.LINK
|
||||
main?: boolean
|
||||
fieldName?: string
|
||||
tableId: string
|
||||
}
|
||||
export interface ManyToManyRelationshipFieldMetadata
|
||||
extends BaseRelationshipFieldMetadata {
|
||||
relationshipType: RelationshipType.MANY_TO_MANY
|
||||
through: string
|
||||
throughFrom: string
|
||||
throughTo: string
|
||||
}
|
||||
interface OneSidedRelationshipFieldMetadata {
|
||||
relationshipType: RelationshipType.ONE_TO_MANY | RelationshipType.MANY_TO_ONE
|
||||
export interface OneToManyRelationshipFieldMetadata
|
||||
extends BaseRelationshipFieldMetadata {
|
||||
relationshipType: RelationshipType.ONE_TO_MANY
|
||||
foreignKey: string
|
||||
}
|
||||
export type RelationshipFieldMetadata = BaseFieldSchema & {
|
||||
type: FieldType.LINK
|
||||
main?: boolean
|
||||
fieldName?: string
|
||||
tableId: string
|
||||
} & (ManyToManyRelationshipFieldMetadata | OneSidedRelationshipFieldMetadata)
|
||||
export interface ManyToOneRelationshipFieldMetadata
|
||||
extends BaseRelationshipFieldMetadata {
|
||||
relationshipType: RelationshipType.MANY_TO_ONE
|
||||
foreignKey: string
|
||||
}
|
||||
export type RelationshipFieldMetadata =
|
||||
| ManyToManyRelationshipFieldMetadata
|
||||
| OneToManyRelationshipFieldMetadata
|
||||
| ManyToOneRelationshipFieldMetadata
|
||||
|
||||
export interface AutoColumnFieldMetadata extends BaseFieldSchema {
|
||||
type: FieldType.AUTO
|
||||
|
@ -106,6 +117,7 @@ interface BaseFieldSchema extends UIFieldMetadata {
|
|||
externalType?: string
|
||||
constraints?: FieldConstraints
|
||||
autocolumn?: boolean
|
||||
autoReason?: AutoReason
|
||||
subtype?: string
|
||||
}
|
||||
|
||||
|
@ -113,7 +125,6 @@ interface OtherFieldMetadata extends BaseFieldSchema {
|
|||
type: Exclude<
|
||||
FieldType,
|
||||
| FieldType.DATETIME
|
||||
| FieldType.DATETIME
|
||||
| FieldType.LINK
|
||||
| FieldType.AUTO
|
||||
| FieldType.STRING
|
||||
|
|
Loading…
Reference in New Issue