예제 #1
0
MojErr MojDbPropExtractor::handleVal(const MojObject& val, KeySet& valsOut, MojSize idx) const
{
    LOG_TRACE("Entering function %s", __FUNCTION__);

	MojAssert(idx < m_prop.size());

	MojErr err = MojErrNone;
	if (idx == m_prop.size() - 1) {
		// if we're at the end of the prop path, use this object as the value
		if (m_tokenizer.get() && val.type() == MojObject::TypeString) {
			MojString text;
			err = val.stringValue(text);
			MojErrCheck(err);
			if (m_tokenizer.get()) {
				err = m_tokenizer->tokenize(text, m_collator.get(), valsOut);
				MojErrCheck(err);
			}
		} else {
			MojDbKey key;
			err = key.assign(val, m_collator.get());
			MojErrCheck(err);
			err = valsOut.put(key);
			MojErrCheck(err);
		}
	} else {
		// otherwise, keep recursing
		err = valsImpl(val, valsOut, idx + 1);
		MojErrCheck(err);
	}
	return MojErrNone;
}
예제 #2
0
MojErr MojDbTextTokenizer::tokenize(const MojString& text, MojDbTextCollator* collator, KeySet& keysOut) const
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
    MojAssert(m_ubrk.get());

    // convert to UChar from str
    MojDbTextUtils::UnicodeVec unicodeStr;
    MojErr err = MojDbTextUtils::strToUnicode(text, unicodeStr);
    MojErrCheck(err);

    // clone break iterator and set text
    MojByte buf[U_BRK_SAFECLONE_BUFFERSIZE];
    UErrorCode status = U_ZERO_ERROR;
    MojInt32 size = sizeof(buf);
    IterPtr ubrk(ubrk_safeClone(m_ubrk.get(), buf, &size, &status));
    MojUnicodeErrCheck(status);
    MojAssert(ubrk.get());
    ubrk_setText(ubrk.get(), unicodeStr.begin(), (MojInt32) unicodeStr.size(), &status);
    MojUnicodeErrCheck(status);

    MojInt32 tokBegin = -1;
    MojInt32 pos = ubrk_first(ubrk.get());
    while (pos != UBRK_DONE) {
        UWordBreak status = (UWordBreak) ubrk_getRuleStatus(ubrk.get());
        if (status != UBRK_WORD_NONE) {
            MojAssert(tokBegin != -1);
            MojDbKey key;
            const UChar* tokChars = unicodeStr.begin() + tokBegin;
            MojSize tokSize = (MojSize) (pos - tokBegin);
            if (collator) {
                err = collator->sortKey(tokChars, tokSize, key);
                MojErrCheck(err);
            } else {
                MojString tok;
                err = MojDbTextUtils::unicodeToStr(tokChars, tokSize, tok);
                MojErrCheck(err);
                err = key.assign(tok);
                MojErrCheck(err);
            }
            err = keysOut.put(key);
            MojErrCheck(err);
        }
        tokBegin = pos;
        pos = ubrk_next(ubrk.get());
    }
    return MojErrNone;
}
예제 #3
0
MojErr MojDbPropExtractor::valsImpl(const MojObject& obj, KeySet& valsOut, MojSize idx) const
{
    LOG_TRACE("Entering function %s", __FUNCTION__);

	MojAssert(!m_prop.empty() && idx < m_prop.size());

	MojErr err = MojErrNone;
	const MojString& propKey = m_prop[idx];
	if (propKey == WildcardKey) {
		// get all prop vals if we have a wildcard
		for (MojObject::ConstIterator i = obj.begin(); i != obj.end(); ++i) {
			err = handleVal(*i, valsOut, idx);
			MojErrCheck(err);
		}
	} else {
		// get object corresponding to the current component in the prop path
		MojObject::ConstIterator i = obj.find(propKey);
		if (i == obj.end()) {
			err = valsOut.put(m_default);
			MojErrCheck(err);
		} else {
			if (i->type() == MojObject::TypeArray) {
				// if the value is an array, act on its elements rather than the array object itself
				MojObject::ConstArrayIterator end = i->arrayEnd();
				for (MojObject::ConstArrayIterator j = i->arrayBegin(); j != end; ++j) {
					err = handleVal(*j, valsOut, idx);
					MojErrCheck(err);
				}
			} else {
				// not an array
				err = handleVal(*i, valsOut, idx);
				MojErrCheck(err);
			}
		}
	}
	return MojErrNone;
}
예제 #4
0
MojErr MojDbIndex::update(const MojObject* newObj, const MojObject* oldObj, MojDbStorageTxn* txn, bool forcedel)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(isOpen());
	MojAssert(newObj || oldObj);

	// figure out which versions we include
	bool includeOld = includeObj(oldObj);
	bool includeNew = includeObj(newObj);

	if (includeNew && !includeOld) {
		// we include the new but not the old, so just put all the new keys
		MojAssert(newObj);
		KeySet newKeys;
		MojErr err = getKeys(*newObj, newKeys);
		MojErrCheck(err);
		err = insertKeys(newKeys, txn);
		MojErrCheck(err);
		err = notifyWatches(newKeys, txn);
		MojErrCheck(err);
        LOG_DEBUG("[db_mojodb] IndexAdd: %s; Keys= %zu \n", this->m_name.data(), newKeys.size());
	} else if (includeOld && !includeNew) {
		// we include the old but not the new objects, so del all the old keys
		MojAssert(oldObj);
		KeySet oldKeys;
		MojErr err = getKeys(*oldObj, oldKeys);
		MojErrCheck(err);
		err = delKeys(oldKeys, txn, forcedel);
		MojErrCheck(err);
		err = notifyWatches(oldKeys, txn);
		MojErrCheck(err);
        LOG_DEBUG("[db_mojodb] IndexDel: %s; Keys= %zu \n", this->name().data(), oldKeys.size());
	} else if (includeNew && includeOld) {
		// we include old and new objects
		MojAssert(newObj && oldObj);
		KeySet newKeys;
		MojErr err = getKeys(*newObj, newKeys);
		MojErrCheck(err);
		KeySet oldKeys;
		err = getKeys(*oldObj, oldKeys);
		MojErrCheck(err);
		// we need to put the keys that are in the new set, but not in the old
		KeySet keysToPut;
		err = newKeys.diff(oldKeys, keysToPut);
		MojErrCheck(err);
		// we need to del the keys that are in the old set, but not in the new
		KeySet keysToDel;
		err = oldKeys.diff(newKeys, keysToDel);
		MojErrCheck(err);
		err = insertKeys(keysToPut, txn);
		MojErrCheck(err);
		err = delKeys(keysToDel, txn, forcedel);
		
        LOG_DEBUG("[db_mojodb] IndexMerge: %s; OldKeys= %zu; NewKeys= %zu; Dropped= %zu; Added= %zu ; err = %d\n",
			this->name().data(), oldKeys.size(), newKeys.size(), keysToDel.size(), keysToPut.size(), (int)err);

		MojErrCheck(err);
		// notify on union of old and new keys
		err = newKeys.put(oldKeys);
		MojErrCheck(err);
		err = notifyWatches(newKeys, txn);
		MojErrCheck(err);
	
	}
	return MojErrNone;
}