MojErr MojLogEngine::configure(const MojObject& conf, const MojChar* name) { MojAssert(name); MojErr err = MojErrNone; MojLogger::Level defaultLevel = MojLogger::LevelDefault; MojAutoPtr<MojLogAppender> appender; LevelMap levels; // validate entire configuration before we apply any changes MojObject logConf; if (conf.get(LogKey, logConf)) { // appender MojObject obj; if (logConf.get(AppenderKey, obj)) { err = createAppender(obj, name, appender); MojErrCheck(err); } // levels if (logConf.get(LevelsKey, obj)) { // configure loggers MojString str; for (MojObject::ConstIterator i = obj.begin(); i != obj.end(); ++i) { MojLogger::Level level = MojLogger::LevelNone; err = i.value().stringValue(str); MojErrCheck(err); err = MojLogger::levelFromString(str, level); MojErrCheck(err); if (i.key() == DefaultKey) { defaultLevel = level; } else { err = levels.put(i.key(), level); MojErrCheck(err); } } } } // apply changes MojThreadGuard guard(m_mutex); // update name err = m_name.assign(name); MojErrCheck(err); // update appender updateAppender(appender); // update levels m_levels = levels; m_defaultLogger.level(defaultLevel); updateLoggers(); return MojErrNone; }
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; }
MojErr MojDb::mergeInto(MojObject& dest, const MojObject& obj, const MojObject& prev) { MojLogTrace(s_log); // TODO: support field deletion // TODO: move merge fn out of db MojErr err; MojObject::ConstIterator objIter = obj.begin(); MojObject::ConstIterator prevIter = prev.begin(); while (objIter != obj.end() || prevIter != prev.end()) { // compare keys from two iters int comp; if (objIter == obj.end()) { comp = 1; } else if (prevIter == prev.end()) { comp = -1; } else { comp = objIter.key().compare(prevIter.key()); } // put the appropriate value into dest if (comp > 0) { err = dest.put(prevIter.key(), prevIter.value()); MojErrCheck(err); ++prevIter; } else if (comp < 0) { err = dest.put(objIter.key(), objIter.value()); MojErrCheck(err); ++objIter; } else { MojObject::Type newType = objIter.value().type(); MojObject::Type prevType = prevIter.value().type(); if (newType == MojObject::TypeObject && prevType == MojObject::TypeObject) { MojObject merged(MojObject::TypeObject); err = mergeInto(merged, objIter.value(), prevIter.value()); MojErrCheck(err); err = dest.put(objIter.key(), merged); MojErrCheck(err); } else { err = dest.put(objIter.key(), objIter.value()); MojErrCheck(err); } ++prevIter; ++objIter; } } return MojErrNone; }
/** **************************************************************************************************** * @run MojObject stores key-value pairs.Internally it provides separate implmentation for all data types. Provides facility to push single entry or entire array of data into MojObject. Supports put/get/delete operation. Data having key and value is converted to Node type and then node is inserted into TreeBase. All operation happens on TreeBase are based on key. Provides interface to convert JSON string to JSON object and viceversa. * @param : None * @retval : MojErr **************************************************************************************************** **/ MojErr MojObjectTest::run() { MojObject obj0; MojObject obj1; MojObject obj2; MojObject obj3; MojObject obj4; MojString str1; MojObjectBuilder builder; int count = 0; bool found = false; // empty object MojTestAssert(obj1.type() == MojObject::TypeUndefined); MojErr err = emptyTest(obj1); MojTestErrCheck(err); obj1.clear(MojObject::TypeNull); MojTestAssert(obj1.type() == MojObject::TypeNull); err = emptyTest(obj1); MojTestErrCheck(err); obj1.clear(MojObject::TypeObject); MojTestAssert(obj1.type() == MojObject::TypeObject); err = emptyTest(obj1); MojTestErrCheck(err); obj1.clear(MojObject::TypeArray); MojTestAssert(obj1.type() == MojObject::TypeArray); err = emptyTest(obj1); MojTestErrCheck(err); obj1.clear(MojObject::TypeString); MojTestAssert(obj1.type() == MojObject::TypeString); err = emptyTest(obj1); MojTestErrCheck(err); obj1.clear(MojObject::TypeBool); MojTestAssert(obj1.type() == MojObject::TypeBool); err = emptyTest(obj1); MojTestErrCheck(err); obj1.clear(MojObject::TypeDecimal); MojTestAssert(obj1.type() == MojObject::TypeDecimal); err = emptyTest(obj1); MojTestErrCheck(err); obj1.clear(MojObject::TypeInt); MojTestAssert(obj1.type() == MojObject::TypeInt); err = emptyTest(obj1); MojTestErrCheck(err); err = obj2.fromJson("{}"); MojTestAssert(obj2.type() == MojObject::TypeObject); MojTestErrCheck(err); err = emptyTest(obj2); MojTestErrCheck(err); err = obj3.put(_T("hello"), 5LL); MojTestErrCheck(err); err = obj3.del(_T("hello"), found); MojTestErrCheck(err); MojTestAssert(found); err = emptyTest(obj3); MojTestErrCheck(err); err = obj3.put(_T("hello"), 5LL); MojTestErrCheck(err); obj3.clear(); err = emptyTest(obj3); MojTestErrCheck(err); // put/get/del err = putTest(obj1); MojTestErrCheck(err); err = getTest(obj1); MojTestErrCheck(err); err = obj1.visit(builder); MojTestErrCheck(err); err = getTest(builder.object()); MojTestErrCheck(err); err = obj1.toJson(str1); MojTestErrCheck(err); err = obj2.fromJson(str1); MojTestErrCheck(err); err = getTest(obj2); MojTestErrCheck(err); obj3 = obj2; err = getTest(obj3); MojTestErrCheck(err); obj3.clear(); MojTestAssert(obj3.empty()); // iterator for (MojObject::ConstIterator i = obj2.begin(); i != obj2.end(); ++i) { count++; obj3.put(i.key(), i.value()); } MojTestAssert(count == 10); err = getTest(obj3); MojTestErrCheck(err); // types err = typeTest(); MojTestErrCheck(err); return MojErrNone; }