#include "CLucene/StdHeader.h" #ifndef NO_RANGE_QUERY #include "RangeQuery.h" #include "SearchHeader.h" #include "Scorer.h" #include "BooleanQuery.h" #include "TermQuery.h" #include "CLucene/index/Term.h" #include "CLucene/index/Terms.h" #include "CLucene/index/IndexReader.h" #include "CLucene/util/StringBuffer.h" using namespace lucene::index; using namespace lucene::util; namespace lucene{ namespace search{ RangeQuery::RangeQuery(Term* LowerTerm, Term* UpperTerm, const bool Inclusive): /* DSR:CL_BUG: ** Can't call the IGCollectable::pointer method on NULL pointer, which ** either LowerTerm or UpperTerm might be. */ lowerTerm(LowerTerm != NULL ? LowerTerm->pointer() : NULL), upperTerm(UpperTerm != NULL ? UpperTerm->pointer() : NULL), inclusive(Inclusive), query (NULL), reader(NULL) { if (LowerTerm == NULL && UpperTerm == NULL) { //todo - finalize after construct error _THROWC( "At least one term must be non-NULL"); } if (LowerTerm != NULL && UpperTerm != NULL && stringCompare(lowerTerm->Field(), upperTerm->Field()) != 0 ) { _THROWC( "Both terms must be for the same field" ); } } RangeQuery::~RangeQuery() { lowerTerm->finalize(); upperTerm->finalize(); delete query; /* DSR:CL_BUG_LEAK: this->query was not deleted. */ } const char_t* RangeQuery::getQueryName() const{ return _T("RangeQuery"); } void RangeQuery::prepare(IndexReader& reader) { this->query = NULL; this->reader = &reader; } float_t RangeQuery::sumOfSquaredWeights(Searcher& searcher) { return getQuery()->sumOfSquaredWeights(searcher); } void RangeQuery::normalize(const float_t norm) { getQuery()->normalize(norm); } Scorer* RangeQuery::scorer(IndexReader& reader) { return getQuery()->scorer(reader); } BooleanQuery* RangeQuery::getQuery() { if (query == NULL) { BooleanQuery* q = new BooleanQuery(); // if we have a lowerTerm, start there. otherwise, start at beginning if (lowerTerm == NULL) lowerTerm = new Term(getField(), _T("")); TermEnum& _enum = reader->getTerms(lowerTerm); _TRY { const char_t* lowerText = NULL; //char_t* field; bool checkLower = false; if (!inclusive) // make adjustments to set to exclusive { if (lowerTerm != NULL) { lowerText = lowerTerm->Text(); checkLower = true; } if (upperTerm != NULL) { // set upperTerm to an actual term in the index TermEnum& uppEnum = reader->getTerms(upperTerm); /* DSR:CL_BUG_LEAK: uppEnum was neither closed nor ** deleted, and the previous Term pointed to by ** upperTerm was not decrefed. */ upperTerm = uppEnum.getTerm(); uppEnum.close(); delete &uppEnum; } } const char_t* testField = getField(); do { /* DSR:CL_BUG_LEAK: Ordered getTerm not to return reference ** ownership here. */ Term* term = _enum.getTerm(false); if (term != NULL && stringCompare(term->Field(), testField)==0 ) { if (!checkLower || stringCompare(term->Text(),lowerText) > 0) { checkLower = false; if (upperTerm != NULL) { int_t compare = upperTerm->compareTo( *term ); /* if beyond the upper term, or is exclusive and * this is equal to the upper term, break out */ if ((compare < 0) || (!inclusive && compare == 0)) break; } TermQuery& tq = *new TermQuery(*term); // found a match tq.setBoost(boost); // set the boost q->add(tq,true, false, false); // add to q } } else { break; } } while (_enum.next()); }_FINALLY ( _enum.close(); delete &_enum; ); query = q; } return query; } /** Prints a user-readable version of this query. */ const char_t* RangeQuery::toString(const char_t* field) { StringBuffer buffer; if ( stringCompare(getField(),field)!=0 ) { buffer.append( getField() ); buffer.append( _T(":")); } buffer.append(inclusive ? _T("[") : _T("{")); buffer.append(lowerTerm != NULL ? lowerTerm->Text() : _T("NULL")); buffer.append(_T("-")); buffer.append(upperTerm != NULL ? upperTerm->Text() : _T("NULL")); buffer.append(inclusive ? _T("]") : _T("}")); if (boost != 1.0f) { buffer.append( _T("^")); buffer.append( boost,4 ); } return buffer.ToString(); } const char_t* RangeQuery::getField() { return (lowerTerm != NULL ? lowerTerm->Field() : upperTerm->Field()); } }} #endif