[db2] Update.

This commit is contained in:
lzwdgc 2024-04-02 02:11:48 +03:00
parent 1124c73b14
commit 4b54d2c3cf
3 changed files with 150 additions and 99 deletions

View file

@ -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);
}
};

View file

@ -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
View file

@ -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");
{