Ejemplo n.º 1
0
MojErr MojDbQueryPlan::pushSearch(MojDbKeyBuilder& lowerBuilder, MojDbKeyBuilder& upperBuilder,
		const MojObject& val, MojDbTextCollator* collator)
{
	// get text
	MojString text;
	MojErr err = val.stringValue(text);
	MojErrCheck(err);
	MojDbKeyBuilder::KeySet toks;

	// tokenize
	MojRefCountedPtr<MojDbTextTokenizer> tokenizer(new MojDbTextTokenizer);
	MojAllocCheck(tokenizer.get());
	err = tokenizer->init(m_locale);
	MojErrCheck(err);
	err = tokenizer->tokenize(text, collator, toks);
	MojErrCheck(err);

	// remove prefixes
	MojDbKeyBuilder::KeySet::Iterator i;
	err = toks.begin(i);
	MojErrCheck(err);
	MojDbKeyBuilder::KeySet::ConstIterator prev = toks.end();
	while (i != toks.end()) {
		if (prev != toks.end() && prev->stringPrefixOf(*i)) {
			bool found = false;
			err = toks.del(*prev, found);
			MojErrCheck(err);
			MojAssert(found);
		}
		prev = i;
		++i;
	}

	// push toks
	err = lowerBuilder.push(toks);
	MojErrCheck(err);
	err = upperBuilder.push(toks);
	MojErrCheck(err);
	m_groupCount = (MojUInt32) toks.size();

	return MojErrNone;
}
Ejemplo n.º 2
0
MojErr MojDbIndex::getKeys(const MojObject& obj, KeySet& keysOut) const
{
    LOG_TRACE("Entering function %s", __FUNCTION__);

	// build the set of unique keys from object
	MojDbKeyBuilder builder;
	MojErr err = builder.push(m_idSet);
	MojErrCheck(err);
	MojSize idx = 0;
	for (PropVec::ConstIterator i = m_props.begin();
		 i != m_props.end();
		 ++i, ++idx) {
		KeySet vals;
		err = (*i)->vals(obj, vals);
		MojErrCheck(err);
		err = builder.push(vals);
		MojErrCheck(err);
	}
	err = builder.keys(keysOut);
	MojErrCheck(err);

	return MojErrNone;
}
Ejemplo n.º 3
0
MojErr MojDbQueryPlan::pushVal(MojDbKeyBuilder& builder, const MojObject& val, MojDbTextCollator* collator)
{
	MojErr err = MojErrNone;
	MojDbKey key;
	MojDbKeyBuilder::KeySet keys;
	if (val.type() == MojObject::TypeArray) {
		MojObject::ConstArrayIterator end = val.arrayEnd();
		for (MojObject::ConstArrayIterator i = val.arrayBegin(); i != end; ++i) {
			err = key.assign(*i, collator);
			MojErrCheck(err);
			err = keys.put(key);
			MojErrCheck(err);
		}
	} else {
		err = key.assign(val, collator);
		MojErrCheck(err);
		err = keys.put(key);
		MojErrCheck(err);
	}
	err = builder.push(keys);
	MojErrCheck(err);

	return MojErrNone;
}
Ejemplo n.º 4
0
MojErr MojDbQueryPlan::buildRanges(const MojDbIndex& index)
{
	MojAssert(!index.props().empty());

	MojErr err = MojErrNone;
	const MojDbQuery::WhereMap& where = m_query.where();
	const StringVec& props = index.props();
	const MojDbQuery::WhereClause* lastClause = NULL;
	MojDbKeyBuilder lowerBuilder;
	MojDbKeyBuilder upperBuilder;
	MojDbKeyBuilder::KeySet prefixKeys;

	err = pushVal(lowerBuilder, index.id(), NULL);
	MojErrCheck(err);
	err = pushVal(upperBuilder, index.id(), NULL);
	MojErrCheck(err);

	// push vals for all props in index prop order to create upper and lower bounds
	for (StringVec::ConstIterator i = props.begin(); i != props.end(); ++i) {
		// get clause for prop
		MojDbQuery::WhereMap::ConstIterator clause = where.find(*i);
		if (clause == where.end()) {
			MojAssert((MojSize)(i - props.begin()) == where.size());
			break;
		}

		// create collator
		MojRefCountedPtr<MojDbTextCollator> collator;
		MojDbCollationStrength coll = clause->collation();
		if (coll != MojDbCollationInvalid) {
			collator.reset(new MojDbTextCollator);
			MojAllocCheck(collator.get());
			err = collator->init(m_locale, coll);
			MojErrCheck(err);
		}

		// push vals for clause
		MojDbQuery::CompOp lowerOp = clause->lowerOp();
		if (lowerOp == MojDbQuery::OpSearch) {
			// tokenize search strings
			err = pushSearch(lowerBuilder, upperBuilder, clause->lowerVal(), collator.get());
			MojErrCheck(err);
		} else {
			// copy off prefix before writing an inequality val
			if (lowerOp != MojDbQuery::OpEq && lowerOp != MojDbQuery::OpPrefix) {
				err = lowerBuilder.keys(prefixKeys);
				MojErrCheck(err);
				if (prefixKeys.empty()) {
					// if there is no prefix yet, put an empty key
					err = prefixKeys.put(MojDbKey());
					MojErrCheck(err);
				}
			}
			// append lower-value to lower-key
			err = pushVal(lowerBuilder, clause->lowerVal(), collator.get());
			MojErrCheck(err);
			// append appropriate value to upper-key
			if (clause->upperOp() == MojDbQuery::OpNone) {
				err = pushVal(upperBuilder, clause->lowerVal(), collator.get());
				MojErrCheck(err);
			} else {
				err = pushVal(upperBuilder, clause->upperVal(), collator.get());
				MojErrCheck(err);
			}
		}
		lastClause = &clause.value();
	}

	// go from builders to ranges
	KeySet lowerKeys;
	err = lowerBuilder.keys(lowerKeys);
	MojErrCheck(err);
	KeySet upperKeys;
	err = upperBuilder.keys(upperKeys);
	MojErrCheck(err);
	if (prefixKeys.empty()) {
		prefixKeys = lowerKeys;
	}
	err = rangesFromKeySets(lowerKeys, upperKeys, prefixKeys, lastClause);
	MojErrCheck(err);

	return MojErrNone;
}