Returns one if we overwrote a value
| 125 | |
| 126 | // Returns one if we overwrote a value |
| 127 | bool setWithKey(redisDb *db, robj_roptr key, robj *val, bool fCreateBuckets) { |
| 128 | const char *pchCur = szFromObj(key); |
| 129 | const char *pchStart = pchCur; |
| 130 | const char *pchMax = pchCur + sdslen(pchCur); |
| 131 | robj *o = nullptr; |
| 132 | |
| 133 | while (pchCur <= pchMax) { |
| 134 | if (pchCur == pchMax || *pchCur == '.') { |
| 135 | // WARNING: Don't deref pchCur as it may be pchMax |
| 136 | |
| 137 | // New word |
| 138 | if ((pchCur - pchStart) < 1) { |
| 139 | throw shared.syntaxerr; // malformed |
| 140 | } |
| 141 | |
| 142 | DbDictWrapper src; |
| 143 | if (o == nullptr) |
| 144 | src = db; |
| 145 | else |
| 146 | src = (dict*)ptrFromObj(o); |
| 147 | |
| 148 | sdsstring str(pchStart, pchCur - pchStart); |
| 149 | dict_iter di = src.find(str.get()); |
| 150 | |
| 151 | if (pchCur == pchMax) { |
| 152 | val->addref(); |
| 153 | if (di.val() != nullptr) { |
| 154 | decrRefCount(di.val()); |
| 155 | di.setval(val); |
| 156 | return true; |
| 157 | } else { |
| 158 | src.add(str.release(), val); |
| 159 | return false; |
| 160 | } |
| 161 | } else { |
| 162 | o = di.val(); |
| 163 | |
| 164 | if (o == nullptr) { |
| 165 | if (!fCreateBuckets) |
| 166 | throw shared.nokeyerr; // Not Found |
| 167 | o = createNestHashBucket(); |
| 168 | serverAssert(src.add(str.release(), o)); |
| 169 | } else if (o->type != OBJ_NESTEDHASH) { |
| 170 | decrRefCount(o); |
| 171 | o = createNestHashBucket(); |
| 172 | di.setval(o); |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | pchStart = pchCur + 1; |
| 177 | } |
| 178 | ++pchCur; |
| 179 | } |
| 180 | throw "Internal Error"; |
| 181 | } |
| 182 | |
| 183 | void writeNestedHashToClient(client *c, robj_roptr o) { |
| 184 | if (o == nullptr) { |
no test coverage detected