MojErr MojDbTextCollator::init(const MojChar* locale, MojDbCollationStrength level) { MojAssert(locale); MojAssert(!m_ucol); UCollationStrength strength = UCOL_PRIMARY; switch (level) { case MojDbCollationPrimary: strength = UCOL_PRIMARY; break; case MojDbCollationSecondary: strength = UCOL_SECONDARY; break; case MojDbCollationTertiary: strength = UCOL_TERTIARY; break; case MojDbCollationIdentical: strength = UCOL_IDENTICAL; break; default: MojAssertNotReached(); } UErrorCode status = U_ZERO_ERROR; m_ucol = ucol_open(locale, &status); MojUnicodeErrCheck(status); MojAssert(m_ucol); ucol_setAttribute(m_ucol, UCOL_NORMALIZATION_MODE, UCOL_ON, &status); MojUnicodeErrCheck(status); ucol_setStrength(m_ucol, strength); return MojErrNone; }
MojErr MojDbTextCollator::init(const MojChar* locale, MojDbCollationStrength level) { LOG_TRACE("Entering function %s", __FUNCTION__); MojAssert(locale); MojAssert(!m_ucol); UCollationStrength strength = UCOL_PRIMARY; switch (level) { case MojDbCollationPrimary: strength = UCOL_PRIMARY; break; case MojDbCollationSecondary: strength = UCOL_SECONDARY; break; case MojDbCollationTertiary: strength = UCOL_TERTIARY; break; case MojDbCollationQuaternary: strength = UCOL_QUATERNARY; break; case MojDbCollationIdentical: strength = UCOL_IDENTICAL; break; default: MojAssertNotReached(); } UErrorCode status = U_ZERO_ERROR; m_ucol = ucol_open(locale, &status); MojUnicodeErrCheck(status); MojAssert(m_ucol); ucol_setAttribute(m_ucol, UCOL_NORMALIZATION_MODE, UCOL_ON, &status); if (level == MojDbCollationIdentical) { // Combination of IDENTICAL and NUMERIC option cover full-width comparison and ["001","01","1"] ordering. // NUMERIC option converts number charcter to numeric "a021" -> ["a",21] ucol_setAttribute(m_ucol, UCOL_NUMERIC_COLLATION, UCOL_ON, &status); } MojUnicodeErrCheck(status); ucol_setStrength(m_ucol, strength); return MojErrNone; }
MojErr MojDbQueryPlan::rangesFromKeys(MojDbKey lowerKey, MojDbKey upperKey, MojDbKey prefix, MojUInt32 index, const MojDbQuery::WhereClause* clause) { MojErr err = MojErrNone; MojUInt32 group = 0; MojDbQuery::CompOp lowerOp = MojDbQuery::OpEq; MojDbQuery::CompOp upperOp = MojDbQuery::OpNone; if (clause) { lowerOp = clause->lowerOp(); upperOp = clause->upperOp(); } // set up upper bound switch (upperOp) { case MojDbQuery::OpNone: MojAssert(lowerOp != MojDbQuery::OpNone); upperKey = prefix; // no break. fall through to OpLessThanEq case case MojDbQuery::OpLessThanEq: // match while less-than ++upperKey err = upperKey.increment(); MojErrCheck(err); break; default: MojAssert(upperOp == MojDbQuery::OpLessThan); break; } // set up lower bound switch (lowerOp) { case MojDbQuery::OpNone: // seek to prefix and match while less than upperKey MojAssert(upperOp != MojDbQuery::OpNone); err = addRange(lowerKey, upperKey); MojErrCheck(err); break; case MojDbQuery::OpSearch: group = index % m_groupCount; // no break. fall through to OpPrefix case case MojDbQuery::OpPrefix: // remove null terminator MojAssert(!prefix.empty()); if (prefix.byteVec().back() == 0) { err = prefix.byteVec().pop(); MojErrCheck(err); } // no break. fall through to OpEq case case MojDbQuery::OpEq: // seek to lowerKey and match while less than ++prefix err = prefix.increment(); MojErrCheck(err); err = addRange(lowerKey, prefix, group); MojErrCheck(err); break; case MojDbQuery::OpNotEq: // seek to prefix and match while less than lowerKey err = addRange(prefix, lowerKey); MojErrCheck(err); // seek to ++lowerKey, and match while less than ++prefix err = lowerKey.increment(); MojErrCheck(err); err = prefix.increment(); MojErrCheck(err); err = addRange(lowerKey, prefix); MojErrCheck(err); break; case MojDbQuery::OpGreaterThan: // seek to ++lowerKey and match while less than upperKey err = lowerKey.increment(); MojErrCheck(err); // no break. fall through to OpGreaterThanEq case case MojDbQuery::OpGreaterThanEq: // seek to lowerKey and match while less than upperKey err = addRange(lowerKey, upperKey); MojErrCheck(err); break; default: MojAssertNotReached(); break; } return MojErrNone; }