std::string Database_Dummy::loadBlock(v3s16 blockpos) { if (m_database.count(getBlockAsInteger(blockpos))) return m_database[getBlockAsInteger(blockpos)]; else return ""; }
void Database_LevelDB::saveBlock(MapBlock *block) { DSTACK(__FUNCTION_NAME); /* Dummy blocks are not written */ if(!block || block->isDummy()) { return; } // Format used for writing u8 version = SER_FMT_VER_HIGHEST_WRITE; // Get destination v3s16 p3d = block->getPos(); /* [0] u8 serialization version [1] data */ std::ostringstream o(std::ios_base::binary); o.write((char*)&version, 1); // Write basic data block->serialize(o, version, true); // Write block to database std::string tmp = o.str(); m_database->Put(leveldb::WriteOptions(), getBlockAsString(p3d), tmp); m_database->Delete(leveldb::WriteOptions(), i64tos(getBlockAsInteger(p3d))); // delete old format // We just wrote it to the disk so clear modified flag block->resetModified(); }
std::string Database_Dummy::loadBlock(const v3s16 &pos) { s64 i = getBlockAsInteger(pos); std::map<s64, std::string>::iterator it = m_database.find(i); if (it == m_database.end()) return ""; return it->second; }
void Database_LevelDB::loadBlock(const v3s16 &pos, std::string *block) { std::string datastr; leveldb::Status status = m_database->Get(leveldb::ReadOptions(), i64tos(getBlockAsInteger(pos)), &datastr); *block = (status.ok()) ? datastr : ""; }
std::string Database_LevelDB::loadBlock(v3s16 blockpos) { std::string datastr; leveldb::Status status = m_database->Get(leveldb::ReadOptions(), i64tos(getBlockAsInteger(blockpos)), &datastr); if(status.ok()) return datastr; else return ""; }
bool Database_LevelDB::saveBlock(const v3s16 &pos, const std::string &data) { leveldb::Status status = m_database->Put(leveldb::WriteOptions(), i64tos(getBlockAsInteger(pos)), data); if (!status.ok()) { warningstream << "saveBlock: LevelDB error saving block " << PP(pos) << ": " << status.ToString() << std::endl; return false; } return true; }
bool Database_LevelDB::deleteBlock(v3s16 blockpos) { leveldb::Status status = m_database->Delete(leveldb::WriteOptions(), i64tos(getBlockAsInteger(blockpos))); if (!status.ok()) { errorstream << "WARNING: deleteBlock: LevelDB error deleting block " << PP(blockpos) << ": " << status.ToString() << std::endl; return false; } return true; }
void Database_SQLite3::saveBlock(MapBlock *block) { DSTACK(__FUNCTION_NAME); /* Dummy blocks are not written */ if(!block || block->isDummy()) { /*v3s16 p = block->getPos(); infostream<<"Database_SQLite3::saveBlock(): WARNING: Not writing dummy block " <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/ return; } // Format used for writing u8 version = SER_FMT_VER_HIGHEST_WRITE; // Get destination v3s16 p3d = block->getPos(); /* [0] u8 serialization version [1] data */ verifyDatabase(); std::ostringstream o(std::ios_base::binary); o.write((char*)&version, 1); // Write basic data block->serialize(o, version, true); // Write block to database std::string tmp = o.str(); const char *bytes = tmp.c_str(); if(sqlite3_bind_int64(m_database_write, 1, getBlockAsInteger(p3d)) != SQLITE_OK) infostream<<"WARNING: Block position failed to bind: "<<sqlite3_errmsg(m_database)<<std::endl; if(sqlite3_bind_blob(m_database_write, 2, (void *)bytes, o.tellp(), NULL) != SQLITE_OK) // TODO this mught not be the right length infostream<<"WARNING: Block data failed to bind: "<<sqlite3_errmsg(m_database)<<std::endl; int written = sqlite3_step(m_database_write); if(written != SQLITE_DONE) infostream<<"WARNING: Block failed to save ("<<p3d.X<<", "<<p3d.Y<<", "<<p3d.Z<<") " <<sqlite3_errmsg(m_database)<<std::endl; // Make ready for later reuse sqlite3_reset(m_database_write); // We just wrote it to the disk so clear modified flag block->resetModified(); }
std::string Database_Redis::loadBlock(v3s16 blockpos) { std::string tmp = i64tos(getBlockAsInteger(blockpos)); redisReply *reply; reply = (redisReply*) redisCommand(ctx, "HGET %s %s", hash.c_str(), tmp.c_str()); if(!reply) throw FileNotGoodException(std::string("redis command 'HGET %s %s' failed: ") + ctx->errstr); if(reply->type != REDIS_REPLY_STRING) { freeReplyObject(reply); return ""; } std::string str(reply->str, reply->len); freeReplyObject(reply); // std::string copies the memory so this won't cause any problems return str; }
bool Database_Redis::deleteBlock(const v3s16 &pos) { std::string tmp = i64tos(getBlockAsInteger(pos)); redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "HDEL %s %s", hash.c_str(), tmp.c_str())); if (!reply) { throw FileNotGoodException(std::string( "Redis command 'HDEL %s %s' failed: ") + ctx->errstr); } else if (reply->type == REDIS_REPLY_ERROR) { errorstream << "WARNING: deleteBlock: deleting block " << PP(pos) << " failed: " << reply->str << std::endl; freeReplyObject(reply); return false; } freeReplyObject(reply); return true; }
std::string Database_Redis::loadBlock(const v3s16 &pos) { std::string tmp = i64tos(getBlockAsInteger(pos)); redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "HGET %s %s", hash.c_str(), tmp.c_str())); if (!reply) { throw FileNotGoodException(std::string( "Redis command 'HGET %s %s' failed: ") + ctx->errstr); } switch (reply->type) { case REDIS_REPLY_STRING: { std::string str(reply->str, reply->len); // std::string copies the memory so this won't cause any problems freeReplyObject(reply); return str; } case REDIS_REPLY_ERROR: { std::string errstr = reply->str; freeReplyObject(reply); errorstream << "loadBlock: loading block " << PP(pos) << " failed: " << errstr << std::endl; throw FileNotGoodException(std::string( "Redis command 'HGET %s %s' errored: ") + errstr); } case REDIS_REPLY_NIL: { // block not found in database freeReplyObject(reply); return ""; } } errorstream << "loadBlock: loading block " << PP(pos) << " returned invalid reply type " << reply->type << ": " << reply->str << std::endl; freeReplyObject(reply); throw FileNotGoodException(std::string( "Redis command 'HGET %s %s' gave invalid reply.")); }
bool Database_Redis::saveBlock(const v3s16 &pos, const std::string &data) { std::string tmp = i64tos(getBlockAsInteger(pos)); redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "HSET %s %s %b", hash.c_str(), tmp.c_str(), data.c_str(), data.size())); if (!reply) { errorstream << "WARNING: saveBlock: redis command 'HSET' failed on " "block " << PP(pos) << ": " << ctx->errstr << std::endl; freeReplyObject(reply); return false; } if (reply->type == REDIS_REPLY_ERROR) { errorstream << "WARNING: saveBlock: saving block " << PP(pos) << " failed: " << reply->str << std::endl; freeReplyObject(reply); return false; } freeReplyObject(reply); return true; }
bool Database_Redis::deleteBlock(v3s16 blockpos) { std::string tmp = i64tos(getBlockAsInteger(blockpos)); redisReply *reply = (redisReply *)redisCommand(ctx, "HDEL %s %s", hash.c_str(), tmp.c_str()); if (!reply) { errorstream << "WARNING: deleteBlock: redis command 'HDEL' failed on " "block " << PP(blockpos) << ": " << ctx->errstr << std::endl; freeReplyObject(reply); return false; } if (reply->type == REDIS_REPLY_ERROR) { errorstream << "WARNING: deleteBlock: deleting block " << PP(blockpos) << "failed" << std::endl; freeReplyObject(reply); return false; } freeReplyObject(reply); return true; }
MapBlock* Database_LevelDB::loadBlock(v3s16 blockpos) { v2s16 p2d(blockpos.X, blockpos.Z); std::string datastr; leveldb::Status s = m_database->Get(leveldb::ReadOptions(), getBlockAsString(blockpos), &datastr); if (!datastr.length()) { s = m_database->Get(leveldb::ReadOptions(), i64tos(getBlockAsInteger(blockpos)), &datastr); if (datastr.length() == 0 && s.ok()) { errorstream << "Blank block data in database (datastr.length() == 0) (" << blockpos.X << "," << blockpos.Y << "," << blockpos.Z << ")" << std::endl; if (g_settings->getBool("ignore_world_load_errors")) { errorstream << "Ignoring block load error. Duck and cover! " << "(ignore_world_load_errors)" << std::endl; } else { throw SerializationError("Blank block data in database"); } return NULL; } } if (s.ok()) { try { std::istringstream is(datastr, std::ios_base::binary); u8 version = SER_FMT_VER_INVALID; is.read((char *)&version, 1); if (is.fail()) throw SerializationError("ServerMap::loadBlock(): Failed" " to read MapBlock version"); MapBlock *block = NULL; bool created_new = false; block = srvmap->getBlockNoCreateNoEx(blockpos); if (block == NULL) { block = srvmap->createBlankBlockNoInsert(blockpos); created_new = true; } // Read basic data block->deSerialize(is, version, true); // If it's a new block, insert it to the map if (created_new) srvmap->insertBlock(block); /* Save blocks loaded in old format in new format */ //if(version < SER_FMT_VER_HIGHEST || save_after_load) // Only save if asked to; no need to update version //if(save_after_load) // saveBlock(block); // We just loaded it from, so it's up-to-date. block->resetModified(); } catch (SerializationError &e) { errorstream << "Invalid block data in database" << " (" << blockpos.X << "," << blockpos.Y << "," << blockpos.Z << ") (SerializationError): " << e.what() << std::endl; // TODO: Block should be marked as invalid in memory so that it is // not touched but the game can run if (g_settings->getBool("ignore_world_load_errors")) { errorstream << "Ignoring block load error. Duck and cover! " << "(ignore_world_load_errors)" << std::endl; } else { throw SerializationError("Invalid block data in database"); //assert(0); } } return srvmap->getBlockNoCreateNoEx(blockpos); // should not be using this here } return NULL; }
bool Database_Dummy::saveBlock(v3s16 blockpos, std::string &data) { m_database[getBlockAsInteger(blockpos)] = data; return true; }
bool Database_Dummy::deleteBlock(v3s16 blockpos) { m_database.erase(getBlockAsInteger(blockpos)); return true; }
MapBlock* Database_SQLite3::loadBlock(v3s16 blockpos) { v2s16 p2d(blockpos.X, blockpos.Z); verifyDatabase(); 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) { /* Make sure sector is loaded */ MapSector *sector = srvmap->createSector(p2d); /* Load block */ const char * data = (const char *)sqlite3_column_blob(m_database_read, 0); size_t len = sqlite3_column_bytes(m_database_read, 0); std::string datastr(data, len); // srvmap->loadBlock(&datastr, blockpos, sector, false); try { std::istringstream is(datastr, std::ios_base::binary); u8 version = SER_FMT_VER_INVALID; is.read((char*)&version, 1); if(is.fail()) throw SerializationError("ServerMap::loadBlock(): Failed" " to read MapBlock version"); MapBlock *block = NULL; bool created_new = false; block = sector->getBlockNoCreateNoEx(blockpos.Y); if(block == NULL) { block = sector->createBlankBlockNoInsert(blockpos.Y); created_new = true; } // Read basic data block->deSerialize(is, version, true); // If it's a new block, insert it to the map if(created_new) sector->insertBlock(block); /* Save blocks loaded in old format in new format */ //if(version < SER_FMT_VER_HIGHEST || save_after_load) // Only save if asked to; no need to update version //if(save_after_load) // saveBlock(block); // We just loaded it from, so it's up-to-date. block->resetModified(); } catch(SerializationError &e) { errorstream<<"Invalid block data in database" <<" ("<<blockpos.X<<","<<blockpos.Y<<","<<blockpos.Z<<")" <<" (SerializationError): "<<e.what()<<std::endl; // TODO: Block should be marked as invalid in memory so that it is // not touched but the game can run if(g_settings->getBool("ignore_world_load_errors")){ errorstream<<"Ignoring block load error. Duck and cover! " <<"(ignore_world_load_errors)"<<std::endl; } else { throw SerializationError("Invalid block data in database"); //assert(0); } } sqlite3_step(m_database_read); // We should never get more than 1 row, so ok to reset sqlite3_reset(m_database_read); return srvmap->getBlockNoCreateNoEx(blockpos); // should not be using this here } sqlite3_reset(m_database_read); return(NULL); }
inline void Database_SQLite3::bindPos(sqlite3_stmt *stmt, const v3s16 &pos, int index) { SQLOK(sqlite3_bind_int64(stmt, index, getBlockAsInteger(pos))); }
bool Database_Dummy::deleteBlock(const v3s16 &pos) { m_database.erase(getBlockAsInteger(pos)); return true; }
bool Database_Dummy::saveBlock(const v3s16 &pos, const std::string &data) { m_database[getBlockAsInteger(pos)] = data; return true; }
inline void Database_SQLite3::bindPos(sqlite3_stmt *stmt, const v3s16 &pos, int index) { SQLOK(sqlite3_bind_int64(stmt, index, getBlockAsInteger(pos)), "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); }
MapBlock* Database_Dummy::loadBlock(v3s16 blockpos) { v2s16 p2d(blockpos.X, blockpos.Z); if(m_database.count(getBlockAsInteger(blockpos))) { /* Make sure sector is loaded */ MapSector *sector = srvmap->createSector(p2d); /* Load block */ std::string datastr = m_database[getBlockAsInteger(blockpos)]; // srvmap->loadBlock(&datastr, blockpos, sector, false); try { std::istringstream is(datastr, std::ios_base::binary); u8 version = SER_FMT_VER_INVALID; is.read((char*)&version, 1); if(is.fail()) throw SerializationError("ServerMap::loadBlock(): Failed" " to read MapBlock version"); MapBlock *block = NULL; bool created_new = false; block = sector->getBlockNoCreateNoEx(blockpos.Y); if(block == NULL) { block = sector->createBlankBlockNoInsert(blockpos.Y); created_new = true; } // Read basic data block->deSerialize(is, version, true); // If it's a new block, insert it to the map if(created_new) sector->insertBlock(block); /* Save blocks loaded in old format in new format */ //if(version < SER_FMT_VER_HIGHEST || save_after_load) // Only save if asked to; no need to update version //if(save_after_load) // saveBlock(block); // We just loaded it from, so it's up-to-date. block->resetModified(); } catch(SerializationError &e) { errorstream<<"Invalid block data in database" <<" ("<<blockpos.X<<","<<blockpos.Y<<","<<blockpos.Z<<")" <<" (SerializationError): "<<e.what()<<std::endl; // TODO: Block should be marked as invalid in memory so that it is // not touched but the game can run if(g_settings->getBool("ignore_world_load_errors")){ errorstream<<"Ignoring block load error. Duck and cover! " <<"(ignore_world_load_errors)"<<std::endl; } else { throw SerializationError("Invalid block data in database"); //assert(0); } } return srvmap->getBlockNoCreateNoEx(blockpos); // should not be using this here } return(NULL); }