4 #include <wibble/regexp.h>
5 #include <wibble/sys/pipe.h>
6 #include <wibble/sys/exec.h>
31 return term[0] ==
'X' && term[1] ==
'T';
38 mutable Xapian::MSet::const_iterator
m_iter;
81 Xapian::Enquire
const &
enq()
const {
82 return *
reinterpret_cast< Xapian::Enquire
const *
>(
m_enqPlace );
85 List( Xapian::Enquire _enq )
87 Xapian::Enquire *e =
new (
m_enqPlace) Xapian::Enquire( _enq );
88 assert_eq( e, &
enq() );
101 typedef std::set< std::string >
Terms;
118 return wibble::Tokenizer( q,
"[A-Za-z0-9._+:-]+", REG_EXTENDED );
121 template<
typename Out >
125 for (wibble::Tokenizer::const_iterator i = tok.begin(); i != tok.end(); ++i )
127 if ( (*i).find(
"::" ) != std::string::npos ) {
130 std::string t = wibble::str::tolower(*i);
131 std::string s =
m_stem(t);
139 template<
typename Out >
144 Xapian::MSet mset =
m_enq.get_mset(0, 5);
145 for ( Xapian::MSet::iterator i = mset.begin(); i != mset.end(); ++i )
146 rset.add_document(i);
149 Xapian::ESet eset =
m_enq.get_eset(5, rset, &tagf);
150 for ( Xapian::ESetIterator i = eset.begin(); i != eset.end(); ++i )
156 Xapian::Query inc( Xapian::Query::OP_OR,
159 exc( Xapian::Query::OP_OR,
162 secondary( Xapian::Query::OP_OR,
165 secondary1( Xapian::Query::OP_SCALE_WEIGHT, secondary, 0.02 ),
166 query1( Xapian::Query::OP_AND_NOT, inc, exc ),
167 query( Xapian::Query::OP_OR, query1, secondary1 );
169 m_enq.set_query( query );
179 Xapian::MSet first =
m_enq.get_mset(0, 1, 0, 0, 0);
180 Xapian::MSetIterator ifirst = first.begin();
181 if ( ifirst != first.end() ) {
194 std::map< std::string, int > relev;
196 Xapian::MSet mset =
m_enq.get_mset(0, 100);
197 for ( Xapian::MSet::iterator i = mset.begin(); i != mset.end(); ++i )
198 rset.add_document(i);
201 Xapian::ESet eset =
m_enq.get_eset(n, rset, &tagf);
202 for ( Xapian::ESetIterator i = eset.begin(); i != eset.end(); ++i )
203 relev.insert( relev.begin(),
205 std::string( *i, 2, std::string::npos ),
210 void addTerms( std::string t,
bool partial =
false,
bool exclude =
false ) {
214 std::vector< std::string > tok;
217 if ( tok.back().size() == 1 ) {
221 m_db->allterms_begin( tok.back() ),
222 m_db->allterms_end( tok.back() ),
223 std::back_inserter( tok ) );
226 std::copy( tok.begin(), tok.end(), std::inserter( to, to.begin() ) );
231 std::copy( t.begin(), t.end(), std::inserter( to, to.begin() ) );
237 m_db->allterms_begin( term ),
238 m_db->allterms_end( term ),
255 static std::string
toLower(
const std::string& str);
270 Xapian::Database&
db() {
276 const Xapian::Database&
db()
const {
283 m_db = Xapian::Database();
297 op =
new OpProgress();
299 wibble::exception::AddContext _ctx(
"Rebuilding Xapian database." );
303 wibble::sys::Exec ex(
"update-apt-xapian-index" );
304 ex.args.push_back(
"--batch-mode" );
305 ex.searchInPath =
true;
306 ex.forkAndRedirect( 0, &outfd, 0 );
308 wibble::sys::Pipe monit( outfd );
309 while ( !monit.eof() ) {
310 std::string line = monit.nextLine();
311 if ( line.empty() ) {
315 std::cerr <<
"got : " << line << std::endl;
316 if ( wibble::str::startsWith( line,
"begin: " ) ) {
317 op_str = std::string( line, 7, std::string::npos );
318 op->OverallProgress( 0, 100, 100, op_str );
320 }
else if ( wibble::str::startsWith( line,
"done: " ) ) {
322 }
else if ( wibble::str::startsWith( line,
"progress: " ) ) {
323 wibble::ERegexp re(
"progress: ([0-9]+)/([0-9]+)", 3 );
324 if ( re.match( line ) ) {
325 assert_eq( re[2],
"100" );
326 op->OverallProgress( atoi( re[1].c_str() ), 100, 100, op_str );
339 int qualityCutoff = 50 )
345 if ( s.length() > 2 )
359 Xapian::docid
docidByName(
const std::string& pkgname)
const;
364 Xapian::Query
makeORQuery(
const std::string& keywords)
const;
377 template<
typename ITER>
378 Xapian::Query
makeORQuery(
const ITER& begin,
const ITER& end)
const
380 return Xapian::Query(Xapian::Query::OP_OR, begin, end);
384 std::vector<std::string>
expand(Xapian::Enquire& enq)
const;
397 Xapian::valueno val_id)
const;
402 int getIntValue(
const std::string& pkgname, Xapian::valueno val_id)
const;