| 101 | // If the types for a and B differ then pass them as mValues to this specialization. |
| 102 | template <> |
| 103 | json_spirit::mObject JSONDoc::mergeOperator<json_spirit::mValue>(const std::string& op, |
| 104 | const json_spirit::mObject& op_a, |
| 105 | const json_spirit::mObject& op_b, |
| 106 | json_spirit::mValue const& a, |
| 107 | json_spirit::mValue const& b) { |
| 108 | // Returns { $latest : <a or b>, timestamp: <a or b timestamp> } |
| 109 | // where the thing (a or b) with the highest timestamp operator arg will be chosen |
| 110 | if (op == "$latest") { |
| 111 | double ts_a = 0, ts_b = 0; |
| 112 | JSONDoc(op_a).tryGet("timestamp", ts_a); |
| 113 | JSONDoc(op_b).tryGet("timestamp", ts_b); |
| 114 | if (ts_a > ts_b) |
| 115 | return { { op, a }, { "timestamp", ts_a } }; |
| 116 | return { { op, b }, { "timestamp", ts_b } }; |
| 117 | } |
| 118 | |
| 119 | // Simply selects the last thing to be merged. |
| 120 | // Returns { $last : b } |
| 121 | if (op == "$last") |
| 122 | return { { op, b } }; |
| 123 | |
| 124 | // $expires will reduce its value to null if the "version" operator argument is present, nonzero, and has a value |
| 125 | // that is less than JSONDoc::expires_reference_version. This DOES mean that if the "version" argument |
| 126 | // is not present or has a value of 0 then the operator's value will be considered NOT expired. |
| 127 | // When two $expires operations are merged, the result is |
| 128 | // { $expires : <value> } where value is the result of a merger between null and any unexpired |
| 129 | // values for a or b. |
| 130 | if (op == "$expires") { |
| 131 | uint64_t ver_a = 0, ver_b = 0; |
| 132 | // Whichever has the most recent "timestamp" in its operator object will be used |
| 133 | JSONDoc(op_a).tryGet("version", ver_a); |
| 134 | JSONDoc(op_b).tryGet("version", ver_b); |
| 135 | |
| 136 | json_spirit::mValue r; |
| 137 | // If version is 0 or greater than the current reference version then use the value |
| 138 | if (ver_a == 0 || ver_a > JSONDoc::expires_reference_version) |
| 139 | r = a; |
| 140 | if (ver_b == 0 || ver_b > JSONDoc::expires_reference_version) |
| 141 | mergeValueInto(r, b); |
| 142 | |
| 143 | return { { op, r } }; |
| 144 | } |
| 145 | |
| 146 | throw std::exception(); |
| 147 | } |
| 148 | |
| 149 | void JSONDoc::cleanOps(json_spirit::mObject& obj) { |
| 150 | auto kv = obj.begin(); |