MojErr MojDb::getImpl(const MojObject& id, MojObjectVisitor& visitor, MojDbOp op, MojDbReq& req) { MojRefCountedPtr<MojDbStorageItem> item; MojErr err = m_objDb->get(id, req.txn(), false, item); MojErrCheck(err); if (item.get()) { MojString kindId; err = item->kindId(kindId, m_kindEngine); MojErrCheck(err); err = m_kindEngine.checkPermission(kindId, op, req); MojErrCheck(err); err = item->visit(visitor, m_kindEngine); MojErrCheck(err); err = item->close(); MojErrCheck(err); } return MojErrNone; }
MojErr MojDb::putImpl(MojObject& obj, MojUInt32 flags, MojDbReq& req, bool checkSchema) { MojLogTrace(s_log); MojRefCountedPtr<MojDbStorageItem> prevItem; MojObject id; if (obj.get(IdKey, id)) { // get previous revision if we have an id MojErr err = m_objDb->get(id, req.txn(), true, prevItem); MojErrCheck(err); } if (MojFlagGet(flags, FlagIgnoreMissing) && MojFlagGet(flags, FlagMerge)) { if (!prevItem.get()) { MojErr err = obj.putBool(MojDb::IgnoreIdKey, true); // so that we can drop it in output MojErrCheck(err); return MojErrNone; } } MojDbOp op = OpCreate; MojObject* prevPtr = NULL; MojObject prev; if (prevItem.get()) { // deal with prev, if it exists op = OpUpdate; prevPtr = &prev; MojErr err = prevItem->toObject(prev, m_kindEngine); MojErrCheck(err); if (MojFlagGet(flags, FlagMerge)) { // do merge MojObject merged; err = mergeInto(merged, obj, prev); MojErrCheck(err); obj = merged; } else if (!MojFlagGet(flags, FlagForce)) { // if the force flag is not set, throw error if we are updating // an existing, non-deleted object and no rev was specified MojInt64 rev; if (obj.get(RevKey, rev) == false) { bool deleted = false; if (!prev.get(DelKey, deleted) || !deleted) MojErrThrow(MojErrDbRevNotSpecified); } } } // if the new object has a rev and it doesn't match the old rev, don't do the update MojInt64 newRev; if (prevPtr != NULL && obj.get(RevKey, newRev)) { MojInt64 oldRev; MojErr err = prevPtr->getRequired(RevKey, oldRev); MojErrCheck(err); if (!MojFlagGet(flags, FlagForce) && newRev != oldRev) MojErrThrowMsg(MojErrDbRevisionMismatch, _T("db: revision mismatch - expected %lld, got %lld"), oldRev, newRev); } // save it MojErr err = putObj(id, obj, prevPtr, prevItem.get(), req, op, checkSchema); MojErrCheck(err); if (prevItem.get()) { err = prevItem->close(); MojErrCheck(err); } return MojErrNone; }