Explorar o código

Add sqlite3 backend hack for android

sapier %!s(int64=10) %!d(string=hai) anos
pai
achega
fa427d641b
Modificáronse 3 ficheiros con 45 adicións e 9 borrados
  1. 41 3
      src/database-sqlite3.cpp
  2. 3 0
      src/database-sqlite3.h
  3. 1 6
      src/subgame.cpp

+ 41 - 3
src/database-sqlite3.cpp

@@ -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";

+ 3 - 0
src/database-sqlite3.h

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

+ 1 - 6
src/subgame.cpp

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