Skip to content

Commit

Permalink
Simplify JSON functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
jedelbo committed Jan 12, 2024
1 parent a3bf8dc commit 9169fa1
Show file tree
Hide file tree
Showing 60 changed files with 2,578 additions and 723 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
-----------

### Internals
* None.
* to_json API changed according to https://docs.google.com/document/d/1YtJN0sC89LMb4UVcPKFIfwC0Hsi9Vj7sIEP2vHQzVcY/edit?usp=sharing. Links to not embedded objects will never be followed.

----------------------------------------------

Expand Down
46 changes: 0 additions & 46 deletions src/realm/collection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,50 +226,4 @@ void Collection::get_any(QueryCtrlBlock& ctrl, Mixed val, size_t index)
}
}

std::pair<std::string, std::string> CollectionBase::get_open_close_strings(size_t link_depth,
JSONOutputMode output_mode) const
{
std::string open_str;
std::string close_str;
auto collection_type = get_collection_type();
Table* target_table = get_target_table().unchecked_ptr();
auto ck = get_col_key();
auto type = ck.get_type();
if (type == col_type_Link) {
bool is_embedded = target_table->is_embedded();
bool link_depth_reached = !is_embedded && (link_depth == 0);

if (output_mode == output_mode_xjson_plus) {
open_str = std::string("{ ") + (is_embedded ? "\"$embedded" : "\"$link");
open_str += collection_type_name(collection_type, true);
open_str += "\": ";
close_str += " }";
}

if ((link_depth_reached && output_mode != output_mode_xjson) || output_mode == output_mode_xjson_plus) {
open_str += "{ \"table\": \"" + std::string(target_table->get_name()) + "\", ";
open_str += ((is_embedded || collection_type == CollectionType::Dictionary) ? "\"values" : "\"keys");
open_str += "\": ";
close_str += "}";
}
}
else {
if (output_mode == output_mode_xjson_plus) {
switch (collection_type) {
case CollectionType::List:
break;
case CollectionType::Set:
open_str = "{ \"$set\": ";
close_str = " }";
break;
case CollectionType::Dictionary:
open_str = "{ \"$dictionary\": ";
close_str = " }";
break;
}
}
}
return {open_str, close_str};
}

} // namespace realm
5 changes: 2 additions & 3 deletions src/realm/collection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class Collection {
{
return size() == 0;
}
virtual void to_json(std::ostream&, size_t, JSONOutputMode, util::FunctionRef<void(const Mixed&)>) const {}
virtual void to_json(std::ostream&, JSONOutputMode, util::FunctionRef<void(const Mixed&)>) const {}
/// Get collection type (set, list, dictionary)
virtual CollectionType get_collection_type() const noexcept = 0;

Expand Down Expand Up @@ -258,7 +258,6 @@ class CollectionBase : public Collection {
CollectionBase& operator=(CollectionBase&&) noexcept = default;

void validate_index(const char* msg, size_t index, size_t size) const;
std::pair<std::string, std::string> get_open_close_strings(size_t link_depth, JSONOutputMode output_mode) const;
};

inline std::string_view collection_type_name(CollectionType col_type, bool uppercase = false)
Expand Down Expand Up @@ -567,7 +566,7 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {
m_content_version = 0;
}

void to_json(std::ostream&, size_t, JSONOutputMode, util::FunctionRef<void(const Mixed&)>) const override;
void to_json(std::ostream&, JSONOutputMode, util::FunctionRef<void(const Mixed&)>) const override;

using Interface::get_owner_key;
using Interface::get_table;
Expand Down
18 changes: 10 additions & 8 deletions src/realm/dictionary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1119,17 +1119,17 @@ void Dictionary::migrate()
}

