diff --git a/build.gradle.kts b/build.gradle.kts index fd779ca..982f303 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,7 +19,7 @@ buildscript { } group = "ru.landgrafhomyak.serdha" -version = "v1.0" +version = "v0.1" repositories { mavenCentral() diff --git a/settings.gradle.kts b/settings.gradle.kts index c0518d0..5d31846 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,5 @@ plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } -rootProject.name = "serdha-api" +rootProject.name = "serdha-api-v0" diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/Module.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/Module.kt new file mode 100644 index 0000000..07164c6 --- /dev/null +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/Module.kt @@ -0,0 +1,7 @@ +package ru.landgrafhomyak.serdha.api.v0.ddl + +public interface Module<W : Any> { + public val wrapper: W + + public val versionKey: String +} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ModuleModifyingRound.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ModuleModifyingRound.kt new file mode 100644 index 0000000..4d4bccb --- /dev/null +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ModuleModifyingRound.kt @@ -0,0 +1,52 @@ +package ru.landgrafhomyak.serdha.api.v0.ddl + +import ru.landgrafhomyak.serdha.api.v0.dml.Insert +import ru.landgrafhomyak.serdha.api.v0.dml.InsertCreator +import ru.landgrafhomyak.serdha.api.v0.dml.Select +import ru.landgrafhomyak.serdha.api.v0.dml.SelectCreator +import ru.landgrafhomyak.serdha.api.v0.dml.Update +import ru.landgrafhomyak.serdha.api.v0.dml.UpdateCreator + +public interface ModuleModifyingRound { + public fun <TableUserWrapper : Any> createTable( + namespace: Namespace, + name: String, + initializer: (TableCreator<TableUserWrapper>) -> TableUserWrapper + ): Table<TableUserWrapper, Nothing> + + public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> updateTable( + oldTable: Table<TableOldUserWrapper, *>, + initializer: (TableUpdater<TableNewUserWrapper, TableOldUserWrapper>) -> TableNewUserWrapper + ): Table<TableNewUserWrapper, TableOldUserWrapper> + + public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> renameTable( + table: Table<TableNewUserWrapper, TableOldUserWrapper>, + newName: String + ): Table<TableNewUserWrapper, TableOldUserWrapper> + + public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> renameTable( + table: Table<TableNewUserWrapper, TableOldUserWrapper>, + newNamespace: Namespace, + newName: String + ): Table<TableNewUserWrapper, TableOldUserWrapper> + + public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> updateAndRenameTable( + table: Table<TableOldUserWrapper, *>, + newName: String, + initializer: (TableUpdater<TableNewUserWrapper, TableOldUserWrapper>) -> TableNewUserWrapper + ): Table<TableNewUserWrapper, TableOldUserWrapper> + + public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> updateAndRenameTable( + table: Table<TableNewUserWrapper, TableOldUserWrapper>, + newNamespace: Namespace, + newName: String, + initializer: (TableUpdater<TableNewUserWrapper, TableOldUserWrapper>) -> TableNewUserWrapper + ): Table<TableNewUserWrapper, TableOldUserWrapper> + + public fun <QueryUserWrapper : Any> createSelect(initializer: (SelectCreator<QueryUserWrapper>) -> QueryUserWrapper): Select<QueryUserWrapper> + public fun <TableUserWrapper : Any, QueryUserWrapper : Any> createInsert(table: Table<TableUserWrapper, *>, initializer: (InsertCreator<TableUserWrapper, QueryUserWrapper>) -> QueryUserWrapper): Insert<QueryUserWrapper> + public fun <TableUserWrapper : Any, QueryUserWrapper : Any> createUpdate(table: Table<TableUserWrapper, *>, initializer: (UpdateCreator<TableUserWrapper, QueryUserWrapper>) -> QueryUserWrapper): Update<QueryUserWrapper> + + public fun <W : Any> substituteModule(rootNs: Namespace, template: ModuleTemplate<W>): Module<W> + public fun <W : Any> upgradeModule(oldModule: Module<*>, rootNs: Namespace, template: ModuleTemplate<W>): Module<W> +} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ModuleTemplate.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ModuleTemplate.kt new file mode 100644 index 0000000..cba1ba6 --- /dev/null +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/ModuleTemplate.kt @@ -0,0 +1,10 @@ +package ru.landgrafhomyak.serdha.api.v0.ddl + +public interface ModuleTemplate<W : Any> { + public fun <NW : Any> modify( + newVersionKey: String, + updater: (oldModule: ModuleTemplate<W>, rootNs: Namespace, updater: ModuleModifyingRound) -> NW + ): ModuleTemplate<NW> + + public val versionKey: String +} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/Namespace.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/Namespace.kt new file mode 100644 index 0000000..af5011f --- /dev/null +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/ddl/Namespace.kt @@ -0,0 +1,10 @@ +package ru.landgrafhomyak.serdha.api.v0.ddl + +public interface Namespace { + @Suppress("SpellCheckingInspection") + public fun subnamespace(name: String): Namespace + + public val name: String + + public val path: List<String> +} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/ResultSet.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/Row.kt similarity index 95% rename from src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/ResultSet.kt rename to src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/Row.kt index d02007a..c6ac5fe 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/ResultSet.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/Row.kt @@ -2,7 +2,7 @@ package ru.landgrafhomyak.serdha.api.v0.runtime import ru.landgrafhomyak.serdha.api.v0.ddl.Column -public interface ResultSet<QueryUserWrapper : Any> { +public interface Row<QueryUserWrapper : Any> { public operator fun <RuntimeType> get(c: Column<RuntimeType, *, QueryUserWrapper>): RuntimeType public operator fun get(c: Column<Byte, *, QueryUserWrapper>): Byte = this.get<Byte>(c) diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/Database.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/SynchronizedDatabase.kt similarity index 70% rename from src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/Database.kt rename to src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/SynchronizedDatabase.kt index 852051a..98e71a7 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/Database.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/SynchronizedDatabase.kt @@ -1,8 +1,9 @@ package ru.landgrafhomyak.serdha.api.v0.runtime import ru.landgrafhomyak.serdha.api.v0.LowLevelApi +import ru.landgrafhomyak.serdha.api.v0.ddl.Module -public interface Database { +public interface SynchronizedDatabase<W : Any> : Module<W> { @Suppress("FunctionName") @LowLevelApi public suspend fun _startTransaction(): Transaction diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/Synchronizer.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/Synchronizer.kt deleted file mode 100644 index 8fd5b06..0000000 --- a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/Synchronizer.kt +++ /dev/null @@ -1,19 +0,0 @@ -package ru.landgrafhomyak.serdha.api.v0.runtime - -import ru.landgrafhomyak.serdha.api.v0.ddl.Table -import ru.landgrafhomyak.serdha.api.v0.ddl.TableCreator -import ru.landgrafhomyak.serdha.api.v0.ddl.TableUpdater -import ru.landgrafhomyak.serdha.api.v0.dml.Insert -import ru.landgrafhomyak.serdha.api.v0.dml.InsertCreator -import ru.landgrafhomyak.serdha.api.v0.dml.Select -import ru.landgrafhomyak.serdha.api.v0.dml.SelectCreator -import ru.landgrafhomyak.serdha.api.v0.dml.Update -import ru.landgrafhomyak.serdha.api.v0.dml.UpdateCreator - -public interface Synchronizer { - public fun <TableUserWrapper : Any> createTable(initializer: (TableCreator<TableUserWrapper>) -> TableUserWrapper): Table<TableUserWrapper, Nothing> - public fun <TableOldUserWrapper : Any, TableNewUserWrapper : Any> updateTable(oldTable: Table<TableOldUserWrapper, *>, initializer: (TableUpdater<TableNewUserWrapper, TableOldUserWrapper>) -> TableNewUserWrapper): Table<TableNewUserWrapper, TableOldUserWrapper> - public fun <QueryUserWrapper : Any> createSelect(initializer: (SelectCreator<QueryUserWrapper>) -> QueryUserWrapper): Select<QueryUserWrapper> - public fun <TableUserWrapper : Any, QueryUserWrapper : Any> createInsert(table: Table<TableUserWrapper, *>, initializer: (InsertCreator<TableUserWrapper, QueryUserWrapper>) -> QueryUserWrapper): Insert<QueryUserWrapper> - public fun <TableUserWrapper : Any, QueryUserWrapper : Any> createUpdate(table: Table<TableUserWrapper, *>, initializer: (UpdateCreator<TableUserWrapper, QueryUserWrapper>) -> QueryUserWrapper): Update<QueryUserWrapper> -} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/UnsynchronizedDatabase.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/UnsynchronizedDatabase.kt new file mode 100644 index 0000000..ac86127 --- /dev/null +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/UnsynchronizedDatabase.kt @@ -0,0 +1,12 @@ +package ru.landgrafhomyak.serdha.api.v0.runtime + +import ru.landgrafhomyak.serdha.api.v0.ddl.ModuleModifyingRound +import ru.landgrafhomyak.serdha.api.v0.ddl.ModuleTemplate +import ru.landgrafhomyak.serdha.api.v0.ddl.Namespace + +@Suppress("SpellCheckingInspection") +public interface UnsynchronizedDatabase { + public fun <W : Any> createModule(initialVersionKey: String, content: (rootNs: Namespace, updater: ModuleModifyingRound) -> W): ModuleTemplate<W> + + public suspend fun <W : Any> synchronize(conent: ModuleTemplate<W>): SynchronizedDatabase<W> +} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/_ResultSet.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/_ResultSet.kt index 2becc7d..7328dd3 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/_ResultSet.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/_ResultSet.kt @@ -4,7 +4,7 @@ import ru.landgrafhomyak.serdha.api.v0.LowLevelApi @Suppress("ClassName") @LowLevelApi -public interface _ResultSet<QueryUserWrapper : Any> : ResultSet<QueryUserWrapper> { +public interface _ResultSet<QueryUserWrapper : Any> : Row<QueryUserWrapper> { @Suppress("FunctionName") @LowLevelApi public suspend fun _next(): Boolean diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/transaction_methods.kt b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/transaction_methods.kt index 5c47cd2..d62f3be 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/transaction_methods.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/serdha/api/v0/runtime/transaction_methods.kt @@ -90,7 +90,7 @@ internal suspend inline fun <Q : Any, R> _wrapWithLambdasSingleOrNull( queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>, parameters: (ParametersSetter<Q>) -> Unit, hasReturning: Boolean, - returning: (ResultSet<Q>) -> R, + returning: (Row<Q>) -> R, queryWithoutErrorMessage: String ): R? { contract { @@ -123,7 +123,7 @@ internal suspend inline fun <Q : Any> _wrapWithLambdasIterate( queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>, parameters: (ParametersSetter<Q>) -> Unit, hasReturning: Boolean, - returning: (ResultSet<Q>) -> Unit, + returning: (Row<Q>) -> Unit, queryWithoutErrorMessage: String ) { contract { @@ -143,7 +143,7 @@ internal suspend inline fun <Q : Any, R> _wrapWithLambdasMap( queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>, parameters: (ParametersSetter<Q>) -> Unit, hasReturning: Boolean, - returning: (ResultSet<Q>) -> R, + returning: (Row<Q>) -> R, queryWithoutErrorMessage: String ): List<R> { contract { @@ -170,7 +170,7 @@ internal suspend inline fun <Q : Any, R> _wrapWithLambdasMap( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectSingleOrNull( compiledQuery: Select<QueryUserWrapper>, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {}, - rowsConsumer: (ResultSet<QueryUserWrapper>) -> R + rowsConsumer: (Row<QueryUserWrapper>) -> R ): R? { contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) @@ -190,7 +190,7 @@ public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectSingleOr public suspend inline fun <QueryUserWrapper : Any> Transaction.selectThenIterate( compiledQuery: Select<QueryUserWrapper>, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, - rowsConsumer: (ResultSet<QueryUserWrapper>) -> Unit + rowsConsumer: (Row<QueryUserWrapper>) -> Unit ) { contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) @@ -210,7 +210,7 @@ public suspend inline fun <QueryUserWrapper : Any> Transaction.selectThenIterate public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectThenMap( compiledQuery: Select<QueryUserWrapper>, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, - rowsConsumer: (ResultSet<QueryUserWrapper>) -> R + rowsConsumer: (Row<QueryUserWrapper>) -> R ): List<R> { contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) @@ -249,7 +249,7 @@ public suspend inline fun <QueryUserWrapper : Any> Transaction.insert( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturningSingleOrNull( compiledQuery: Insert<QueryUserWrapper>, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {}, - rowsConsumer: (ResultSet<QueryUserWrapper>) -> R + rowsConsumer: (Row<QueryUserWrapper>) -> R ): R? { contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) @@ -269,7 +269,7 @@ public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturnin public suspend inline fun <QueryUserWrapper : Any> Transaction.insertReturningIterate( compiledQuery: Insert<QueryUserWrapper>, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, - rowsConsumer: (ResultSet<QueryUserWrapper>) -> Unit + rowsConsumer: (Row<QueryUserWrapper>) -> Unit ) { contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) @@ -289,7 +289,7 @@ public suspend inline fun <QueryUserWrapper : Any> Transaction.insertReturningIt public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturningMap( compiledQuery: Insert<QueryUserWrapper>, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, - rowsConsumer: (ResultSet<QueryUserWrapper>) -> R + rowsConsumer: (Row<QueryUserWrapper>) -> R ): List<R> { contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) @@ -327,7 +327,7 @@ public suspend inline fun <QueryUserWrapper : Any> Transaction.update( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturningSingleOrNull( compiledQuery: Update<QueryUserWrapper>, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {}, - rowsConsumer: (ResultSet<QueryUserWrapper>) -> R + rowsConsumer: (Row<QueryUserWrapper>) -> R ): R? { contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) @@ -347,7 +347,7 @@ public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturnin public suspend inline fun <QueryUserWrapper : Any> Transaction.updateReturningIterate( compiledQuery: Update<QueryUserWrapper>, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, - rowsConsumer: (ResultSet<QueryUserWrapper>) -> Unit + rowsConsumer: (Row<QueryUserWrapper>) -> Unit ) { contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) @@ -367,7 +367,7 @@ public suspend inline fun <QueryUserWrapper : Any> Transaction.updateReturningIt public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturningMap( compiledQuery: Update<QueryUserWrapper>, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, - rowsConsumer: (ResultSet<QueryUserWrapper>) -> R + rowsConsumer: (Row<QueryUserWrapper>) -> R ): List<R> { contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) @@ -383,3 +383,14 @@ public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturnin ) } +@OptIn(LowLevelApi::class) +public suspend fun <R> SynchronizedDatabase<*>.transaction(body: (Transaction) -> R):R { + contract { + callsInPlace(body, InvocationKind.EXACTLY_ONCE) + } + + val tr = this._startTransaction() + _safeAutoClose(onAbort = { tr.rollback(); tr._assertTransactionFinishedAndReleaseResources() }, onSuccess = { tr._assertTransactionFinishedAndReleaseResources() }) { + return@transaction body(tr) + } +} \ No newline at end of file diff --git a/src/jvmMain/java/Test.java b/src/jvmMain/java/Test.java deleted file mode 100644 index 084dda7..0000000 --- a/src/jvmMain/java/Test.java +++ /dev/null @@ -1,27 +0,0 @@ -import org.jetbrains.annotations.NotNull; -import ru.landgrafhomyak.serdha.api.v0.Column; -import ru.landgrafhomyak.serdha.api.v0.ColumnType; -import ru.landgrafhomyak.serdha.api.v0.ForeignKey; -import ru.landgrafhomyak.serdha.api.v0.Index; -import ru.landgrafhomyak.serdha.api.v0.Table; -import ru.landgrafhomyak.serdha.api.v0.TableCreator; - -public class Test implements TableCreator { - @NotNull - @Override - public Column column(@NotNull String name, @NotNull ColumnType type) { - return null; - } - - @NotNull - @Override - public Index index(@NotNull String name, @NotNull Column[] columns) { - return null; - } - - @NotNull - @Override - public ForeignKey foreignKey(@NotNull Column fromColumn, @NotNull Table toTable, @NotNull Column toColumn, @NotNull ForeignKey.OnUpdateAction onUpdate, @NotNull ForeignKey.OnDeleteAction onDelete) { - this.foreignKey(null, null, null); - } -}