diff --git a/controller/DB.hpp b/controller/DB.hpp index efb08d63b..aebe4e112 100644 --- a/controller/DB.hpp +++ b/controller/DB.hpp @@ -114,6 +114,28 @@ public: } protected: + inline bool _compareRecords(const nlohmann::json &a,const nlohmann::json &b) + { + if (a.is_object() == b.is_object()) { + if (a.is_object()) { + if (a.size() != b.size()) + return false; + auto amap = a.get(); + auto bmap = b.get(); + for(auto ai=amap.begin();ai!=amap.end();++ai) { + if (ai->first != "revision") { // ignore revision, compare only non-revision-counter fields + auto bi = bmap.find(ai->first); + if ((bi == bmap.end())||(bi->second != ai->second)) + return false; + } + } + return true; + } + return (a == b); + } + return false; + } + struct _Network { _Network() : mostRecentDeauthTime(0) {} diff --git a/controller/DBMirrorSet.cpp b/controller/DBMirrorSet.cpp index 5d9ea0507..5b491216d 100644 --- a/controller/DBMirrorSet.cpp +++ b/controller/DBMirrorSet.cpp @@ -125,14 +125,14 @@ bool DBMirrorSet::save(nlohmann::json &record,bool notifyListeners) } if (notifyListeners) { for(auto d=dbs.begin();d!=dbs.end();++d) { - if ((*d)->save(record,notifyListeners)) + if ((*d)->save(record,true)) return true; } return false; } else { bool modified = false; for(auto d=dbs.begin();d!=dbs.end();++d) { - modified |= (*d)->save(record,notifyListeners); + modified |= (*d)->save(record,false); } return modified; } diff --git a/controller/FileDB.cpp b/controller/FileDB.cpp index 1dc2498ab..cf5847d6a 100644 --- a/controller/FileDB.cpp +++ b/controller/FileDB.cpp @@ -98,7 +98,7 @@ bool FileDB::save(nlohmann::json &record,bool notifyListeners) if (nwid) { nlohmann::json old; get(nwid,old); - if ((!old.is_object())||(old != record)) { + if ((!old.is_object())||(!_compareRecords(old,record))) { record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),nwid); if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1))) @@ -115,7 +115,7 @@ bool FileDB::save(nlohmann::json &record,bool notifyListeners) if ((id)&&(nwid)) { nlohmann::json network,old; get(nwid,network,id,old); - if ((!old.is_object())||(old != record)) { + if ((!old.is_object())||(!_compareRecords(old,record))) { record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; OSUtils::ztsnprintf(pb,sizeof(pb),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member",_networksPath.c_str(),(unsigned long long)nwid); OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.10llx.json",pb,(unsigned long long)id); diff --git a/controller/LFDB.cpp b/controller/LFDB.cpp index 3b800ec2a..35068321d 100644 --- a/controller/LFDB.cpp +++ b/controller/LFDB.cpp @@ -369,7 +369,7 @@ bool LFDB::save(nlohmann::json &record,bool notifyListeners) if (nwid) { nlohmann::json old; get(nwid,old); - if ((!old.is_object())||(old != record)) { + if ((!old.is_object())||(!_compareRecords(old,record))) { record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; _networkChanged(old,record,notifyListeners); { @@ -385,7 +385,7 @@ bool LFDB::save(nlohmann::json &record,bool notifyListeners) if ((id)&&(nwid)) { nlohmann::json network,old; get(nwid,network,id,old); - if ((!old.is_object())||(old != record)) { + if ((!old.is_object())||(!_compareRecords(old,record))) { record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; _memberChanged(old,record,notifyListeners); { diff --git a/controller/PostgreSQL.cpp b/controller/PostgreSQL.cpp index a43e2118b..66b49394e 100644 --- a/controller/PostgreSQL.cpp +++ b/controller/PostgreSQL.cpp @@ -183,7 +183,7 @@ bool PostgreSQL::save(nlohmann::json &record,bool notifyListeners) if (nwid) { nlohmann::json old; get(nwid,old); - if ((!old.is_object())||(old != record)) { + if ((!old.is_object())||(!_compareRecords(old,record))) { record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; _commitQueue.post(std::pair(record,notifyListeners)); modified = true; @@ -195,25 +195,13 @@ bool PostgreSQL::save(nlohmann::json &record,bool notifyListeners) if ((id)&&(nwid)) { nlohmann::json network,old; get(nwid,network,id,old); - if ((!old.is_object())||(old != record)) { + if ((!old.is_object())||(!_compareRecords(old,record))) { record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; _commitQueue.post(std::pair(record,notifyListeners)); modified = true; } } } - /* - waitForReady(); - if (orig) { - if (*orig != record) { - record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1; - _commitQueue.post(new nlohmann::json(record)); - } - } else { - record["revision"] = 1; - _commitQueue.post(new nlohmann::json(record)); - } - */ } catch (std::exception &e) { fprintf(stderr, "Error on PostgreSQL::save: %s\n", e.what()); } catch (...) {