template <>
void CollectionBaseImpl<DictionaryBase>::to_json(std::ostream&, size_t, JSONOutputMode,
void CollectionBaseImpl<DictionaryBase>::to_json(std::ostream&, JSONOutputMode,
util::FunctionRef<void(const Mixed&)>) const
{
}

void Dictionary::to_json(std::ostream& out, size_t link_depth, JSONOutputMode output_mode,
void Dictionary::to_json(std::ostream& out, JSONOutputMode output_mode,
util::FunctionRef<void(const Mixed&)> fn) const
{
auto [open_str, close_str] = get_open_close_strings(link_depth, output_mode);

out << open_str;
if (output_mode == output_mode_xjson_plus) {
out << "{ \"$dictionary\": ";
}
out << "{";

auto sz = size();
Expand All @@ -1144,20 +1144,22 @@ void Dictionary::to_json(std::ostream& out, size_t link_depth, JSONOutputMode ou
else if (val.is_type(type_Dictionary)) {
DummyParent parent(this->get_table(), val.get_ref());
Dictionary dict(parent, 0);
dict.to_json(out, link_depth, output_mode, fn);
dict.to_json(out, output_mode, fn);
}
else if (val.is_type(type_List)) {
DummyParent parent(this->get_table(), val.get_ref());
Lst<Mixed> list(parent, 0);
list.to_json(out, link_depth, output_mode, fn);
list.to_json(out, output_mode, fn);
}
else {
val.to_json(out, output_mode);
}
}

out << "}";
out << close_str;
if (output_mode == output_mode_xjson_plus) {
out << "}";
}
}

ref_type Dictionary::get_collection_ref(Index index, CollectionType type) const
Expand Down
2 changes: 1 addition & 1 deletion src/realm/dictionary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class Dictionary final : public CollectionBaseImpl<DictionaryBase>, public Colle
void set_collection_ref(Index, ref_type ref, CollectionType) override;
StableIndex build_index(Mixed key) const;

void to_json(std::ostream&, size_t, JSONOutputMode, util::FunctionRef<void(const Mixed&)>) const override;
void to_json(std::ostream&, JSONOutputMode, util::FunctionRef<void(const Mixed&)>) const override;

private:
template <typename T, typename Op>
Expand Down
11 changes: 3 additions & 8 deletions src/realm/exec/realm2json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ void abort_if(bool cond, FormatStr fmt, Args... args)

int main(int argc, char const* argv[])
{
std::map<std::string, std::string> renames;
size_t link_depth = 0;
bool output_schema = false;
realm::JSONOutputMode output_mode = realm::output_mode_json;

Expand All @@ -53,9 +51,6 @@ int main(int argc, char const* argv[])
if (arg == "--schema") {
output_schema = true;
}
else if (arg == "--link-depth") {
link_depth = strtol(argv[++idx], nullptr, 0);
}
else if (arg == "--output-mode") {
auto output_mode_val = strtol(argv[++idx], nullptr, 0);
abort_if(output_mode_val > 2, "Received unknown value for output_mode option: %d", output_mode_val);
Expand Down Expand Up @@ -92,7 +87,7 @@ int main(int argc, char const* argv[])

auto print = [&](realm::TransactionRef tr) {
if (output_schema) {
tr->schema_to_json(std::cout, &renames);
tr->schema_to_json(std::cout);
}
else if (table_filter.size()) {
realm::TableRef target = tr->get_table(table_filter);
Expand All @@ -101,10 +96,10 @@ int main(int argc, char const* argv[])
realm::TableView results = q.find_all();
std::cout << realm::util::format("filter '%1' found %2 results", query_filter, results.size())
<< std::endl;
results.to_json(std::cout, link_depth, renames, output_mode);
results.to_json(std::cout, output_mode);
}
else {
tr->to_json(std::cout, link_depth, &renames, output_mode);
tr->to_json(std::cout, output_mode);
}
};

Expand Down
5 changes: 2 additions & 3 deletions src/realm/group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,8 @@ class Group : public ArrayParent {
//@}

// Conversion
void schema_to_json(std::ostream& out, std::map<std::string, std::string>* renames = nullptr) const;
void to_json(std::ostream& out, size_t link_depth = 0, std::map<std::string, std::string>* renames = nullptr,
JSONOutputMode output_mode = output_mode_json) const;
void schema_to_json(std::ostream& out) const;
void to_json(std::ostream& out, JSONOutputMode output_mode = output_mode_json) const;

/// Compare two groups for equality. Two groups are equal if, and
/// only if, they contain the same tables in the same order, that
Expand Down
19 changes: 5 additions & 14 deletions src/realm/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ void Lst<T>::distinct(std::vector<size_t>& indices, util::Optional<bool> sort_or
/********************************** LstBase *********************************/

template <>
void CollectionBaseImpl<LstBase>::to_json(std::ostream& out, size_t, JSONOutputMode output_mode,
void CollectionBaseImpl<LstBase>::to_json(std::ostream& out, JSONOutputMode output_mode,
util::FunctionRef<void(const Mixed&)> fn) const
{
auto sz = size();
Expand Down Expand Up @@ -723,12 +723,9 @@ util::Optional<Mixed> Lst<Mixed>::avg(size_t* return_cnt) const
return AverageHelper<Mixed>::not_found(return_cnt);
}

void Lst<Mixed>::to_json(std::ostream& out, size_t link_depth, JSONOutputMode output_mode,
void Lst<Mixed>::to_json(std::ostream& out, JSONOutputMode output_mode,
util::FunctionRef<void(const Mixed&)> fn) const
{
auto [open_str, close_str] = get_open_close_strings(link_depth, output_mode);

out << open_str;
out << "[";

auto sz = size();
Expand All @@ -742,20 +739,19 @@ void Lst<Mixed>::to_json(std::ostream& out, size_t link_depth, JSONOutputMode ou
else if (val.is_type(type_Dictionary)) {
DummyParent parent(this->get_table(), val.get_ref());
Dictionary dict(parent, i);
dict.to_json(out, link_depth, output_mode, fn);
dict.to_json(out, output_mode, fn);
}
else if (val.is_type(type_List)) {
DummyParent parent(this->get_table(), val.get_ref());
Lst<Mixed> list(parent, i);
list.to_json(out, link_depth, output_mode, fn);
list.to_json(out, output_mode, fn);
}
else {
val.to_json(out, output_mode);
}
}

out << "]";
out << close_str;
}

ref_type Lst<Mixed>::get_collection_ref(Index index, CollectionType type) const
Expand Down Expand Up @@ -955,12 +951,8 @@ void LnkLst::remove_all_target_rows()
}
}

void LnkLst::to_json(std::ostream& out, size_t link_depth, JSONOutputMode output_mode,
util::FunctionRef<void(const Mixed&)> fn) const
void LnkLst::to_json(std::ostream& out, JSONOutputMode, util::FunctionRef<void(const Mixed&)> fn) const
{
auto [open_str, close_str] = get_open_close_strings(link_depth, output_mode);

out << open_str;
out << "[";

auto sz = m_list.size();
Expand All @@ -972,7 +964,6 @@ void LnkLst::to_json(std::ostream& out, size_t link_depth, JSONOutputMode output
}

out << "]";
out << close_str;
}

void LnkLst::replace_link(ObjKey old_val, ObjKey new_val)
Expand Down
4 changes: 2 additions & 2 deletions src/realm/list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ class Lst<Mixed> final : public CollectionBaseImpl<LstBase>, public CollectionPa
bool check_collection_ref(Index, CollectionType) const noexcept override;
void set_collection_ref(Index, ref_type ref, CollectionType) override;

void to_json(std::ostream&, size_t, JSONOutputMode, util::FunctionRef<void(const Mixed&)>) const override;
void to_json(std::ostream&, JSONOutputMode, util::FunctionRef<void(const Mixed&)>) const override;

private:
// `do_` methods here perform the action after preconditions have been
Expand Down Expand Up @@ -781,8 +781,8 @@ class LnkLst final : public ObjCollectionBase<LstBase> {
m_list.set_owner(std::move(parent), index);
}

void to_json(std::ostream&, size_t, JSONOutputMode, util::FunctionRef<void(const Mixed&)>) const override;
void replace_link(ObjKey old_link, ObjKey new_link);
void to_json(std::ostream&, JSONOutputMode, util::FunctionRef<void(const Mixed&)>) const override;

private:
friend class TableView;
Expand Down
4 changes: 2 additions & 2 deletions src/realm/obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1106,13 +1106,13 @@ void Obj::add_index(Path& path, const Index& index) const
std::string Obj::to_string() const
{
std::ostringstream ostr;
to_json(ostr, 0, {});
to_json(ostr);
return ostr.str();
}

std::ostream& operator<<(std::ostream& ostr, const Obj& obj)
{
obj.to_json(ostr, -1, {});
obj.to_json(ostr);
return ostr;
}

Expand Down
9 changes: 1 addition & 8 deletions src/realm/obj.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,7 @@ class Obj : public CollectionParent {
template <class T>
bool evaluate(T func) const;

void to_json(std::ostream& out, size_t link_depth, const std::map<std::string, std::string>& renames,
std::vector<ObjLink>& followed, JSONOutputMode output_mode) const;
void to_json(std::ostream& out, size_t link_depth, const std::map<std::string, std::string>& renames,
JSONOutputMode output_mode = output_mode_json) const
{
std::vector<ObjLink> followed;
to_json(out, link_depth, renames, followed, output_mode);
}
void to_json(std::ostream& out, JSONOutputMode output_mode = output_mode_json) const;

std::string to_string() const;

Expand Down
10 changes: 7 additions & 3 deletions src/realm/object_id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,16 @@ Timestamp ObjectId::get_timestamp() const

std::string ObjectId::to_string() const
{
constexpr size_t buffer_size = 2 * sizeof(ObjectIdBytes);
char buffer[buffer_size];
std::string ret;
char* p = buffer;
for (size_t i = 0; i < m_bytes.size(); i++) {
ret += hex_digits[m_bytes[i] >> 4];
ret += hex_digits[m_bytes[i] & 0xf];
auto c = m_bytes[i];
*p++ = hex_digits[c >> 4];
*p++ = hex_digits[c & 0xf];
}
return ret;
return {buffer, buffer_size};
}

ObjectId::ObjectIdBytes ObjectId::to_bytes() const
Expand Down
16 changes: 5 additions & 11 deletions src/realm/set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,11 @@ void SetBase::assign_symmetric_difference(It1 first, It2 last)
}

template <>
void CollectionBaseImpl<SetBase>::to_json(std::ostream& out, size_t, JSONOutputMode output_mode,
void CollectionBaseImpl<SetBase>::to_json(std::ostream& out, JSONOutputMode output_mode,
util::FunctionRef<void(const Mixed&)> fn) const
{
int closing = 0;
if (output_mode == output_mode_xjson_plus) {
out << "{ \"$set\": ";
closing++;
}

out << "[";
Expand All @@ -263,16 +261,17 @@ void CollectionBaseImpl<SetBase>::to_json(std::ostream& out, size_t, JSONOutputM
if (i > 0)
out << ",";
Mixed val = get_any(i);
if (val.is_type(type_TypedLink)) {
if (val.is_type(type_Link, type_TypedLink)) {
fn(val);
}
else {
val.to_json(out, output_mode);
}
}
out << "]";
while (closing--)
if (output_mode == output_mode_xjson_plus) {
out << "}";
}
}

bool SetBase::do_init_from_parent(ref_type ref, bool allow_create) const
Expand Down Expand Up @@ -512,12 +511,8 @@ void LnkSet::remove_all_target_rows()
}
}

void LnkSet::to_json(std::ostream& out, size_t link_depth, JSONOutputMode output_mode,
util::FunctionRef<void(const Mixed&)> fn) const
void LnkSet::to_json(std::ostream& out, JSONOutputMode, util::FunctionRef<void(const Mixed&)> fn) const
{
auto [open_str, close_str] = get_open_close_strings(link_depth, output_mode);

out << open_str;
out << "[";

auto sz = m_set.size();
Expand All @@ -529,7 +524,6 @@ void LnkSet::to_json(std::ostream& out, size_t link_depth, JSONOutputMode output
}

out << "]";
out << close_str;
}


Expand Down
Loading

0 comments on commit 9169fa1

Please sign in to comment.