Exemplo n.º 1
0
TEST_F(ReqSuite, deleteUpdateRollback)
{
    buildSample();
    mark1();

    {
        MojDbReq req;
        // start transaction
        req.begin(&db, false);

        checkMarkWithUpdate(50ul, -1, req);
        checkMarkWithUpdate(0ul, -3, req);

        deleteMark(50ul, -1, req);

        checkMarkWithUpdate(0ul, -1, req);
        checkMarkWithUpdate(0ul, -3, req);

        mark3(req);

        checkMarkWithUpdate(0ul, -1, req);
        checkMarkWithUpdate(33ul, -3, req);

    }
    checkMarkWithUpdate(50ul, -1);
    checkMarkWithUpdate(0ul, -3);
}
Exemplo n.º 2
0
MojErr MojDb::updateLocale(const MojChar* locale, MojDbReqRef req)
{
	MojAssert(locale);
	MojLogTrace(s_log);

	MojErr err = beginReq(req, true);
	MojErrCheck(err);
	MojString oldLocale;
	err = getLocale(oldLocale, req);
	MojErrCheck(err);
	MojString newLocale;
	err = newLocale.assign(locale);
	MojErrCheck(err);
	MojErr updateErr = err = updateLocaleImpl(oldLocale, newLocale, req);
	MojErrCatchAll(err) {
		err = req->abort();
		MojErrCheck(err);
		err = m_kindEngine.close();
		MojErrCheck(err);
		MojDbReq openReq;
		err = beginReq(openReq, true);
		MojErrCheck(err);
		err = m_kindEngine.open(this, openReq);
		MojErrCheck(err);
		err = openReq.end();
		MojErrCheck(err);
		MojErrThrow(updateErr);
	}
	return MojErrNone;
}
Exemplo n.º 3
0
MojErr MojDb::delObj(const MojObject& id, const MojObject& obj, MojDbStorageItem* item, MojObject& foundObjOut, MojDbReq& req, MojUInt32 flags)
{
	MojAssert(item);
	MojLogTrace(s_log);

	if (MojFlagGet(flags, FlagPurge)) {
		// update indexes
		MojTokenSet tokenSet;
		// we want purge to force delete
		req.fixmode(true);
		MojErr err = m_kindEngine.update(NULL, &obj, req, OpDelete, tokenSet);
		MojErrCheck(err);
		// gross layering violation
		err = req.txn()->offsetQuota(-(MojInt64) item->size());
		MojErrCheck(err);
		// permanently delete
		bool found = false;
		err = m_objDb->del(id, req.txn(), found);
		MojErrCheck(err);
		if (!found)
			MojErrThrow(MojErrDbCorruptDatabase);
		err = foundObjOut.put(IdKey, id);
		MojErrCheck(err);
	} else {
		// set deleted flag and put if we are not purging
		MojObject newObj = obj;
		MojErr err = newObj.putBool(DelKey, true);
		MojErrCheck(err);
		err = putObj(id, newObj, &obj, item, req, OpDelete);
		MojErrCheck(err);
		foundObjOut = newObj;
	}
	return MojErrNone;
}
Exemplo n.º 4
0
MojErr MojDbIndex::find(MojDbCursor& cursor, MojDbWatcher* watcher, MojDbReq& req)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(isOpen());

	MojAutoPtr<MojDbQueryPlan> plan(new MojDbQueryPlan(*m_kindEngine));
	MojAllocCheck(plan.get());
	MojErr err = plan->init(cursor.query(), *this);
	MojErrCheck(err);
	if (watcher) {
		// we have to add the watch before beginning the txn or we may miss events
		MojAssert(cursor.txn() == NULL);
		err = addWatch(*plan, cursor, watcher, req);
		MojErrCheck(err);
	}
	if (!cursor.txn()) {
		MojDbStorageTxn* txn = req.txn();
		bool cursorOwnsTxn = !(req.batch() || txn);
		if (txn) {
			cursor.txn(txn, cursorOwnsTxn);
		} else {
			MojRefCountedPtr<MojDbStorageTxn> localTxn;
			err = m_collection->beginTxn(localTxn);
			MojErrCheck(err);
			cursor.txn(localTxn.get(), cursorOwnsTxn);
			req.txn(localTxn.get());
		}
	}
	cursor.m_dbIndex = this;	// for debugging
	err = m_collection->find(plan, cursor.txn(), cursor.m_storageQuery);
	MojErrCheck(err);
	cursor.m_watcher = watcher;
	
	return MojErrNone;
}
Exemplo n.º 5
0
MojErr MojDbIndex::addWatch(const MojDbQueryPlan& plan, MojDbCursor& cursor, MojDbWatcher* watcher, MojDbReq& req)
{
	MojAssert(watcher);
	MojLogTrace(s_log);

	// TODO: use interval tree instead of vector for watches
	MojThreadWriteGuard guard(m_lock);
	MojErr err = m_watcherVec.push(watcher);
	MojErrCheck(err);
	// update count map
	watcher->domain(req.domain());
	WatcherMap::Iterator iter;
	err = m_watcherMap.find(req.domain(), iter);
	MojErrCheck(err);
	if (iter == m_watcherMap.end()) {
		err = m_watcherMap.put(req.domain(), 1);
		MojErrCheck(err);
	} else {
		iter.value() += 1;
		if (iter.value() > WatchWarningThreshold) {
			MojLogWarning(s_log, _T("db:'%s' has %zd watches open on index '%s - %s'"),
					req.domain().data(), iter.value(), m_kind->id().data(), m_name.data());
		}
	}
	MojLogInfo(s_log, _T("DbIndex_addWatch - '%s' on index '%s - %s'"),
					req.domain().data(),  m_kind->id().data(), m_name.data());
	// drop lock before acquiring watcher mutex in init
	guard.unlock();
	watcher->init(this, plan.ranges(), plan.desc(), false);

	return MojErrNone;
}
Exemplo n.º 6
0
TEST_F(ReqSuite, original)
{
    buildSample();
    mark1();

    // test visibility with update
    {
        MojDbReq req;

        // start transaction
        req.begin(&db, false);
        mark2(req);

        // visible within transaction
        checkMarkWithUpdate(50ul, -2, req);
    }

    // invisible after aborted transaction
    checkMarkWithUpdate(0ul, -2);

    // test visibility with delete
    mark1();
    {
        MojDbReq req;
        // start transaction
        req.begin(&db, false);

        deleteMark(50ul, -1, req);

        // visible within transaction
        {
            MojDbQuery query;
            MojAssertNoErr( query.from(_T("Test:1")) );
            MojAssertNoErr( query.where(_T("bar"), MojDbQuery::OpLessThan, 2) );

            MojObject update;

            MojUInt32 count = 0xbaddcafe;
            MojAssertNoErr( db.merge(query, update, count, MojDb::FlagNone, req) );
            EXPECT_EQ( 33ul, count);
        }
    }

    // invisible after aborted transaction
    {
        MojDbQuery query;
        MojAssertNoErr( query.from(_T("Test:1")) );
        MojAssertNoErr( query.where(_T("bar"), MojDbQuery::OpLessThan, 2) );

        MojObject update;
        // Note: should not set value to something that will introduce double-update

        MojUInt32 count = 0xbaddcafe;
        MojAssertNoErr( db.merge(query, update, count) );

        EXPECT_EQ( 83ul, count);
    }
}
Exemplo n.º 7
0
MojErr MojDbIndex::updateLocale(const MojChar* locale, MojDbReq& req)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(isOpen());
	MojAssert(locale);

	bool haveCollate = false;
	for (PropVec::ConstIterator i = m_props.begin(); i != m_props.end(); ++i) {
       if ((*i)->collation() != MojDbCollationInvalid) {
			haveCollate = true;
			MojErr err = (*i)->updateLocale(locale);
			MojErrCheck(err);
       }
	}
	if (haveCollate) {
		// drop and reindex
		MojErr err = drop(req);
		MojErrCheck(err);
		err = build(req.txn());
		MojErrCheck(err);
	}
    m_locale.assign(locale);
    
	return MojErrNone;
}
Exemplo n.º 8
0
MojErr MojDbKindState::writeIds(const MojChar* key, const MojObject& obj, MojDbReq& req, MojRefCountedPtr<MojDbStorageItem>& oldItem)
{
	MojErr err = writeObj(key, obj, m_kindEngine->indexIdDb(), req.txn(), oldItem);
	MojErrCheck(err);

	return MojErrNone;
}
Exemplo n.º 9
0
MojErr MojDbIndex::stats(MojObject& objOut, MojSize& usageOut, MojDbReq& req)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(isOpen());
	
	MojSize count = 0;
	MojSize size = 0;
	MojErr err = m_index->stats(req.txn(), count, size);

    LOG_DEBUG("[db_mojodb] IndexStats: Kind: %s;Index: %s; Id: %zX; count= %zu; size= %zu; delMisses = %d, err= %d \n",
        m_kind->name().data(), m_name.data(), idIndex(), count, size, m_delMisses, err);

	MojErrCheck(err);
	usageOut += size;

	err = objOut.put(SizeKey, (MojInt64) size);
	MojErrCheck(err);
	err = objOut.put(CountKey, (MojInt64) count);
	MojErrCheck(err);
	err = objOut.put(DelMissesKey, (MojInt64) m_delMisses); // cumulative since start
	MojErrCheck(err);

	MojThreadReadGuard guard(m_lock);
	if (!m_watcherMap.empty()) {
		MojObject watcherInfo;
		for (WatcherMap::ConstIterator i = m_watcherMap.begin(); i != m_watcherMap.end(); ++i) {
			err = watcherInfo.put(i.key(), (MojInt64) i.value());
			MojErrCheck(err);
		}
		err = objOut.put(WatchesKey, watcherInfo);
		MojErrCheck(err);
	}
	return MojErrNone;
}
Exemplo n.º 10
0
MojErr MojDbIndex::open(MojDbStorageIndex* index, const MojObject& id, MojDbReq& req, bool created)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(!isOpen() && !m_props.empty());
	MojAssert(index);

	// we don't want to take built-in props into account when sorting indexes,
	m_sortKey = m_propNames;
	m_id = id;

	MojDbKey idKey;
	MojErr err = idKey.assign(id);
	MojErrCheck(err);
	err = m_idSet.put(idKey);
	MojErrCheck(err);
	err = addBuiltinProps();
	MojErrCheck(err);

	if (created && !isIdIndex()) {
		// if this index was just created, we need to re-index before committing the transaction
		MojDbStorageTxn* txn = req.txn();
		txn->notifyPreCommit(m_preCommitSlot);
		txn->notifyPostCommit(m_postCommitSlot);
	} else {
		// otherwise it's ready
		m_ready = true;
	}
	// and we're open
	m_index.reset(index);
	m_collection = m_index.get();

	return MojErrNone;
}
Exemplo n.º 11
0
MojErr MojDbKindState::readIds(const MojChar* key, MojDbReq& req, MojObject& objOut, MojRefCountedPtr<MojDbStorageItem>& itemOut)
{
	MojErr err = readObj(key, objOut, m_kindEngine->indexIdDb(), req.txn(), itemOut);
	MojErrCheck(err);

	return MojErrNone;
}
Exemplo n.º 12
0
TEST_F(ReqSuite, visibility)
{
    buildSample();
    mark1();

    MojDbReq req;
    // start transaction
    req.begin(&db, false);

    checkMarkWithUpdate(50ul, -1, req);
    checkMarkWithUpdate(0ul, -2, req);

    mark2(req);

    checkMarkWithUpdate(50ul, -2, req);
}
Exemplo n.º 13
0
MojErr MojDbKind::updateOwnIndexes(const MojObject* newObj, const MojObject* oldObj, const MojDbReq& req, MojInt32& idxcount)
{
	
	MojInt32 count = 0;

	for (IndexVec::ConstIterator i = m_indexes.begin();
		 i != m_indexes.end(); ++i) {
		count++;
		MojErr err = (*i)->update(newObj, oldObj, req.txn(), req.fixmode());
		MojErrCheck(err);
	}
	MojLogInfo(s_log, _T("Kind_UpdateOwnIndexes: %s; count: %d \n"), this->id().data(), count);
	
	idxcount += count;
	return MojErrNone;
}
Exemplo n.º 14
0
MojErr MojDbKind::update(MojObject* newObj, const MojObject* oldObj, MojDbOp op, MojDbReq& req, bool checkSchema)
{
	MojLogTrace(s_log);

	MojErr err = checkPermission(op, req);
	MojErrCheck(err);
	err = req.curKind(this);
	MojErrCheck(err);

#if defined(TESTDBKIND)
	MojString s;
	MojErr e2;
	
	if (oldObj) {
		e2 = oldObj->toJson(s);
		MojLogInfo(s_log, _T("Kind_Update_OldObj: %s ;\n"), s.data());
	}
	if (newObj) {
		e2 = newObj->toJson(s);
		MojLogInfo(s_log, _T("Kind_Update_NewObj: %s ;\n"), s.data());
	}
#endif
	if (newObj) {
		// add the _backup property if not set
		if (m_backup && !newObj->contains(MojDb::SyncKey)) {
			err = newObj->putBool(MojDb::SyncKey, true);
			MojErrCheck(err);
		}

		// TEMPORARY!!! This should be done in pre-update to also check parent kinds
        	// warning message comes from preUpdate
		if(checkSchema)
		{
		   
		   MojSchema::Result res;
		   err = m_schema.validate(*newObj, res);
		   MojErrCheck(err);
		   if (!res.valid())
		   {
		      MojErrThrowMsg(MojErrSchemaValidation, _T("schema validation failed for kind '%s': %s"),
		                     m_id.data(), res.msg().data());
		   }
		}
        
	}

	// update revSets and validate schema
	err = preUpdate(newObj, oldObj, req);
	MojErrCheck(err);
	// update indexes
	MojVector<MojDbKind*> kindVec;
	MojInt32 idxcount = 0;
	err = updateIndexes(newObj, oldObj, req, op, kindVec, idxcount);
	MojLogInfo(s_log, _T("Kind_UpdateIndexes_End: %s; supers = %zu; indexcount = %zu; updated = %d \n"), this->id().data(), 
				m_supers.size(), m_indexes.size(), idxcount);

	MojErrCheck(err);

	return MojErrNone;
}
Exemplo n.º 15
0
MojErr MojDbQuotaEngine::initUsage(MojDbKind* kind, MojDbReq& req)
{
	MojAssert(kind);

	MojRefCountedPtr<MojDbStorageItem> item;
	MojErr err = m_usageDb->get(kind->id(), req.txn(), false, item);
	MojErrCheck(err);
	if (!item.get()) {
		MojObject stats;
		MojSize usage = 0;
		err = kind->stats(stats, usage, req, false);
		MojErrCheck(err);
		err = insertUsage(kind->id(), (MojInt64) usage, req.txn());
		MojErrCheck(err);
	}
	return MojErrNone;
}
Exemplo n.º 16
0
MojErr MojDbKind::deny(MojDbReq& req)
{
	MojLogWarning(s_log, _T("db: permission denied for caller '%s' on kind '%s'"), req.domain().data(), m_id.data());
	if (m_kindEngine->permissionEngine()->enabled()) {
		// don't leak any information in an error message
		MojErrThrow(MojErrDbPermissionDenied);
	}
	return MojErrNone;
}
Exemplo n.º 17
0
MojDbPermissionEngine::Value MojDbKind::objectPermission(const MojChar* op, MojDbReq& req)
{
	MojDbPermissionEngine::Value val = m_kindEngine->permissionEngine()->
			check(PermissionType, m_id, req.domain(), op);
	if (val == MojDbPermissionEngine::ValueUndefined && !m_supers.empty()) {
		val = m_supers[0]->objectPermission(op, req);
	}
	return val;
}
Exemplo n.º 18
0
MojErr MojDbIndex::drop(MojDbReq& req)
{
	MojAssert(isOpen());
	MojLogTrace(s_log);

	MojErr err = m_index->drop(req.txn());
	MojErrCheck(err);

	return MojErrNone;
}
Exemplo n.º 19
0
MojErr MojDbIndex::drop(MojDbReq& req)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(isOpen());

	MojErr err = m_index->drop(req.txn());
	MojErrCheck(err);

	return MojErrNone;
}
Exemplo n.º 20
0
TEST_F(ReqSuite, updateRollback)
{
    buildSample();
    mark1();

    {
        MojDbReq req;
        // start transaction
        req.begin(&db, false);

        checkMarkWithUpdate(50ul, -1, req);
        checkMarkWithUpdate(0ul, -2, req);

        mark2(req);

        checkMarkWithUpdate(50ul, -2, req);
    }
    checkMarkWithUpdate(50ul, -1);
    checkMarkWithUpdate(0ul, -2);
}
Exemplo n.º 21
0
MojErr MojDb::drop(const MojChar* path)
{
	MojAssert(path);
	MojLogTrace(s_log);

	MojErr err = requireOpen();
	MojErrCheck(err);

	MojDbReq req;
	err = req.begin(this, true);
	MojErrCheck(err);
	err = m_storageEngine->drop(path, req.txn());
	MojErrCheck(err);
	err = req.end();
	MojErrCheck(err);
	err = close();
	MojErrCheck(err);

	return MojErrNone;
}
Exemplo n.º 22
0
MojErr MojDbKind::updateLocale(const MojChar* locale, MojDbReq& req)
{
	MojLogTrace(s_log);
	MojAssert(locale);

	MojErr err = req.curKind(this);
	MojErrCheck(err);
	for (IndexVec::ConstIterator i = m_indexes.begin(); i != m_indexes.end(); ++i) {
		err = (*i)->updateLocale(locale, req);
		MojErrCheck(err);
	}
	return MojErrNone;
}
Exemplo n.º 23
0
MojErr MojDb::updateLocaleImpl(const MojString& oldLocale, const MojString& newLocale, MojDbReq& req)
{
	if (oldLocale != newLocale) {
		MojErr err = m_kindEngine.updateLocale(newLocale, req);
		MojErrCheck(err);
		err = updateState(LocaleKey, newLocale, req);
		MojErrCheck(err);
	}
	MojErr err = req.end();
	MojErrCheck(err);

	return MojErrNone;
}
Exemplo n.º 24
0
MojErr MojDbQuotaEngine::open(const MojObject& conf, MojDb* db, MojDbReq& req)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(db);

	MojErr err = db->storageEngine()->openDatabase(_T("UsageDbName"), req.txn(), m_usageDb);
	MojErrCheck(err);
	err = MojDbPutHandler::open(conf, db, req);
	MojErrCheck(err);

	MojDbKindEngine::KindMap& kinds = db->kindEngine()->kindMap();
	for (MojDbKindEngine::KindMap::ConstIterator i = kinds.begin();
		 i != kinds.end(); ++i) {
		err = initUsage(i.value().get(), req);
		MojErrCheck(err);
	}
	err = refreshImpl(req.txn());
	MojErrCheck(err);

	m_isOpen = true;

	return MojErrNone;
}
Exemplo n.º 25
0
MojErr MojDbKindState::initTokens(MojDbReq& req, const StringSet& strings)
{
	// TODO: bug inside this function. (latest strace step)
	MojAssertMutexLocked(m_lock);

	// TODO: filing load tokens. Go inside readObj
	// load tokens
	MojErr err = readObj(TokensKey, m_tokensObj, m_kindEngine->kindDb(), req.txn(), m_oldTokensItem);
	MojErrCheck(err);

	// populate token vec
	MojUInt8 maxToken = 0;
	err = m_tokenVec.resize(m_tokensObj.size());
	MojErrCheck(err);
	for (MojObject::ConstIterator i = m_tokensObj.begin(); i != m_tokensObj.end(); ++i) {
		MojString key = i.key();
		MojInt64 value = i.value().intValue();
		MojSize idx = (MojSize) (value - MojObjectWriter::TokenStartMarker);
		if (value < MojObjectWriter::TokenStartMarker || value >= MojUInt8Max || idx >= m_tokenVec.size()) {
			MojErrThrow(MojErrDbInvalidToken);
		}
		if (value > maxToken) {
			maxToken = (MojUInt8) value;
		}
		err = m_tokenVec.setAt(idx, key);
		MojErrCheck(err);
	}
	if (maxToken > 0) {
		m_nextToken = (MojUInt8) (maxToken + 1);
	}

	// add strings
	bool updated = false;
	for (StringSet::ConstIterator i = strings.begin(); i != strings.end(); ++i) {
		if (!m_tokensObj.contains(*i)) {
			updated = true;
			MojUInt8 token = 0;
			TokenVec tokenVec;
			MojObject tokenObj;
			err = addPropImpl(*i, false, token, tokenVec, tokenObj);
			MojErrCheck(err);
		}
	}
	if (updated) {
		err = writeTokens(m_tokensObj);
		MojErrCheck(err);
	}
	return MojErrNone;
}
Exemplo n.º 26
0
TEST_F(ReqSuite, originalEq)
{
    buildSample();
    mark1();

    // test visibility with update
    {
        MojDbReq req;

        // start transaction
        req.begin(&db, false);
        mark2(req);

        // visible within transaction
        checkMarkWithUpdate(50ul, -2, req);
    }

    // invisible after aborted transaction
    checkMarkWithUpdate(0ul, -2);

    // test visibility with delete
    mark1();
    {
        MojDbReq req;
        // start transaction
        req.begin(&db, false);

        deleteMark(50ul, -1, req);
        // visible within transaction
        checkMarkWithUpdate(0ul, -1, req);
    }

    // invisible after aborted transaction
    checkMarkWithUpdate(50ul, -1);

}
Exemplo n.º 27
0
MojErr MojDbIndex::addWatch(const MojDbQueryPlan& plan, MojDbCursor& cursor, MojDbWatcher* watcher, MojDbReq& req)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(watcher);

	// TODO: use interval tree instead of vector for watches
	MojThreadWriteGuard guard(m_lock);
	MojErr err = m_watcherVec.push(watcher);
	MojErrCheck(err);
	// update count map
	watcher->domain(req.domain());
	WatcherMap::Iterator iter;
	err = m_watcherMap.find(req.domain(), iter);
	MojErrCheck(err);
	if (iter == m_watcherMap.end()) {
		err = m_watcherMap.put(req.domain(), 1);
		MojErrCheck(err);
	} else {
		iter.value() += 1;
		if (iter.value() > WatchWarningThreshold) {
            LOG_WARNING(MSGID_MOJ_DB_INDEX_WARNING, 4,
            		PMLOGKS("domain", req.domain().data()),
            		PMLOGKFV("iter", "%zd", iter.value()),
            		PMLOGKS("kindId", m_kind->id().data()),
            		PMLOGKS("name", m_name.data()),
            		"db:'domain' has 'iter' watches open on index 'kindId - name'");
		}
	}
	LOG_DEBUG("[db_mojodb] DbIndex_addWatch - '%s' on index '%s - %s'",
		req.domain().data(),  m_kind->id().data(), m_name.data());
	// drop lock before acquiring watcher mutex in init
	guard.unlock();
	watcher->init(this, plan.ranges(), plan.desc(), false);

	return MojErrNone;
}
Exemplo n.º 28
0
MojErr MojDbQuotaEngine::stats(MojObject& objOut, MojDbReq& req)
{
	// check for admin permission
	if (!req.admin()) {
		MojErrThrow(MojErrDbPermissionDenied);
	}
	for (QuotaMap::ConstIterator i = m_quotas.begin(); i != m_quotas.end(); ++i) {
		MojObject quota;
		MojErr err = quota.put(MojDbServiceDefs::SizeKey, i.value()->size());
		MojErrCheck(err);
		err = quota.put(MojDbServiceDefs::UsedKey, i.value()->usage());
		MojErrCheck(err);
		err = objOut.put(i.key(), quota);
		MojErrCheck(err);
	}
	return MojErrNone;
}
Exemplo n.º 29
0
MojErr MojDbQuotaEngine::put(MojObject& obj, MojDbReq& req, bool putObj)
{
	MojLogTrace(s_log);
	MojAssertWriteLocked(m_db->schemaLock());

	// check for admin permission
	if (!req.admin()) {
		MojErrThrow(MojErrDbPermissionDenied);
	}

	// pull params out of object
	MojString owner;
	MojErr err = obj.getRequired(MojDbServiceDefs::OwnerKey, owner);
	MojErrCheck(err);
	MojInt64 size = 0;
	err = obj.getRequired(MojDbServiceDefs::SizeKey, size);
	MojErrCheck(err);

	// validate owner
	err = validateWildcard(owner, MojErrDbInvalidOwner);
	MojErrCheck(err);

	// put object
	if (putObj) {
		MojString id;
		err = id.format(_T("_quotas/%s"), owner.data());
		MojErrCheck(err);
		err = obj.put(MojDb::IdKey, id);
		MojErrCheck(err);
		err = obj.putString(MojDb::KindKey, MojDbKindEngine::QuotaId);
		MojErrCheck(err);

		MojDbAdminGuard adminGuard(req);
		err = m_db->put(obj, MojDb::FlagForce, req);
		MojErrCheck(err);

		// defer commit of quota until txn commit
		MojRefCountedPtr<MojDbQuotaCommitHandler> handler(new MojDbQuotaCommitHandler(this, owner, size, req.txn()));
		MojAllocCheck(handler.get());
	} else {
		err = commitQuota(owner, size);
		MojErrCheck(err);
	}
	return MojErrNone;
}
Exemplo n.º 30
0
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;
}