mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
[db2] Update.
This commit is contained in:
parent
1124c73b14
commit
4b54d2c3cf
3 changed files with 150 additions and 99 deletions
206
src/common/db2.h
206
src/common/db2.h
|
|
@ -19,10 +19,41 @@
|
|||
#include "common.h"
|
||||
#include "mmap.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <primitives/templates2/overload.h>
|
||||
#include <primitives/templates2/type_name.h>
|
||||
|
||||
#include <variant>
|
||||
|
||||
std::string utf8_to_dbstr(const char8_t *s, int codepage = 1251) {
|
||||
return str2str((const char *)s, CP_UTF8, codepage);
|
||||
}
|
||||
std::string utf8_to_dbstr(const char *s) {
|
||||
return utf8_to_dbstr((const char8_t *)s);
|
||||
}
|
||||
std::string utf8_to_dbstr(const std::string &s) {
|
||||
return utf8_to_dbstr((const char8_t *)s.c_str());
|
||||
}
|
||||
|
||||
struct mem_stream {
|
||||
std::vector<uint8_t> d;
|
||||
|
||||
template <typename T>
|
||||
operator T &() {
|
||||
d.resize(d.size() + sizeof(T));
|
||||
auto p = d.data() + d.size() - sizeof(T);
|
||||
auto &r = *(T *)p;
|
||||
return r;
|
||||
}
|
||||
void operator+=(const mem_stream &s) {
|
||||
d.append_range(s.d);
|
||||
}
|
||||
template <typename T>
|
||||
T &at(size_t i) {
|
||||
return *(T *)(d.data() + i);
|
||||
}
|
||||
};
|
||||
|
||||
struct db2 {
|
||||
using char20 = char[0x20];
|
||||
|
||||
|
|
@ -127,10 +158,124 @@ struct db2 {
|
|||
|
||||
db2_memory m;
|
||||
|
||||
auto begin(this auto &&d) {return d.m.begin();}
|
||||
auto end(this auto &&d) {return d.m.end();}
|
||||
auto &operator[](this auto &&d, const std::string &s) {
|
||||
return d.m[s];
|
||||
}
|
||||
void save() {
|
||||
auto to_json() const {
|
||||
nlohmann::json ja;
|
||||
for (auto &&[tn,t] : m) {
|
||||
auto &jt = ja[tn];
|
||||
for (auto &&[vn,v] : t) {
|
||||
auto &jv = jt[vn];
|
||||
for (auto &&[fn, fv] : v) {
|
||||
std::visit(overload{
|
||||
[&](const int &v){jv[fn] = v;},
|
||||
[&](const float &v){jv[fn] = v;},
|
||||
[&](const std::string &v){jv[fn] = v;},
|
||||
}, fv);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ja;
|
||||
}
|
||||
size_t fields_size() const {
|
||||
size_t sz{};
|
||||
return sz;
|
||||
}
|
||||
size_t tables_size() const {
|
||||
size_t sz{};
|
||||
return sz;
|
||||
}
|
||||
size_t tab_size() const {
|
||||
return tables_size() + fields_size();
|
||||
}
|
||||
size_t ind_size() const {
|
||||
return tables_size() + fields_size();
|
||||
}
|
||||
size_t dat_size() const {
|
||||
return tables_size() + fields_size();
|
||||
}
|
||||
void save(const path &fn) {
|
||||
auto tabsz = tab_size();
|
||||
auto indsz = ind_size();
|
||||
auto datsz = dat_size();
|
||||
|
||||
auto s_to_char20 = [&](char20 &dst, const std::string &in) {
|
||||
auto s = utf8_to_dbstr(in);
|
||||
if (s.size() + 1 > sizeof(char20)) {
|
||||
throw std::runtime_error{"too long string"};
|
||||
}
|
||||
memcpy(dst, s.c_str(), s.size());
|
||||
};
|
||||
|
||||
mem_stream tabv,tabv_fields;
|
||||
tab &tab_ = tabv;
|
||||
auto get_tab = [&](){};
|
||||
int table_id{1};
|
||||
int total_fields{};
|
||||
for (auto &&[tn,td] : m) {
|
||||
tab::table &t = tabv;
|
||||
t.id = table_id;
|
||||
s_to_char20(t.name, tn);
|
||||
|
||||
std::set<std::pair<std::string, field_type>> fields;
|
||||
for (auto &&[_,fd] : td) {
|
||||
for (auto &&[fn,fv] : fd) {
|
||||
fields.emplace(std::pair<std::string, field_type>{fn,(field_type)fv.index()});
|
||||
}
|
||||
}
|
||||
int field_id{1};
|
||||
for (auto &&[fn,ft] : fields) {
|
||||
tab::field &f = tabv_fields;
|
||||
f.id = field_id;
|
||||
f.table_id = table_id;
|
||||
f.type = ft;
|
||||
s_to_char20(f.name, fn);
|
||||
++total_fields;
|
||||
}
|
||||
|
||||
++table_id;
|
||||
}
|
||||
tabv += tabv_fields;
|
||||
{
|
||||
auto &tab_ = tabv.at<tab>(0);
|
||||
tab_.n_tables = m.size();
|
||||
tab_.n_fields = total_fields;
|
||||
}
|
||||
|
||||
mem_stream indv, datv;
|
||||
for (auto &&[tn, td] : m) {
|
||||
tab::table &t = tabv;
|
||||
t.id = table_id;
|
||||
s_to_char20(t.name, tn);
|
||||
|
||||
std::set<std::pair<std::string, field_type>> fields;
|
||||
for (auto &&[_, fd] : td) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*db2 x{};
|
||||
auto newdb = x.open();
|
||||
for (auto &&[t,vals] : ja.items()) {
|
||||
for (auto &&[v,fields] : vals.items()) {
|
||||
for (auto &&[f,val] : fields.items()) {
|
||||
auto s = newdb(t, v, f);
|
||||
if (0) {
|
||||
} else if (val.is_number_float()) {
|
||||
s = val.get<float>();
|
||||
} else if (val.is_number_integer()) {
|
||||
s = val.get<int>();
|
||||
} else if (val.is_string()) {
|
||||
s = val.get<std::string>();
|
||||
} else {
|
||||
throw std::logic_error{"bad type"};
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
};
|
||||
|
|
@ -183,68 +328,9 @@ struct db2 {
|
|||
}
|
||||
return m;
|
||||
}
|
||||
/*auto to_json() const {
|
||||
auto prepare_string = [](auto &&in) {
|
||||
auto s = str2utf8(in);
|
||||
boost::trim(s);
|
||||
return s;
|
||||
};
|
||||
|
||||
auto tbl = tab_.data->tables();
|
||||
nlohmann::json ja;
|
||||
for (auto &&t : tbl) {
|
||||
auto &jt = ja[prepare_string(t.name)];
|
||||
auto fields = tab_.data->fields(t.id);
|
||||
for (auto &&v : ind_.data->values(t.id)) {
|
||||
auto vn = prepare_string(v.name);
|
||||
if (jt.contains(vn)) {
|
||||
throw std::logic_error{"duplicate"};
|
||||
}
|
||||
auto &jv = jt[vn];
|
||||
auto p = dat_.f.p + v.offset;
|
||||
auto max = p + v.size;
|
||||
while (p < max) {
|
||||
auto vb = (db2::dat::field_value_base *)p;
|
||||
p += sizeof(db2::dat::field_value_base);
|
||||
auto f = std::ranges::find_if(fields, [&](auto &f) {
|
||||
return f.id == vb->field_id;
|
||||
});
|
||||
if (f == fields.end()) {
|
||||
throw std::logic_error{"unknown field"};
|
||||
}
|
||||
auto fn = prepare_string(f->name);
|
||||
switch (f->type) {
|
||||
case db2::field_type::integer:
|
||||
jv[fn] = *(int *)p;
|
||||
break;
|
||||
case db2::field_type::float_:
|
||||
jv[fn] = *(float *)p;
|
||||
break;
|
||||
case db2::field_type::string:
|
||||
jv[fn] = prepare_string((const char *)p);
|
||||
break;
|
||||
default:
|
||||
throw std::logic_error{"bad type"};
|
||||
}
|
||||
p += vb->size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
};
|
||||
|
||||
auto open() {
|
||||
return files{*this, fn};
|
||||
}
|
||||
|
||||
private:
|
||||
std::string utf8_to_dbstr(const std::string &s) const {
|
||||
return utf8_to_dbstr((const char8_t *)s.c_str());
|
||||
}
|
||||
std::string utf8_to_dbstr(const char *s) const {
|
||||
return utf8_to_dbstr((const char8_t *)s);
|
||||
}
|
||||
std::string utf8_to_dbstr(const char8_t *s) const {
|
||||
return str2str((const char *)s, CP_UTF8, codepage);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@
|
|||
#include <primitives/sw/main.h>
|
||||
#include <primitives/sw/settings.h>
|
||||
#include <primitives/sw/cl.h>
|
||||
#include <primitives/templates2/overload.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <span>
|
||||
|
|
@ -39,43 +37,9 @@ int main(int argc, char *argv[])
|
|||
|
||||
db2 db{db_fn};
|
||||
auto f = db.open();
|
||||
auto tbl = f.to_map();
|
||||
|
||||
nlohmann::json ja;
|
||||
for (auto &&[tn,t] : tbl) {
|
||||
auto &jt = ja[tn];
|
||||
for (auto &&[vn,v] : t) {
|
||||
auto &jv = jt[vn];
|
||||
for (auto &&[fn, fv] : v) {
|
||||
std::visit(overload{
|
||||
[&](const int &v){jv[fn] = v;},
|
||||
[&](const float &v){jv[fn] = v;},
|
||||
[&](const std::string &v){jv[fn] = v;},
|
||||
}, fv);
|
||||
}
|
||||
}
|
||||
}
|
||||
write_file(path{db_fn} += ".json", ja.dump(1));
|
||||
|
||||
db2 x{path{db_fn} += "new"};
|
||||
auto newdb = x.open();
|
||||
for (auto &&[t,vals] : ja.items()) {
|
||||
for (auto &&[v,fields] : vals.items()) {
|
||||
for (auto &&[f,val] : fields.items()) {
|
||||
auto s = newdb(t, v, f);
|
||||
if (0) {
|
||||
} else if (val.is_number_float()) {
|
||||
s = val.get<float>();
|
||||
} else if (val.is_number_integer()) {
|
||||
s = val.get<int>();
|
||||
} else if (val.is_string()) {
|
||||
s = val.get<std::string>();
|
||||
} else {
|
||||
throw std::logic_error{"bad type"};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto m = f.to_map();
|
||||
write_file(path{db_fn} += ".json", m.to_json().dump(1));
|
||||
m.save(path{db_fn} += "new");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
1
sw.cpp
1
sw.cpp
|
|
@ -96,6 +96,7 @@ void build(Solution &s)
|
|||
|
||||
auto &aim1_mod_maker = add_exe_with_common("aim1.mod_maker", "aim1_mod_maker"); // actually a library
|
||||
aim1_mod_maker.Public += "pub.egorpugin.primitives.command"_dep;
|
||||
aim1_mod_maker.Public += "org.sw.demo.nlohmann.json.natvis"_dep;
|
||||
|
||||
auto &aim1_community_fix = tools.addExecutable("examples.mods.aim1.community_fix");
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue