diff options
Diffstat (limited to 'src/database')
-rw-r--r-- | src/database/database-dummy.cpp | 2 | ||||
-rw-r--r-- | src/database/database-files.cpp | 9 | ||||
-rw-r--r-- | src/database/database-leveldb.cpp | 67 | ||||
-rw-r--r-- | src/database/database-postgresql.cpp | 433 | ||||
-rw-r--r-- | src/database/database-postgresql.h | 36 | ||||
-rw-r--r-- | src/database/database-redis.cpp | 85 | ||||
-rw-r--r-- | src/database/database-sqlite3.cpp | 377 | ||||
-rw-r--r-- | src/database/database-sqlite3.h | 22 | ||||
-rw-r--r-- | src/database/database.cpp | 9 |
9 files changed, 516 insertions, 524 deletions
diff --git a/src/database/database-dummy.cpp b/src/database/database-dummy.cpp index 3d30761be..a3d8cd579 100644 --- a/src/database/database-dummy.cpp +++ b/src/database/database-dummy.cpp @@ -23,6 +23,7 @@ Dummy database class #include "database-dummy.h" + bool Database_Dummy::saveBlock(const v3s16 &pos, const std::string &data) { m_database[getBlockAsInteger(pos)] = data; @@ -55,3 +56,4 @@ void Database_Dummy::listAllLoadableBlocks(std::vector<v3s16> &dst) dst.push_back(getIntegerAsBlock(x->first)); } } + diff --git a/src/database/database-files.cpp b/src/database/database-files.cpp index fe5293a68..d2b0b1543 100644 --- a/src/database/database-files.cpp +++ b/src/database/database-files.cpp @@ -95,7 +95,7 @@ void PlayerDatabaseFiles::savePlayer(RemotePlayer *player) if (!path_found) { errorstream << "Didn't find free file for player " << player->getName() - << std::endl; + << std::endl; return; } @@ -156,8 +156,7 @@ bool PlayerDatabaseFiles::loadPlayer(RemotePlayer *player, PlayerSAO *sao) path = players_path + player_to_load + itos(i); } - infostream << "Player file for player " << player_to_load << " not found" - << std::endl; + infostream << "Player file for player " << player_to_load << " not found" << std::endl; return false; } @@ -165,8 +164,8 @@ void PlayerDatabaseFiles::listPlayers(std::vector<std::string> &res) { std::vector<fs::DirListNode> files = fs::GetDirListing(m_savedir); // list files into players directory - for (std::vector<fs::DirListNode>::const_iterator it = files.begin(); - it != files.end(); ++it) { + for (std::vector<fs::DirListNode>::const_iterator it = files.begin(); it != + files.end(); ++it) { // Ignore directories if (it->dir) continue; diff --git a/src/database/database-leveldb.cpp b/src/database/database-leveldb.cpp index 51830ff35..1976ae13d 100644 --- a/src/database/database-leveldb.cpp +++ b/src/database/database-leveldb.cpp @@ -33,18 +33,20 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "leveldb/db.h" -#define ENSURE_STATUS_OK(s) \ - if (!(s).ok()) { \ - throw DatabaseException( \ - std::string("LevelDB error: ") + (s).ToString()); \ + +#define ENSURE_STATUS_OK(s) \ + if (!(s).ok()) { \ + throw DatabaseException(std::string("LevelDB error: ") + \ + (s).ToString()); \ } + Database_LevelDB::Database_LevelDB(const std::string &savedir) { leveldb::Options options; options.create_if_missing = true; - leveldb::Status status = leveldb::DB::Open( - options, savedir + DIR_DELIM + "map.db", &m_database); + leveldb::Status status = leveldb::DB::Open(options, + savedir + DIR_DELIM + "map.db", &m_database); ENSURE_STATUS_OK(status); } @@ -55,11 +57,11 @@ Database_LevelDB::~Database_LevelDB() bool Database_LevelDB::saveBlock(const v3s16 &pos, const std::string &data) { - leveldb::Status status = m_database->Put( - leveldb::WriteOptions(), i64tos(getBlockAsInteger(pos)), 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; + warningstream << "saveBlock: LevelDB error saving block " + << PP(pos) << ": " << status.ToString() << std::endl; return false; } @@ -69,19 +71,19 @@ bool Database_LevelDB::saveBlock(const v3s16 &pos, const std::string &data) 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); + leveldb::Status status = m_database->Get(leveldb::ReadOptions(), + i64tos(getBlockAsInteger(pos)), &datastr); *block = (status.ok()) ? datastr : ""; } bool Database_LevelDB::deleteBlock(const v3s16 &pos) { - leveldb::Status status = m_database->Delete( - leveldb::WriteOptions(), i64tos(getBlockAsInteger(pos))); + leveldb::Status status = m_database->Delete(leveldb::WriteOptions(), + i64tos(getBlockAsInteger(pos))); if (!status.ok()) { - warningstream << "deleteBlock: LevelDB error deleting block " << PP(pos) - << ": " << status.ToString() << std::endl; + warningstream << "deleteBlock: LevelDB error deleting block " + << PP(pos) << ": " << status.ToString() << std::endl; return false; } @@ -90,11 +92,11 @@ bool Database_LevelDB::deleteBlock(const v3s16 &pos) void Database_LevelDB::listAllLoadableBlocks(std::vector<v3s16> &dst) { - leveldb::Iterator *it = m_database->NewIterator(leveldb::ReadOptions()); + leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions()); for (it->SeekToFirst(); it->Valid(); it->Next()) { dst.push_back(getIntegerAsBlock(stoi64(it->key().ToString()))); } - ENSURE_STATUS_OK(it->status()); // Check for any errors found during the scan + ENSURE_STATUS_OK(it->status()); // Check for any errors found during the scan delete it; } @@ -102,8 +104,8 @@ PlayerDatabaseLevelDB::PlayerDatabaseLevelDB(const std::string &savedir) { leveldb::Options options; options.create_if_missing = true; - leveldb::Status status = leveldb::DB::Open( - options, savedir + DIR_DELIM + "players.db", &m_database); + leveldb::Status status = leveldb::DB::Open(options, + savedir + DIR_DELIM + "players.db", &m_database); ENSURE_STATUS_OK(status); } @@ -149,8 +151,8 @@ void PlayerDatabaseLevelDB::savePlayer(RemotePlayer *player) player->inventory.serialize(os); - leveldb::Status status = m_database->Put( - leveldb::WriteOptions(), player->getName(), os.str()); + leveldb::Status status = m_database->Put(leveldb::WriteOptions(), + player->getName(), os.str()); ENSURE_STATUS_OK(status); player->onSuccessfulSave(); } @@ -164,8 +166,8 @@ bool PlayerDatabaseLevelDB::removePlayer(const std::string &name) bool PlayerDatabaseLevelDB::loadPlayer(RemotePlayer *player, PlayerSAO *sao) { std::string raw; - leveldb::Status s = - m_database->Get(leveldb::ReadOptions(), player->getName(), &raw); + leveldb::Status s = m_database->Get(leveldb::ReadOptions(), + player->getName(), &raw); if (!s.ok()) return false; std::istringstream is(raw); @@ -192,7 +194,7 @@ bool PlayerDatabaseLevelDB::loadPlayer(RemotePlayer *player, PlayerSAO *sao) player->inventory.deSerialize(is); } catch (SerializationError &e) { errorstream << "Failed to deserialize player inventory. player_name=" - << player->getName() << " " << e.what() << std::endl; + << player->getName() << " " << e.what() << std::endl; } return true; @@ -200,7 +202,7 @@ bool PlayerDatabaseLevelDB::loadPlayer(RemotePlayer *player, PlayerSAO *sao) void PlayerDatabaseLevelDB::listPlayers(std::vector<std::string> &res) { - leveldb::Iterator *it = m_database->NewIterator(leveldb::ReadOptions()); + leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions()); res.clear(); for (it->SeekToFirst(); it->Valid(); it->Next()) { res.push_back(it->key().ToString()); @@ -212,8 +214,8 @@ AuthDatabaseLevelDB::AuthDatabaseLevelDB(const std::string &savedir) { leveldb::Options options; options.create_if_missing = true; - leveldb::Status status = leveldb::DB::Open( - options, savedir + DIR_DELIM + "auth.db", &m_database); + leveldb::Status status = leveldb::DB::Open(options, + savedir + DIR_DELIM + "auth.db", &m_database); ENSURE_STATUS_OK(status); } @@ -265,15 +267,16 @@ bool AuthDatabaseLevelDB::saveAuth(const AuthEntry &authEntry) os << serializeString(authEntry.password); size_t privilege_count = authEntry.privileges.size(); - FATAL_ERROR_IF(privilege_count > U16_MAX, "Unsupported number of privileges"); + FATAL_ERROR_IF(privilege_count > U16_MAX, + "Unsupported number of privileges"); writeU16(os, privilege_count); for (const std::string &privilege : authEntry.privileges) { os << serializeString(privilege); } writeS64(os, authEntry.last_login); - leveldb::Status s = m_database->Put( - leveldb::WriteOptions(), authEntry.name, os.str()); + leveldb::Status s = m_database->Put(leveldb::WriteOptions(), + authEntry.name, os.str()); return s.ok(); } @@ -290,7 +293,7 @@ bool AuthDatabaseLevelDB::deleteAuth(const std::string &name) void AuthDatabaseLevelDB::listNames(std::vector<std::string> &res) { - leveldb::Iterator *it = m_database->NewIterator(leveldb::ReadOptions()); + leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions()); res.clear(); for (it->SeekToFirst(); it->Valid(); it->Next()) { res.emplace_back(it->key().ToString()); diff --git a/src/database/database-postgresql.cpp b/src/database/database-postgresql.cpp index 3d5e1947c..e1bb39928 100644 --- a/src/database/database-postgresql.cpp +++ b/src/database/database-postgresql.cpp @@ -23,12 +23,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "database-postgresql.h" #ifdef _WIN32 -// Without this some of the network functions are not found on mingw -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0501 -#endif -#include <windows.h> -#include <winsock2.h> + // Without this some of the network functions are not found on mingw + #ifndef _WIN32_WINNT + #define _WIN32_WINNT 0x0501 + #endif + #include <windows.h> + #include <winsock2.h> #else #include <netinet/in.h> #endif @@ -40,21 +40,19 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "server/player_sao.h" Database_PostgreSQL::Database_PostgreSQL(const std::string &connect_string) : - m_connect_string(connect_string) + m_connect_string(connect_string) { if (m_connect_string.empty()) { throw SettingNotFoundException( - "Set pgsql_connection string in world.mt to " - "use the postgresql backend\n" - "Notes:\n" - "pgsql_connection has the following form: \n" - "\tpgsql_connection = host=127.0.0.1 port=5432 " - "user=mt_user " - "password=mt_password dbname=minetest_world\n" - "mt_user should have CREATE TABLE, INSERT, SELECT, " - "UPDATE and " - "DELETE rights on the database.\n" - "Don't create mt_user as a SUPERUSER!"); + "Set pgsql_connection string in world.mt to " + "use the postgresql backend\n" + "Notes:\n" + "pgsql_connection has the following form: \n" + "\tpgsql_connection = host=127.0.0.1 port=5432 user=mt_user " + "password=mt_password dbname=minetest_world\n" + "mt_user should have CREATE TABLE, INSERT, SELECT, UPDATE and " + "DELETE rights on the database.\n" + "Don't create mt_user as a SUPERUSER!"); } } @@ -68,24 +66,25 @@ void Database_PostgreSQL::connectToDatabase() m_conn = PQconnectdb(m_connect_string.c_str()); if (PQstatus(m_conn) != CONNECTION_OK) { - throw DatabaseException(std::string("PostgreSQL database error: ") + - PQerrorMessage(m_conn)); + throw DatabaseException(std::string( + "PostgreSQL database error: ") + + PQerrorMessage(m_conn)); } m_pgversion = PQserverVersion(m_conn); /* - * We are using UPSERT feature from PostgreSQL 9.5 - * to have the better performance where possible. - */ + * We are using UPSERT feature from PostgreSQL 9.5 + * to have the better performance where possible. + */ if (m_pgversion < 90500) { warningstream << "Your PostgreSQL server lacks UPSERT " - << "support. Use version 9.5 or better if possible." - << std::endl; + << "support. Use version 9.5 or better if possible." + << std::endl; } infostream << "PostgreSQL Database: Version " << m_pgversion - << " Connection made." << std::endl; + << " Connection made." << std::endl; createDatabase(); initStatements(); @@ -103,8 +102,9 @@ void Database_PostgreSQL::verifyDatabase() void Database_PostgreSQL::ping() { if (PQping(m_connect_string.c_str()) != PQPING_OK) { - throw DatabaseException(std::string("PostgreSQL database error: ") + - PQerrorMessage(m_conn)); + throw DatabaseException(std::string( + "PostgreSQL database error: ") + + PQerrorMessage(m_conn)); } } @@ -123,8 +123,9 @@ PGresult *Database_PostgreSQL::checkResults(PGresult *result, bool clear) break; case PGRES_FATAL_ERROR: default: - throw DatabaseException(std::string("PostgreSQL database error: ") + - PQresultErrorMessage(result)); + throw DatabaseException( + std::string("PostgreSQL database error: ") + + PQresultErrorMessage(result)); } if (clear) @@ -133,11 +134,11 @@ PGresult *Database_PostgreSQL::checkResults(PGresult *result, bool clear) return result; } -void Database_PostgreSQL::createTableIfNotExists( - const std::string &table_name, const std::string &definition) +void Database_PostgreSQL::createTableIfNotExists(const std::string &table_name, + const std::string &definition) { std::string sql_check_table = "SELECT relname FROM pg_class WHERE relname='" + - table_name + "';"; + table_name + "';"; PGresult *result = checkResults(PQexec(m_conn, sql_check_table.c_str()), false); // If table doesn't exist, create it @@ -164,57 +165,61 @@ void Database_PostgreSQL::rollback() checkResults(PQexec(m_conn, "ROLLBACK;")); } -MapDatabasePostgreSQL::MapDatabasePostgreSQL(const std::string &connect_string) : - Database_PostgreSQL(connect_string), MapDatabase() +MapDatabasePostgreSQL::MapDatabasePostgreSQL(const std::string &connect_string): + Database_PostgreSQL(connect_string), + MapDatabase() { connectToDatabase(); } + void MapDatabasePostgreSQL::createDatabase() { - createTableIfNotExists("blocks", "CREATE TABLE blocks (" - "posX INT NOT NULL," - "posY INT NOT NULL," - "posZ INT NOT NULL," - "data BYTEA," - "PRIMARY KEY (posX,posY,posZ)" - ");"); + createTableIfNotExists("blocks", + "CREATE TABLE blocks (" + "posX INT NOT NULL," + "posY INT NOT NULL," + "posZ INT NOT NULL," + "data BYTEA," + "PRIMARY KEY (posX,posY,posZ)" + ");" + ); infostream << "PostgreSQL: Map Database was initialized." << std::endl; } void MapDatabasePostgreSQL::initStatements() { - prepareStatement("read_block", "SELECT data FROM blocks " - "WHERE posX = $1::int4 AND posY = $2::int4 AND " - "posZ = $3::int4"); + prepareStatement("read_block", + "SELECT data FROM blocks " + "WHERE posX = $1::int4 AND posY = $2::int4 AND " + "posZ = $3::int4"); if (getPGVersion() < 90500) { prepareStatement("write_block_insert", - "INSERT INTO blocks (posX, posY, posZ, data) SELECT " + "INSERT INTO blocks (posX, posY, posZ, data) SELECT " "$1::int4, $2::int4, $3::int4, $4::bytea " "WHERE NOT EXISTS (SELECT true FROM blocks " "WHERE posX = $1::int4 AND posY = $2::int4 AND " "posZ = $3::int4)"); prepareStatement("write_block_update", - "UPDATE blocks SET data = $4::bytea " + "UPDATE blocks SET data = $4::bytea " "WHERE posX = $1::int4 AND posY = $2::int4 AND " "posZ = $3::int4"); } else { prepareStatement("write_block", - "INSERT INTO blocks (posX, posY, posZ, data) VALUES " + "INSERT INTO blocks (posX, posY, posZ, data) VALUES " "($1::int4, $2::int4, $3::int4, $4::bytea) " "ON CONFLICT ON CONSTRAINT blocks_pkey DO " "UPDATE SET data = $4::bytea"); } - prepareStatement("delete_block", - "DELETE FROM blocks WHERE " - "posX = $1::int4 AND posY = $2::int4 AND posZ = $3::int4"); + prepareStatement("delete_block", "DELETE FROM blocks WHERE " + "posX = $1::int4 AND posY = $2::int4 AND posZ = $3::int4"); prepareStatement("list_all_loadable_blocks", - "SELECT posX, posY, posZ FROM blocks"); + "SELECT posX, posY, posZ FROM blocks"); } bool MapDatabasePostgreSQL::saveBlock(const v3s16 &pos, const std::string &data) @@ -222,8 +227,8 @@ bool MapDatabasePostgreSQL::saveBlock(const v3s16 &pos, const std::string &data) // Verify if we don't overflow the platform integer with the mapblock size if (data.size() > INT_MAX) { errorstream << "Database_PostgreSQL::saveBlock: Data truncation! " - << "data.size() over 0xFFFFFFFF (== " << data.size() << ")" - << std::endl; + << "data.size() over 0xFFFFFFFF (== " << data.size() + << ")" << std::endl; return false; } @@ -234,9 +239,11 @@ bool MapDatabasePostgreSQL::saveBlock(const v3s16 &pos, const std::string &data) y = htonl(pos.Y); z = htonl(pos.Z); - const void *args[] = {&x, &y, &z, data.c_str()}; - const int argLen[] = {sizeof(x), sizeof(y), sizeof(z), (int)data.size()}; - const int argFmt[] = {1, 1, 1, 1}; + const void *args[] = { &x, &y, &z, data.c_str() }; + const int argLen[] = { + sizeof(x), sizeof(y), sizeof(z), (int)data.size() + }; + const int argFmt[] = { 1, 1, 1, 1 }; if (getPGVersion() < 90500) { execPrepared("write_block_update", ARRLEN(args), args, argLen, argFmt); @@ -256,18 +263,17 @@ void MapDatabasePostgreSQL::loadBlock(const v3s16 &pos, std::string *block) y = htonl(pos.Y); z = htonl(pos.Z); - const void *args[] = {&x, &y, &z}; - const int argLen[] = {sizeof(x), sizeof(y), sizeof(z)}; - const int argFmt[] = {1, 1, 1}; + const void *args[] = { &x, &y, &z }; + const int argLen[] = { sizeof(x), sizeof(y), sizeof(z) }; + const int argFmt[] = { 1, 1, 1 }; - PGresult *results = execPrepared( - "read_block", ARRLEN(args), args, argLen, argFmt, false); + PGresult *results = execPrepared("read_block", ARRLEN(args), args, + argLen, argFmt, false); *block = ""; if (PQntuples(results)) - *block = std::string( - PQgetvalue(results, 0, 0), PQgetlength(results, 0, 0)); + *block = std::string(PQgetvalue(results, 0, 0), PQgetlength(results, 0, 0)); PQclear(results); } @@ -281,9 +287,9 @@ bool MapDatabasePostgreSQL::deleteBlock(const v3s16 &pos) y = htonl(pos.Y); z = htonl(pos.Z); - const void *args[] = {&x, &y, &z}; - const int argLen[] = {sizeof(x), sizeof(y), sizeof(z)}; - const int argFmt[] = {1, 1, 1}; + const void *args[] = { &x, &y, &z }; + const int argLen[] = { sizeof(x), sizeof(y), sizeof(z) }; + const int argFmt[] = { 1, 1, 1 }; execPrepared("delete_block", ARRLEN(args), args, argLen, argFmt); @@ -294,8 +300,8 @@ void MapDatabasePostgreSQL::listAllLoadableBlocks(std::vector<v3s16> &dst) { verifyDatabase(); - PGresult *results = execPrepared( - "list_all_loadable_blocks", 0, NULL, NULL, NULL, false, false); + PGresult *results = execPrepared("list_all_loadable_blocks", 0, + NULL, NULL, NULL, false, false); int numrows = PQntuples(results); @@ -308,63 +314,67 @@ void MapDatabasePostgreSQL::listAllLoadableBlocks(std::vector<v3s16> &dst) /* * Player Database */ -PlayerDatabasePostgreSQL::PlayerDatabasePostgreSQL(const std::string &connect_string) : - Database_PostgreSQL(connect_string), PlayerDatabase() +PlayerDatabasePostgreSQL::PlayerDatabasePostgreSQL(const std::string &connect_string): + Database_PostgreSQL(connect_string), + PlayerDatabase() { connectToDatabase(); } + void PlayerDatabasePostgreSQL::createDatabase() { - createTableIfNotExists("player", "CREATE TABLE player (" - "name VARCHAR(60) NOT NULL," - "pitch NUMERIC(15, 7) NOT NULL," - "yaw NUMERIC(15, 7) NOT NULL," - "posX NUMERIC(15, 7) NOT NULL," - "posY NUMERIC(15, 7) NOT NULL," - "posZ NUMERIC(15, 7) NOT NULL," - "hp INT NOT NULL," - "breath INT NOT NULL," - "creation_date TIMESTAMP WITHOUT TIME ZONE NOT " - "NULL DEFAULT NOW()," - "modification_date TIMESTAMP WITHOUT TIME ZONE " - "NOT NULL DEFAULT NOW()," - "PRIMARY KEY (name)" - ");"); - - createTableIfNotExists("player_inventories", "CREATE TABLE player_inventories (" - "player VARCHAR(60) NOT NULL," - "inv_id INT NOT NULL," - "inv_width INT NOT NULL," - "inv_name TEXT NOT NULL DEFAULT ''," - "inv_size INT NOT NULL," - "PRIMARY KEY(player, inv_id)," - "CONSTRAINT player_inventories_fkey " - "FOREIGN KEY (player) REFERENCES " - "player (name) ON DELETE CASCADE" - ");"); + createTableIfNotExists("player", + "CREATE TABLE player (" + "name VARCHAR(60) NOT NULL," + "pitch NUMERIC(15, 7) NOT NULL," + "yaw NUMERIC(15, 7) NOT NULL," + "posX NUMERIC(15, 7) NOT NULL," + "posY NUMERIC(15, 7) NOT NULL," + "posZ NUMERIC(15, 7) NOT NULL," + "hp INT NOT NULL," + "breath INT NOT NULL," + "creation_date TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW()," + "modification_date TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW()," + "PRIMARY KEY (name)" + ");" + ); + + createTableIfNotExists("player_inventories", + "CREATE TABLE player_inventories (" + "player VARCHAR(60) NOT NULL," + "inv_id INT NOT NULL," + "inv_width INT NOT NULL," + "inv_name TEXT NOT NULL DEFAULT ''," + "inv_size INT NOT NULL," + "PRIMARY KEY(player, inv_id)," + "CONSTRAINT player_inventories_fkey FOREIGN KEY (player) REFERENCES " + "player (name) ON DELETE CASCADE" + ");" + ); createTableIfNotExists("player_inventory_items", - "CREATE TABLE player_inventory_items (" + "CREATE TABLE player_inventory_items (" "player VARCHAR(60) NOT NULL," "inv_id INT NOT NULL," "slot_id INT NOT NULL," "item TEXT NOT NULL DEFAULT ''," "PRIMARY KEY(player, inv_id, slot_id)," - "CONSTRAINT player_inventory_items_fkey FOREIGN KEY (player) " - "REFERENCES " + "CONSTRAINT player_inventory_items_fkey FOREIGN KEY (player) REFERENCES " "player (name) ON DELETE CASCADE" - ");"); + ");" + ); createTableIfNotExists("player_metadata", - "CREATE TABLE player_metadata (" + "CREATE TABLE player_metadata (" "player VARCHAR(60) NOT NULL," "attr VARCHAR(256) NOT NULL," "value TEXT," "PRIMARY KEY(player, attr)," "CONSTRAINT player_metadata_fkey FOREIGN KEY (player) REFERENCES " "player (name) ON DELETE CASCADE" - ");"); + ");" + ); infostream << "PostgreSQL: Player Database was inited." << std::endl; } @@ -373,24 +383,18 @@ void PlayerDatabasePostgreSQL::initStatements() { if (getPGVersion() < 90500) { prepareStatement("create_player", - "INSERT INTO player(name, pitch, yaw, posX, posY, posZ, " - "hp, breath) VALUES " + "INSERT INTO player(name, pitch, yaw, posX, posY, posZ, hp, breath) VALUES " "($1, $2, $3, $4, $5, $6, $7::int, $8::int)"); prepareStatement("update_player", - "UPDATE SET pitch = $2, yaw = $3, posX = $4, posY = $5, " - "posZ = $6, hp = $7::int, " - "breath = $8::int, modification_date = NOW() WHERE name " - "= $1"); + "UPDATE SET pitch = $2, yaw = $3, posX = $4, posY = $5, posZ = $6, hp = $7::int, " + "breath = $8::int, modification_date = NOW() WHERE name = $1"); } else { prepareStatement("save_player", - "INSERT INTO player(name, pitch, yaw, posX, posY, posZ, " - "hp, breath) VALUES " + "INSERT INTO player(name, pitch, yaw, posX, posY, posZ, hp, breath) VALUES " "($1, $2, $3, $4, $5, $6, $7::int, $8::int)" - "ON CONFLICT ON CONSTRAINT player_pkey DO UPDATE SET " - "pitch = $2, yaw = $3, " - "posX = $4, posY = $5, posZ = $6, hp = $7::int, breath = " - "$8::int, " + "ON CONFLICT ON CONSTRAINT player_pkey DO UPDATE SET pitch = $2, yaw = $3, " + "posX = $4, posY = $5, posZ = $6, hp = $7::int, breath = $8::int, " "modification_date = NOW()"); } @@ -399,47 +403,46 @@ void PlayerDatabasePostgreSQL::initStatements() prepareStatement("load_player_list", "SELECT name FROM player"); prepareStatement("remove_player_inventories", - "DELETE FROM player_inventories WHERE player = $1"); + "DELETE FROM player_inventories WHERE player = $1"); prepareStatement("remove_player_inventory_items", - "DELETE FROM player_inventory_items WHERE player = $1"); + "DELETE FROM player_inventory_items WHERE player = $1"); prepareStatement("add_player_inventory", - "INSERT INTO player_inventories (player, inv_id, inv_width, " - "inv_name, inv_size) VALUES " + "INSERT INTO player_inventories (player, inv_id, inv_width, inv_name, inv_size) VALUES " "($1, $2::int, $3::int, $4, $5::int)"); prepareStatement("add_player_inventory_item", - "INSERT INTO player_inventory_items (player, inv_id, slot_id, " - "item) VALUES " + "INSERT INTO player_inventory_items (player, inv_id, slot_id, item) VALUES " "($1, $2::int, $3::int, $4)"); - prepareStatement("load_player_inventories", "SELECT inv_id, inv_width, inv_name, " - "inv_size FROM player_inventories " - "WHERE player = $1 ORDER BY inv_id"); + prepareStatement("load_player_inventories", + "SELECT inv_id, inv_width, inv_name, inv_size FROM player_inventories " + "WHERE player = $1 ORDER BY inv_id"); prepareStatement("load_player_inventory_items", - "SELECT slot_id, item FROM player_inventory_items WHERE " + "SELECT slot_id, item FROM player_inventory_items WHERE " "player = $1 AND inv_id = $2::int"); - prepareStatement("load_player", "SELECT pitch, yaw, posX, posY, posZ, hp, breath " - "FROM player WHERE name = $1"); + prepareStatement("load_player", + "SELECT pitch, yaw, posX, posY, posZ, hp, breath FROM player WHERE name = $1"); prepareStatement("remove_player_metadata", - "DELETE FROM player_metadata WHERE player = $1"); + "DELETE FROM player_metadata WHERE player = $1"); - prepareStatement("save_player_metadata", "INSERT INTO player_metadata (player, " - "attr, value) VALUES ($1, $2, $3)"); + prepareStatement("save_player_metadata", + "INSERT INTO player_metadata (player, attr, value) VALUES ($1, $2, $3)"); prepareStatement("load_player_metadata", - "SELECT attr, value FROM player_metadata WHERE player = $1"); + "SELECT attr, value FROM player_metadata WHERE player = $1"); + } bool PlayerDatabasePostgreSQL::playerDataExists(const std::string &playername) { verifyDatabase(); - const char *values[] = {playername.c_str()}; + const char *values[] = { playername.c_str() }; PGresult *results = execPrepared("load_player", 1, values, false); bool res = (PQntuples(results) > 0); @@ -449,7 +452,7 @@ bool PlayerDatabasePostgreSQL::playerDataExists(const std::string &playername) void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player) { - PlayerSAO *sao = player->getPlayerSAO(); + PlayerSAO* sao = player->getPlayerSAO(); if (!sao) return; @@ -463,11 +466,16 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player) std::string posz = ftos(pos.Z); std::string hp = itos(sao->getHP()); std::string breath = itos(sao->getBreath()); - const char *values[] = {player->getName(), pitch.c_str(), yaw.c_str(), - posx.c_str(), posy.c_str(), posz.c_str(), hp.c_str(), - breath.c_str()}; + const char *values[] = { + player->getName(), + pitch.c_str(), + yaw.c_str(), + posx.c_str(), posy.c_str(), posz.c_str(), + hp.c_str(), + breath.c_str() + }; - const char *rmvalues[] = {player->getName()}; + const char* rmvalues[] = { player->getName() }; beginSave(); if (getPGVersion() < 90500) { @@ -475,23 +483,28 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player) execPrepared("create_player", 8, values, true, false); else execPrepared("update_player", 8, values, true, false); - } else + } + else execPrepared("save_player", 8, values, true, false); // Write player inventories execPrepared("remove_player_inventories", 1, rmvalues); execPrepared("remove_player_inventory_items", 1, rmvalues); - std::vector<const InventoryList *> inventory_lists = - sao->getInventory()->getLists(); + std::vector<const InventoryList*> inventory_lists = sao->getInventory()->getLists(); for (u16 i = 0; i < inventory_lists.size(); i++) { - const InventoryList *list = inventory_lists[i]; + const InventoryList* list = inventory_lists[i]; const std::string &name = list->getName(); - std::string width = itos(list->getWidth()), inv_id = itos(i), - lsize = itos(list->getSize()); - - const char *inv_values[] = {player->getName(), inv_id.c_str(), - width.c_str(), name.c_str(), lsize.c_str()}; + std::string width = itos(list->getWidth()), + inv_id = itos(i), lsize = itos(list->getSize()); + + const char* inv_values[] = { + player->getName(), + inv_id.c_str(), + width.c_str(), + name.c_str(), + lsize.c_str() + }; execPrepared("add_player_inventory", 5, inv_values); for (u32 j = 0; j < list->getSize(); j++) { @@ -499,8 +512,12 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player) list->getItem(j).serialize(os); std::string itemStr = os.str(), slotId = itos(j); - const char *invitem_values[] = {player->getName(), inv_id.c_str(), - slotId.c_str(), itemStr.c_str()}; + const char* invitem_values[] = { + player->getName(), + inv_id.c_str(), + slotId.c_str(), + itemStr.c_str() + }; execPrepared("add_player_inventory_item", 4, invitem_values); } } @@ -508,8 +525,11 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player) execPrepared("remove_player_metadata", 1, rmvalues); const StringMap &attrs = sao->getMeta().getStrings(); for (const auto &attr : attrs) { - const char *meta_values[] = {player->getName(), attr.first.c_str(), - attr.second.c_str()}; + const char *meta_values[] = { + player->getName(), + attr.first.c_str(), + attr.second.c_str() + }; execPrepared("save_player_metadata", 3, meta_values); } endSave(); @@ -522,7 +542,7 @@ bool PlayerDatabasePostgreSQL::loadPlayer(RemotePlayer *player, PlayerSAO *sao) sanity_check(sao); verifyDatabase(); - const char *values[] = {player->getName()}; + const char *values[] = { player->getName() }; PGresult *results = execPrepared("load_player", 1, values, false, false); // Player not found, return not found @@ -533,10 +553,13 @@ bool PlayerDatabasePostgreSQL::loadPlayer(RemotePlayer *player, PlayerSAO *sao) sao->setLookPitch(pg_to_float(results, 0, 0)); sao->setRotation(v3f(0, pg_to_float(results, 0, 1), 0)); - sao->setBasePosition(v3f(pg_to_float(results, 0, 2), pg_to_float(results, 0, 3), - pg_to_float(results, 0, 4))); - sao->setHPRaw((u16)pg_to_int(results, 0, 5)); - sao->setBreath((u16)pg_to_int(results, 0, 6), false); + sao->setBasePosition(v3f( + pg_to_float(results, 0, 2), + pg_to_float(results, 0, 3), + pg_to_float(results, 0, 4)) + ); + sao->setHPRaw((u16) pg_to_int(results, 0, 5)); + sao->setBreath((u16) pg_to_int(results, 0, 6), false); PQclear(results); @@ -546,16 +569,19 @@ bool PlayerDatabasePostgreSQL::loadPlayer(RemotePlayer *player, PlayerSAO *sao) int resultCount = PQntuples(results); for (int row = 0; row < resultCount; ++row) { - InventoryList *invList = player->inventory.addList( - PQgetvalue(results, row, 2), pg_to_uint(results, row, 3)); + InventoryList* invList = player->inventory. + addList(PQgetvalue(results, row, 2), pg_to_uint(results, row, 3)); invList->setWidth(pg_to_uint(results, row, 1)); u32 invId = pg_to_uint(results, row, 0); std::string invIdStr = itos(invId); - const char *values2[] = {player->getName(), invIdStr.c_str()}; - PGresult *results2 = execPrepared( - "load_player_inventory_items", 2, values2, false, false); + const char* values2[] = { + player->getName(), + invIdStr.c_str() + }; + PGresult *results2 = execPrepared("load_player_inventory_items", 2, + values2, false, false); int resultCount2 = PQntuples(results2); for (int row2 = 0; row2 < resultCount2; row2++) { @@ -575,8 +601,7 @@ bool PlayerDatabasePostgreSQL::loadPlayer(RemotePlayer *player, PlayerSAO *sao) int numrows = PQntuples(results); for (int row = 0; row < numrows; row++) { - sao->getMeta().setString( - PQgetvalue(results, row, 0), PQgetvalue(results, row, 1)); + sao->getMeta().setString(PQgetvalue(results, row, 0), PQgetvalue(results, row, 1)); } sao->getMeta().setModified(false); @@ -592,7 +617,7 @@ bool PlayerDatabasePostgreSQL::removePlayer(const std::string &name) verifyDatabase(); - const char *values[] = {name.c_str()}; + const char *values[] = { name.c_str() }; execPrepared("remove_player", 1, values); return true; @@ -619,48 +644,43 @@ AuthDatabasePostgreSQL::AuthDatabasePostgreSQL(const std::string &connect_string void AuthDatabasePostgreSQL::createDatabase() { - createTableIfNotExists("auth", "CREATE TABLE auth (" - "id SERIAL," - "name TEXT UNIQUE," - "password TEXT," - "last_login INT NOT NULL DEFAULT 0," - "PRIMARY KEY (id)" - ");"); + createTableIfNotExists("auth", + "CREATE TABLE auth (" + "id SERIAL," + "name TEXT UNIQUE," + "password TEXT," + "last_login INT NOT NULL DEFAULT 0," + "PRIMARY KEY (id)" + ");"); - createTableIfNotExists("user_privileges", "CREATE TABLE user_privileges (" - "id INT," - "privilege TEXT," - "PRIMARY KEY (id, privilege)," - "CONSTRAINT fk_id FOREIGN KEY (id) " - "REFERENCES auth (id) ON DELETE CASCADE" - ");"); + createTableIfNotExists("user_privileges", + "CREATE TABLE user_privileges (" + "id INT," + "privilege TEXT," + "PRIMARY KEY (id, privilege)," + "CONSTRAINT fk_id FOREIGN KEY (id) REFERENCES auth (id) ON DELETE CASCADE" + ");"); } void AuthDatabasePostgreSQL::initStatements() { - prepareStatement("auth_read", "SELECT id, name, password, last_login FROM auth " - "WHERE name = $1"); - prepareStatement("auth_write", "UPDATE auth SET name = $1, password = $2, " - "last_login = $3 WHERE id = $4"); - prepareStatement("auth_create", "INSERT INTO auth (name, password, last_login) " - "VALUES ($1, $2, $3) RETURNING id"); + prepareStatement("auth_read", "SELECT id, name, password, last_login FROM auth WHERE name = $1"); + prepareStatement("auth_write", "UPDATE auth SET name = $1, password = $2, last_login = $3 WHERE id = $4"); + prepareStatement("auth_create", "INSERT INTO auth (name, password, last_login) VALUES ($1, $2, $3) RETURNING id"); prepareStatement("auth_delete", "DELETE FROM auth WHERE name = $1"); prepareStatement("auth_list_names", "SELECT name FROM auth ORDER BY name DESC"); - prepareStatement("auth_read_privs", - "SELECT privilege FROM user_privileges WHERE id = $1"); - prepareStatement("auth_write_privs", - "INSERT INTO user_privileges (id, privilege) VALUES ($1, $2)"); - prepareStatement( - "auth_delete_privs", "DELETE FROM user_privileges WHERE id = $1"); + prepareStatement("auth_read_privs", "SELECT privilege FROM user_privileges WHERE id = $1"); + prepareStatement("auth_write_privs", "INSERT INTO user_privileges (id, privilege) VALUES ($1, $2)"); + prepareStatement("auth_delete_privs", "DELETE FROM user_privileges WHERE id = $1"); } bool AuthDatabasePostgreSQL::getAuth(const std::string &name, AuthEntry &res) { verifyDatabase(); - const char *values[] = {name.c_str()}; + const char *values[] = { name.c_str() }; PGresult *result = execPrepared("auth_read", 1, values, false, false); int numrows = PQntuples(result); if (numrows == 0) { @@ -676,7 +696,7 @@ bool AuthDatabasePostgreSQL::getAuth(const std::string &name, AuthEntry &res) PQclear(result); std::string playerIdStr = itos(res.id); - const char *privsValues[] = {playerIdStr.c_str()}; + const char *privsValues[] = { playerIdStr.c_str() }; PGresult *results = execPrepared("auth_read_privs", 1, privsValues, false); numrows = PQntuples(results); @@ -697,10 +717,10 @@ bool AuthDatabasePostgreSQL::saveAuth(const AuthEntry &authEntry) std::string lastLoginStr = itos(authEntry.last_login); std::string idStr = itos(authEntry.id); const char *values[] = { - authEntry.name.c_str(), - authEntry.password.c_str(), - lastLoginStr.c_str(), - idStr.c_str(), + authEntry.name.c_str() , + authEntry.password.c_str(), + lastLoginStr.c_str(), + idStr.c_str(), }; execPrepared("auth_write", 4, values); @@ -715,8 +735,11 @@ bool AuthDatabasePostgreSQL::createAuth(AuthEntry &authEntry) verifyDatabase(); std::string lastLoginStr = itos(authEntry.last_login); - const char *values[] = {authEntry.name.c_str(), authEntry.password.c_str(), - lastLoginStr.c_str()}; + const char *values[] = { + authEntry.name.c_str() , + authEntry.password.c_str(), + lastLoginStr.c_str() + }; beginSave(); @@ -724,8 +747,7 @@ bool AuthDatabasePostgreSQL::createAuth(AuthEntry &authEntry) int numrows = PQntuples(result); if (numrows == 0) { - errorstream << "Strange behaviour on auth creation, no ID returned." - << std::endl; + errorstream << "Strange behaviour on auth creation, no ID returned." << std::endl; PQclear(result); rollback(); return false; @@ -744,7 +766,7 @@ bool AuthDatabasePostgreSQL::deleteAuth(const std::string &name) { verifyDatabase(); - const char *values[] = {name.c_str()}; + const char *values[] = { name.c_str() }; execPrepared("auth_delete", 1, values); // privileges deleted by foreign key on delete cascade @@ -755,8 +777,8 @@ void AuthDatabasePostgreSQL::listNames(std::vector<std::string> &res) { verifyDatabase(); - PGresult *results = execPrepared( - "auth_list_names", 0, NULL, NULL, NULL, false, false); + PGresult *results = execPrepared("auth_list_names", 0, + NULL, NULL, NULL, false, false); int numrows = PQntuples(results); @@ -774,13 +796,14 @@ void AuthDatabasePostgreSQL::reload() void AuthDatabasePostgreSQL::writePrivileges(const AuthEntry &authEntry) { std::string authIdStr = itos(authEntry.id); - const char *values[] = {authIdStr.c_str()}; + const char *values[] = { authIdStr.c_str() }; execPrepared("auth_delete_privs", 1, values); for (const std::string &privilege : authEntry.privileges) { - const char *values[] = {authIdStr.c_str(), privilege.c_str()}; + const char *values[] = { authIdStr.c_str(), privilege.c_str() }; execPrepared("auth_write_privs", 2, values); } } + #endif // USE_POSTGRESQL diff --git a/src/database/database-postgresql.h b/src/database/database-postgresql.h index 36940b112..f47deda33 100644 --- a/src/database/database-postgresql.h +++ b/src/database/database-postgresql.h @@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., class Settings; -class Database_PostgreSQL : public Database +class Database_PostgreSQL: public Database { public: Database_PostgreSQL(const std::string &connect_string); @@ -38,6 +38,7 @@ public: bool initialized() const; + protected: // Conversion helpers inline int pg_to_int(PGresult *res, int row, int col) @@ -47,41 +48,41 @@ protected: inline u32 pg_to_uint(PGresult *res, int row, int col) { - return (u32)atoi(PQgetvalue(res, row, col)); + return (u32) atoi(PQgetvalue(res, row, col)); } inline float pg_to_float(PGresult *res, int row, int col) { - return (float)atof(PQgetvalue(res, row, col)); + return (float) atof(PQgetvalue(res, row, col)); } inline v3s16 pg_to_v3s16(PGresult *res, int row, int col) { - return v3s16(pg_to_int(res, row, col), pg_to_int(res, row, col + 1), - pg_to_int(res, row, col + 2)); + return v3s16( + pg_to_int(res, row, col), + pg_to_int(res, row, col + 1), + pg_to_int(res, row, col + 2) + ); } inline PGresult *execPrepared(const char *stmtName, const int paramsNumber, - const void **params, const int *paramsLengths = NULL, - const int *paramsFormats = NULL, bool clear = true, - bool nobinary = true) + const void **params, + const int *paramsLengths = NULL, const int *paramsFormats = NULL, + bool clear = true, bool nobinary = true) { return checkResults(PQexecPrepared(m_conn, stmtName, paramsNumber, - (const char *const *)params, - paramsLengths, paramsFormats, - nobinary ? 1 : 0), - clear); + (const char* const*) params, paramsLengths, paramsFormats, + nobinary ? 1 : 0), clear); } inline PGresult *execPrepared(const char *stmtName, const int paramsNumber, - const char **params, bool clear = true, bool nobinary = true) + const char **params, bool clear = true, bool nobinary = true) { - return execPrepared(stmtName, paramsNumber, (const void **)params, NULL, - NULL, clear, nobinary); + return execPrepared(stmtName, paramsNumber, + (const void **)params, NULL, NULL, clear, nobinary); } - void createTableIfNotExists( - const std::string &table_name, const std::string &definition); + void createTableIfNotExists(const std::string &table_name, const std::string &definition); void verifyDatabase(); // Database initialization @@ -94,7 +95,6 @@ protected: } const int getPGVersion() const { return m_pgversion; } - private: // Database connectivity checks void ping(); diff --git a/src/database/database-redis.cpp b/src/database/database-redis.cpp index e75063f73..096ea504d 100644 --- a/src/database/database-redis.cpp +++ b/src/database/database-redis.cpp @@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <hiredis.h> #include <cassert> + Database_Redis::Database_Redis(Settings &conf) { std::string tmp; @@ -38,15 +39,13 @@ Database_Redis::Database_Redis(Settings &conf) tmp = conf.get("redis_address"); hash = conf.get("redis_hash"); } catch (SettingNotFoundException &) { - throw SettingNotFoundException( - "Set redis_address and " - "redis_hash in world.mt to use the redis backend"); + throw SettingNotFoundException("Set redis_address and " + "redis_hash in world.mt to use the redis backend"); } const char *addr = tmp.c_str(); int port = conf.exists("redis_port") ? conf.getU16("redis_port") : 6379; // if redis_address contains '/' assume unix socket, else hostname/ip - ctx = tmp.find('/') != std::string::npos ? redisConnectUnix(addr) - : redisConnect(addr, port); + ctx = tmp.find('/') != std::string::npos ? redisConnectUnix(addr) : redisConnect(addr, port); if (!ctx) { throw DatabaseException("Cannot allocate redis context"); } else if (ctx->err) { @@ -56,13 +55,11 @@ Database_Redis::Database_Redis(Settings &conf) } if (conf.exists("redis_password")) { tmp = conf.get("redis_password"); - redisReply *reply = static_cast<redisReply *>( - redisCommand(ctx, "AUTH %s", tmp.c_str())); + redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "AUTH %s", tmp.c_str())); if (!reply) throw DatabaseException("Redis authentication failed"); if (reply->type == REDIS_REPLY_ERROR) { - std::string err = "Redis authentication failed: " + - std::string(reply->str, reply->len); + std::string err = "Redis authentication failed: " + std::string(reply->str, reply->len); freeReplyObject(reply); throw DatabaseException(err); } @@ -75,22 +72,20 @@ Database_Redis::~Database_Redis() redisFree(ctx); } -void Database_Redis::beginSave() -{ +void Database_Redis::beginSave() { redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "MULTI")); if (!reply) { - throw DatabaseException(std::string("Redis command 'MULTI' failed: ") + - ctx->errstr); + throw DatabaseException(std::string( + "Redis command 'MULTI' failed: ") + ctx->errstr); } freeReplyObject(reply); } -void Database_Redis::endSave() -{ +void Database_Redis::endSave() { redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "EXEC")); if (!reply) { - throw DatabaseException(std::string("Redis command 'EXEC' failed: ") + - ctx->errstr); + throw DatabaseException(std::string( + "Redis command 'EXEC' failed: ") + ctx->errstr); } freeReplyObject(reply); } @@ -103,16 +98,14 @@ bool Database_Redis::saveBlock(const v3s16 &pos, const std::string &data) hash.c_str(), tmp.c_str(), data.c_str(), data.size())); if (!reply) { warningstream << "saveBlock: redis command 'HSET' failed on " - "block " - << PP(pos) << ": " << ctx->errstr << std::endl; + "block " << PP(pos) << ": " << ctx->errstr << std::endl; freeReplyObject(reply); return false; } if (reply->type == REDIS_REPLY_ERROR) { warningstream << "saveBlock: saving block " << PP(pos) - << " failed: " << std::string(reply->str, reply->len) - << std::endl; + << " failed: " << std::string(reply->str, reply->len) << std::endl; freeReplyObject(reply); return false; } @@ -124,13 +117,12 @@ bool Database_Redis::saveBlock(const v3s16 &pos, const std::string &data) void Database_Redis::loadBlock(const v3s16 &pos, std::string *block) { std::string tmp = i64tos(getBlockAsInteger(pos)); - redisReply *reply = static_cast<redisReply *>( - redisCommand(ctx, "HGET %s %s", hash.c_str(), tmp.c_str())); + redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, + "HGET %s %s", hash.c_str(), tmp.c_str())); if (!reply) { - throw DatabaseException( - std::string("Redis command 'HGET %s %s' failed: ") + - ctx->errstr); + throw DatabaseException(std::string( + "Redis command 'HGET %s %s' failed: ") + ctx->errstr); } switch (reply->type) { @@ -144,10 +136,9 @@ void Database_Redis::loadBlock(const v3s16 &pos, std::string *block) std::string errstr(reply->str, reply->len); freeReplyObject(reply); errorstream << "loadBlock: loading block " << PP(pos) - << " failed: " << errstr << std::endl; - throw DatabaseException( - std::string("Redis command 'HGET %s %s' errored: ") + - errstr); + << " failed: " << errstr << std::endl; + throw DatabaseException(std::string( + "Redis command 'HGET %s %s' errored: ") + errstr); } case REDIS_REPLY_NIL: { *block = ""; @@ -158,27 +149,25 @@ void Database_Redis::loadBlock(const v3s16 &pos, std::string *block) } errorstream << "loadBlock: loading block " << PP(pos) - << " returned invalid reply type " << reply->type << ": " - << std::string(reply->str, reply->len) << std::endl; + << " returned invalid reply type " << reply->type + << ": " << std::string(reply->str, reply->len) << std::endl; freeReplyObject(reply); - throw DatabaseException( - std::string("Redis command 'HGET %s %s' gave invalid reply.")); + throw DatabaseException(std::string( + "Redis command 'HGET %s %s' gave invalid reply.")); } 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())); + redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, + "HDEL %s %s", hash.c_str(), tmp.c_str())); if (!reply) { - throw DatabaseException( - std::string("Redis command 'HDEL %s %s' failed: ") + - ctx->errstr); + throw DatabaseException(std::string( + "Redis command 'HDEL %s %s' failed: ") + ctx->errstr); } else if (reply->type == REDIS_REPLY_ERROR) { warningstream << "deleteBlock: deleting block " << PP(pos) - << " failed: " << std::string(reply->str, reply->len) - << std::endl; + << " failed: " << std::string(reply->str, reply->len) << std::endl; freeReplyObject(reply); return false; } @@ -189,11 +178,10 @@ bool Database_Redis::deleteBlock(const v3s16 &pos) void Database_Redis::listAllLoadableBlocks(std::vector<v3s16> &dst) { - redisReply *reply = static_cast<redisReply *>( - redisCommand(ctx, "HKEYS %s", hash.c_str())); + redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "HKEYS %s", hash.c_str())); if (!reply) { - throw DatabaseException(std::string("Redis command 'HKEYS %s' failed: ") + - ctx->errstr); + throw DatabaseException(std::string( + "Redis command 'HKEYS %s' failed: ") + ctx->errstr); } switch (reply->type) { case REDIS_REPLY_ARRAY: @@ -204,11 +192,12 @@ void Database_Redis::listAllLoadableBlocks(std::vector<v3s16> &dst) } break; case REDIS_REPLY_ERROR: - throw DatabaseException( - std::string("Failed to get keys from database: ") + - std::string(reply->str, reply->len)); + throw DatabaseException(std::string( + "Failed to get keys from database: ") + + std::string(reply->str, reply->len)); } freeReplyObject(reply); } #endif // USE_REDIS + diff --git a/src/database/database-sqlite3.cpp b/src/database/database-sqlite3.cpp index 5a9cee5ce..4560743b9 100644 --- a/src/database/database-sqlite3.cpp +++ b/src/database/database-sqlite3.cpp @@ -24,6 +24,7 @@ SQLite format specification: BLOB data */ + #include "database-sqlite3.h" #include "log.h" @@ -39,31 +40,32 @@ SQLite format specification: // When to print messages when the database is being held locked by another process // Note: I've seen occasional delays of over 250ms while running minetestmapper. -#define BUSY_INFO_TRESHOLD 100 // Print first informational message after 100ms. -#define BUSY_WARNING_TRESHOLD 250 // Print warning message after 250ms. Lag is increased. -#define BUSY_ERROR_TRESHOLD 1000 // Print error message after 1000ms. Significant lag. -#define BUSY_FATAL_TRESHOLD \ - 3000 // Allow SQLITE_BUSY to be returned, which will cause a minetest crash. -#define BUSY_ERROR_INTERVAL 10000 // Safety net: report again every 10 seconds - -#define SQLRES(s, r, m) \ - if ((s) != (r)) { \ - throw DatabaseException( \ - std::string(m) + ": " + sqlite3_errmsg(m_database)); \ +#define BUSY_INFO_TRESHOLD 100 // Print first informational message after 100ms. +#define BUSY_WARNING_TRESHOLD 250 // Print warning message after 250ms. Lag is increased. +#define BUSY_ERROR_TRESHOLD 1000 // Print error message after 1000ms. Significant lag. +#define BUSY_FATAL_TRESHOLD 3000 // Allow SQLITE_BUSY to be returned, which will cause a minetest crash. +#define BUSY_ERROR_INTERVAL 10000 // Safety net: report again every 10 seconds + + +#define SQLRES(s, r, m) \ + if ((s) != (r)) { \ + throw DatabaseException(std::string(m) + ": " +\ + sqlite3_errmsg(m_database)); \ } #define SQLOK(s, m) SQLRES(s, SQLITE_OK, m) -#define PREPARE_STATEMENT(name, query) \ - SQLOK(sqlite3_prepare_v2(m_database, query, -1, &m_stmt_##name, NULL), \ - "Failed to prepare query '" query "'") +#define PREPARE_STATEMENT(name, query) \ + SQLOK(sqlite3_prepare_v2(m_database, query, -1, &m_stmt_##name, NULL),\ + "Failed to prepare query '" query "'") -#define SQLOK_ERRSTREAM(s, m) \ - if ((s) != SQLITE_OK) { \ - errorstream << (m) << ": " << sqlite3_errmsg(m_database) << std::endl; \ +#define SQLOK_ERRSTREAM(s, m) \ + if ((s) != SQLITE_OK) { \ + errorstream << (m) << ": " \ + << sqlite3_errmsg(m_database) << std::endl; \ } -#define FINALIZE_STATEMENT(statement) \ - SQLOK_ERRSTREAM(sqlite3_finalize(statement), "Failed to finalize " #statement) +#define FINALIZE_STATEMENT(statement) SQLOK_ERRSTREAM(sqlite3_finalize(statement), \ + "Failed to finalize " #statement) int Database_SQLite3::busyHandler(void *data, int count) { @@ -76,7 +78,7 @@ int Database_SQLite3::busyHandler(void *data, int count) prev_time = first_time; } else { while (cur_time < prev_time) - cur_time += s64(1) << 32; + cur_time += s64(1)<<32; } if (cur_time - first_time < BUSY_INFO_TRESHOLD) { @@ -84,25 +86,24 @@ int Database_SQLite3::busyHandler(void *data, int count) } else if (cur_time - first_time >= BUSY_INFO_TRESHOLD && prev_time - first_time < BUSY_INFO_TRESHOLD) { infostream << "SQLite3 database has been locked for " - << cur_time - first_time << " ms." << std::endl; + << cur_time - first_time << " ms." << std::endl; } else if (cur_time - first_time >= BUSY_WARNING_TRESHOLD && prev_time - first_time < BUSY_WARNING_TRESHOLD) { warningstream << "SQLite3 database has been locked for " - << cur_time - first_time << " ms." << std::endl; + << cur_time - first_time << " ms." << std::endl; } else if (cur_time - first_time >= BUSY_ERROR_TRESHOLD && prev_time - first_time < BUSY_ERROR_TRESHOLD) { errorstream << "SQLite3 database has been locked for " - << cur_time - first_time << " ms; this causes lag." - << std::endl; + << cur_time - first_time << " ms; this causes lag." << std::endl; } else if (cur_time - first_time >= BUSY_FATAL_TRESHOLD && prev_time - first_time < BUSY_FATAL_TRESHOLD) { errorstream << "SQLite3 database has been locked for " - << cur_time - first_time << " ms - giving up!" << std::endl; + << cur_time - first_time << " ms - giving up!" << std::endl; } else if ((cur_time - first_time) / BUSY_ERROR_INTERVAL != (prev_time - first_time) / BUSY_ERROR_INTERVAL) { // Safety net: keep reporting every BUSY_ERROR_INTERVAL errorstream << "SQLite3 database has been locked for " - << (cur_time - first_time) / 1000 << " seconds!" << std::endl; + << (cur_time - first_time) / 1000 << " seconds!" << std::endl; } prev_time = cur_time; @@ -111,10 +112,10 @@ int Database_SQLite3::busyHandler(void *data, int count) return cur_time - first_time < BUSY_FATAL_TRESHOLD; } -Database_SQLite3::Database_SQLite3( - const std::string &savedir, const std::string &dbname) : - m_savedir(savedir), - m_dbname(dbname) + +Database_SQLite3::Database_SQLite3(const std::string &savedir, const std::string &dbname) : + m_savedir(savedir), + m_dbname(dbname) { } @@ -122,7 +123,7 @@ void Database_SQLite3::beginSave() { verifyDatabase(); SQLRES(sqlite3_step(m_stmt_begin), SQLITE_DONE, - "Failed to start SQLite3 transaction"); + "Failed to start SQLite3 transaction"); sqlite3_reset(m_stmt_begin); } @@ -130,14 +131,13 @@ void Database_SQLite3::endSave() { verifyDatabase(); SQLRES(sqlite3_step(m_stmt_end), SQLITE_DONE, - "Failed to commit SQLite3 transaction"); + "Failed to commit SQLite3 transaction"); sqlite3_reset(m_stmt_end); } void Database_SQLite3::openDatabase() { - if (m_database) - return; + if (m_database) return; std::string dbp = m_savedir + DIR_DELIM + m_dbname + ".sqlite"; @@ -145,37 +145,35 @@ void Database_SQLite3::openDatabase() if (!fs::CreateAllDirs(m_savedir)) { infostream << "Database_SQLite3: Failed to create directory \"" - << m_savedir << "\"" << std::endl; + << m_savedir << "\"" << std::endl; throw FileNotGoodException("Failed to create database " - "save directory"); + "save directory"); } bool needs_create = !fs::PathExists(dbp); SQLOK(sqlite3_open_v2(dbp.c_str(), &m_database, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL), - std::string("Failed to open SQLite3 database file ") + dbp); + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL), + std::string("Failed to open SQLite3 database file ") + dbp); SQLOK(sqlite3_busy_handler(m_database, Database_SQLite3::busyHandler, - m_busy_handler_data), - "Failed to set SQLite3 busy handler"); + m_busy_handler_data), "Failed to set SQLite3 busy handler"); if (needs_create) { createDatabase(); } - std::string query_str = std::string("PRAGMA synchronous = ") + - itos(g_settings->getU16("sqlite_synchronous")); + std::string query_str = std::string("PRAGMA synchronous = ") + + itos(g_settings->getU16("sqlite_synchronous")); SQLOK(sqlite3_exec(m_database, query_str.c_str(), NULL, NULL, NULL), - "Failed to modify sqlite3 synchronous mode"); + "Failed to modify sqlite3 synchronous mode"); SQLOK(sqlite3_exec(m_database, "PRAGMA foreign_keys = ON", NULL, NULL, NULL), - "Failed to enable sqlite3 foreign key support"); + "Failed to enable sqlite3 foreign key support"); } void Database_SQLite3::verifyDatabase() { - if (m_initialized) - return; + if (m_initialized) return; openDatabase(); @@ -199,8 +197,9 @@ Database_SQLite3::~Database_SQLite3() * Map database */ -MapDatabaseSQLite3::MapDatabaseSQLite3(const std::string &savedir) : - Database_SQLite3(savedir, "map"), MapDatabase() +MapDatabaseSQLite3::MapDatabaseSQLite3(const std::string &savedir): + Database_SQLite3(savedir, "map"), + MapDatabase() { } @@ -212,24 +211,25 @@ MapDatabaseSQLite3::~MapDatabaseSQLite3() FINALIZE_STATEMENT(m_stmt_delete) } + void MapDatabaseSQLite3::createDatabase() { assert(m_database); // Pre-condition SQLOK(sqlite3_exec(m_database, - "CREATE TABLE IF NOT EXISTS `blocks` (\n" - " `pos` INT PRIMARY KEY,\n" - " `data` BLOB\n" - ");\n", - NULL, NULL, NULL), - "Failed to create database table"); + "CREATE TABLE IF NOT EXISTS `blocks` (\n" + " `pos` INT PRIMARY KEY,\n" + " `data` BLOB\n" + ");\n", + NULL, NULL, NULL), + "Failed to create database table"); } void MapDatabaseSQLite3::initStatements() { PREPARE_STATEMENT(read, "SELECT `data` FROM `blocks` WHERE `pos` = ? LIMIT 1"); #ifdef __ANDROID__ - PREPARE_STATEMENT(write, "INSERT INTO `blocks` (`pos`, `data`) VALUES (?, ?)"); + PREPARE_STATEMENT(write, "INSERT INTO `blocks` (`pos`, `data`) VALUES (?, ?)"); #else PREPARE_STATEMENT(write, "REPLACE INTO `blocks` (`pos`, `data`) VALUES (?, ?)"); #endif @@ -242,8 +242,7 @@ void MapDatabaseSQLite3::initStatements() inline void MapDatabaseSQLite3::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__)); + "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); } bool MapDatabaseSQLite3::deleteBlock(const v3s16 &pos) @@ -256,8 +255,8 @@ bool MapDatabaseSQLite3::deleteBlock(const v3s16 &pos) sqlite3_reset(m_stmt_delete); if (!good) { - warningstream << "deleteBlock: Block failed to delete " << PP(pos) << ": " - << sqlite3_errmsg(m_database) << std::endl; + warningstream << "deleteBlock: Block failed to delete " + << PP(pos) << ": " << sqlite3_errmsg(m_database) << std::endl; } return good; } @@ -281,8 +280,7 @@ bool MapDatabaseSQLite3::saveBlock(const v3s16 &pos, const std::string &data) bindPos(m_stmt_write, pos); SQLOK(sqlite3_bind_blob(m_stmt_write, 2, data.data(), data.size(), NULL), - "Internal error: failed to bind query at " __FILE__ - ":" TOSTRING(__LINE__)); + "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); SQLRES(sqlite3_step(m_stmt_write), SQLITE_DONE, "Failed to save block") sqlite3_reset(m_stmt_write); @@ -301,7 +299,7 @@ void MapDatabaseSQLite3::loadBlock(const v3s16 &pos, std::string *block) return; } - const char *data = (const char *)sqlite3_column_blob(m_stmt_read, 0); + const char *data = (const char *) sqlite3_column_blob(m_stmt_read, 0); size_t len = sqlite3_column_bytes(m_stmt_read, 0); *block = (data) ? std::string(data, len) : ""; @@ -325,128 +323,118 @@ void MapDatabaseSQLite3::listAllLoadableBlocks(std::vector<v3s16> &dst) * Player Database */ -PlayerDatabaseSQLite3::PlayerDatabaseSQLite3(const std::string &savedir) : - Database_SQLite3(savedir, "players"), PlayerDatabase() +PlayerDatabaseSQLite3::PlayerDatabaseSQLite3(const std::string &savedir): + Database_SQLite3(savedir, "players"), + PlayerDatabase() { } -PlayerDatabaseSQLite3::~PlayerDatabaseSQLite3(){ - FINALIZE_STATEMENT(m_stmt_player_load) FINALIZE_STATEMENT(m_stmt_player_add) FINALIZE_STATEMENT( - m_stmt_player_update) FINALIZE_STATEMENT(m_stmt_player_remove) FINALIZE_STATEMENT(m_stmt_player_list) - FINALIZE_STATEMENT(m_stmt_player_add_inventory) FINALIZE_STATEMENT( - m_stmt_player_add_inventory_items) FINALIZE_STATEMENT(m_stmt_player_remove_inventory) - FINALIZE_STATEMENT(m_stmt_player_remove_inventory_items) FINALIZE_STATEMENT( - m_stmt_player_load_inventory) FINALIZE_STATEMENT(m_stmt_player_load_inventory_items) - FINALIZE_STATEMENT(m_stmt_player_metadata_load) FINALIZE_STATEMENT( - m_stmt_player_metadata_add) - FINALIZE_STATEMENT( - m_stmt_player_metadata_remove)}; +PlayerDatabaseSQLite3::~PlayerDatabaseSQLite3() +{ + FINALIZE_STATEMENT(m_stmt_player_load) + FINALIZE_STATEMENT(m_stmt_player_add) + FINALIZE_STATEMENT(m_stmt_player_update) + FINALIZE_STATEMENT(m_stmt_player_remove) + FINALIZE_STATEMENT(m_stmt_player_list) + FINALIZE_STATEMENT(m_stmt_player_add_inventory) + FINALIZE_STATEMENT(m_stmt_player_add_inventory_items) + FINALIZE_STATEMENT(m_stmt_player_remove_inventory) + FINALIZE_STATEMENT(m_stmt_player_remove_inventory_items) + FINALIZE_STATEMENT(m_stmt_player_load_inventory) + FINALIZE_STATEMENT(m_stmt_player_load_inventory_items) + FINALIZE_STATEMENT(m_stmt_player_metadata_load) + FINALIZE_STATEMENT(m_stmt_player_metadata_add) + FINALIZE_STATEMENT(m_stmt_player_metadata_remove) +}; + void PlayerDatabaseSQLite3::createDatabase() { assert(m_database); // Pre-condition SQLOK(sqlite3_exec(m_database, - "CREATE TABLE IF NOT EXISTS `player` (" - "`name` VARCHAR(50) NOT NULL," - "`pitch` NUMERIC(11, 4) NOT NULL," - "`yaw` NUMERIC(11, 4) NOT NULL," - "`posX` NUMERIC(11, 4) NOT NULL," - "`posY` NUMERIC(11, 4) NOT NULL," - "`posZ` NUMERIC(11, 4) NOT NULL," - "`hp` INT NOT NULL," - "`breath` INT NOT NULL," - "`creation_date` DATETIME NOT NULL DEFAULT " - "CURRENT_TIMESTAMP," - "`modification_date` DATETIME NOT NULL DEFAULT " - "CURRENT_TIMESTAMP," - "PRIMARY KEY (`name`));", - NULL, NULL, NULL), - "Failed to create player table"); + "CREATE TABLE IF NOT EXISTS `player` (" + "`name` VARCHAR(50) NOT NULL," + "`pitch` NUMERIC(11, 4) NOT NULL," + "`yaw` NUMERIC(11, 4) NOT NULL," + "`posX` NUMERIC(11, 4) NOT NULL," + "`posY` NUMERIC(11, 4) NOT NULL," + "`posZ` NUMERIC(11, 4) NOT NULL," + "`hp` INT NOT NULL," + "`breath` INT NOT NULL," + "`creation_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP," + "`modification_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP," + "PRIMARY KEY (`name`));", + NULL, NULL, NULL), + "Failed to create player table"); SQLOK(sqlite3_exec(m_database, - "CREATE TABLE IF NOT EXISTS `player_metadata` (" - " `player` VARCHAR(50) NOT NULL," - " `metadata` VARCHAR(256) NOT NULL," - " `value` TEXT," - " PRIMARY KEY(`player`, `metadata`)," - " FOREIGN KEY (`player`) REFERENCES player (`name`) ON " - "DELETE CASCADE );", - NULL, NULL, NULL), - "Failed to create player metadata table"); + "CREATE TABLE IF NOT EXISTS `player_metadata` (" + " `player` VARCHAR(50) NOT NULL," + " `metadata` VARCHAR(256) NOT NULL," + " `value` TEXT," + " PRIMARY KEY(`player`, `metadata`)," + " FOREIGN KEY (`player`) REFERENCES player (`name`) ON DELETE CASCADE );", + NULL, NULL, NULL), + "Failed to create player metadata table"); SQLOK(sqlite3_exec(m_database, - "CREATE TABLE IF NOT EXISTS `player_inventories` (" - " `player` VARCHAR(50) NOT NULL," - " `inv_id` INT NOT NULL," - " `inv_width` INT NOT NULL," - " `inv_name` TEXT NOT NULL DEFAULT ''," - " `inv_size` INT NOT NULL," - " PRIMARY KEY(player, inv_id)," - " FOREIGN KEY (`player`) REFERENCES player (`name`) ON " - "DELETE CASCADE );", - NULL, NULL, NULL), - "Failed to create player inventory table"); + "CREATE TABLE IF NOT EXISTS `player_inventories` (" + " `player` VARCHAR(50) NOT NULL," + " `inv_id` INT NOT NULL," + " `inv_width` INT NOT NULL," + " `inv_name` TEXT NOT NULL DEFAULT ''," + " `inv_size` INT NOT NULL," + " PRIMARY KEY(player, inv_id)," + " FOREIGN KEY (`player`) REFERENCES player (`name`) ON DELETE CASCADE );", + NULL, NULL, NULL), + "Failed to create player inventory table"); SQLOK(sqlite3_exec(m_database, - "CREATE TABLE `player_inventory_items` (" - " `player` VARCHAR(50) NOT NULL," - " `inv_id` INT NOT NULL," - " `slot_id` INT NOT NULL," - " `item` TEXT NOT NULL DEFAULT ''," - " PRIMARY KEY(player, inv_id, slot_id)," - " FOREIGN KEY (`player`) REFERENCES player (`name`) ON " - "DELETE CASCADE );", - NULL, NULL, NULL), - "Failed to create player inventory items table"); + "CREATE TABLE `player_inventory_items` (" + " `player` VARCHAR(50) NOT NULL," + " `inv_id` INT NOT NULL," + " `slot_id` INT NOT NULL," + " `item` TEXT NOT NULL DEFAULT ''," + " PRIMARY KEY(player, inv_id, slot_id)," + " FOREIGN KEY (`player`) REFERENCES player (`name`) ON DELETE CASCADE );", + NULL, NULL, NULL), + "Failed to create player inventory items table"); } void PlayerDatabaseSQLite3::initStatements() { - PREPARE_STATEMENT(player_load, - "SELECT `pitch`, `yaw`, `posX`, `posY`, `posZ`, `hp`, " - "`breath`" - "FROM `player` WHERE `name` = ?") - PREPARE_STATEMENT(player_add, - "INSERT INTO `player` (`name`, `pitch`, `yaw`, `posX`, " - "`posY`, `posZ`, `hp`, `breath`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)") - PREPARE_STATEMENT(player_update, - "UPDATE `player` SET `pitch` = ?, `yaw` = ?, " + PREPARE_STATEMENT(player_load, "SELECT `pitch`, `yaw`, `posX`, `posY`, `posZ`, `hp`, " + "`breath`" + "FROM `player` WHERE `name` = ?") + PREPARE_STATEMENT(player_add, "INSERT INTO `player` (`name`, `pitch`, `yaw`, `posX`, " + "`posY`, `posZ`, `hp`, `breath`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)") + PREPARE_STATEMENT(player_update, "UPDATE `player` SET `pitch` = ?, `yaw` = ?, " "`posX` = ?, `posY` = ?, `posZ` = ?, `hp` = ?, `breath` = ?, " "`modification_date` = CURRENT_TIMESTAMP WHERE `name` = ?") PREPARE_STATEMENT(player_remove, "DELETE FROM `player` WHERE `name` = ?") PREPARE_STATEMENT(player_list, "SELECT `name` FROM `player`") - PREPARE_STATEMENT(player_add_inventory, - "INSERT INTO `player_inventories` " - "(`player`, `inv_id`, `inv_width`, `inv_name`, `inv_size`) " - "VALUES (?, ?, ?, ?, ?)") - PREPARE_STATEMENT(player_add_inventory_items, - "INSERT INTO `player_inventory_items` " - "(`player`, `inv_id`, `slot_id`, `item`) VALUES (?, ?, ?, ?)") + PREPARE_STATEMENT(player_add_inventory, "INSERT INTO `player_inventories` " + "(`player`, `inv_id`, `inv_width`, `inv_name`, `inv_size`) VALUES (?, ?, ?, ?, ?)") + PREPARE_STATEMENT(player_add_inventory_items, "INSERT INTO `player_inventory_items` " + "(`player`, `inv_id`, `slot_id`, `item`) VALUES (?, ?, ?, ?)") PREPARE_STATEMENT(player_remove_inventory, "DELETE FROM `player_inventories` " - "WHERE `player` = ?") - PREPARE_STATEMENT(player_remove_inventory_items, - "DELETE FROM `player_inventory_items` " - "WHERE `player` = ?") - PREPARE_STATEMENT(player_load_inventory, - "SELECT `inv_id`, `inv_width`, `inv_name`, " - "`inv_size` FROM `player_inventories` WHERE `player` = ? ORDER " - "BY inv_id") - PREPARE_STATEMENT(player_load_inventory_items, - "SELECT `slot_id`, `item` " - "FROM `player_inventory_items` WHERE `player` = ? AND `inv_id` = " - "?") + "WHERE `player` = ?") + PREPARE_STATEMENT(player_remove_inventory_items, "DELETE FROM `player_inventory_items` " + "WHERE `player` = ?") + PREPARE_STATEMENT(player_load_inventory, "SELECT `inv_id`, `inv_width`, `inv_name`, " + "`inv_size` FROM `player_inventories` WHERE `player` = ? ORDER BY inv_id") + PREPARE_STATEMENT(player_load_inventory_items, "SELECT `slot_id`, `item` " + "FROM `player_inventory_items` WHERE `player` = ? AND `inv_id` = ?") PREPARE_STATEMENT(player_metadata_load, "SELECT `metadata`, `value` FROM " - "`player_metadata` WHERE `player` = ?") - PREPARE_STATEMENT(player_metadata_add, - "INSERT INTO `player_metadata` " - "(`player`, `metadata`, `value`) VALUES (?, ?, ?)") + "`player_metadata` WHERE `player` = ?") + PREPARE_STATEMENT(player_metadata_add, "INSERT INTO `player_metadata` " + "(`player`, `metadata`, `value`) VALUES (?, ?, ?)") PREPARE_STATEMENT(player_metadata_remove, "DELETE FROM `player_metadata` " - "WHERE `player` = ?") - verbosestream << "ServerEnvironment: SQLite3 database opened (players)." - << std::endl; + "WHERE `player` = ?") + verbosestream << "ServerEnvironment: SQLite3 database opened (players)." << std::endl; } bool PlayerDatabaseSQLite3::playerDataExists(const std::string &name) @@ -460,7 +448,7 @@ bool PlayerDatabaseSQLite3::playerDataExists(const std::string &name) void PlayerDatabaseSQLite3::savePlayer(RemotePlayer *player) { - PlayerSAO *sao = player->getPlayerSAO(); + PlayerSAO* sao = player->getPlayerSAO(); sanity_check(sao); const v3f &pos = sao->getBasePosition(); @@ -502,10 +490,9 @@ void PlayerDatabaseSQLite3::savePlayer(RemotePlayer *player) sqlite3_vrfy(sqlite3_step(m_stmt_player_remove_inventory_items), SQLITE_DONE); sqlite3_reset(m_stmt_player_remove_inventory_items); - std::vector<const InventoryList *> inventory_lists = - sao->getInventory()->getLists(); + std::vector<const InventoryList*> inventory_lists = sao->getInventory()->getLists(); for (u16 i = 0; i < inventory_lists.size(); i++) { - const InventoryList *list = inventory_lists[i]; + const InventoryList* list = inventory_lists[i]; str_to_sqlite(m_stmt_player_add_inventory, 1, player->getName()); int_to_sqlite(m_stmt_player_add_inventory, 2, i); @@ -520,13 +507,11 @@ void PlayerDatabaseSQLite3::savePlayer(RemotePlayer *player) list->getItem(j).serialize(os); std::string itemStr = os.str(); - str_to_sqlite(m_stmt_player_add_inventory_items, 1, - player->getName()); + str_to_sqlite(m_stmt_player_add_inventory_items, 1, player->getName()); int_to_sqlite(m_stmt_player_add_inventory_items, 2, i); int_to_sqlite(m_stmt_player_add_inventory_items, 3, j); str_to_sqlite(m_stmt_player_add_inventory_items, 4, itemStr); - sqlite3_vrfy(sqlite3_step(m_stmt_player_add_inventory_items), - SQLITE_DONE); + sqlite3_vrfy(sqlite3_step(m_stmt_player_add_inventory_items), SQLITE_DONE); sqlite3_reset(m_stmt_player_add_inventory_items); } } @@ -561,16 +546,16 @@ bool PlayerDatabaseSQLite3::loadPlayer(RemotePlayer *player, PlayerSAO *sao) sao->setLookPitch(sqlite_to_float(m_stmt_player_load, 0)); sao->setPlayerYaw(sqlite_to_float(m_stmt_player_load, 1)); sao->setBasePosition(sqlite_to_v3f(m_stmt_player_load, 2)); - sao->setHPRaw((u16)MYMIN(sqlite_to_int(m_stmt_player_load, 5), U16_MAX)); - sao->setBreath((u16)MYMIN(sqlite_to_int(m_stmt_player_load, 6), U16_MAX), false); + sao->setHPRaw((u16) MYMIN(sqlite_to_int(m_stmt_player_load, 5), U16_MAX)); + sao->setBreath((u16) MYMIN(sqlite_to_int(m_stmt_player_load, 6), U16_MAX), false); sqlite3_reset(m_stmt_player_load); // Load inventory str_to_sqlite(m_stmt_player_load_inventory, 1, player->getName()); while (sqlite3_step(m_stmt_player_load_inventory) == SQLITE_ROW) { InventoryList *invList = player->inventory.addList( - sqlite_to_string(m_stmt_player_load_inventory, 2), - sqlite_to_uint(m_stmt_player_load_inventory, 3)); + sqlite_to_string(m_stmt_player_load_inventory, 2), + sqlite_to_uint(m_stmt_player_load_inventory, 3)); invList->setWidth(sqlite_to_uint(m_stmt_player_load_inventory, 1)); u32 invId = sqlite_to_uint(m_stmt_player_load_inventory, 0); @@ -578,15 +563,11 @@ bool PlayerDatabaseSQLite3::loadPlayer(RemotePlayer *player, PlayerSAO *sao) str_to_sqlite(m_stmt_player_load_inventory_items, 1, player->getName()); int_to_sqlite(m_stmt_player_load_inventory_items, 2, invId); while (sqlite3_step(m_stmt_player_load_inventory_items) == SQLITE_ROW) { - const std::string itemStr = sqlite_to_string( - m_stmt_player_load_inventory_items, 1); + const std::string itemStr = sqlite_to_string(m_stmt_player_load_inventory_items, 1); if (itemStr.length() > 0) { ItemStack stack; stack.deSerialize(itemStr); - invList->changeItem( - sqlite_to_uint(m_stmt_player_load_inventory_items, - 0), - stack); + invList->changeItem(sqlite_to_uint(m_stmt_player_load_inventory_items, 0), stack); } } sqlite3_reset(m_stmt_player_load_inventory_items); @@ -654,43 +635,37 @@ void AuthDatabaseSQLite3::createDatabase() assert(m_database); // Pre-condition SQLOK(sqlite3_exec(m_database, - "CREATE TABLE IF NOT EXISTS `auth` (" - "`id` INTEGER PRIMARY KEY AUTOINCREMENT," - "`name` VARCHAR(32) UNIQUE," - "`password` VARCHAR(512)," - "`last_login` INTEGER" - ");", - NULL, NULL, NULL), - "Failed to create auth table"); + "CREATE TABLE IF NOT EXISTS `auth` (" + "`id` INTEGER PRIMARY KEY AUTOINCREMENT," + "`name` VARCHAR(32) UNIQUE," + "`password` VARCHAR(512)," + "`last_login` INTEGER" + ");", + NULL, NULL, NULL), + "Failed to create auth table"); SQLOK(sqlite3_exec(m_database, - "CREATE TABLE IF NOT EXISTS `user_privileges` (" - "`id` INTEGER," - "`privilege` VARCHAR(32)," - "PRIMARY KEY (id, privilege)" - "CONSTRAINT fk_id FOREIGN KEY (id) REFERENCES auth (id) ON " - "DELETE CASCADE" - ");", - NULL, NULL, NULL), - "Failed to create auth privileges table"); + "CREATE TABLE IF NOT EXISTS `user_privileges` (" + "`id` INTEGER," + "`privilege` VARCHAR(32)," + "PRIMARY KEY (id, privilege)" + "CONSTRAINT fk_id FOREIGN KEY (id) REFERENCES auth (id) ON DELETE CASCADE" + ");", + NULL, NULL, NULL), + "Failed to create auth privileges table"); } void AuthDatabaseSQLite3::initStatements() { - PREPARE_STATEMENT(read, - "SELECT id, name, password, last_login FROM auth WHERE name = ?"); - PREPARE_STATEMENT(write, "UPDATE auth set name = ?, password = ?, last_login = ? " - "WHERE id = ?"); - PREPARE_STATEMENT(create, - "INSERT INTO auth (name, password, last_login) VALUES (?, ?, ?)"); + PREPARE_STATEMENT(read, "SELECT id, name, password, last_login FROM auth WHERE name = ?"); + PREPARE_STATEMENT(write, "UPDATE auth set name = ?, password = ?, last_login = ? WHERE id = ?"); + PREPARE_STATEMENT(create, "INSERT INTO auth (name, password, last_login) VALUES (?, ?, ?)"); PREPARE_STATEMENT(delete, "DELETE FROM auth WHERE name = ?"); PREPARE_STATEMENT(list_names, "SELECT name FROM auth ORDER BY name DESC"); - PREPARE_STATEMENT( - read_privs, "SELECT privilege FROM user_privileges WHERE id = ?"); - PREPARE_STATEMENT(write_privs, "INSERT OR IGNORE INTO user_privileges (id, " - "privilege) VALUES (?, ?)"); + PREPARE_STATEMENT(read_privs, "SELECT privilege FROM user_privileges WHERE id = ?"); + PREPARE_STATEMENT(write_privs, "INSERT OR IGNORE INTO user_privileges (id, privilege) VALUES (?, ?)"); PREPARE_STATEMENT(delete_privs, "DELETE FROM user_privileges WHERE id = ?"); PREPARE_STATEMENT(last_insert_rowid, "SELECT last_insert_rowid()"); diff --git a/src/database/database-sqlite3.h b/src/database/database-sqlite3.h index ce568ae27..d7202a918 100644 --- a/src/database/database-sqlite3.h +++ b/src/database/database-sqlite3.h @@ -37,7 +37,6 @@ public: void endSave(); bool initialized() const { return m_initialized; } - protected: Database_SQLite3(const std::string &savedir, const std::string &dbname); @@ -62,7 +61,7 @@ protected: inline void int64_to_sqlite(sqlite3_stmt *s, int iCol, s64 val) const { - sqlite3_vrfy(sqlite3_bind_int64(s, iCol, (sqlite3_int64)val)); + sqlite3_vrfy(sqlite3_bind_int64(s, iCol, (sqlite3_int64) val)); } inline void double_to_sqlite(sqlite3_stmt *s, int iCol, double val) const @@ -72,8 +71,7 @@ protected: inline std::string sqlite_to_string(sqlite3_stmt *s, int iCol) { - const char *text = reinterpret_cast<const char *>( - sqlite3_column_text(s, iCol)); + const char* text = reinterpret_cast<const char*>(sqlite3_column_text(s, iCol)); return std::string(text ? text : ""); } @@ -84,22 +82,22 @@ protected: inline u32 sqlite_to_uint(sqlite3_stmt *s, int iCol) { - return (u32)sqlite3_column_int(s, iCol); + return (u32) sqlite3_column_int(s, iCol); } inline s64 sqlite_to_int64(sqlite3_stmt *s, int iCol) { - return (s64)sqlite3_column_int64(s, iCol); + return (s64) sqlite3_column_int64(s, iCol); } inline u64 sqlite_to_uint64(sqlite3_stmt *s, int iCol) { - return (u64)sqlite3_column_int64(s, iCol); + return (u64) sqlite3_column_int64(s, iCol); } inline float sqlite_to_float(sqlite3_stmt *s, int iCol) { - return (float)sqlite3_column_double(s, iCol); + return (float) sqlite3_column_double(s, iCol); } inline const v3f sqlite_to_v3f(sqlite3_stmt *s, int iCol) @@ -109,15 +107,13 @@ protected: } // Query verifiers helpers - inline void sqlite3_vrfy( - int s, const std::string &m = "", int r = SQLITE_OK) const + inline void sqlite3_vrfy(int s, const std::string &m = "", int r = SQLITE_OK) const { if (s != r) throw DatabaseException(m + ": " + sqlite3_errmsg(m_database)); } - inline void sqlite3_vrfy( - const int s, const int r, const std::string &m = "") const + inline void sqlite3_vrfy(const int s, const int r, const std::string &m = "") const { sqlite3_vrfy(s, m, r); } @@ -127,7 +123,6 @@ protected: virtual void initStatements() = 0; sqlite3 *m_database = nullptr; - private: // Open the database void openDatabase(); @@ -158,7 +153,6 @@ public: void beginSave() { Database_SQLite3::beginSave(); } void endSave() { Database_SQLite3::endSave(); } - protected: virtual void createDatabase(); virtual void initStatements(); diff --git a/src/database/database.cpp b/src/database/database.cpp index 01cb2b5fc..12e0e1a0f 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "database.h" #include "irrlichttypes.h" + /**************** * Black magic! * **************** @@ -36,6 +37,7 @@ static inline s16 unsigned_to_signed(u16 i, u16 max_positive) return i - (max_positive * 2); } + // Modulo of a negative number does not work consistently in C static inline s64 pythonmodulo(s64 i, s16 mod) { @@ -45,11 +47,15 @@ static inline s64 pythonmodulo(s64 i, s16 mod) return mod - ((-i) % mod); } + s64 MapDatabase::getBlockAsInteger(const v3s16 &pos) { - return (u64)pos.Z * 0x1000000 + (u64)pos.Y * 0x1000 + (u64)pos.X; + return (u64) pos.Z * 0x1000000 + + (u64) pos.Y * 0x1000 + + (u64) pos.X; } + v3s16 MapDatabase::getIntegerAsBlock(s64 i) { v3s16 pos; @@ -60,3 +66,4 @@ v3s16 MapDatabase::getIntegerAsBlock(s64 i) pos.Z = unsigned_to_signed(pythonmodulo(i, 4096), 2048); return pos; } + |