MojErr MojDb::loadImpl(MojObject& obj, MojUInt32 flags, MojDbReq& req) { bool found = false; MojString kindName; MojErr err = obj.get(MojDb::KindKey, kindName, found); MojErrCheck(err); if (!found) MojErrThrow(MojErrDbKindNotSpecified); bool deleted = false; obj.get(MojDb::DelKey, deleted); // when loading objects, if the object is deleted, call delKind/del // otherwise, call putKind, putPermissions or put depending on the kind if (deleted) { MojObject id; if (obj.get(MojDbServiceDefs::IdKey, id)) { if (kindName.startsWith(MojDbKindEngine::KindKindIdPrefix)) { err = delKind(id, found, flags, req); MojErrCheck(err); } else { err = del(id, found, flags, req); MojErrCheck(err); } } } else { if (kindName.startsWith(MojDbKindEngine::KindKindIdPrefix)) { err = putKind(obj, flags, req); MojErrCheck(err); } else if (kindName.startsWith(MojDbKindEngine::PermissionIdPrefix)) { err = putPermissions(&obj, &obj + 1, req); MojErrCatch(err, MojErrDbKindNotRegistered); // kind may not have been backed up MojErrCheck(err); } else { err = putImpl(obj, flags, req, false /*checkSchema*/); MojErrCatch(err, MojErrDbKindNotRegistered); // kind may not have been backed up MojErrCheck(err); } } return MojErrNone; }
MojErr MojDb::putObj(const MojObject& id, MojObject& obj, const MojObject* oldObj, MojDbStorageItem* oldItem, MojDbReq& req, MojDbOp op, bool checkSchema) { MojLogTrace(s_log); // if nothing changed, don't do the update if (oldObj != NULL && obj == *oldObj) return MojErrNone; // update revision MojInt64 rev; MojErr err = nextId(rev); MojErrCheck(err); err = obj.put(RevKey, rev); MojErrCheck(err); // assign id MojObject putId = id; if (putId.undefined()) { err = m_idGenerator.id(putId); MojErrCheck(err); err = obj.put(IdKey, putId); MojErrCheck(err); } // assign ids to subobjects in arrays - only for regular objects MojString kindName; bool found = false; err = obj.get(MojDb::KindKey, kindName, found); MojErrCheck(err); if (!found) MojErrThrow(MojErrDbKindNotSpecified); if (!kindName.startsWith(MojDbKindEngine::KindKindIdPrefix)) { err = assignIds(obj); MojErrCheck(err); } // validate, update indexes, etc. MojTokenSet tokenSet; err = m_kindEngine.update(&obj, oldObj, req, op, tokenSet, checkSchema); MojErrCheck(err); // serialize object MojDbObjectHeader header(putId); err = header.extractFrom(obj); MojErrCheck(err); MojBuffer buf; err = header.write(buf, m_kindEngine); MojErrCheck(err); MojObjectWriter writer(buf, &tokenSet); err = obj.visit(writer); MojErrCheck(err); // store it in the db if (oldItem) { err = m_objDb->update(putId, buf, oldItem, req.txn()); MojErrCheck(err); } else { err = m_objDb->insert(putId, buf, req.txn()); MojErrCheck(err); } // put header back in the object for response purposes err = header.addTo(obj); MojErrCheck(err); return MojErrNone; }