mirror of
https://github.com/minetest/minetestmapper.git
synced 2024-11-21 23:13:53 +01:00
Prepare statements at startup and finalize them
This commit is contained in:
parent
66813a36b8
commit
6e565e93d1
@ -2,73 +2,82 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <unistd.h> // for usleep
|
#include <unistd.h> // for usleep
|
||||||
|
|
||||||
DBSQLite3::DBSQLite3(const std::string &mapdir) {
|
#define SQLRES(f, good) \
|
||||||
|
result = (sqlite3_##f);\
|
||||||
std::string db_name = mapdir + "map.sqlite";
|
if (result != good) {\
|
||||||
if (sqlite3_open_v2(db_name.c_str(), &m_db, SQLITE_OPEN_READONLY | SQLITE_OPEN_PRIVATECACHE, 0) != SQLITE_OK) {
|
throw std::runtime_error(sqlite3_errmsg(m_db));\
|
||||||
throw std::runtime_error(std::string(sqlite3_errmsg(m_db)) + ", Database file: " + db_name);
|
|
||||||
}
|
}
|
||||||
|
#define SQLOK(f) SQLRES(f, SQLITE_OK)
|
||||||
|
|
||||||
|
DBSQLite3::DBSQLite3(const std::string &mapdir) {
|
||||||
|
int result;
|
||||||
|
std::string db_name = mapdir + "map.sqlite";
|
||||||
|
|
||||||
|
SQLOK(open_v2(db_name.c_str(), &m_db, SQLITE_OPEN_READONLY | SQLITE_OPEN_PRIVATECACHE, 0))
|
||||||
|
|
||||||
|
SQLOK(prepare_v2(m_db,
|
||||||
|
"SELECT pos, data FROM blocks WHERE (pos >= ? AND pos <= ?)",
|
||||||
|
-1, &stmt_get_blocks, NULL))
|
||||||
|
|
||||||
|
SQLOK(prepare_v2(m_db,
|
||||||
|
"SELECT pos FROM blocks",
|
||||||
|
-1, &stmt_get_block_pos, NULL))
|
||||||
}
|
}
|
||||||
|
|
||||||
DBSQLite3::~DBSQLite3() {
|
DBSQLite3::~DBSQLite3() {
|
||||||
sqlite3_close(m_db);
|
int result;
|
||||||
|
SQLOK(finalize(stmt_get_blocks));
|
||||||
|
SQLOK(finalize(stmt_get_block_pos));
|
||||||
|
|
||||||
|
SQLOK(close(m_db));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int64_t> DBSQLite3::getBlockPos() {
|
std::vector<int64_t> DBSQLite3::getBlockPos() {
|
||||||
std::vector<int64_t> vec;
|
std::vector<int64_t> vec;
|
||||||
sqlite3_stmt *statement;
|
int result = 0;
|
||||||
std::string sql = "SELECT pos FROM blocks";
|
while ((result = sqlite3_step(stmt_get_block_pos)) != SQLITE_DONE) {
|
||||||
if (sqlite3_prepare_v2(m_db, sql.c_str(), sql.length(), &statement, 0) == SQLITE_OK) {
|
if (result == SQLITE_ROW) {
|
||||||
int result = 0;
|
int64_t blockpos = sqlite3_column_int64(stmt_get_block_pos, 0);
|
||||||
while (true) {
|
vec.push_back(blockpos);
|
||||||
result = sqlite3_step(statement);
|
} else if (result == SQLITE_BUSY) { // Wait some time and try again
|
||||||
if(result == SQLITE_ROW) {
|
usleep(10000);
|
||||||
sqlite3_int64 blocknum = sqlite3_column_int64(statement, 0);
|
} else {
|
||||||
vec.push_back(blocknum);
|
throw std::runtime_error(sqlite3_errmsg(m_db));
|
||||||
} else if (result == SQLITE_BUSY) // Wait some time and try again
|
|
||||||
usleep(10000);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw std::runtime_error("Failed to get list of MapBlocks");
|
|
||||||
}
|
}
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBBlockList DBSQLite3::getBlocksOnZ(int zPos)
|
DBBlockList DBSQLite3::getBlocksOnZ(int zPos)
|
||||||
{
|
{
|
||||||
sqlite3_stmt *statement;
|
|
||||||
std::string sql = "SELECT pos, data FROM blocks WHERE (pos >= ? AND pos <= ?)";
|
|
||||||
if (sqlite3_prepare_v2(m_db, sql.c_str(), sql.length(), &statement, 0) != SQLITE_OK) {
|
|
||||||
throw std::runtime_error("Failed to prepare statement");
|
|
||||||
}
|
|
||||||
DBBlockList blocks;
|
DBBlockList blocks;
|
||||||
|
|
||||||
sqlite3_int64 psMin;
|
sqlite3_int64 psMin;
|
||||||
sqlite3_int64 psMax;
|
sqlite3_int64 psMax;
|
||||||
|
|
||||||
psMin = (static_cast<sqlite3_int64>(zPos) * 16777216l) - 0x800000;
|
psMin = (static_cast<sqlite3_int64>(zPos) * 16777216L) - 0x800000;
|
||||||
psMax = (static_cast<sqlite3_int64>(zPos) * 16777216l) + 0x7fffff;
|
psMax = (static_cast<sqlite3_int64>(zPos) * 16777216L) + 0x7fffff;
|
||||||
sqlite3_bind_int64(statement, 1, psMin);
|
sqlite3_bind_int64(stmt_get_blocks, 1, psMin);
|
||||||
sqlite3_bind_int64(statement, 2, psMax);
|
sqlite3_bind_int64(stmt_get_blocks, 2, psMax);
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
while (true) {
|
while ((result = sqlite3_step(stmt_get_blocks)) != SQLITE_DONE) {
|
||||||
result = sqlite3_step(statement);
|
if (result == SQLITE_ROW) {
|
||||||
if(result == SQLITE_ROW) {
|
int64_t blocknum = sqlite3_column_int64(stmt_get_blocks, 0);
|
||||||
sqlite3_int64 blocknum = sqlite3_column_int64(statement, 0);
|
const unsigned char *data = reinterpret_cast<const unsigned char *>(sqlite3_column_blob(stmt_get_blocks, 1));
|
||||||
const unsigned char *data = reinterpret_cast<const unsigned char *>(sqlite3_column_blob(statement, 1));
|
int size = sqlite3_column_bytes(stmt_get_blocks, 1);
|
||||||
int size = sqlite3_column_bytes(statement, 1);
|
|
||||||
blocks.push_back(DBBlock(blocknum, std::basic_string<unsigned char>(data, size)));
|
blocks.push_back(DBBlock(blocknum, std::basic_string<unsigned char>(data, size)));
|
||||||
} else if (result == SQLITE_BUSY) { // Wait some time and try again
|
} else if (result == SQLITE_BUSY) { // Wait some time and try again
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
} else {
|
} else {
|
||||||
break;
|
throw std::runtime_error(sqlite3_errmsg(m_db));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3_reset(statement);
|
SQLOK(reset(stmt_get_blocks));
|
||||||
|
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef SQLRES
|
||||||
|
#undef SQLOK
|
||||||
|
|
||||||
|
@ -12,6 +12,9 @@ public:
|
|||||||
~DBSQLite3();
|
~DBSQLite3();
|
||||||
private:
|
private:
|
||||||
sqlite3 *m_db;
|
sqlite3 *m_db;
|
||||||
|
|
||||||
|
sqlite3_stmt *stmt_get_block_pos;
|
||||||
|
sqlite3_stmt *stmt_get_blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _DB_SQLITE3_H
|
#endif // _DB_SQLITE3_H
|
||||||
|
Loading…
Reference in New Issue
Block a user