Add sqlite3 backend hack for android
authorsapier <Sapier at GMX dot net>
Mon, 7 Jul 2014 20:57:11 +0000 (22:57 +0200)
committersapier <Sapier at GMX dot net>
Sat, 16 Aug 2014 10:28:07 +0000 (12:28 +0200)
src/database-sqlite3.cpp
src/database-sqlite3.h
src/subgame.cpp

index 7e1767a8fb0b7bee2d3a6765b41964a7450a06c0..4d48796fc7d38995eea86da92d46ab474981a96a 100644 (file)
@@ -120,13 +120,24 @@ void Database_SQLite3::verifyDatabase() {
                errorstream<<"SQLite3 read statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
                throw FileNotGoodException("Cannot prepare read statement");
        }
-
-       d = sqlite3_prepare(m_database, "REPLACE INTO `blocks` VALUES(?, ?)", -1, &m_database_write, NULL);
+#ifdef __ANDROID__
+       d = sqlite3_prepare(m_database, "INSERT INTO `blocks` VALUES(?, ?);", -1, &m_database_write, NULL);
+#else
+       d = sqlite3_prepare(m_database, "REPLACE INTO `blocks` VALUES(?, ?);", -1, &m_database_write, NULL);
+#endif
        if(d != SQLITE_OK) {
                errorstream<<"SQLite3 write statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
                throw FileNotGoodException("Cannot prepare write statement");
        }
 
+#ifdef __ANDROID__
+       d = sqlite3_prepare(m_database, "DELETE FROM `blocks` WHERE `pos`=?;", -1, &m_database_delete, NULL);
+       if(d != SQLITE_OK) {
+               infostream<<"WARNING: SQLite3 database delete statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
+               throw FileNotGoodException("Cannot prepare delete statement");
+       }
+#endif
+
        d = sqlite3_prepare(m_database, "SELECT `pos` FROM `blocks`", -1, &m_database_list, NULL);
        if(d != SQLITE_OK) {
                infostream<<"SQLite3 list statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
@@ -140,6 +151,32 @@ bool Database_SQLite3::saveBlock(v3s16 blockpos, std::string &data)
 {
        verifyDatabase();
 
+#ifdef __ANDROID__
+       /**
+        * Note: For some unknown reason sqlite3 fails to REPLACE blocks on android,
+        * deleting them and inserting first works.
+        */
+       if (sqlite3_bind_int64(m_database_read, 1, getBlockAsInteger(blockpos)) != SQLITE_OK) {
+               infostream << "WARNING: Could not bind block position for load: "
+                       << sqlite3_errmsg(m_database)<<std::endl;
+       }
+
+       if (sqlite3_step(m_database_read) == SQLITE_ROW) {
+               if (sqlite3_bind_int64(m_database_delete, 1, getBlockAsInteger(blockpos)) != SQLITE_OK) {
+                       infostream << "WARNING: Could not bind block position for delete: "
+                               << sqlite3_errmsg(m_database)<<std::endl;
+               }
+
+               if (sqlite3_step(m_database_delete) != SQLITE_DONE) {
+                       errorstream << "WARNING: saveBlock: Block failed to delete "
+                               << PP(blockpos) << ": " << sqlite3_errmsg(m_database) << std::endl;
+                       return false;
+               }
+               sqlite3_reset(m_database_delete);
+       }
+       sqlite3_reset(m_database_read);
+#endif
+
        if (sqlite3_bind_int64(m_database_write, 1, getBlockAsInteger(blockpos)) != SQLITE_OK) {
                errorstream << "WARNING: saveBlock: Block position failed to bind: "
                        << PP(blockpos) << ": " << sqlite3_errmsg(m_database) << std::endl;
@@ -162,6 +199,7 @@ bool Database_SQLite3::saveBlock(v3s16 blockpos, std::string &data)
        }
 
        sqlite3_reset(m_database_write);
+
        return true;
 }
 
@@ -203,7 +241,7 @@ void Database_SQLite3::createDatabase()
                        "`data` BLOB"
                ");"
        , NULL, NULL, NULL);
-       if(e == SQLITE_ABORT)
+       if(e != SQLITE_OK)
                throw FileNotGoodException("Could not create sqlite3 database structure");
        else
                infostream<<"ServerMap: SQLite3 database structure was created";
index 81f7d459dd11b33b9145dbfb9fe9cc04cdbc44cc..45619b8852d63cfb47c05119b4dc06ac381127cf 100644 (file)
@@ -47,6 +47,9 @@ private:
        sqlite3 *m_database;
        sqlite3_stmt *m_database_read;
        sqlite3_stmt *m_database_write;
+#ifdef __ANDROID__
+       sqlite3_stmt *m_database_delete;
+#endif
        sqlite3_stmt *m_database_list;
 
        // Create the database structure
index 1030d535a7b51613c3e1bd2350b4edb939153c92..f2465c93e3d87432312e4b8a8419c0ea964b453c 100644 (file)
@@ -242,12 +242,7 @@ bool initializeWorld(const std::string &path, const std::string &gameid)
                infostream<<"Creating world.mt ("<<worldmt_path<<")"<<std::endl;
                fs::CreateAllDirs(path);
                std::ostringstream ss(std::ios_base::binary);
-               ss<<"gameid = "<<gameid<<
-#ifdef __ANDROID__
-                               "\nbackend = leveldb\n";
-#else
-                               "\nbackend = sqlite3\n";
-#endif
+               ss<<"gameid = "<<gameid<< "\nbackend = sqlite3\n";
                fs::safeWriteToFile(worldmt_path, ss.str());
        }
        return true;