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