MojErr MojDb::del(const MojObject* idsBegin, const MojObject* idsEnd, MojUInt32& countOut, MojObject& arrOut, MojUInt32 flags, MojDbReqRef req) { MojAssert(idsBegin || idsBegin == idsEnd); MojAssert(idsEnd >= idsBegin); MojLogTrace(s_log); countOut = 0; MojErr err = beginReq(req); MojErrCheck(err); // do the dels MojUInt32 count= 0; for (const MojObject* i = idsBegin; i != idsEnd; ++i) { MojObject foundObj; bool found = false; err = delImpl(*i, found, foundObj, req, flags); MojErrCheck(err); if (found) { count++; err = arrOut.push(foundObj); MojErrCheck(err); } } // commit txn err = req->end(); MojErrCheck(err); countOut = count; return MojErrNone; }
MojErr MojDb::del(const MojDbQuery& query, MojUInt32& countOut, MojUInt32 flags, MojDbReqRef req) { MojLogTrace(s_log); countOut = 0; MojErr err = beginReq(req); MojErrCheck(err); err = delImpl(query, countOut, req, flags); MojErrCheck(err); err = req->end(); MojErrCheck(err); return MojErrNone; }
MojErr MojDb::delKind(const MojObject& id, bool& foundOut, MojUInt32 flags, MojDbReqRef req) { MojLogTrace(s_log); foundOut = false; MojErr err = beginReq(req, true); MojErrCheck(err); // del kind obj MojString idStr; err = id.stringValue(idStr); MojErrCheck(err); MojDbKind *pk = NULL; // If Kinds has sub-kinds, we give an error err = m_kindEngine.getKind(idStr.data(), pk); MojErrCheck(err); if (pk->nsubkinds() > 0) { MojLogWarning(s_log, _T("delKind_error: %s has %d subkinds \n"), idStr.data(), pk->nsubkinds()); MojErrThrow(MojErrDbKindHasSubKinds); } //MojLogInfo(s_log, _T("delKind: %s \n"), idStr.data()); MojLogWarning(s_log, _T("delKind: %s \n"), idStr.data()); err = m_kindEngine.checkOwnerPermission(idStr, req); MojErrCheck(err); MojString dbId; err = formatKindId(idStr, dbId); MojErrCheck(err); MojObject deleted; bool found = false; MojDbAdminGuard adminGuard(req); err = delImpl(dbId, found, deleted, req, flags); MojErrCheck(err); if (found) { // del objects MojDbQuery query; err = query.from(idStr); MojErrCheck(err); err = query.includeDeleted(true); MojErrCheck(err); MojUInt32 count; req->fixmode(true); err = delImpl(query, count, req, flags | FlagPurge); MojErrCheck(err); // del associated permissions query.clear(); err = query.from(MojDbKindEngine::PermissionId); MojErrCheck(err); err = query.where(MojDbServiceDefs::ObjectKey, MojDbQuery::OpEq, idStr); MojErrCheck(err); req->fixmode(true); err = delImpl(query, count, req, flags); MojErrCheck(err); // del kind MojErr errAcc = m_kindEngine.delKind(idStr, req); MojErrAccumulate(err, errAcc); } err = commitKind(idStr, req, err); MojErrCheck(err); foundOut = found; return MojErrNone; }
MojErr MojDb::purgeImpl(MojObject& obj, MojUInt32& countOut, MojDbReq& req) { MojLogTrace(s_log); MojObject val; MojErr err = obj.getRequired(RevNumKey, val); MojErrCheck(err); MojObject timestamp; err = obj.getRequired(TimestampKey, timestamp); MojErrCheck(err); // purge all objects that were deleted on or prior to this rev num // query for objects in two passes - once where backup is true and once where backup is false MojDbQuery objQuery; err = objQuery.from(MojDbKindEngine::RootKindId); MojErrCheck(err); err = objQuery.where(DelKey, MojDbQuery::OpEq, true); MojErrCheck(err); err = objQuery.where(SyncKey, MojDbQuery::OpEq, true); MojErrCheck(err); err = objQuery.where(RevKey, MojDbQuery::OpLessThanEq, val); MojErrCheck(err); MojUInt32 backupCount = 0; req.autobatch(true); req.fixmode(true); objQuery.limit(AutoBatchSize); err = delImpl(objQuery, backupCount, req, FlagPurge); MojErrCheck(err); MojDbQuery objQuery2; err = objQuery2.from(MojDbKindEngine::RootKindId); MojErrCheck(err); err = objQuery2.where(DelKey, MojDbQuery::OpEq, true); MojErrCheck(err); err = objQuery2.where(SyncKey, MojDbQuery::OpEq, false); MojErrCheck(err); err = objQuery2.where(RevKey, MojDbQuery::OpLessThanEq, val); MojErrCheck(err); MojUInt32 count = 0; MojUInt32 batchRemain = 0; if (backupCount <= AutoBatchSize) batchRemain = AutoBatchSize - backupCount; req.autobatch(true); // enable auto batch req.fixmode(true); // force deletion of bad entries if (batchRemain > 0) { objQuery2.limit(batchRemain); err = delImpl(objQuery2, count, req, FlagPurge); MojErrCheck(err); } countOut = count + backupCount; req.autobatch(false); // if we actually deleted objects, store this rev num as the last purge rev if (countOut > 0) { err = updateState(LastPurgedRevKey, val, req); MojErrCheck(err); } // delete all the RevTimestamp entries prior to this one MojDbQuery revTimestampQuery; err = revTimestampQuery.from(MojDbKindEngine::RevTimestampId); MojErrCheck(err); err = revTimestampQuery.where(TimestampKey, MojDbQuery::OpLessThanEq, timestamp); MojErrCheck(err); count = 0; err = delImpl(revTimestampQuery, count, req, FlagPurge); MojErrCheck(err); return MojErrNone; }