SQL: change cache code type to integer via a bit naive conversions. Too lazy to use loops ;)

sql-rework
Tomasz Golinski 2020-09-14 21:23:34 +02:00
rodzic ff971f716c
commit 1db28d00c4
2 zmienionych plików z 58 dodań i 12 usunięć

Wyświetl plik

@ -55,8 +55,8 @@ bool OCdb::init(const std::string& dump_path) {
throw 1;
if (!request("CREATE TABLE IF NOT EXISTS revision (revision INTEGER PRIMARY KEY);") ||
!request("CREATE TABLE IF NOT EXISTS caches (code TEXT PRIMARY KEY, name TEXT, location TEXT, type TEXT, status INTEGER, size TEXT, difficulty INTEGER, terrain INTEGER, country TEXT, region TEXT, owner TEXT);") ||
!request("CREATE TABLE IF NOT EXISTS logs (uuid TEXT PRIMARY KEY, cache_code TEXT, date TEXT, user TEXT, type INTEGER);") ||
!request("CREATE TABLE IF NOT EXISTS caches (code INTEGER PRIMARY KEY, name TEXT, location TEXT, type TEXT, status INTEGER, size TEXT, difficulty INTEGER, terrain INTEGER, country TEXT, region TEXT, owner TEXT);") ||
!request("CREATE TABLE IF NOT EXISTS logs (uuid TEXT PRIMARY KEY, cache_code INTEGER, date TEXT, user TEXT, type INTEGER);") ||
!request("CREATE INDEX idx_user on logs (user, type);"))
throw 1;
request("COMMIT;");
@ -119,7 +119,9 @@ bool OCdb::parse_item(const json& j) {
update_cache(j);
} else if (j.count("change_type") && j["change_type"] == "delete") {
Debug(2) << "Deleting cache " << j["object_key"]["code"].get<std::string>() << ".\n";
sql = "DELETE FROM caches WHERE code='" + j["object_key"]["code"].get<std::string>() + "';";
sql = "DELETE FROM caches WHERE code='";
sql += cache_code_to_int(j["object_key"]["code"].get<std::string>());
sql += "';";
request(sql);
} else {
Debug(1) << "Incorrect change type: " << j["change_type"] << ".\n";
@ -142,14 +144,14 @@ bool OCdb::parse_item(const json& j) {
}
bool OCdb::update_cache(const json& j) {
// (code TEXT PRIMARY KEY, name TEXT, location TEXT, type TEXT, status INTEGER, size TEXT, difficulty INTEGER, terrain INTEGER, country TEXT, region TEXT, owner TEXT)
// (code INTEGER PRIMARY KEY, name TEXT, location TEXT, type TEXT, status INTEGER, size TEXT, difficulty INTEGER, terrain INTEGER, country TEXT, region TEXT, owner TEXT)
std::map<std::string, std::string> fields;
std::map<std::string, short> fields2;
int res;
if (!j.count("object_key") || !j["object_key"].count("code") || !j.count("data")) return 0;
std::string code = j["object_key"]["code"].get<std::string>();
int code = cache_code_to_int(j["object_key"]["code"].get<std::string>());
if (j["data"].count("names") && j["data"]["names"].count("pl") && !j["data"]["names"]["pl"].is_null())
fields["name"] = j["data"]["names"]["pl"].get<std::string>();
else if (j["data"].count("names") && j["data"]["names"].count("en") && !j["data"]["names"]["en"].is_null())
@ -189,7 +191,7 @@ bool OCdb::update_cache(const json& j) {
for (auto& i : fields2)
sql += i.first + ',';
sql.pop_back();
sql += ") VALUES ('" + code + "',";
sql += ") VALUES ('" + std::to_string(code) + "',";
for (__attribute__((unused)) auto& i : fields)
sql += "?,";
for (__attribute__((unused)) auto& i : fields2)
@ -227,7 +229,7 @@ bool OCdb::update_cache(const json& j) {
}
bool OCdb::update_log(const json& j) {
// logs (uuid TEXT PRIMARY KEY, cache_code TEXT, date TEXT, user TEXT, type TEXT);"))
// logs (uuid TEXT PRIMARY KEY, cache_code INTEGER, date TEXT, user TEXT, type TEXT);"))
std::map<std::string, std::string> fields;
std::map<std::string, short> fields2;
int res;
@ -236,7 +238,7 @@ bool OCdb::update_log(const json& j) {
std::string uuid = j["object_key"]["uuid"].get<std::string>();
if (j["data"].count("cache_code") && !j["data"]["cache_code"].is_null())
fields["cache_code"] = j["data"]["cache_code"].get<std::string>();
fields2["cache_code"] = cache_code_to_int(j["data"]["cache_code"].get<std::string>());
if (j["data"].count("date") && !j["data"]["date"].is_null())
fields["date"] = j["data"]["date"].get<std::string>();
if (j["data"].count("user") && j["data"]["user"].count("uuid") && !j["data"]["user"]["uuid"].is_null())
@ -337,7 +339,7 @@ Caches OCdb::get_user_caches_not_found(const std::string& uuid) const {
res = sqlite3_step(stmt);
while (res == SQLITE_ROW) {
Cache c;
if (sqlite3_column_text(stmt, 0)) c.code = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
if (sqlite3_column_text(stmt, 0)) c.code = int_to_cache_code(sqlite3_column_int(stmt, 0));
if (sqlite3_column_text(stmt, 1)) c.pos = Position(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)));
if (sqlite3_column_text(stmt, 2)) c.region = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
c.status = ok;
@ -357,7 +359,7 @@ Caches OCdb::get_user_caches_not_found(const std::string& uuid) const {
Caches OCdb::get_user_caches(const std::string& uuid, __attribute__((unused)) int count) const {
int res;
//code TEXT PRIMARY KEY, name TEXT, location TEXT, type TEXT, status INTEGER, size TEXT, difficulty INTEGER, terrain INTEGER, country TEXT, region TEXT, owner TEXT)
//code INTEGER PRIMARY KEY, name TEXT, location TEXT, type TEXT, status INTEGER, size TEXT, difficulty INTEGER, terrain INTEGER, country TEXT, region TEXT, owner TEXT)
sql = "SELECT code, location, type, size, difficulty, terrain, country, region, owner, status, name FROM caches WHERE EXISTS (SELECT cache_code FROM logs WHERE cache_code = code AND type = ";
sql += found;
sql += " and user = ?);";
@ -375,7 +377,7 @@ Caches OCdb::get_user_caches(const std::string& uuid, __attribute__((unused)) in
Caches OCdb::get_user_caches_owned(const std::string& uuid) const {
int res;
//code TEXT PRIMARY KEY, name TEXT, location TEXT, type TEXT, status TEXT, size TEXT, difficulty INTEGER, terrain INTEGER, country TEXT, region TEXT, owner TEXT)
//code INTEGER PRIMARY KEY, name TEXT, location TEXT, type TEXT, status TEXT, size TEXT, difficulty INTEGER, terrain INTEGER, country TEXT, region TEXT, owner TEXT)
sql = "SELECT code, location, type, size, difficulty, terrain, country, region, owner, status, name FROM caches WHERE owner = ?;";
res = sqlite3_prepare_v2(db, sql.c_str(), sql.length() + 1, &stmt, NULL);
@ -395,7 +397,7 @@ Caches OCdb::parse_sql_caches() const {
res = sqlite3_step(stmt);
while (res == SQLITE_ROW) {
Cache c;
if (sqlite3_column_text(stmt, 0)) c.code = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
if (sqlite3_column_text(stmt, 0)) c.code = int_to_cache_code(sqlite3_column_int(stmt, 0));
if (sqlite3_column_text(stmt, 1)) c.pos = Position(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)));
if (sqlite3_column_text(stmt, 2)) c.type = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
if (sqlite3_column_text(stmt, 3)) c.size = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
@ -479,3 +481,43 @@ std::map<std::string, int> OCdb::get_region_stats() {
sqlite3_finalize(stmt);
return count;
}
std::string OCdb::int_to_cache_code(int n) const {
const int n5 = 36 * 36 * 36 * 36;
const int n4 = 36 * 36 * 36;
const int n3 = 36 * 36;
const int n2 = 36;
int x;
std::stringstream ss;
ss << cache_code_prefix;
if (n >= n5) {
x = n/n5;
if (x >= 10) ss << static_cast<char>('A' + x - 10);
else ss << x;
n %= n5;
}
x = n/n4;
if (x >= 10) ss << static_cast<char>('A' + x - 10);
else ss << x;
n %= n4;
x = n/n3;
if (x >= 10) ss << static_cast<char>('A' + x - 10);
else ss << x;
n %= n3;
x = n/n2;
if (x >= 10) ss << static_cast<char>('A' + x - 10);
else ss << x;
n %= n2;
x = n;
if (x >= 10) ss << static_cast<char>('A' + x - 10);
else ss << x;
return ss.str();
}
int OCdb::cache_code_to_int(std::string code) const {
code = code.substr(2);
return std::stoi(code, nullptr, 36);
}

4
ocdb.h
Wyświetl plik

@ -19,6 +19,10 @@ private:
mutable sqlite3_stmt* stmt;
mutable std::string sql;
int revision;
std::string cache_code_prefix = "OP";
std::string int_to_cache_code(int n) const;
int cache_code_to_int(std::string code) const;
bool request(const std::string& req) const;
bool init_part(const std::string& json_file); // read db dump