diff --git a/include/ircd/db/cursor.h b/include/ircd/db/cursor.h index 1a0bfe77a..6c555e315 100644 --- a/include/ircd/db/cursor.h +++ b/include/ircd/db/cursor.h @@ -146,7 +146,13 @@ ircd::db::cursor::const_iterator::const_iterator(const cursor &c, !bool(this->idx) || !row.valid(this->idx->first) } { - if(!invalid && this->where && !(*this->where)(this->operator*())) + if(invalid) + return; + + if(!this->where) + return; + + if(!(*this->where)(this->operator*())) seek(pos::NEXT); } @@ -201,32 +207,11 @@ const typename ircd::db::cursor::const_iterator::value_type & ircd::db::cursor::const_iterator::operator*() const { - if(stale) - { - for(const auto &cell : row) - { - const column &c{cell}; - const database::descriptor &desc{describe(c)}; - - if(desc.type.second == typeid(string_view)) - { - if(cell.valid(idx->first)) - json::set(v, cell.col(), cell.val()); - else - json::set(v, cell.col(), string_view{}); - } - else - { - if(cell.valid(idx->first)) - json::set(v, cell.col(), byte_view{cell.val()}); - else - json::set(v, cell.col(), byte_view{string_view{}}); - } - } - - stale = false; - } + if(!stale) + return v; + assign(v, row, idx->first); + stale = false; return v; } diff --git a/include/ircd/db/json.h b/include/ircd/db/json.h index c925998e9..f68bff917 100644 --- a/include/ircd/db/json.h +++ b/include/ircd/db/json.h @@ -25,44 +25,133 @@ namespace ircd::db { - template tuple make_tuple(const row &r); - template void set_index(it begin, it end, const string_view &index); - template void write(database &, const string_view &index, const json::tuple &, const sopts & = {}); + template bool assign(tuple &, const cell &); + template bool assign(tuple &, const cell &, const string_view &keyeq); + + template size_t assign(tuple &, const row &); + template size_t assign(tuple &, const row &, const string_view &keyeq); + + template tuple make_tuple(args&&...); } -// -// Commit a json::tuple to the database as a single transaction. -// -template -void -ircd::db::set_index(it b, - it e, - const string_view &index) +namespace ircd::db { - std::for_each(b, e, [&index] - (auto &delta) - { - std::get<2>(delta) = index; - }); + template void _assign_invalid(tuple &, const cell &); + template void _assign_valid(tuple &, const cell &); } -template -void -ircd::db::write(database &database, - const string_view &index, - const json::tuple &tuple, - const sopts &opts) +template +tuple +ircd::db::make_tuple(args&&... a) { - std::array deltas; - deltas(index, tuple, begin(deltas)); - database(begin(deltas), end(deltas)); + tuple ret; + assign(ret, std::forward(a)...); + return ret; } template -tuple -ircd::db::make_tuple(const row &row) +size_t +ircd::db::assign(tuple &t, + const row &row, + const string_view &keyeq) { - tuple ret; - set(ret, row); - return ret; + return std::count_if(std::begin(row), std::end(row), [&t, &keyeq] + (const auto &cell) + { + return assign(t, cell, keyeq); + }); +} + +template +size_t +ircd::db::assign(tuple &t, + const row &row) +{ + return std::count_if(std::begin(row), std::end(row), [&t] + (const auto &cell) + { + return assign(t, cell); + }); +} + +template +bool +ircd::db::assign(tuple &t, + const cell &cell) +{ + const bool valid + { + cell.valid() + }; + + if(valid) + _assign_valid(t, cell); + else + _assign_invalid(t, cell); + + return valid; +} + +template +bool +ircd::db::assign(tuple &t, + const cell &cell, + const string_view &keyeq) +{ + const bool valid + { + cell.valid(keyeq) + }; + + if(valid) + _assign_valid(t, cell); + else + _assign_invalid(t, cell); + + return valid; +} + +template +void +ircd::db::_assign_invalid(tuple &t, + const cell &cell) +{ + const column &c{cell}; + const auto &descriptor + { + describe(c) + }; + + const bool is_string + { + descriptor.type.second == typeid(string_view) + }; + + if(is_string) + json::set(t, cell.col(), string_view{}); + else + json::set(t, cell.col(), byte_view{string_view{}}); +} + +template +void +ircd::db::_assign_valid(tuple &t, + const cell &cell) +{ + const column &c{cell}; + const auto &descriptor + { + describe(c) + }; + + const bool is_string + { + descriptor.type.second == typeid(string_view) + }; + + if(is_string) + json::set(t, cell.col(), cell.val()); + else + json::set(t, cell.col(), byte_view{cell.val()}); }