Modules, namespaces and top-level interfaces

This commit is contained in:
Andrew Golovashevich 2024-11-24 19:40:46 +03:00
parent b3a6b7f52c
commit c6172bfd78
13 changed files with 120 additions and 63 deletions

View File

@ -19,7 +19,7 @@ buildscript {
} }
group = "ru.landgrafhomyak.serdha" group = "ru.landgrafhomyak.serdha"
version = "v1.0" version = "v0.1"
repositories { repositories {
mavenCentral() mavenCentral()

View File

@ -1,5 +1,5 @@
plugins { plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
} }
rootProject.name = "serdha-api" rootProject.name = "serdha-api-v0"

View File

@ -0,0 +1,7 @@
package ru.landgrafhomyak.serdha.api.v0.ddl
public interface Module<W : Any> {
public val wrapper: W
public val versionKey: String
}

View File

@ -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>
}

View File

@ -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
}

View File

@ -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>
}

View File

@ -2,7 +2,7 @@ package ru.landgrafhomyak.serdha.api.v0.runtime
import ru.landgrafhomyak.serdha.api.v0.ddl.Column 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 <RuntimeType> get(c: Column<RuntimeType, *, QueryUserWrapper>): RuntimeType
public operator fun get(c: Column<Byte, *, QueryUserWrapper>): Byte = this.get<Byte>(c) public operator fun get(c: Column<Byte, *, QueryUserWrapper>): Byte = this.get<Byte>(c)

View File

@ -1,8 +1,9 @@
package ru.landgrafhomyak.serdha.api.v0.runtime package ru.landgrafhomyak.serdha.api.v0.runtime
import ru.landgrafhomyak.serdha.api.v0.LowLevelApi 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") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public suspend fun _startTransaction(): Transaction public suspend fun _startTransaction(): Transaction

View File

@ -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>
}

View File

@ -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>
}

View File

@ -4,7 +4,7 @@ import ru.landgrafhomyak.serdha.api.v0.LowLevelApi
@Suppress("ClassName") @Suppress("ClassName")
@LowLevelApi @LowLevelApi
public interface _ResultSet<QueryUserWrapper : Any> : ResultSet<QueryUserWrapper> { public interface _ResultSet<QueryUserWrapper : Any> : Row<QueryUserWrapper> {
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public suspend fun _next(): Boolean public suspend fun _next(): Boolean

View File

@ -90,7 +90,7 @@ internal suspend inline fun <Q : Any, R> _wrapWithLambdasSingleOrNull(
queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>, queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>,
parameters: (ParametersSetter<Q>) -> Unit, parameters: (ParametersSetter<Q>) -> Unit,
hasReturning: Boolean, hasReturning: Boolean,
returning: (ResultSet<Q>) -> R, returning: (Row<Q>) -> R,
queryWithoutErrorMessage: String queryWithoutErrorMessage: String
): R? { ): R? {
contract { contract {
@ -123,7 +123,7 @@ internal suspend inline fun <Q : Any> _wrapWithLambdasIterate(
queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>, queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>,
parameters: (ParametersSetter<Q>) -> Unit, parameters: (ParametersSetter<Q>) -> Unit,
hasReturning: Boolean, hasReturning: Boolean,
returning: (ResultSet<Q>) -> Unit, returning: (Row<Q>) -> Unit,
queryWithoutErrorMessage: String queryWithoutErrorMessage: String
) { ) {
contract { contract {
@ -143,7 +143,7 @@ internal suspend inline fun <Q : Any, R> _wrapWithLambdasMap(
queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>, queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>,
parameters: (ParametersSetter<Q>) -> Unit, parameters: (ParametersSetter<Q>) -> Unit,
hasReturning: Boolean, hasReturning: Boolean,
returning: (ResultSet<Q>) -> R, returning: (Row<Q>) -> R,
queryWithoutErrorMessage: String queryWithoutErrorMessage: String
): List<R> { ): List<R> {
contract { contract {
@ -170,7 +170,7 @@ internal suspend inline fun <Q : Any, R> _wrapWithLambdasMap(
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectSingleOrNull( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectSingleOrNull(
compiledQuery: Select<QueryUserWrapper>, compiledQuery: Select<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {}, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowsConsumer: (ResultSet<QueryUserWrapper>) -> R rowsConsumer: (Row<QueryUserWrapper>) -> R
): R? { ): R? {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) 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( public suspend inline fun <QueryUserWrapper : Any> Transaction.selectThenIterate(
compiledQuery: Select<QueryUserWrapper>, compiledQuery: Select<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (ResultSet<QueryUserWrapper>) -> Unit rowsConsumer: (Row<QueryUserWrapper>) -> Unit
) { ) {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) 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( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectThenMap(
compiledQuery: Select<QueryUserWrapper>, compiledQuery: Select<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (ResultSet<QueryUserWrapper>) -> R rowsConsumer: (Row<QueryUserWrapper>) -> R
): List<R> { ): List<R> {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) 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( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturningSingleOrNull(
compiledQuery: Insert<QueryUserWrapper>, compiledQuery: Insert<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {}, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowsConsumer: (ResultSet<QueryUserWrapper>) -> R rowsConsumer: (Row<QueryUserWrapper>) -> R
): R? { ): R? {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) 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( public suspend inline fun <QueryUserWrapper : Any> Transaction.insertReturningIterate(
compiledQuery: Insert<QueryUserWrapper>, compiledQuery: Insert<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (ResultSet<QueryUserWrapper>) -> Unit rowsConsumer: (Row<QueryUserWrapper>) -> Unit
) { ) {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) 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( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturningMap(
compiledQuery: Insert<QueryUserWrapper>, compiledQuery: Insert<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (ResultSet<QueryUserWrapper>) -> R rowsConsumer: (Row<QueryUserWrapper>) -> R
): List<R> { ): List<R> {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) 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( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturningSingleOrNull(
compiledQuery: Update<QueryUserWrapper>, compiledQuery: Update<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {}, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowsConsumer: (ResultSet<QueryUserWrapper>) -> R rowsConsumer: (Row<QueryUserWrapper>) -> R
): R? { ): R? {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) 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( public suspend inline fun <QueryUserWrapper : Any> Transaction.updateReturningIterate(
compiledQuery: Update<QueryUserWrapper>, compiledQuery: Update<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (ResultSet<QueryUserWrapper>) -> Unit rowsConsumer: (Row<QueryUserWrapper>) -> Unit
) { ) {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) 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( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturningMap(
compiledQuery: Update<QueryUserWrapper>, compiledQuery: Update<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (ResultSet<QueryUserWrapper>) -> R rowsConsumer: (Row<QueryUserWrapper>) -> R
): List<R> { ): List<R> {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) 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)
}
}

View File

@ -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);
}
}