diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
--- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
+++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
@@ -493,6 +493,69 @@
   Logger::log("Encryption completed successfully.");
 }
 
+auto &SQLiteQueryExecutor::getStorage() {
+  static auto storage = make_storage(
+      SQLiteQueryExecutor::sqliteFilePath,
+      make_index("messages_idx_thread_time", &Message::thread, &Message::time),
+      make_index("media_idx_container", &Media::container),
+      make_table(
+          "drafts",
+          make_column("key", &Draft::key, unique(), primary_key()),
+          make_column("text", &Draft::text)),
+      make_table(
+          "messages",
+          make_column("id", &Message::id, unique(), primary_key()),
+          make_column("local_id", &Message::local_id),
+          make_column("thread", &Message::thread),
+          make_column("user", &Message::user),
+          make_column("type", &Message::type),
+          make_column("future_type", &Message::future_type),
+          make_column("content", &Message::content),
+          make_column("time", &Message::time)),
+      make_table(
+          "olm_persist_account",
+          make_column("id", &OlmPersistAccount::id, unique(), primary_key()),
+          make_column("account_data", &OlmPersistAccount::account_data)),
+      make_table(
+          "olm_persist_sessions",
+          make_column(
+              "target_user_id",
+              &OlmPersistSession::target_user_id,
+              unique(),
+              primary_key()),
+          make_column("session_data", &OlmPersistSession::session_data)),
+      make_table(
+          "media",
+          make_column("id", &Media::id, unique(), primary_key()),
+          make_column("container", &Media::container),
+          make_column("thread", &Media::thread),
+          make_column("uri", &Media::uri),
+          make_column("type", &Media::type),
+          make_column("extras", &Media::extras)),
+      make_table(
+          "threads",
+          make_column("id", &Thread::id, unique(), primary_key()),
+          make_column("type", &Thread::type),
+          make_column("name", &Thread::name),
+          make_column("description", &Thread::description),
+          make_column("color", &Thread::color),
+          make_column("creation_time", &Thread::creation_time),
+          make_column("parent_thread_id", &Thread::parent_thread_id),
+          make_column("containing_thread_id", &Thread::containing_thread_id),
+          make_column("community", &Thread::community),
+          make_column("members", &Thread::members),
+          make_column("roles", &Thread::roles),
+          make_column("current_user", &Thread::current_user),
+          make_column("source_message_id", &Thread::source_message_id),
+          make_column("replies_count", &Thread::replies_count)),
+      make_table(
+          "metadata",
+          make_column("name", &Metadata::name, unique(), primary_key()),
+          make_column("data", &Metadata::data)));
+  storage.on_open = on_database_open;
+  return storage;
+}
+
 typedef bool ShouldBeInTransaction;
 typedef std::pair<std::function<bool(sqlite3 *)>, ShouldBeInTransaction>
     SQLiteMigration;
@@ -537,6 +600,29 @@
   version_msg << "db version: " << current_user_version << std::endl;
   Logger::log(version_msg.str());
 
+  if (current_user_version == 0) {
+    SQLiteQueryExecutor::getStorage().sync_schema();
+
+    Logger::log("Creating new database, syncing structure with ORM storage.");
+
+    auto latest_version = migrations.back().first;
+
+    std::stringstream update_version;
+    update_version << "PRAGMA user_version=" << latest_version << ";";
+    auto update_version_str = update_version.str();
+
+    char *error;
+    sqlite3_exec(db, update_version_str.c_str(), nullptr, nullptr, &error);
+
+    if (error) {
+      std::ostringstream errorStream;
+      errorStream << "Error saving database version: " << error;
+      throw std::runtime_error(errorStream.str());
+    }
+
+    return;
+  }
+
   for (const auto &[idx, migration] : migrations) {
     if (idx <= current_user_version) {
       continue;
@@ -581,69 +667,6 @@
   SQLiteQueryExecutor::encryptionKey = encryptionKey;
 }
 
-auto &SQLiteQueryExecutor::getStorage() {
-  static auto storage = make_storage(
-      SQLiteQueryExecutor::sqliteFilePath,
-      make_index("messages_idx_thread_time", &Message::thread, &Message::time),
-      make_index("media_idx_container", &Media::container),
-      make_table(
-          "drafts",
-          make_column("key", &Draft::key, unique(), primary_key()),
-          make_column("text", &Draft::text)),
-      make_table(
-          "messages",
-          make_column("id", &Message::id, unique(), primary_key()),
-          make_column("local_id", &Message::local_id),
-          make_column("thread", &Message::thread),
-          make_column("user", &Message::user),
-          make_column("type", &Message::type),
-          make_column("future_type", &Message::future_type),
-          make_column("content", &Message::content),
-          make_column("time", &Message::time)),
-      make_table(
-          "olm_persist_account",
-          make_column("id", &OlmPersistAccount::id, unique(), primary_key()),
-          make_column("account_data", &OlmPersistAccount::account_data)),
-      make_table(
-          "olm_persist_sessions",
-          make_column(
-              "target_user_id",
-              &OlmPersistSession::target_user_id,
-              unique(),
-              primary_key()),
-          make_column("session_data", &OlmPersistSession::session_data)),
-      make_table(
-          "media",
-          make_column("id", &Media::id, unique(), primary_key()),
-          make_column("container", &Media::container),
-          make_column("thread", &Media::thread),
-          make_column("uri", &Media::uri),
-          make_column("type", &Media::type),
-          make_column("extras", &Media::extras)),
-      make_table(
-          "threads",
-          make_column("id", &Thread::id, unique(), primary_key()),
-          make_column("type", &Thread::type),
-          make_column("name", &Thread::name),
-          make_column("description", &Thread::description),
-          make_column("color", &Thread::color),
-          make_column("creation_time", &Thread::creation_time),
-          make_column("parent_thread_id", &Thread::parent_thread_id),
-          make_column("containing_thread_id", &Thread::containing_thread_id),
-          make_column("community", &Thread::community),
-          make_column("members", &Thread::members),
-          make_column("roles", &Thread::roles),
-          make_column("current_user", &Thread::current_user),
-          make_column("source_message_id", &Thread::source_message_id),
-          make_column("replies_count", &Thread::replies_count)),
-      make_table(
-          "metadata",
-          make_column("name", &Metadata::name, unique(), primary_key()),
-          make_column("data", &Metadata::data)));
-  storage.on_open = on_database_open;
-  return storage;
-}
-
 void SQLiteQueryExecutor::initialize(std::string &databasePath) {
   std::call_once(SQLiteQueryExecutor::initialized, [&databasePath]() {
     SQLiteQueryExecutor::sqliteFilePath = databasePath;