pike.git / lib / modules / Search.pmod / Query.pmod

version» Context lines:

pike.git/lib/modules/Search.pmod/Query.pmod:1:   // This file is part of Roxen Search   // Copyright © 2001 Roxen IS. All rights reserved.   // - // $Id: Query.pmod,v 1.23 2001/09/25 22:02:37 js Exp $ + // $Id: Query.pmod,v 1.24 2002/05/15 14:28:53 mattias Exp $      static function(string,int:string) blobfeeder(Search.Database.Base db, array words)   {    mapping state = mkmapping(words,allocate(sizeof(words)));    mapping(string:mapping(int:string)) blobcache = ([ ]);    return lambda( string word, int foo )    {    return db->get_blob(word, state[word]++, blobcache);    };   }
pike.git/lib/modules/Search.pmod/Query.pmod:102:       // Used when search is limited to another field than "any:".    static Search.RankingProfile specialRanking;       static void create(Search.Database.Base _db, Search.RankingProfile _defaultRanking) {    db = _db;    defaultRanking = _defaultRanking;    specialRanking = defaultRanking->copy();    }    +  static array(array(string)) split_words(array(string) words) +  { +  array a=({}),b=({}); +  foreach(words, string word) +  if(has_value(word, "*") || has_value(word, "?")) +  b+=({ word }); +  else +  a+=({ word }); +  return ({ a, b }); +  } +     static constant ParseNode = Search.Grammar.ParseNode;       static array(array(string)|string) words = ({ });    static array(Search.ResultSet) stack = ({ });    static void push(Search.ResultSet r) {    stack = ({ r }) + stack;    }    static Search.ResultSet pop() {    if (!sizeof(stack))    error("Very bad!");
pike.git/lib/modules/Search.pmod/Query.pmod:125:    }       array(Search.ResultSet|array(string)) execute(ParseNode q) {    exec(q);    if (sizeof(stack) != 1)    throw ("Stack should have exactly one item!");    return ({ pop(), words });    }       void exec(ParseNode q) { +  int max_globs = 100;    switch (q->op) {    case "and":    {    int first = 1;    foreach (q->children, ParseNode child)    if (child->op != "date") {    exec(child);    if (!first) {    Search.ResultSet r2 = pop();    Search.ResultSet r1 = pop();
pike.git/lib/modules/Search.pmod/Query.pmod:167:    first = 0;    }    break;    case "date":    // NOT IMPLEMENTED YET    break;    case "text":    {    Search.RankingProfile ranking = defaultRanking;    -  if (q->field != "any") { +  if (q->field != "any") +  {    ranking = specialRanking;    int fieldID = db->get_field_id(q->field, 1); -  if (!fieldID && q->field != "body") { +  if (!fieldID && q->field != "body") +  {    // There was no such field, so we push an empty ResultSet !    push(Search.ResultSet());    break;    }    ranking->field_ranking = allocate(65);    ranking->field_ranking[fieldID] = 1;    }    -  +  [array plusWords, array plusWordGlobs] = split_words(q->plusWords); +  [array ordinaryWords, array ordinaryWordGlobs] = split_words(q->words); +  [array minusWords, array minusWordGlobs] = split_words(q->minusWords); +  + // werror("[%-10s] plus: %-15s ordinary: %-15s minus: %-15s\n", q->field, q>plusWords*", ", q->words*", ", q->minusWords*", "); +     int hasPlus = sizeof(q->plusWords) || sizeof(q->plusPhrases);    int hasOrdinary = sizeof(q->words) || sizeof(q->phrases);    int hasMinus = sizeof(q->minusWords) || sizeof(q->minusPhrases); -  if (hasPlus) { +  +  if(hasPlus) +  {    int first = 1; -  if (sizeof(q->plusWords)) { -  words += q->plusWords; -  push(do_query_and(db, q->plusWords, ranking)); +  if(sizeof(plusWords)) +  { +  words += plusWords; +  push(do_query_and(db, plusWords, ranking));    first = 0;    } -  foreach (q->plusPhrases, array(string) ph) { +  foreach(plusWordGlobs, string plusWordGlob) +  { +  push(do_query_or(db, db->expand_word_glob(plusWordGlob, max_globs), ranking)); +  if (!first) +  { +  Search.ResultSet r2 = pop(); +  Search.ResultSet r1 = pop(); +  push(r1 & r2); +  } +  first = 0; +  } +  foreach (q->plusPhrases, array(string) ph) +  {    words += ph;    push(do_query_phrase(db, ph, ranking)); -  if (!first) { +  if (!first) +  {    Search.ResultSet r2 = pop();    Search.ResultSet r1 = pop();    push(r1 & r2);    }    first = 0;    }    } -  if (hasOrdinary) { +  +  if(hasOrdinary) +  {    int first = 1; -  if (sizeof(q->words)) { -  words += q->words; -  push(do_query_or(db, q->words, ranking)); +  if (sizeof(ordinaryWords)) +  { +  words += ordinaryWords; +  push(do_query_or(db, ordinaryWords, ranking));    first = 0;    } -  foreach (q->phrases, array(string) ph) { +  foreach(ordinaryWordGlobs, string ordinaryWordGlob) +  { +  push(do_query_or(db, db->expand_word_glob(ordinaryWordGlob, max_globs), ranking)); +  if (!first) +  { +  Search.ResultSet r2 = pop(); +  Search.ResultSet r1 = pop(); +  push(r1 | r2); +  } +  first = 0; +  } +  foreach (q->phrases, array(string) ph) +  {    words += ph;    push(do_query_phrase(db, ph, ranking)); -  if (!first) { +  if(!first) +  {    Search.ResultSet r2 = pop();    Search.ResultSet r1 = pop();    push(r1 | r2);    }    first = 0;    }    }    -  if (hasPlus && hasOrdinary) { +  if(hasPlus && hasOrdinary) +  {    Search.ResultSet r2 = pop();    Search.ResultSet r1 = pop();    // If a document contains must-have words AND ALSO may-have words,    // it's ranking is increased.    push(r1->add_ranking(r2));    }    -  if ((hasPlus || hasOrdinary) && hasMinus) { +  if((hasPlus || hasOrdinary) && hasMinus) +  {    int first = 1; -  if (sizeof(q->minusWords)) { +  if (sizeof(q->minusWords)) +  {    push(do_query_or(db, q->minusWords, ranking));    first = 0;    } -  foreach (q->minusPhrases, array(string) ph) { +  foreach(minusWordGlobs, string minusWordGlob) +  { +  push(do_query_or(db, db->expand_word_glob(minusWordGlob, max_globs), ranking)); +  if(!first) +  { +  Search.ResultSet r2 = pop(); +  Search.ResultSet r1 = pop(); +  push(r1 | r2); +  } +  first = 0; +  } +  foreach (q->minusPhrases, array(string) ph) +  {    push(do_query_phrase(db, ph, ranking)); -  if (!first) { +  if (!first) +  {    Search.ResultSet r2 = pop();    Search.ResultSet r1 = pop();    push(r1 | r2);    }    first = 0;    }    Search.ResultSet r2 = pop();    Search.ResultSet r1 = pop();    push(r1 - r2);    } -  +     }    break;    default:    error("Unknown type of ParseNode!");    } // switch (q->op)    }       } (db, defaultRanking)->execute(q);   }