diff --git a/src/database-sqlite3.cpp b/src/database-sqlite3.cpp index 7e1767a8fb0b7bee2d3a6765b41964a7450a06c0..4d48796fc7d38995eea86da92d46ab474981a96a 100644 --- a/src/database-sqlite3.cpp +++ b/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"; diff --git a/src/database-sqlite3.h b/src/database-sqlite3.h index 81f7d459dd11b33b9145dbfb9fe9cc04cdbc44cc..45619b8852d63cfb47c05119b4dc06ac381127cf 100644 --- a/src/database-sqlite3.h +++ b/src/database-sqlite3.h @@ -47,6 +47,9 @@ class Database_SQLite3 : public Database 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 diff --git a/src/subgame.cpp b/src/subgame.cpp index 1030d535a7b51613c3e1bd2350b4edb939153c92..f2465c93e3d87432312e4b8a8419c0ea964b453c 100644 --- a/src/subgame.cpp +++ b/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;