From 3607030a87fe80af5e4bbabf793fe58a4be17853 Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich <landgrafhomyak@gmail.com> Date: Thu, 2 Jan 2025 02:09:27 +0300 Subject: [PATCH] Changing ForeignKey to ForeignRowReference --- .../serdha/api/v0/ddl/ColumnType.kt | 5 +- .../serdha/api/v0/ddl/ForeignKey.kt | 118 ------------------ .../serdha/api/v0/ddl/ForeignRowReference.kt | 63 ++++++++++ .../serdha/api/v0/ddl/TableCreator.kt | 68 ++-------- .../serdha/api/v0/ddl/TableUpdater.kt | 41 +++--- 5 files changed, 95 insertions(+), 200 deletions(-) delete mode 100644 src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ForeignKey.kt create mode 100644 src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ForeignRowReference.kt diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ColumnType.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ColumnType.kt index 07fdea6..ab81c80 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ColumnType.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ColumnType.kt @@ -28,6 +28,8 @@ public interface ColumnType<@Suppress("unused") RuntimeType> { public interface Builder { /** * Type of internal row id. Can't be casted to types like integers or pointers. + * @param TableUserExtension User's extension type for target table. For static type checking. + * @param table Descriptor of table whose row_id type will be obtained. */ @Suppress("INAPPLICABLE_JVM_NAME") @JvmName("ROW_ID") @@ -172,9 +174,10 @@ public interface ColumnType<@Suppress("unused") RuntimeType> { /** * Descriptor of an internal row id type for static type-checking. + * @param TargetTableUserWrapper User's extension type for target table. For static type checking. * @see ColumnType.Builder.ROW_ID */ - public interface ROW_ID : ColumnType<RowId<*>> + public interface ROW_ID<TargetTableUserWrapper: Any> : ColumnType<RowId<TargetTableUserWrapper>> /** * Descriptor of a boolean type for static type-checking. diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ForeignKey.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ForeignKey.kt deleted file mode 100644 index ede502a..0000000 --- a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ForeignKey.kt +++ /dev/null @@ -1,118 +0,0 @@ -package ru.landgrafhomyak.serdha.api.v0.ddl - -import kotlin.jvm.JvmName -import kotlin.jvm.JvmStatic - -/** - * Descriptor of a foreign key. Used for schema manipulations. - * - * @param ContainerTableUserExtension Type of [owner table's][ForeignKey.fromTable] user expression for static reporting errors when this descriptor passed to wrong table. - * @param TargetTableUserExtension Type of [target table's][ForeignKey.toTable] user expression for static reporting errors when this descriptor passed to wrong table. - */ -public interface ForeignKey<ContainerTableUserExtension : Any, TargetTableUserExtension : Any> { - /** - * Table that contains this foreign key. For debugging. - */ - @Suppress("INAPPLICABLE_JVM_NAME") - @get:JvmName("fromTable") - public val fromTable: Table<ContainerTableUserExtension, *> - - /** - * Columns in [ForeignKey.fromTable] which are used to reference row in [ForeignKey.toTable]. For debugging. - */ - @Suppress("INAPPLICABLE_JVM_NAME") - @get:JvmName("fromColumns") - public val fromColumns: List<Column<*, *, ContainerTableUserExtension>> - - /** - * Table referenced by this foreign key. For debugging. - */ - @Suppress("INAPPLICABLE_JVM_NAME") - @get:JvmName("toTable") - public val toTable: Table<TargetTableUserExtension, *> - - /** - * Columns in [ForeignKey.toTable] that are identifying row(s). For debugging. - */ - @Suppress("INAPPLICABLE_JVM_NAME") - @get:JvmName("toColumns") - public val toColumns: List<Column<*, *, TargetTableUserExtension>> - - /** - * Enum of actions to do when value in any of [ForeignKey.toColumns] in referenced row is changed. - */ - public enum class OnUpdateAction { - /** - * Don't perform any actions in [ForeignKey.fromColumns]. May break reference. - */ - NO_ACTION, - - /** - * Forbids changing values in [ForeignKey.toColumns] if there is at least one reference from [ForeignKey.fromTable]. - */ - RESTRICT, - - /** - * Sets `null` value to all columns in [ForeignKey.fromColumns] if any cell in [ForeignKey.toColumns] in referenced row was changed. - * - * All of [ForeignKey.fromColumns] must be nullable. - */ - SET_NULL, - - /** - * Sets default value to all columns in [ForeignKey.fromColumns] if any cell in [ForeignKey.toColumns] in referenced row was changed. - * - * All of [ForeignKey.fromColumns] must have [DefaultConstraint]. - */ - SET_DEFAULT, - - /** - * Reflects all changes from [ForeignKey.toColumns] to [ForeignKey.fromColumns]. - */ - CASCADE - } - - /** - * Enum of actions to do when referenced row in [ForeignKey.toTable] deleted. - */ - public enum class OnDeleteAction { - /** - * Don't perform any actions in [ForeignKey.fromColumns]. Breaks reference. - */ - NO_ACTION, - - /** - * Forbids deleting row in [ForeignKey.toTable] if there is at least one reference from [ForeignKey.fromTable]. - */ - RESTRICT, - - /** - * Sets `null` value to all columns in [ForeignKey.fromColumns] if referenced row was deleted. - * - * All of [ForeignKey.fromColumns] must be nullable. - */ - SET_NULL, - - /** - * Sets default value to all columns in [ForeignKey.fromColumns] if referenced row was deleted. - * - * All of [ForeignKey.fromColumns] must have [DefaultConstraint]. - */ - SET_DEFAULT, - - /** - * Deletes all rows in [ForeignKey.fromTable] that are referencing deleted row in [ForeignKey.toTable]. - */ - CASCADE - } - - public companion object { - @JvmStatic - public val DEFAULT_ON_UPDATE_ACTION: OnUpdateAction - inline get() = OnUpdateAction.CASCADE - - @JvmStatic - public val DEFAULT_ON_DELETE_ACTION: OnDeleteAction - inline get() = OnDeleteAction.RESTRICT - } -} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ForeignRowReference.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ForeignRowReference.kt new file mode 100644 index 0000000..a7d72a7 --- /dev/null +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ForeignRowReference.kt @@ -0,0 +1,63 @@ +package ru.landgrafhomyak.serdha.api.v0.ddl + +import kotlin.jvm.JvmName +import kotlin.jvm.JvmStatic + +/** + * Descriptor of a reference to row in another table (== foreign key to `INTEGER PRIMARY KEY AUTOINCREMENT`). Used for schema manipulations. + * + * @param ContainerTableUserExtension Type of [owner table's][ForeignRowReference.fromTable] user expression for static reporting errors when this descriptor passed to wrong table. + * @param TargetTableUserExtension Type of [target table's][ForeignRowReference.toTable] user expression for static reporting errors when this descriptor passed to wrong table. + */ +public interface ForeignRowReference<ContainerTableUserExtension : Any, TargetTableUserExtension : Any> { + /** + * Table that contains references. For debugging. + */ + @Suppress("INAPPLICABLE_JVM_NAME") + @get:JvmName("fromTable") + public val fromTable: Table<ContainerTableUserExtension, *> + + /** + * Column in [ForeignRowReference.fromTable] which references row in [ForeignRowReference.toTable]. For debugging. + */ + @Suppress("INAPPLICABLE_JVM_NAME") + @get:JvmName("fromColumn") + public val fromColumn: Column<RowId<TargetTableUserExtension>, ColumnType.ROW_ID<TargetTableUserExtension>, ContainerTableUserExtension> + + /** + * Table referenced by this foreign key. For debugging. + */ + @Suppress("INAPPLICABLE_JVM_NAME") + @get:JvmName("toTable") + public val toTable: Table<TargetTableUserExtension, *> + + /** + * Row id column in [ForeignRowReference.toTable]. For debugging. + */ + @Suppress("INAPPLICABLE_JVM_NAME") + @get:JvmName("toColumn") + public val toColumn: Column<RowId<TargetTableUserExtension>, ColumnType.ROW_ID<TargetTableUserExtension>, TargetTableUserExtension> + + + /** + * Enum of actions to do when referenced row in [ForeignRowReference.toTable] deleted. + */ + public enum class OnDeleteAction { + /** + * Forbids deleting row in [ForeignRowReference.toTable] if there is at least one reference from [ForeignRowReference.fromTable]. + */ + RESTRICT, + + /** + * Replaces all references to deleted row in [ForeignRowReference.fromColumn] with `null`. + * + * Type of [ForeignRowReference.fromColumn] must be [nullable][ColumnType.Builder.nullableOf]. + */ + SET_NULL, + + /** + * Deletes all rows in [ForeignRowReference.fromTable] that are referencing deleted row in [ForeignRowReference.toTable]. + */ + CASCADE + } +} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/TableCreator.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/TableCreator.kt index 8644598..5d51bee 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/TableCreator.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/TableCreator.kt @@ -1,7 +1,6 @@ package ru.landgrafhomyak.serdha.api.v0.ddl import ru.landgrafhomyak.serdha.api.v0.Expression -import ru.landgrafhomyak.serdha.api.v0.LowLevelApi public interface TableCreator<TableUserExtension : Any> { public val expressionBuilder: Expression.Builder<TableUserExtension> @@ -22,64 +21,15 @@ public interface TableCreator<TableUserExtension : Any> { @Suppress("PropertyName") public val rowId_uniqueConstraint: UniqueIndex<TableUserExtension> - @Suppress("FunctionName") - @LowLevelApi - public fun <TargetTableUserWrapper : Any> _foreignKey( - fromColumns: Array<Column<*, *, TableUserExtension>>, - toTable: Table<TargetTableUserWrapper, *>, - toColumns: Array<Column<*, *, TargetTableUserWrapper>>, - onUpdate: ForeignKey.OnUpdateAction, - onDelete: ForeignKey.OnDeleteAction, - ): ForeignKey<TableUserExtension, TargetTableUserWrapper> + public fun <TargetTableUserWrapper : Any> selfRowReference( + onDelete: ForeignRowReference.OnDeleteAction, + toColumn: Column<RowId<TargetTableUserWrapper>, ColumnType.ROW_ID<TargetTableUserWrapper>, TargetTableUserWrapper>, + ): ForeignRowReference<TableUserExtension, TableUserExtension> - @OptIn(LowLevelApi::class) - public fun <TargetTableUserWrapper : Any, ColumnType1 : ColumnType<*>> foreignKey( - fromColumn: Column<*, ColumnType1, TableUserExtension>, + public fun <TargetTableUserWrapper : Any> foreignRowReference( + fromColumn: Column<RowId<TargetTableUserWrapper>, ColumnType.ROW_ID<TargetTableUserWrapper>, TableUserExtension>, toTable: Table<TargetTableUserWrapper, *>, - toColumn: Column<*, ColumnType1, TargetTableUserWrapper>, - onUpdate: ForeignKey.OnUpdateAction, - onDelete: ForeignKey.OnDeleteAction, - ): ForeignKey<TableUserExtension, TargetTableUserWrapper> = this._foreignKey( - fromColumns = arrayOf(fromColumn), - toTable = toTable, - toColumns = arrayOf(toColumn), - onUpdate = onUpdate, - onDelete = onDelete - ) - - @OptIn(LowLevelApi::class) - public fun <TargetTableUserWrapper : Any, ColumnType1 : ColumnType<*>, ColumnType2 : ColumnType<*>> foreignKey( - fromColumn1: Column<*, ColumnType1, TableUserExtension>, - fromColumn2: Column<*, ColumnType2, TableUserExtension>, - toTable: Table<TargetTableUserWrapper, *>, - toColumn1: Column<*, ColumnType1, TargetTableUserWrapper>, - toColumn2: Column<*, ColumnType2, TargetTableUserWrapper>, - onUpdate: ForeignKey.OnUpdateAction, - onDelete: ForeignKey.OnDeleteAction, - ): ForeignKey<TableUserExtension, TargetTableUserWrapper> = this._foreignKey( - fromColumns = arrayOf(fromColumn1, fromColumn2), - toTable = toTable, - toColumns = arrayOf(toColumn1, toColumn2), - onUpdate = onUpdate, - onDelete = onDelete - ) - - @OptIn(LowLevelApi::class) - public fun <TargetTableUserWrapper : Any, ColumnType1 : ColumnType<*>, ColumnType2 : ColumnType<*>, ColumnType3 : ColumnType<*>> foreignKey( - fromColumn1: Column<*, ColumnType1, TableUserExtension>, - fromColumn2: Column<*, ColumnType2, TableUserExtension>, - fromColumn3: Column<*, ColumnType3, TableUserExtension>, - toTable: Table<TargetTableUserWrapper, *>, - toColumn1: Column<*, ColumnType1, TargetTableUserWrapper>, - toColumn2: Column<*, ColumnType2, TargetTableUserWrapper>, - toColumn3: Column<*, ColumnType3, TargetTableUserWrapper>, - onUpdate: ForeignKey.OnUpdateAction, - onDelete: ForeignKey.OnDeleteAction, - ): ForeignKey<TableUserExtension, TargetTableUserWrapper> = this._foreignKey( - fromColumns = arrayOf(fromColumn1, fromColumn2, fromColumn3), - toTable = toTable, - toColumns = arrayOf(toColumn1, toColumn2, toColumn3), - onUpdate = onUpdate, - onDelete = onDelete - ) + toColumn: Column<RowId<TargetTableUserWrapper>, ColumnType.ROW_ID<TargetTableUserWrapper>, TargetTableUserWrapper>, + onDelete: ForeignRowReference.OnDeleteAction, + ): ForeignRowReference<TableUserExtension, TargetTableUserWrapper> } \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/TableUpdater.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/TableUpdater.kt index edb67b0..0e612f8 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/TableUpdater.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/TableUpdater.kt @@ -30,31 +30,28 @@ public interface TableUpdater<TableNewUserExtension : Any, TableOldUserExtension public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType>> changeDefaultValue(c: Column<RuntimeType, DatabaseType, TableNewUserExtension>, d: DefaultConstraint<*, *, TableOldUserExtension>): DefaultConstraint<RuntimeType, DatabaseType, TableNewUserExtension> public fun deleteDefaultValue(i: DefaultConstraint<*, *, TableOldUserExtension>) - public fun <TargetTableOldUserWrapper : Any, TargetTableNewUserWrapper : Any> keepForeignKeyToUpdatedTable( - fk: ForeignKey<TableOldUserExtension, TargetTableOldUserWrapper>, + public fun <TargetTableUserWrapper : Any> keepForeignRowReference( + frr: ForeignRowReference<TableOldUserExtension, TargetTableUserWrapper>, + onDelete: ForeignRowReference.OnDeleteAction? = null + ): ForeignRowReference<TableNewUserExtension, TargetTableUserWrapper> + + public fun <TargetTableOldUserWrapper : Any, TargetTableNewUserWrapper : Any> keepForeignRowReferenceToUpdatedTable( + frr: ForeignRowReference<TableOldUserExtension, TargetTableOldUserWrapper>, updatedTable: Table<TargetTableNewUserWrapper, TargetTableOldUserWrapper>, - onUpdate: ForeignKey.OnUpdateAction? = null, - onDelete: ForeignKey.OnDeleteAction? = null - ): ForeignKey<TableNewUserExtension, TargetTableNewUserWrapper> + onDelete: ForeignRowReference.OnDeleteAction? = null + ): ForeignRowReference<TableNewUserExtension, TargetTableNewUserWrapper> - public fun <TargetTableUserWrapper : Any> keepForeignKey( - fk: ForeignKey<TableOldUserExtension, TargetTableUserWrapper>, - onUpdate: ForeignKey.OnUpdateAction? = null, - onDelete: ForeignKey.OnDeleteAction? = null - ): ForeignKey<TableNewUserExtension, TargetTableUserWrapper> + public fun <TargetTableUserWrapper : Any> renameAndKeepForeignRowReference( + frr: ForeignRowReference<TableOldUserExtension, TargetTableUserWrapper>, + onDelete: ForeignRowReference.OnDeleteAction? = null + ): ForeignRowReference<TableNewUserExtension, TargetTableUserWrapper> - public fun <TargetTableOldUserWrapper : Any, TargetTableNewUserWrapper : Any> renameAndKeepForeignKeyToUpdatedTable( - fk: ForeignKey<TableOldUserExtension, TargetTableOldUserWrapper>, + + public fun <TargetTableOldUserWrapper : Any, TargetTableNewUserWrapper : Any> renameAndKeepForeignRowReferenceToUpdatedTable( + frr: ForeignRowReference<TableOldUserExtension, TargetTableOldUserWrapper>, updatedTable: Table<TargetTableNewUserWrapper, TargetTableOldUserWrapper>, - onUpdate: ForeignKey.OnUpdateAction? = null, - onDelete: ForeignKey.OnDeleteAction? = null - ): ForeignKey<TableNewUserExtension, TargetTableNewUserWrapper> + onDelete: ForeignRowReference.OnDeleteAction? = null + ): ForeignRowReference<TableNewUserExtension, TargetTableNewUserWrapper> - public fun <TargetTableUserWrapper : Any> renameAndKeepForeignKey( - fk: ForeignKey<TableOldUserExtension, TargetTableUserWrapper>, - onUpdate: ForeignKey.OnUpdateAction? = null, - onDelete: ForeignKey.OnDeleteAction? = null - ): ForeignKey<TableNewUserExtension, TargetTableUserWrapper> - - public fun deleteForeignKey(fk: ForeignKey<TableOldUserExtension, *>) + public fun deleteForeignRowReference(frr: ForeignRowReference<TableOldUserExtension, *>) } \ No newline at end of file