diff --git a/examples/add.pike b/examples/add.pike --- a/examples/add.pike +++ b/examples/add.pike @@ -1,34 +1,36 @@ import Public.Xapian; int main(int argc, array argv) { object database = WriteableDatabase(argv[1], DB_CREATE_OR_OPEN); string doc = Stdio.read_file(argv[2]); doc = map(doc, lambda(int i){ return (!(i > 'z' || i < '0'))?i:' '; }); array terms = (doc / " ") - ({""}); object s = Stem("english"); object d = Document(); d->add_value(0, argv[2]); + // adding terms to the database + // see http://xapian.org/docs/termgenerator.html foreach(terms; int i; string term) { term = lower_case(term); werror("term: " + term + " -> " + s(term) + "\n"); d->add_posting(term, i, 1); if(!(term[0] >= '0' && term[0] <= '9')) d->add_term("Z" + s(term), 1); } d->set_data(Stdio.read_file(argv[2])); d->add_value(0, argv[2]); database->add_document(d); database = 0; return 0; } diff --git a/xapian.ccmod b/xapian.ccmod --- a/xapian.ccmod +++ b/xapian.ccmod @@ -1,5474 +1,5688 @@ /*! @module Public */ /*! @module Xapian *! An interface to the Xapian full text engine. *! *! For details, please see http://www.xapian.org */ #define _GNU_SOURCE extern "C" { #include "xapian_config.h" #include "util.h" } #include <xapian.h> #include <algorithm> #include <iostream> #include <string> #include <vector> using namespace Xapian; using namespace std; #include <ctype.h> #define OBJ2_MSET(o) ((struct MSet_struct *)get_storage(o, MSet_program)) #define OBJ2_ESET(o) ((struct ESet_struct *)get_storage(o, ESet_program)) #define OBJ2_STEM(o) ((struct Stem_struct *)get_storage(o, Stem_program)) #define OBJ2_STOPPER(o) ((struct Stopper_struct *)get_storage(o, Stopper_program)) #define OBJ2_MSETITERATOR(o) ((struct MSetIterator_struct *)get_storage(o, MSetIterator_program)) #define OBJ2_ESETITERATOR(o) ((struct ESetIterator_struct *)get_storage(o, ESetIterator_program)) #define OBJ2_VALUEITERATOR(o) ((struct ValueIterator_struct *)get_storage(o, ValueIterator_program)) #define OBJ2_TERMITERATOR(o) ((struct TermIterator_struct *)get_storage(o, TermIterator_program)) #define OBJ2_POSITIONITERATOR(o) ((struct PositionIterator_struct *)get_storage(o, PositionIterator_program)) #define OBJ2_DOCUMENT(o) ((struct Document_struct *)get_storage(o, Document_program)) #define OBJ2_DATABASE(o) ((struct Database_struct *)get_storage(o, Database_program)) #define OBJ2_QUERY(o) ((struct Query_struct *)get_storage(o, Query_program)) +#define OBJ2_TERMGENERATOR(o) ((struct TermGenerator_struct *)get_storage(o, TermGenerator_program)) #define OBJ2_VALUERANGEPROCESSOR(o) ((struct ValueRangeProcessor_struct *)get_storage(o, ValueRangeProcessor_program)) extern "C" struct program * Document_program; extern "C" struct program * MSetIterator_program; extern "C" struct program * ValueIterator_program; extern "C" struct program * TermIterator_program; extern "C" struct program * PositionIterator_program; extern "C" struct program * MSet_program; extern "C" struct program * Stem_program; +extern "C" struct program * TermGenerator_program; extern "C" struct program * ValueRangeProcessor_program; extern "C" typedef struct { Database *database; } XAPIAN_DATABASE_OBJECT_DATA; extern "C" typedef struct { Stem *stem; } XAPIAN_STEM_OBJECT_DATA; extern "C" typedef struct { Weight *weight; } XAPIAN_WEIGHT_OBJECT_DATA; extern "C" typedef struct { + TermGenerator *termgenerator; +} XAPIAN_TERMGENERATOR_OBJECT_DATA; + +extern "C" typedef struct +{ QueryParser *parser; } XAPIAN_QUERYPARSER_OBJECT_DATA; extern "C" typedef struct { Stopper *stopper; } XAPIAN_STOPPER_OBJECT_DATA; extern "C" typedef struct { Enquire *enquire; } XAPIAN_ENQUIRE_OBJECT_DATA; extern "C" typedef struct { Query *query; } XAPIAN_QUERY_OBJECT_DATA; extern "C" typedef struct { MSet *mset; } XAPIAN_MSET_OBJECT_DATA; extern "C" typedef struct { RSet *rset; } XAPIAN_RSET_OBJECT_DATA; extern "C" typedef struct { MSetIterator *mseti; } XAPIAN_MSETITERATOR_OBJECT_DATA; extern "C" typedef struct { ValueIterator *valuei; } XAPIAN_VALUEITERATOR_OBJECT_DATA; extern "C" typedef struct { PositionIterator *positioni; } XAPIAN_POSITIONITERATOR_OBJECT_DATA; extern "C" typedef struct { ESet *eset; } XAPIAN_ESET_OBJECT_DATA; extern "C" typedef struct { ESetIterator *eseti; } XAPIAN_ESETITERATOR_OBJECT_DATA; extern "C" typedef struct { TermIterator *termi; } XAPIAN_TERMITERATOR_OBJECT_DATA; extern "C" typedef struct { Document *document; } XAPIAN_DOCUMENT_OBJECT_DATA; extern "C" typedef struct { ValueRangeProcessor *processor; } XAPIAN_VALUERANGEPROCESSOR_OBJECT_DATA; /*! @decl string sortable_serialise(float value) *! *! Convert a floating point number to a string, preserving sort order. */ PIKEFUN string sortable_serialise(float value) { string str = sortable_serialise(value); pop_stack(); push_text(str.c_str()); } /*! @decl float sortable_unserialise(string value) *! *! Convert a string encoded using sortable_serialise back to a floating *! point number. */ PIKEFUN float sortable_unserialise(string value) { double f; string str((const char *)value->str, (size_t)value->len); f = sortable_unserialise(str); push_float(f); } /*! @decl int minor_version() */ PIKEFUN int minor_version() { push_int(minor_version()); } /*! @decl int major_version() */ PIKEFUN int major_version() { push_int(major_version()); } /*! @decl int revision() */ PIKEFUN int revision() { push_int(revision()); } /*! @decl string version_string() *! Report the version string of the library which the program is linked *! with. */ PIKEFUN string version_string() { push_text(version_string()); } - /*! @class Weight */ PIKECLASS Weight { CVAR XAPIAN_WEIGHT_OBJECT_DATA *object_data; /* Weight.int get_sumpart_needs_doclength() */ /*! @decl int get_sumpart_needs_doclength() *! *! returns false if the weight object doesn't need doclength *! @returns *! *! */ PIKEFUN int get_sumpart_needs_doclength() { Weight *weight; weight = THIS->object_data->weight; bool i = weight->get_sumpart_needs_doclength(); push_int(i?1:0); } /* Weight.float get_maxpart() */ /*! @decl float get_maxpart() *! *! Gets the maximum value that @[get_sumpart]() may return. *! *! This is used in optimising searches, by having the postlist tree *! decay appropriately when parts of it can have limited, or no, further *! effect. *! @returns *! *! */ PIKEFUN float get_maxpart() { Weight *weight; weight = THIS->object_data->weight; Xapian::weight i = weight->get_maxpart(); push_float((FLOAT_TYPE)i); } /* Weight.float get_maxextra() */ /*! @decl float get_maxextra() *! *! Gets the maximum value that @[get_sumextra]() may return. *! *! This is used in optimising searches. *! @returns *! *! */ PIKEFUN float get_maxextra() { Weight *weight; weight = THIS->object_data->weight; Xapian::weight i = weight->get_maxextra(); push_float((FLOAT_TYPE)i); } /* Weight.float get_sumextra(int len) */ /*! @decl float get_sumextra(int len) *! *! Get an extra weight for a document to add to the sum calculated over *! the query terms. *! *! This returns a weight for a given document, and is used by some *! weighting schemes to account for influence such as document length. *! @param len *! the (unnormalised) document length. *! *! @returns *! *! */ PIKEFUN float get_sumextra(int len) { Weight *weight; weight = THIS->object_data->weight; Xapian::weight i = weight->get_sumextra((doclength)len); push_float((FLOAT_TYPE)i); } /* Weight.float get_sumpart(int wdf, int len) */ /*! @decl float get_sumpart(int wdf, int len) *!Get a weight which is part of the sum over terms being performed. *! *! This returns a weight for a given term and document. These weights are *! summed to give a total weight for the document. *! *! @param wdf *! the within document frequency of the term. * ! *! @param len *! the (unnormalised) document length. * ! *! @returns *! *! */ PIKEFUN float get_sumpart(int wdf, int len) { Weight *weight; weight = THIS->object_data->weight; Xapian::weight i = weight->get_sumpart((termcount)wdf, (doclength)len); push_float((FLOAT_TYPE)i); } /* Weight.string serialise() */ /*! @decl string serialise() *! *! Serialise object parameters into a string. *! @returns *! *! */ PIKEFUN string serialise() { Weight *weight; weight = THIS->object_data->weight; string str = weight->serialise(); push_text(str.c_str()); } /* Weight.string name() */ /*! @decl string name() *! *! Name of the weighting scheme. *! *! If the subclass is called FooWeight, this should return "Foo". *! @returns *! *! */ PIKEFUN string name() { Weight *weight; weight = THIS->object_data->weight; string str = weight->name(); push_text(str.c_str()); } INIT { XAPIAN_WEIGHT_OBJECT_DATA * dta = (XAPIAN_WEIGHT_OBJECT_DATA*)malloc(sizeof(XAPIAN_WEIGHT_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->weight = NULL; THIS->object_data = dta; } /* Weight.void destroy() */ /*! @decl void destroy() *! *! *! */ PIKEFUN void destroy() { Weight *weight; weight = THIS->object_data->weight; if(weight) { delete weight; } } EXIT { if(THIS->object_data) { Weight *weight; weight = THIS->object_data->weight; // printf("shutting down!\n"); free(THIS->object_data); } } } /*! @endclass */ /*! @class BM25Weight *! @inherit Weight *! BM25 weighting scheme. */ PIKECLASS BM25Weight { INHERIT Weight; PIKEFUN void create(float k1, float k2, float k3, float b, float min_normlen) { BM25Weight * weight; weight = new BM25Weight((double)k1, (double)k2, (double)k3, (double)b, (double)min_normlen); THIS->object_data->weight = weight; } PIKEFUN object clone() { BM25Weight * weight; BM25Weight * weight2; struct object * obj; weight = (BM25Weight *)THIS->object_data->weight; weight2 = weight->clone(); obj = fast_clone_object(BM25Weight_program); OBJ2_WEIGHT(obj)->object_data->weight = (Weight *)weight2; push_object(obj); } } /*! @endclass */ /*! @class BoolWeight *! @inherit Weight *! Boolean weighting scheme (everything gets 0). */ PIKECLASS BoolWeight { INHERIT Weight; PIKEFUN void create() { BoolWeight * weight; weight = new BoolWeight(); THIS->object_data->weight = weight; } } /*! @endclass */ /*! @class TradWeight *! @inherit Weight *! Traditional probabilistic weighting scheme. *! *! This class implements the Traditional Probabilistic Weighting scheme, *! as described by the early papers on Probabilistic Retrieval. @[BM25Weight] *! generally gives better results. */ PIKECLASS TradWeight { INHERIT Weight; PIKEFUN void create(float k) { TradWeight * weight; weight = new TradWeight((double)k); THIS->object_data->weight = weight; } } /*! @endclass */ /*! @class ValueRangeProcessor *! Base class for value range processors. */ PIKECLASS ValueRangeProcessor { CVAR XAPIAN_VALUERANGEPROCESSOR_OBJECT_DATA *object_data; /*! @decl int `()(string begin, string end) *! *! Is term a stop-word? *! @returns *! 1 if true, 0 otherwise. *! */ PIKEFUN int `()(string begin, string end) { ValueRangeProcessor * vrp; bool i; vrp = THIS->object_data->processor; string str1((const char *)begin->str, (size_t)begin->len); string str2((const char *)end->str, (size_t)end->len); i = (*vrp)(str1, str2); push_int(i?1:0); } INIT { XAPIAN_VALUERANGEPROCESSOR_OBJECT_DATA * dta = (XAPIAN_VALUERANGEPROCESSOR_OBJECT_DATA*)malloc(sizeof(XAPIAN_VALUERANGEPROCESSOR_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->processor = NULL; THIS->object_data = dta; } /*! @decl void destroy() *! *! *! */ PIKEFUN void destroy() { ValueRangeProcessor *vrp; vrp = THIS->object_data->processor; if(vrp) { delete vrp; } } EXIT { if(THIS->object_data) { ValueRangeProcessor *vrp; vrp = THIS->object_data->processor; // printf("shutting down!\n"); free(THIS->object_data); } } } /*! @endclass */ /*! @class StringValueRangeProcessor *! @inherit ValueRangeProcessor *! *! Handle a string range. *! *! The end points can be any strings. */ PIKECLASS StringValueRangeProcessor { INHERIT ValueRangeProcessor; PIKEFUN void create(int valueno) { StringValueRangeProcessor * vrp = new StringValueRangeProcessor(valueno); THIS_VALUERANGEPROCESSOR->object_data->processor = (ValueRangeProcessor*) vrp ; pop_n_elems(args); } } /*! @endclass */ /*! @class NumberValueRangeProcessor *! @inherit ValueRangeProcessor *! *! Handle a number range. *! *! This class must be used on values which have been encoded using *! @[Public.Xapian.sortable_serialise]() which turns numbers into strings *! which will sort in the same order as the numbers (the same values can *! be used to implement a numeric sort). *! */ PIKECLASS NumberValueRangeProcessor { INHERIT ValueRangeProcessor; PIKEFUN void create(int valueno) { NumberValueRangeProcessor * vrp = new NumberValueRangeProcessor(valueno); THIS_VALUERANGEPROCESSOR->object_data->processor = (ValueRangeProcessor*) vrp ; pop_n_elems(args); } /*! @decl void create(int valueno, string _str, int[0..1] is_prefix) *! The string supplied in str_ is used by operator() to decide whether *! the pair of strings supplied to it constitute a valid range. If *! prefix_ is true, the first value in a range must begin with str_ (and *! the second value may optionally begin with str_); if prefix_ is *! false, the second value in a range must end with str_ (and the first *! value may optionally end with str_). *! *! If str_ is empty, the setting of prefix_ is irrelevant, and no special *! strings are required at the start or end of the strings defining the *! range. *! *! The remainder of both strings defining the endpoints must be valid *! floating point numbers. (FIXME: define format recognised). *! *! For example, if str_ is "$" and prefix_ is true, and the range *! processor has been added to the queryparser, the queryparser will *! accept "$10..50" or "$10..50", but not "10..50" or "10..$50" as valid *! ranges. If str_ is *! "kg" and prefix_ is false, the queryparser will accept "10..50kg" or *! "10kg..50kg", but not "10..50" or "10kg..50" as valid ranges. */ PIKEFUN void create(int valueno, string _str, int is_prefix) { NumberValueRangeProcessor * vrp; string str((const char *)_str->str, (size_t)_str->len); vrp = new NumberValueRangeProcessor(valueno, str, is_prefix); THIS_VALUERANGEPROCESSOR->object_data->processor = (ValueRangeProcessor*) vrp ; pop_n_elems(args); } } /*! @endclass */ /*! @class NumberValueRangeProcessor *! @inherit ValueRangeProcessor *! *! Handle a number range. *! *! This class must be used on values which have been encoded using *! @[Public.Xapian.sortable_serialise]() which turns numbers into strings *! which will sort in the same order as the numbers (the same values can *! be used to implement a numeric sort). *! */ PIKECLASS DateValueRangeProcessor { INHERIT ValueRangeProcessor; /*! @decl void create(int valueno, int[0..1] prefer_mdy, int epoch_year) *! @param valueno *! The value number to return from `()(). *! @param prefer_mdy *! Should ambiguous dates be interpreted as month/day/year rather than *! day/month/year? *! @param epoch_year *! Year to use as the epoch for dates with 2 digit years (default: *! 1970, so 1/1/69 is 2069 while 1/1/70 is 1970). */ PIKEFUN void create(int valueno, int prefer_mdy, int epoch_year) { DateValueRangeProcessor * vrp = new DateValueRangeProcessor(valueno, prefer_mdy, epoch_year); THIS_VALUERANGEPROCESSOR->object_data->processor = (ValueRangeProcessor*) vrp ; pop_n_elems(args); } } /*! @endclass */ /*! @class Stopper *! Base class for stop-word decision functor. */ PIKECLASS Stopper { CVAR XAPIAN_STOPPER_OBJECT_DATA *object_data; /*! @decl int `()(string word) *! *! Is term a stop-word? *! @returns *! 1 if true, 0 otherwise. *! */ PIKEFUN int `()(string word) { Stopper *stopper; bool i; stopper = THIS->object_data->stopper; string str((const char *)word->str, (size_t)word->len); i = (*stopper)(str); push_int(i?1:0); } /* Stopper.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { Stopper *stopper; stopper = THIS->object_data->stopper; string str = stopper->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { Stopper *stopper; if(THIS && THIS->object_data && conversion_type == 'O') { stopper = THIS->object_data->stopper; string str = stopper->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } INIT { XAPIAN_STOPPER_OBJECT_DATA * dta = (XAPIAN_STOPPER_OBJECT_DATA*)malloc(sizeof(XAPIAN_STOPPER_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->stopper = NULL; THIS->object_data = dta; } /* Stopper.void destroy() */ /*! @decl void destroy() *! *! *! */ PIKEFUN void destroy() { Stopper *stopper; stopper = THIS->object_data->stopper; if(stopper) { delete stopper; } } EXIT { if(THIS->object_data) { Stopper *stopper; stopper = THIS->object_data->stopper; // printf("shutting down!\n"); free(THIS->object_data); } } } /*! @endclass */ /*! @class SimpleStopper *! @inherit Stopper *! Simple implementation of Stopper class - this will suit most users. */ PIKECLASS SimpleStopper { INHERIT Stopper; PIKEFUN void create() { SimpleStopper * stopper = new SimpleStopper(); THIS->object_data->stopper = (Stopper*) stopper; pop_n_elems(args); } PIKEFUN void create(array words) { int i; vector<string> v; for(i = 0; i < words->size; i++) { string str((const char *)(ITEM(words)[i].u.string->str), (size_t)(ITEM(words)[i].u.string->len)); v.push_back(str); } SimpleStopper * stopper = new SimpleStopper(v.begin(), v.end()); THIS_STOPPER->object_data->stopper = (Stopper*) stopper; pop_n_elems(args); } /*! @decl void add(string word) *! Add a single stop word. */ PIKEFUN void add(string word) { SimpleStopper * stopper; string str((const char*)word->str, (size_t)word->len); stopper = (SimpleStopper *)THIS_STOPPER->object_data->stopper; stopper->add(str); pop_stack(); } } /*! @endclass */ /*! @class Stem *! Class representing a stemming algorithm. */ PIKECLASS Stem { CVAR XAPIAN_STEM_OBJECT_DATA *object_data; /* Stem.void create(string language) */ /*! @decl void create(string language) *! *! Construct a @[Stem] object for a particular language. *! @param language *! Either the English name for the language or the two letter ISO639 code. *! *! The following language names are understood (aliases follow the name): *! *! * none - don't stem terms *! * danish (da) *! * dutch (nl) *! * english (en) - Martin Porter's 2002 revision of his stemmer *! * english_lovins (lovins) - Lovin's stemmer *! * english_porter (porter) - Porter's stemmer as described in his 1980 paper *! * finnish (fi) *! * french (fr) *! * german (de) *! * italian (it) *! * norwegian (no) *! * portuguese (pt) *! * russian (ru) *! * spanish (es) *! * swedish (sv) *! * ! @note *! an error will be thrown if the specified language is unknown. */ PIKEFUN void create(string language) { Stem* stem; const string str((const char *)language->str, (size_t)language->len); try { stem = new Stem(str); } catch(InvalidArgumentError &e) { pop_n_elems(args); Pike_error("InvalidArgumentError\n"); } pop_n_elems(args); THIS->object_data->stem = stem; } /* Stem.void create() */ /*! @decl void create() *! *! *! */ PIKEFUN void create() { Stem* stem = new Stem(); pop_n_elems(args); THIS->object_data->stem = stem; } /* Stem.string stem_word(string word) */ /*! @decl string `()(string word) *! stem a word *! *! @param word *! word to be stemmed * ! *! @returns *! the word stem *! */ PIKEFUN string `()(string word) { Stem *stem; string foo; const string str((const char *)word->str, (size_t)word->len); stem = THIS->object_data->stem; foo = (*stem)(str); pop_n_elems(args); push_text(foo.c_str()); } /* Stem.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { Stem *stem; stem = THIS->object_data->stem; string str = stem->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { Stem *stem; if(THIS && THIS->object_data && conversion_type == 'O') { stem = THIS->object_data->stem; string str = stem->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } INIT { XAPIAN_STEM_OBJECT_DATA * dta = (XAPIAN_STEM_OBJECT_DATA*)malloc(sizeof(XAPIAN_STEM_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->stem = NULL; THIS->object_data = dta; } /* Stem.void destroy() */ /*! @decl void destroy() *! *! *! */ PIKEFUN void destroy() { Stem *stem; stem = THIS->object_data->stem; if(stem) { delete stem; } } EXIT { if(THIS->object_data) { Stem *stem; stem = THIS->object_data->stem; // printf("shutting down!\n"); free(THIS->object_data); } } } /*! @endclass */ /*! @class Query *! Class representing a query. *! *! Queries are represented as a tree of objects. */ PIKECLASS Query { CVAR XAPIAN_QUERY_OBJECT_DATA *object_data; /* Query.void create() */ /*! @decl void create() *! *! Default constructor: makes an empty query which matches no documents. *! *! Also useful for defining a Query object to be assigned to later. *! *! @note *! An exception will be thrown if an attempt is made to use an undefined *! query when building up a composite query. *! */ PIKEFUN void create() { try { Query* query = new Query(); pop_n_elems(args); THIS->object_data->query = query; } catch(...) { Pike_error("an error occurred!\n"); } } /* Query.void create(string term, int wqf, int pos) */ /*! @decl void create(string term, int wqf, int pos) *! *! A query consisting of a single term. *! @param term *! * ! *! @param wqf *! * ! *! @param pos *! * ! *! */ PIKEFUN void create(string term, int wqf, int pos) { try { string str((const char *)term->str, (size_t)term->len); Query* query = new Query(str, (termcount)wqf, (termpos)pos); pop_n_elems(args); THIS->object_data->query = query; } catch(...) { Pike_error("an error occurred!\n"); } } /* Query.void create(int op, string left, string right) */ /*! @decl void create(int op, string left, string right) *! *! A query consisting of two terms, opp-ed together. *! @param op *! * ! *! @param left *! * ! *! @param right *! * ! *! */ PIKEFUN void create(int op, string left, string right) { try { string lstr((const char *)left->str, (size_t)left->len); string rstr((const char *)right->str, (size_t)right->len); Query* query = new Query((Xapian::Query::op)op, lstr, rstr); pop_n_elems(args); THIS->object_data->query = query; } catch(...) { Pike_error("an error occurred!\n"); } } /* Query.void create(int op, object left, object right) */ /*! @decl void create(int op, object left, object right) *! *! A query consisting of two subqueries, opp-ed together. *! @param op *! * ! *! @param left *! * ! *! @param right *! * ! *! */ PIKEFUN void create(int op, object left, object right) { Query * l; Query * r; l = OBJ2_QUERY(left)->object_data->query; r = OBJ2_QUERY(right)->object_data->query; try { Query* query = new Query((Xapian::Query::op)op, l, r); pop_n_elems(args); THIS->object_data->query = query; } catch(...) { Pike_error("an error occurred!\n"); } } /* Query.void create(int op, Query query) */ /*! @decl void create(int op, Query query) *! Apply the specified operator to a single @[Query] object, with a *! double parameter. *! *! @param op *! * ! *! @param query *! * ! *! */ PIKEFUN void create(int op, object query, float param) { Query * q; q = OBJ2_QUERY(query)->object_data->query; try { Query* qe = new Query((Xapian::Query::op)op, *q); pop_n_elems(args); THIS->object_data->query = qe; } catch(...) { Pike_error("an error occurred!\n"); } } /* Query.int get_length() */ /*! @decl int get_length() *! *! Get the length of the query, used by some ranking formulae. *! *! This value is calculated automatically - if you want to override it *! you can pass a different value to @[Enquire.set_query](). *! @returns *! *! */ PIKEFUN int get_length() { Query *query; query = THIS->object_data->query; termcount i = query->get_length(); push_int(i); } /* Query.int empty() */ /*! @decl int empty() *! Test if the query is empty (i.e. was constructed using the default *! constructor). *! *! @returns *! *! */ PIKEFUN int empty() { Query *query; query = THIS->object_data->query; bool i = query->empty(); push_int(i?1:0); } /* Query.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { Query *query; query = THIS->object_data->query; string str = query->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { Query *query; if(THIS && THIS->object_data && conversion_type == 'O') { query = THIS->object_data->query; string str = query->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } INIT { XAPIAN_QUERY_OBJECT_DATA * dta = (XAPIAN_QUERY_OBJECT_DATA*)malloc(sizeof(XAPIAN_QUERY_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->query = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { Query *query; query = THIS->object_data->query; if(query) delete query; free(THIS->object_data); } } EXTRA { /*! @decl constant OP_AND *! Return iff both subqueries are satisfied. */ add_integer_constant("OP_AND", Query::OP_AND, 0); /*! @decl constant OP_OR *! Return if either subquery is satisfied. */ add_integer_constant("OP_OR", Query::OP_OR, 0); /*! @decl constant OP_AND_NOT *! Return if left but not right satisfied. */ add_integer_constant("OP_AND_NOT", Query::OP_AND_NOT, 0); /*! @decl constant OP_XOR *! Return if one query satisfied, but not both. */ add_integer_constant("OP_XOR", Query::OP_XOR, 0); /*! @decl constant OP_AND_MAYBE *! Return iff left satisfied, but use weights from both. */ add_integer_constant("OP_AND_MAYBE", Query::OP_AND_MAYBE, 0); /*! @decl constant OP_FILTER *! As AND, but use only weights from left subquery. */ add_integer_constant("OP_FILTER", Query::OP_FILTER, 0); /*! @decl constant OP_NEAR *! Find occurrences of a list of terms with all the terms occurring *! within a specified window of positions. *! *! Each occurrence of a term must be at a different position, but the *! order they appear in is irrelevant. *! *! The window parameter should be specified for this operation, but will *! default to the number of terms in the list. */ add_integer_constant("OP_NEAR", Query::OP_NEAR, 0); /*! @decl constant OP_PHRASE *! Find occurrences of a list of terms with all the terms occurring *! within a specified window of positions, and all the terms appearing *! in the order specified. *! *! Each occurrence of a term must be at a different position. *! *! The window parameter should be specified for this operation, but will *! default to the number of terms in the list. */ add_integer_constant("OP_PHRASE", Query::OP_PHRASE, 0); /*! @decl constant OP_ELITE_SET *! Select an elite set from the subqueries, and perform a query with *! these combined as an OR query. */ add_integer_constant("OP_ELITE_SET", Query::OP_ELITE_SET, 0); /*! @decl constant OP_VALUE_RANGE *! Filter by a range test on a document value. */ add_integer_constant("OP_VALUE_RANGE", Query::OP_VALUE_RANGE, 0); /*! @decl constant OP_SCALE_WEIGHT *! Scale the weight of a subquery by the specified factor. *! *! A factor of 0 means this subquery will contribute no weight to the *! query - it will act as a purely boolean subquery. *! *! If the factor is negative, an error will be *! thrown. */ add_integer_constant("OP_SCALE_WEIGHT", Query::OP_SCALE_WEIGHT, 0); } } /*! @endclass */ /*! @class PositionIterator */ PIKECLASS PositionIterator { CVAR PositionIterator * pie; CVAR int current_index; CVAR XAPIAN_POSITIONITERATOR_OBJECT_DATA *object_data; PIKEFUN object next() { PositionIterator *pi; pi = THIS->object_data->positioni; struct object * o; (*pi)++; THIS->current_index++; if(*pi == *(THIS->pie)) {push_int(0); return;} push_int(1); } PIKEFUN mixed index() { push_int(THIS->current_index); } PIKEFUN object value() { push_object(this_object()); } PIKEFUN int `==(mixed arg) { struct object * o; PositionIterator *posi; PositionIterator *posb; struct PositionIterator_struct * pis; if(arg->type!= T_OBJECT) RETURN(0); o = arg->u.object; posi = (PositionIterator*)THIS->object_data->positioni; pis = OBJ2_POSITIONITERATOR(o); if(!pis) RETURN(0); posb = pis->object_data->positioni; if(*posi == *posb) RETURN(1); else RETURN(0); } /*! @decl void skip_to(int pos) *! *! *! @returns *! *! */ PIKEFUN void skip_to(int pos) { PositionIterator *posi; try { posi = (PositionIterator*)THIS->object_data->positioni; posi->skip_to(pos); pop_stack(); push_int(0); } catch(RangeError &e) { pop_n_elems(args); Pike_error("RangeError\n"); } } /*! @decl int get_position() *! *! *! @returns *! *! */ PIKEFUN int get_position() { PositionIterator *posi; int i; try { posi = (PositionIterator*)THIS->object_data->positioni; i = (*(*posi)); push_int(i); } catch(RangeError &e) { pop_n_elems(args); Pike_error("RangeError\n"); } } PIKEFUN mixed `+=(int i) { PositionIterator *pi; pi = THIS->object_data->positioni; for(int x = 0; x < i; x++) { (*pi)++; if(*pi == *(THIS->pie)) { pop_stack(); push_int(0); return;} } THIS->current_index++; pop_stack(); push_object(this_object()); } PIKEFUN int `!() { PositionIterator *pi; pi = THIS->object_data->positioni; if(*pi == *(THIS->pie)) { push_int(1); } else push_int(0); } /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { PositionIterator *pi; pi = THIS->object_data->positioni; string str = pi->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { PositionIterator *it; if(THIS && THIS->object_data && conversion_type == 'O') { it = THIS->object_data->positioni; string str = it->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } INIT { XAPIAN_POSITIONITERATOR_OBJECT_DATA * dta = (XAPIAN_POSITIONITERATOR_OBJECT_DATA*)malloc(sizeof(XAPIAN_POSITIONITERATOR_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->positioni = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { PositionIterator *positioni; positioni = THIS->object_data->positioni; if(positioni) delete positioni; free(THIS->object_data); } } } /*! @endclass */ /*! @class ValueIterator */ PIKECLASS ValueIterator { CVAR ValueIterator * vie; CVAR int current_index; CVAR XAPIAN_VALUEITERATOR_OBJECT_DATA *object_data; PIKEFUN object next() { ValueIterator *valuei; valuei = THIS->object_data->valuei; ValueIterator *valuei2; struct object * o; valuei2 = new ValueIterator((*valuei)++); o = fast_clone_object(ValueIterator_program); OBJ2_VALUEITERATOR(o)->object_data->valuei = valuei; push_object(o); } PIKEFUN mixed index() { push_int(THIS->current_index); } PIKEFUN object value() { push_object(this_object()); } PIKEFUN int `==(mixed arg) { struct object * o; ValueIterator *valuei; ValueIterator *valueb; struct ValueIterator_struct * vis; if(arg->type!= T_OBJECT) RETURN(0); o = arg->u.object; valuei = (ValueIterator*)THIS->object_data->valuei; vis = OBJ2_VALUEITERATOR(o); if(!vis) RETURN(0); valueb = vis->object_data->valuei; if(*valuei == *valueb) RETURN(1); else RETURN(0); } /*! @decl int get_valueno() *! *! *! @returns *! *! */ PIKEFUN int get_valueno() { ValueIterator *valuei; valueno i; try { valuei = (ValueIterator*)THIS->object_data->valuei; i = valuei->get_valueno(); push_int((INT_TYPE)i); } catch(RangeError &e) { pop_n_elems(args); Pike_error("RangeError\n"); } } /*! @decl int get_value() *! *! *! @returns *! *! */ PIKEFUN string get_value() { ValueIterator *valuei; string i; try { valuei = (ValueIterator*)THIS->object_data->valuei; i = (*(*valuei)); push_text(i.c_str()); } catch(RangeError &e) { pop_n_elems(args); Pike_error("RangeError\n"); } } PIKEFUN mixed `+=(int i) { ValueIterator *vi; vi = THIS->object_data->valuei; for(int x = 0; x < i; x++) { (*vi)++; if(*vi == *(THIS->vie)) { pop_stack(); push_int(0); return;} } THIS->current_index++; pop_stack(); push_object(this_object()); } PIKEFUN int `!() { ValueIterator *vi; vi = THIS->object_data->valuei; if(*vi == *(THIS->vie)) { push_int(1); } else push_int(0); } /* ValueIterator.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { ValueIterator *valuei; valuei = THIS->object_data->valuei; string str = valuei->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { ValueIterator *it; if(THIS && THIS->object_data && conversion_type == 'O') { it = THIS->object_data->valuei; string str = it->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } INIT { XAPIAN_VALUEITERATOR_OBJECT_DATA * dta = (XAPIAN_VALUEITERATOR_OBJECT_DATA*)malloc(sizeof(XAPIAN_VALUEITERATOR_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->valuei = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { ValueIterator *valuei; valuei = THIS->object_data->valuei; if(valuei) delete valuei; free(THIS->object_data); } } } /*! @endclass */ /*! @class TermIterator */ PIKECLASS TermIterator { CVAR TermIterator * tie; CVAR int current_index; CVAR XAPIAN_TERMITERATOR_OBJECT_DATA *object_data; PIKEFUN object next() { TermIterator * termi; termi = THIS->object_data->termi; TermIterator *termi2; struct object * o; termi2 = new TermIterator(++(*termi)); o = fast_clone_object(TermIterator_program); OBJ2_TERMITERATOR(o)->object_data->termi = termi; push_object(o); } PIKEFUN mixed index() { push_int(THIS->current_index); } PIKEFUN object value() { push_object(this_object()); } PIKEFUN int `==(mixed arg) { struct object * o; TermIterator *termi; TermIterator *termb; struct TermIterator_struct * tis; if(arg->type!= T_OBJECT) RETURN(0); o = arg->u.object; termi = (TermIterator*)THIS->object_data->termi; tis = OBJ2_TERMITERATOR(o); if(!tis) RETURN(0); termb = tis->object_data->termi; if(*termi == *termb) RETURN(1); else RETURN(0); } /*! @decl object position_iterator() *! *! @returns *! an object which can be passed to @[foreach]() *! *! */ PIKEFUN object position_iterator() { TermIterator *ti; ti = THIS->object_data->termi; PositionIterator pi; PositionIterator * pi2; struct object * o; pi = ti->positionlist_begin(); pi2 = new PositionIterator(pi); o = fast_clone_object(PositionIterator_program); OBJ2_POSITIONITERATOR(o)->object_data->positioni = pi2; OBJ2_POSITIONITERATOR(o)->pie = new PositionIterator(ti->positionlist_end()); push_object(o); } /*! @decl int get_wdf() *! *! *! @returns *! *! */ PIKEFUN int get_wdf() { TermIterator *termi; termcount i; termi = (TermIterator*)THIS->object_data->termi; i = termi->get_wdf(); push_int((INT_TYPE)i); } /*! @decl int get_termfreq() *! *! *! @returns *! *! */ PIKEFUN int get_termfreq() { TermIterator *termi; doccount i; termi = (TermIterator*)THIS->object_data->termi; i = termi->get_termfreq(); push_int((INT_TYPE)i); } /*! @decl int positionlist_count() *! *! *! @returns *! *! */ PIKEFUN int positionlist_count() { TermIterator *termi; termcount i; termi = (TermIterator*)THIS->object_data->termi; i = termi->positionlist_count(); push_int((INT_TYPE)i); } /*! @decl string get_term() *! *! *! @returns *! *! */ PIKEFUN string get_term() { TermIterator *termi; string i; termi = (TermIterator*)THIS->object_data->termi; i = (*(*termi)); push_text(i.c_str()); } PIKEFUN mixed `+=(int i) { TermIterator *ti; ti = THIS->object_data->termi; for(int x = 0; x < i; x++) { (*ti)++; if(*ti == *(THIS->tie)) { pop_stack(); push_int(0); return;} } THIS->current_index++; pop_stack(); push_object(this_object()); } PIKEFUN int `!() { TermIterator *ti; ti = THIS->object_data->termi; if(*ti == *(THIS->tie)) { push_int(1); } else push_int(0); } /* TermIterator.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { TermIterator *termi; termi = THIS->object_data->termi; string str = termi->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { TermIterator *it; if(THIS && THIS->object_data && conversion_type == 'O') { it = THIS->object_data->termi; string str = it->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } INIT { XAPIAN_TERMITERATOR_OBJECT_DATA * dta = (XAPIAN_TERMITERATOR_OBJECT_DATA*)malloc(sizeof(XAPIAN_TERMITERATOR_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->termi = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { TermIterator *termi; termi = THIS->object_data->termi; if(termi) delete termi; free(THIS->object_data); } } } /*! @endclass */ /*! @class Document *! A document in the database - holds data, values, terms, and postings. */ PIKECLASS Document { CVAR XAPIAN_DOCUMENT_OBJECT_DATA *object_data; /* Document.void create() */ /*! @decl void create() *! *! *! */ PIKEFUN void create() { try { Document* document = new Document(); pop_n_elems(args); THIS->object_data->document = document; } catch(...) { Pike_error("an error occurred!\n"); } } /* Document.void set_data(string data) */ /*! @decl void set_data(string data) *! *! Set data stored in the document. *! *! @param data *! * ! *! */ PIKEFUN void set_data(string data) { Document *doc; doc = THIS->object_data->document; string str((const char *)data->str, (size_t)data->len); doc->set_data(str); pop_n_elems(args); } /*! @decl ValueIterator value_iterator() *! Get an iterator for the values in this document. *! @returns *! a @[ValueIterator] object which can be passed to @[foreach]() *! *! */ PIKEFUN object value_iterator() { Document *doc; doc = THIS->object_data->document; ValueIterator vi; ValueIterator * vi2; struct object * o; vi = doc->values_begin(); vi2 = new ValueIterator(vi); o = fast_clone_object(ValueIterator_program); OBJ2_VALUEITERATOR(o)->object_data->valuei = vi2; OBJ2_VALUEITERATOR(o)->vie = new ValueIterator(doc->values_end()); push_object(o); } /*! @decl TermIterator term_iterator() *! Get an iterator for the terms in this document. *! @returns *! a @[TermIterator] object which can be passed to @[foreach]() */ PIKEFUN object term_iterator() { Document *doc; doc = THIS->object_data->document; TermIterator ti; TermIterator * ti2; struct object * o; ti = doc->termlist_begin(); ti2 = new TermIterator(ti); o = fast_clone_object(TermIterator_program); OBJ2_TERMITERATOR(o)->object_data->termi = ti2; OBJ2_TERMITERATOR(o)->tie = new TermIterator(doc->termlist_end()); push_object(o); } /* Document.void clear_terms() */ /*! @decl void clear_terms() *! *! Remove all terms (and postings) from the document. *! */ PIKEFUN void clear_terms() { Document *doc; doc = THIS->object_data->document; doc->clear_terms(); } /* Document.void clear_values() */ /*! @decl void clear_values() *! *! Remove all values associated with the document. *! */ PIKEFUN void clear_values() { Document *doc; doc = THIS->object_data->document; doc->clear_values(); } /* Document.string get_data() */ /*! @decl string get_data() *! Get data stored in the document. *! This is a potentially expensive operation, and shouldn't normally be *! used in a match decider function. Put data for use by match deciders *! in a value instead. *! *! @returns *! *! */ PIKEFUN string get_data() { Document *doc; doc = THIS->object_data->document; string str = doc->get_data(); push_text(str.c_str()); } /* Document.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { Document *doc; doc = THIS->object_data->document; string str = doc->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { Document *doc; if(THIS && THIS->object_data && conversion_type == 'O') { doc = THIS->object_data->document; string str = doc->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } /* Document.string get_value(int val) */ /*! @decl string get_value(int val) *! Get value by number. *! *! @param val *! The number of the value. * ! *! @returns *! Returns an empty string if no value with the given number is present *! in the document. *! *! */ PIKEFUN string get_value(int val) { Document *doc; doc = THIS->object_data->document; string str = doc->get_value(val); pop_n_elems(args); if(str.length()) push_text(str.c_str()); else push_int(0); } /* Document.void remove_value(int val) */ /*! @decl void remove_value(int val) *! *! Remove any value with the given number. *! @param val *! * ! *! */ PIKEFUN void remove_value(int val) { Document *doc; doc = THIS->object_data->document; doc->remove_value(val); pop_n_elems(args); } /* Document.void add_term(string tname, int termcount) */ /*! @decl void add_term(string tname, int termcount) *! *! Add a term to the document, without positional information. *! *! Any existing positional information for the term will be left unmodified. *! @param tname *! The name of the term. * ! *! @param termcount *! The increment that will be applied to the wdf for this term. * ! *! */ PIKEFUN void add_term(string tname, int termcount) { Document *doc; doc = THIS->object_data->document; string str(tname->str, tname->len); doc->add_term(str, (unsigned int)termcount); pop_n_elems(args); } /* Document.void add_posting(string tname, int termpos, int termcount) */ /*! @decl void add_posting(string tname, int termpos, int termcount) *!Add an occurrence of a term at a particular position. *! *! Multiple occurrences of the term at the same position are represented *! only once in the positional information, but do increase the wdf. *! *! If the term is not already in the document, it will be added to it. *! *! @param tname *! The name of the term. * ! *! @param termpos *! The position of the term. * ! *! @param termcount *! The increment that will be applied to the wdf for this term. * ! *! */ PIKEFUN void add_posting(string tname, int termpos, int termcount) { Document *doc; doc = THIS->object_data->document; string str(tname->str, tname->len); try { doc->add_posting(str, (unsigned int)termpos, (unsigned int)termcount); } catch(InvalidArgumentError &e) { pop_n_elems(args); Pike_error(e.get_msg().c_str()); } pop_n_elems(args); } /* Document.void remove_term(string tname) */ /*! @decl void remove_term(string tname) *! Remove a term and all postings associated with it. *! *! @param tname *! The name of the term. * ! @note *! An error will be thrown if the term is not present in the document. */ PIKEFUN void remove_term(string tname) { Document *doc; doc = THIS->object_data->document; string str(tname->str, tname->len); try { doc->remove_term(str); } catch(InvalidArgumentError &e) { pop_n_elems(args); Pike_error("InvalidArgumentError\n"); } pop_n_elems(args); } /*! @decl void remove_posting(string tname, int tpos, int wdfdec) *!Remove a posting of a term from the document. *! *! Note that the term will still index the document even if all *! occurrences are removed. To remove a term from a document completely, *! use @[remove_term](). *! *! @param tname *! The name of the term. *! @param tpos *! The position of the term. *! @param wdfdec *! The decrement that will be applied to the wdf when removing this *! posting. The wdf will not go below the value of 0. *! *! @note *! An error will be thrown if the term is not at the position specified *! in the position list for this term in this document or if the term *! is not in the document. */ PIKEFUN void remove_posting(string tname, int tpos, int wdfdec) { Document *doc; doc = THIS->object_data->document; string str(tname->str, tname->len); try { doc->remove_posting(str, tpos, wdfdec); } catch(InvalidArgumentError &e) { pop_n_elems(args); Pike_error("InvalidArgumentError\n"); } pop_n_elems(args); } /* Document.void add_value(int valueno, string value) */ /*! @decl void add_value(int valueno, string value) *!Add a new value. *! *! It will replace any existing value with the same number. *! *! @param valueno *! * ! *! @param value *! * ! *! */ PIKEFUN void add_value(int valueno, string value) { Document *doc; doc = THIS->object_data->document; string str(value->str, value->len); doc->add_value(valueno, str); pop_n_elems(args); } /* Document.int termlist_count() */ /*! @decl int termlist_count() *! *! Count the terms in this document. *! @returns *! the number of terms in the document. *! */ PIKEFUN int termlist_count() { Document *doc; doc = THIS->object_data->document; unsigned int i; i = doc->termlist_count(); push_int((INT_TYPE)i); return; } /* Document.int values_count() */ /*! @decl int values_count() *! *! Count the values in this document. *! @returns *! the number of values in the document. *! */ PIKEFUN int values_count() { Document *doc; doc = THIS->object_data->document; unsigned int i; i = doc->values_count(); push_int((INT_TYPE)i); return; } INIT { XAPIAN_DOCUMENT_OBJECT_DATA * dta = (XAPIAN_DOCUMENT_OBJECT_DATA*)malloc(sizeof(XAPIAN_DOCUMENT_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->document = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { Document *doc; doc = THIS->object_data->document; if(doc) delete doc; // hrm... odd. free(THIS->object_data); } } } /*! @endclass */ /* here are some important helper classes that we'll include rather than compile separately. */ #include "PikeMatchDeciderProxy.cc" #include "PikeExpandDeciderProxy.cc" /*! @class MSetIterator */ PIKECLASS MSetIterator { CVAR int current_index; CVAR MSetIterator * msete; CVAR XAPIAN_MSETITERATOR_OBJECT_DATA *object_data; PIKEFUN object get_document() { MSetIterator *mseti; Document doc; Document *doc2; struct object * o; try { mseti = (MSetIterator*)THIS->object_data->mseti; doc = mseti->get_document(); doc2 = new Document(doc); o = fast_clone_object(Document_program); OBJ2_DOCUMENT(o)->object_data->document = doc2; push_object(o); } catch(RangeError &e) { pop_n_elems(args); Pike_error("RangeError\n"); } } PIKEFUN mixed index() { push_int(THIS->current_index); } PIKEFUN object value() { push_object(this_object()); } PIKEFUN int get_docid() { MSetIterator *mseti; docid i; mseti = (MSetIterator*)THIS->object_data->mseti; i = (*(*mseti)); push_int((INT_TYPE)i); } PIKEFUN int get_percent() { MSetIterator *mseti; docid i; mseti = (MSetIterator*)THIS->object_data->mseti; i = mseti->get_percent(); push_int((INT_TYPE)i); } PIKEFUN float get_weight() { MSetIterator *mseti; weight i; mseti = (MSetIterator*)THIS->object_data->mseti; i = mseti->get_weight(); push_float((FLOAT_TYPE)i); } PIKEFUN int get_collapse_count() { MSetIterator *mseti; docid i; mseti = (MSetIterator*)THIS->object_data->mseti; i = mseti->get_collapse_count(); push_int((INT_TYPE)i); } PIKEFUN object next() { MSetIterator *mseti; mseti = THIS->object_data->mseti; MSetIterator *mseti2; struct object * o; (*mseti)++; THIS->current_index++; if(*mseti == *(THIS->msete)) {push_int(0); return;} push_int(1); } /* PIKEFUN object prev() { MSetIterator *mseti; mseti = THIS->object_data->mseti; MSetIterator *mseti2; struct object * o; mseti2 = new MSetIterator((*mseti)--); o = fast_clone_object(MSetIterator_program); OBJ2_MSETITERATOR(o)->object_data->mseti = mseti2; push_object(o); } */ PIKEFUN mixed `+=(int i) { MSetIterator *mseti; mseti = THIS->object_data->mseti; for(int x = 0; x < i; x++) { (*mseti)++; if(*mseti == *(THIS->msete)) { pop_stack(); push_int(0); return;} } THIS->current_index++; pop_stack(); push_object(this_object()); } PIKEFUN int `!() { MSetIterator *mseti; mseti = THIS->object_data->mseti; if(*mseti == *(THIS->msete)) { push_int(1); } else push_int(0); } PIKEFUN int `==(mixed arg) { struct object * o; struct MSetIterator_struct * msis; MSetIterator *mseti; MSetIterator *msetb; if(arg->type!= T_OBJECT) {RETURN(0);} o = arg->u.object; mseti = (MSetIterator*)THIS->object_data->mseti; msis = OBJ2_MSETITERATOR(o); if(!msis) {RETURN(0);} msetb = msis->object_data->mseti; if(*mseti == *msetb) {RETURN(1);} else {RETURN(0);} } INIT { XAPIAN_MSETITERATOR_OBJECT_DATA * dta = (XAPIAN_MSETITERATOR_OBJECT_DATA*)malloc(sizeof(XAPIAN_MSETITERATOR_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->mseti = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { MSetIterator *mseti; mseti = THIS->object_data->mseti; if(mseti) delete mseti; free(THIS->object_data); } } } /*! @endclass */ /*! @class ESetIterator */ PIKECLASS ESetIterator { CVAR int current_index; CVAR ESetIterator * esete; CVAR XAPIAN_ESETITERATOR_OBJECT_DATA *object_data; PIKEFUN string get_term() { ESetIterator *eseti; string i; eseti = (ESetIterator*)THIS->object_data->eseti; i = (*(*eseti)); push_text(i.c_str()); } PIKEFUN float get_weight() { ESetIterator *eseti; weight i; eseti = (ESetIterator*)THIS->object_data->eseti; i = eseti->get_weight(); push_float((FLOAT_TYPE)i); } PIKEFUN mixed index() { push_int(THIS->current_index); } PIKEFUN object value() { push_object(this_object()); } PIKEFUN object next() { ESetIterator *eseti; eseti = THIS->object_data->eseti; ESetIterator *eseti2; (*eseti)++; THIS->current_index++; if(*eseti == *(THIS->esete)) {push_int(0); return;} push_int(1); } /* PIKEFUN object prev() { ESetIterator *eseti; eseti = THIS->object_data->eseti; ESetIterator *eseti2; struct object * o; eseti2 = new ESetIterator((*eseti)--); o = fast_clone_object(ESetIterator_program); OBJ2_ESETITERATOR(o)->object_data->eseti = eseti2; push_object(o); } */ PIKEFUN mixed `+=(int i) { ESetIterator *eseti; eseti = THIS->object_data->eseti; for(int x = 0; x < i; x++) { (*eseti)++; if(*eseti == *(THIS->esete)) { pop_stack(); push_int(0); return;} } THIS->current_index++; pop_stack(); push_object(this_object()); } PIKEFUN int `!() { ESetIterator *eseti; eseti = THIS->object_data->eseti; if(*eseti == *(THIS->esete)) { push_int(1); } else push_int(0); } PIKEFUN int `==(mixed arg) { struct object * o; ESetIterator *eseti; ESetIterator *esetb; struct ESetIterator_struct * esis; if(arg->type!= T_OBJECT) RETURN(0); o = arg->u.object; eseti = (ESetIterator*)THIS->object_data->eseti; esis = OBJ2_ESETITERATOR(o); if(!esis) RETURN(0); esetb = esis->object_data->eseti; if(eseti == esetb) RETURN(1); else RETURN(0); } INIT { XAPIAN_ESETITERATOR_OBJECT_DATA * dta = (XAPIAN_ESETITERATOR_OBJECT_DATA*)malloc(sizeof(XAPIAN_ESETITERATOR_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->eseti = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { ESetIterator *eseti; eseti = THIS->object_data->eseti; if(eseti) delete eseti; free(THIS->object_data); } } } /*! @endclass */ /*! @class MSet */ PIKECLASS MSet { CVAR XAPIAN_MSET_OBJECT_DATA *object_data; INIT { XAPIAN_MSET_OBJECT_DATA * dta = (XAPIAN_MSET_OBJECT_DATA*)malloc(sizeof(XAPIAN_MSET_OBJECT_DATA)); //printf("allocated mset data.\n"); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->mset = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { MSet *mset; mset = THIS->object_data->mset; if(mset) delete mset; free(THIS->object_data); } } /* MSet.void create() */ /*! @decl void create() *! *! *! */ PIKEFUN void create() { try { MSet * mset = new MSet(); pop_n_elems(args); THIS->object_data->mset = mset; } catch(...) { Pike_error("an error occurred!\n"); } } /* MSet.object begin() */ /*! @decl object begin() *! *! *! @returns *! *! */ PIKEFUN object begin() { MSet *mset; mset = THIS->object_data->mset; MSetIterator mseti; MSetIterator *mseti2; struct object * o; mseti = mset->begin(); mseti2 = new MSetIterator(mseti); o = fast_clone_object(MSetIterator_program); OBJ2_MSETITERATOR(o)->object_data->mseti = mseti2; push_object(o); } PIKEFUN object _get_iterator() { MSet *mset; mset = THIS->object_data->mset; MSetIterator mseti; MSetIterator *mseti2; struct object * o; mseti = mset->begin(); mseti2 = new MSetIterator(mseti); o = fast_clone_object(MSetIterator_program); OBJ2_MSETITERATOR(o)->object_data->mseti = mseti2; OBJ2_MSETITERATOR(o)->msete = new MSetIterator(mset->end()); push_object(o); } /* MSet.object end() */ /*! @decl object end() *! *! *! @returns *! *! */ PIKEFUN object end() { MSet *mset; mset = THIS->object_data->mset; MSetIterator mseti; MSetIterator *mseti2; struct object * o; mseti = mset->end(); mseti2 = new MSetIterator(mseti); o = fast_clone_object(MSetIterator_program); OBJ2_MSETITERATOR(o)->object_data->mseti = mseti2; push_object(o); } /* MSet.object back() */ /*! @decl object back() *! *! *! @returns *! *! */ PIKEFUN object back() { MSet *mset; mset = THIS->object_data->mset; MSetIterator mseti; MSetIterator *mseti2; struct object * o; mseti = mset->back(); mseti2 = new MSetIterator(mseti); o = fast_clone_object(MSetIterator_program); OBJ2_MSETITERATOR(o)->object_data->mseti = mseti2; push_object(o); } /* MSet.void fetch() */ /*! @decl void fetch() *! *! *! */ PIKEFUN void fetch() { MSet *mset; mset = THIS->object_data->mset; mset->fetch(); } /* MSet.int size() */ /*! @decl int size() *! *! *! @returns *! *! */ PIKEFUN int size() { MSet *mset; mset = THIS->object_data->mset; doccount i; i = mset->size(); push_int(i); } /* MSet.int get_matches_estimated() */ /*! @decl int get_matches_estimated() *! *! *! @returns *! *! */ PIKEFUN int get_matches_estimated() { MSet *mset; mset = THIS->object_data->mset; doccount i; i = mset->get_matches_estimated(); push_int(i); } /* MSet.int get_matches_upper_bound() */ /*! @decl int get_matches_upper_bound() *! *! *! @returns *! *! */ PIKEFUN int get_matches_upper_bound() { MSet *mset; mset = THIS->object_data->mset; doccount i; i = mset->get_matches_upper_bound(); push_int(i); } /* MSet.int get_firstitem() */ /*! @decl int get_firstitem() *! *! *! @returns *! *! */ PIKEFUN int get_firstitem() { MSet *mset; mset = THIS->object_data->mset; doccount i; i = mset->get_firstitem(); push_int(i); } /* MSet.int get_matches_lower_bound() */ /*! @decl int get_matches_lower_bound() *! *! *! @returns *! *! */ PIKEFUN int get_matches_lower_bound() { MSet *mset; mset = THIS->object_data->mset; doccount i; i = mset->get_matches_lower_bound(); push_int(i); } /* MSet.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { MSet *mset; mset = THIS->object_data->mset; string str = mset->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { MSet *mset; if(THIS && THIS->object_data && conversion_type == 'O') { mset = THIS->object_data->mset; string str = mset->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } } /*! @endclass */ /*! @class RSet */ PIKECLASS RSet { CVAR XAPIAN_RSET_OBJECT_DATA *object_data; INIT { XAPIAN_RSET_OBJECT_DATA * dta = (XAPIAN_RSET_OBJECT_DATA*)malloc(sizeof(XAPIAN_RSET_OBJECT_DATA)); //printf("allocated eset data.\n"); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->rset = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { RSet *rset; rset = THIS->object_data->rset; if(rset) delete rset; free(THIS->object_data); } } /* RSet.void create() */ /*! @decl void create() *! *! *! */ PIKEFUN void create() { try { RSet * rset = new RSet(); pop_n_elems(args); THIS->object_data->rset = rset; } catch(...) { Pike_error("an error occurred!\n"); } } /* RSet.int size() */ /*! @decl int size() *! *! *! @returns *! *! */ PIKEFUN int size() { RSet *rset; rset = THIS->object_data->rset; doccount i; i = rset->size(); push_int(i); } /* RSet.int empty() */ /*! @decl int empty() *! *! *! @returns *! *! */ PIKEFUN int empty() { RSet *rset; rset = THIS->object_data->rset; bool i; i = rset->empty(); push_int(i?1:0); } /* RSet.void add_document(int docid) */ /*! @decl void add_document(int docid) *! *! *! @param docid *! * ! *! */ PIKEFUN void add_document(int docid) { RSet *rset; rset = THIS->object_data->rset; rset->add_document((Xapian::docid)docid); pop_n_elems(args); } /* RSet.void add_document(object iterator) */ /*! @decl void add_document(object iterator) *! *! *! @param iterator *! * ! *! */ PIKEFUN void add_document(object iterator) { RSet *rset; rset = THIS->object_data->rset; MSetIterator * i; i = OBJ2_MSETITERATOR(iterator)->object_data->mseti; rset->add_document(*i); pop_n_elems(args); } /* RSet.void remove_document(int docid) */ /*! @decl void remove_document(int docid) *! *! *! @param docid *! * ! *! */ PIKEFUN void remove_document(int docid) { RSet *rset; rset = THIS->object_data->rset; rset->remove_document((Xapian::docid)docid); pop_n_elems(args); } /* RSet.void remove_document(object iterator) */ /*! @decl void remove_document(object iterator) *! *! *! @param iterator *! * ! *! */ PIKEFUN void remove_document(object iterator) { RSet *rset; rset = THIS->object_data->rset; MSetIterator * i; i = OBJ2_MSETITERATOR(iterator)->object_data->mseti; rset->remove_document(*i); pop_n_elems(args); } /* RSet.int contains(int docid) */ /*! @decl int contains(int docid) *! *! *! @param docid *! * ! *! @returns *! *! */ PIKEFUN int contains(int docid) { RSet *rset; rset = THIS->object_data->rset; bool r; r = rset->contains((Xapian::docid)docid); pop_n_elems(args); push_int(r?1:0); } /* RSet.int contains(object iterator) */ /*! @decl int contains(object iterator) *! *! *! @param iterator *! * ! *! @returns *! *! */ PIKEFUN int contains(object iterator) { RSet *rset; rset = THIS->object_data->rset; bool r; MSetIterator * i; i = OBJ2_MSETITERATOR(iterator)->object_data->mseti; r = rset->contains(*i); pop_n_elems(args); push_int(r?1:0); } /* RSet.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { RSet *rset; rset = THIS->object_data->rset; string str = rset->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { RSet *rset; if(THIS && THIS->object_data && conversion_type == 'O') { rset = THIS->object_data->rset; string str = rset->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } } /*! @endclass */ /*! @class ESet */ PIKECLASS ESet { CVAR XAPIAN_ESET_OBJECT_DATA *object_data; INIT { XAPIAN_ESET_OBJECT_DATA * dta = (XAPIAN_ESET_OBJECT_DATA*)malloc(sizeof(XAPIAN_ESET_OBJECT_DATA)); //printf("allocated eset data.\n"); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->eset = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { ESet *eset; eset = THIS->object_data->eset; if(eset) delete eset; free(THIS->object_data); } } /* ESet.void create() */ /*! @decl void create() *! *! *! */ PIKEFUN void create() { try { ESet * eset = new ESet(); pop_n_elems(args); THIS->object_data->eset = eset; } catch(...) { Pike_error("an error occurred!\n"); } } /* ESet.object begin() */ /*! @decl object begin() *! *! *! @returns *! *! */ PIKEFUN object begin() { ESet *eset; eset = THIS->object_data->eset; ESetIterator eseti; ESetIterator *eseti2; struct object * o; eseti = eset->begin(); eseti2 = new ESetIterator(eseti); o = fast_clone_object(ESetIterator_program); OBJ2_ESETITERATOR(o)->object_data->eseti = eseti2; push_object(o); } /* ESet.object end() */ /*! @decl object end() *! *! *! @returns *! *! */ PIKEFUN object end() { ESet *eset; eset = THIS->object_data->eset; ESetIterator eseti; ESetIterator *eseti2; struct object * o; eseti = eset->end(); eseti2 = new ESetIterator(eseti); o = fast_clone_object(ESetIterator_program); OBJ2_ESETITERATOR(o)->object_data->eseti = eseti2; push_object(o); } /* ESet.object back() */ /*! @decl object back() *! *! *! @returns *! *! */ PIKEFUN object back() { ESet *eset; eset = THIS->object_data->eset; ESetIterator eseti; ESetIterator *eseti2; struct object * o; eseti = eset->back(); eseti2 = new ESetIterator(eseti); o = fast_clone_object(ESetIterator_program); OBJ2_ESETITERATOR(o)->object_data->eseti = eseti2; push_object(o); } /* ESet.object `[](int i) */ /*! @decl object `[](int i) *! *! *! @param i *! * ! *! @returns *! *! */ PIKEFUN object `[](int i) { ESet *eset; eset = THIS->object_data->eset; ESetIterator eseti; ESetIterator *eseti2; struct object * o; eseti = (*eset)[(termcount)i]; eseti2 = new ESetIterator(eseti); o = fast_clone_object(ESetIterator_program); OBJ2_ESETITERATOR(o)->object_data->eseti = eseti2; push_object(o); } /* ESet.int size() */ /*! @decl int size() *! *! *! @returns *! *! */ PIKEFUN int size() { ESet *eset; eset = THIS->object_data->eset; termcount i; i = eset->size(); push_int(i); } /* ESet.int empty() */ /*! @decl int empty() *! *! *! @returns *! *! */ PIKEFUN int empty() { ESet *eset; eset = THIS->object_data->eset; bool i; i = eset->empty(); push_int(i?1:0); } /* ESet.int max_size() */ /*! @decl int max_size() *! *! *! @returns *! *! */ PIKEFUN int max_size() { ESet *eset; eset = THIS->object_data->eset; termcount i; i = eset->max_size(); push_int(i); } /* ESet.int get_ebound() */ /*! @decl int get_ebound() *! *! *! @returns *! *! */ PIKEFUN int get_ebound() { ESet *eset; eset = THIS->object_data->eset; termcount i; i = eset->get_ebound(); push_int(i); } /* ESet.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { ESet *eset; eset = THIS->object_data->eset; string str = eset->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { ESet *eset; if(THIS && THIS->object_data && conversion_type == 'O') { eset = THIS->object_data->eset; string str = eset->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } } /*! @endclass */ /*! @class Database */ PIKECLASS Database { CVAR XAPIAN_DATABASE_OBJECT_DATA *object_data; /* Database.void create(string path) */ /*! @decl void create(string path) *! *! *! @param path *! * ! *! */ PIKEFUN void create(string path) { string str((const char *)path->str, (size_t)path->len); Database * db = new Database(str); THIS->object_data->database = db; pop_n_elems(args); } /* Database.void create() */ /*! @decl void create() *! *! *! */ PIKEFUN void create() { Database * db = new Database(); THIS->object_data->database = db; } /* Database.void reopen() */ /*! @decl void reopen() *! *! *! */ PIKEFUN void reopen() { Database * db = THIS->object_data->database; db->reopen(); } /* Database.void keep_alive() */ /*! @decl void keep_alive() *! *! *! */ PIKEFUN void keep_alive() { Database * db = THIS->object_data->database; db->keep_alive(); } /* Database.int get_doclength(int did) */ /*! @decl int get_doclength(int did) *! *! *! @param did *! * ! *! @returns *! *! */ PIKEFUN int get_doclength(int did) { Database *db; db = THIS->object_data->database; doclength i = db->get_doclength((docid)did); pop_n_elems(args); push_int((INT_TYPE)i); } /* Database.int get_doccount() */ /*! @decl int get_doccount() *! *! *! @returns *! *! */ PIKEFUN int get_doccount() { Database *db; db = THIS->object_data->database; doccount i = db->get_doccount(); push_int(i); } /* Database.int get_avlength() */ /*! @decl int get_avlength() *! *! *! @returns *! *! */ PIKEFUN int get_avlength() { Database *db; db = THIS->object_data->database; doclength i = db->get_avlength(); push_int((INT_TYPE)i); } /* Database.int get_lastdocid() */ /*! @decl int get_lastdocid() *! *! *! @returns *! *! */ PIKEFUN int get_lastdocid() { Database *db; db = THIS->object_data->database; docid i = db->get_lastdocid(); push_int((INT_TYPE)i); } /* Database.int has_positions() */ /*! @decl int has_positions() *! *! *! @returns *! *! */ PIKEFUN int has_positions() { Database *db; db = THIS->object_data->database; bool i = db->has_positions(); push_int(i?1:0); } /*! @decl TermIterator synonyms_iterator(string term) *! Get an iterator for the synonyms of a term. *! @returns *! a @[TermIterator] object which can be passed to @[foreach]() */ PIKEFUN object synonyms_iterator(string term) { Database *db; db = (Database*)THIS->object_data->database; TermIterator ti; TermIterator * ti2; struct object * o; string str((const char *)term->str, (size_t)term->len); ti = db->synonyms_begin(str); ti2 = new TermIterator(ti); o = fast_clone_object(TermIterator_program); OBJ2_TERMITERATOR(o)->object_data->termi = ti2; OBJ2_TERMITERATOR(o)->tie = new TermIterator(db->synonyms_end(str)); push_object(o); } /* Database.object get_document(int id) */ /*! @decl object get_document(int id) *! *! *! @param id *! * ! *! @returns *! *! */ PIKEFUN object get_document(int id) { Database *db; Document doc; struct object * obj; struct Document_struct * od; db = (Database*)THIS->object_data->database; try { doc = db->get_document((docid)id); } catch(DocNotFoundError &e) { pop_n_elems(args); Pike_error("DocumentNotFoundError\n"); } pop_n_elems(args); obj = fast_clone_object(Document_program); od = OBJ2_DOCUMENT(obj); od->object_data->document = new Document(doc); push_object(obj); } /*! @decl object get_spelling_terms() *! *! @returns *! a @[TermIterator] object which can also be passed to @[foreach]() */ PIKEFUN object get_spelling_terms() { TermIterator ti; TermIterator * ti2; struct object * o; Database *db; db = THIS->object_data->database; ti = db->spellings_begin(); ti2 = new TermIterator(ti); o = fast_clone_object(TermIterator_program); OBJ2_TERMITERATOR(o)->object_data->termi = ti2; OBJ2_TERMITERATOR(o)->tie = new TermIterator(db->spellings_end()); push_object(o); } /*! @decl object get_synonym_terms(string) *! *! @returns *! a @[TermIterator] object which can also be passed to @[foreach]() */ PIKEFUN object get_spelling_terms(string term) { TermIterator ti; TermIterator * ti2; struct object * o; Database *db; db = THIS->object_data->database; ti = db->synonyms_begin(term->str); ti2 = new TermIterator(ti); o = fast_clone_object(TermIterator_program); OBJ2_TERMITERATOR(o)->object_data->termi = ti2; OBJ2_TERMITERATOR(o)->tie = new TermIterator(db->synonyms_end(term->str)); push_object(o); } /*! @decl string get_spelling_suggestion(string word, int max_edit_distance) *! Suggest a spelling correction. *! *! @param word *! The potentially misspelled word. *! @param max_edit_distance *! Only consider words which are at most max_edit_distance edits from *! word. An edit is a character insertion, deletion, or the transposition *! of two adjacent characters (a reasonable starting value is 2). */ PIKEFUN string get_spelling_suggestion(string word, int max_edit_distance) { Database *db; db = (Database*)THIS->object_data->database; string str((const char *)word->str, (size_t)word->len); string nstr = db->get_spelling_suggestion(str, max_edit_distance); pop_n_elems(args); push_text(str.c_str()); } /* Database.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { Database *db; db = THIS->object_data->database; string str = db->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { Database *db; if(THIS && THIS->object_data && conversion_type == 'O') { db = THIS->object_data->database; string str = db->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } INIT { XAPIAN_DATABASE_OBJECT_DATA * dta = (XAPIAN_DATABASE_OBJECT_DATA*)malloc(sizeof(XAPIAN_DATABASE_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->database = NULL; THIS->object_data = dta; } /* Database.void destroy() */ /*! @decl void destroy() *! *! *! */ PIKEFUN void destroy() { Database *db; db = THIS->object_data->database; if(db) { //printf("deleting db\n"); delete db; } } EXIT { if(THIS->object_data) { Database *db; db = THIS->object_data->database; free(THIS->object_data); } } } /*! @endclass */ /*! @class WriteableDatabase *! @inherit Database */ PIKECLASS WriteableDatabase { INHERIT Database; /* WriteableDatabase.void create(string path, int mode) */ /*! @decl void create(string path, int mode) *! *! *! @param path *! * ! *! @param mode *! * ! *! */ PIKEFUN void create(string path, int mode) { try { const string str((const char *)path->str, (size_t)path->len); WritableDatabase* database = new WritableDatabase(str, mode); pop_n_elems(args); THIS->object_data->database = database; } catch(DatabaseLockError &e) { Pike_error("DatabaseLockError\n"); } catch(DatabaseOpeningError &e) { Pike_error("DatabaseOpeningError\n"); } catch(InvalidArgumentError &e) { Pike_error("InvalidArgumentError\n"); } } /* WriteableDatabase.void flush() */ /*! @decl void flush() *! *! *! */ PIKEFUN void flush() { WritableDatabase *db; db = (WritableDatabase*)THIS->object_data->database; try { db->flush(); } catch(Xapian::DatabaseCorruptError &e) { Pike_error("DatabaseCorruptError\n"); } catch(Xapian::DatabaseLockError &e) { Pike_error("DatabaseLockError\n"); } catch(Xapian::DatabaseError &e) { Pike_error("DatabaseError\n"); } } /* WriteableDatabase.int add_document(object document) */ /*! @decl int add_document(object document) *! *! *! @param document *! * ! *! @returns *! *! */ PIKEFUN int add_document(object document) { WritableDatabase *db; Document * doc; docid id; struct Document_struct * od; db = (WritableDatabase*)THIS->object_data->database; od = OBJ2_DOCUMENT(document); if(!od) Pike_error("Not a Document!\n"); doc = od->object_data->document; try { id = db->add_document(*doc); } catch(Xapian::DatabaseCorruptError &e) { Pike_error("DatabaseCorruptError\n"); } catch(Xapian::DatabaseError &e) { Pike_error("DatabaseError\n"); } catch(Xapian::InvalidArgumentError &e) { //printf("%s\n",e.get_msg().c_str()); Pike_error("InvalidArgumentError\n"); } pop_n_elems(args); push_int(id); } /* WriteableDatabase.void replace_document(int did, object document) */ /*! @decl void replace_document(int did, object document) *! *! *! @param did *! * ! *! @param document *! * ! *! */ PIKEFUN void replace_document(int did, object document) { WritableDatabase *db; Document * doc; docid id; struct Document_struct * od; db = (WritableDatabase*)THIS->object_data->database; od = OBJ2_DOCUMENT(document); if(!od) Pike_error("Not a Document!\n"); doc = od->object_data->document; try { db->replace_document((unsigned int)did, *doc); } catch(Xapian::DatabaseCorruptError &e) { Pike_error("DatabaseCorruptError\n"); } catch(Xapian::DatabaseError &e) { Pike_error("DatabaseError\n"); } pop_n_elems(args); } /* WriteableDatabase.void replace_document(string term, object document) */ /*! @decl void replace_document(string term, object document) *! *! *! @param term *! * ! *! @param document *! * ! *! */ PIKEFUN void replace_document(string term, object document) { WritableDatabase *db; Document * doc; docid id; string str; struct Document_struct * od; db = (WritableDatabase*)THIS->object_data->database; od = OBJ2_DOCUMENT(document); if(!od) Pike_error("Not a Document!\n"); doc = od->object_data->document; try { const string str((const char *)term->str, (size_t)term->len); db->replace_document(str, *doc); } catch(Xapian::DatabaseCorruptError &e) { Pike_error("DatabaseCorruptError\n"); } catch(Xapian::DatabaseError &e) { Pike_error("DatabaseError\n"); } pop_n_elems(args); } /* WriteableDatabase.void delete_document(string unique_term) */ /*! @decl void delete_document(string unique_term) *! *! *! @param unique_term *! * ! *! */ PIKEFUN void delete_document(string unique_term) { WritableDatabase *db; db = (WritableDatabase*)THIS->object_data->database; const string str((const char *)unique_term->str, (size_t)unique_term->len); pop_n_elems(args); try { db->delete_document(str); } catch(Xapian::DatabaseCorruptError &e) { Pike_error("DatabaseCorruptError\n"); } catch(Xapian::DatabaseError &e) { Pike_error("DatabaseError\n"); } } /* WriteableDatabase.void delete_document(int did) */ /*! @decl void delete_document(int did) *! *! *! @param did *! * ! *! */ PIKEFUN void delete_document(int did) { WritableDatabase *db; db = (WritableDatabase*)THIS->object_data->database; try { db->delete_document((docid)did); } catch(Xapian::DatabaseCorruptError &e) { pop_n_elems(args); Pike_error("DatabaseCorruptError\n"); } catch(Xapian::DatabaseError &e) { pop_n_elems(args); Pike_error("DatabaseError\n"); } } /* WriteableDatabase.void begin_transaction(int flushed) */ /*! @decl void begin_transaction(int flushed) *! *! *! @param flushed *! * ! *! */ PIKEFUN void begin_transaction(int flushed) { WritableDatabase *db; db = (WritableDatabase*)THIS->object_data->database; try { db->begin_transaction((bool)flushed); } catch(Xapian::InvalidOperationError &e) { pop_n_elems(args); Pike_error("InvalidOperationError\n"); } catch(Xapian::UnimplementedError &e) { pop_n_elems(args); Pike_error("UnimplementedError\n"); } } /* WriteableDatabase.void commit_transaction() */ /*! @decl void commit_transaction() *! *! *! */ PIKEFUN void commit_transaction() { WritableDatabase *db; db = (WritableDatabase*)THIS->object_data->database; try { db->commit_transaction(); } catch(Xapian::InvalidOperationError &e) { Pike_error("InvalidOperationError\n"); } catch(Xapian::DatabaseCorruptError &e) { Pike_error("DatabaseCorruptError\n"); } catch(Xapian::DatabaseError &e) { Pike_error("DatabaseError\n"); } catch(Xapian::UnimplementedError &e) { Pike_error("UnimplementedError\n"); } } /* WriteableDatabase.void cancel_transaction() */ /*! @decl void cancel_transaction() *! *! *! */ PIKEFUN void cancel_transaction() { WritableDatabase *db; db = (WritableDatabase*)THIS->object_data->database; try { db->cancel_transaction(); } catch(Xapian::InvalidOperationError &e) { Pike_error("InvalidOperationError\n"); } catch(Xapian::DatabaseCorruptError &e) { Pike_error("DatabaseCorruptError\n"); } catch(Xapian::DatabaseError &e) { Pike_error("DatabaseError\n"); } catch(Xapian::UnimplementedError &e) { Pike_error("UnimplementedError\n"); } } /* WriteableDatabase.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { WritableDatabase *db; db = (WritableDatabase*)THIS->object_data->database; string str = db->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { WritableDatabase *db; if(THIS && THIS->object_data && conversion_type == 'O') { db = (WritableDatabase*)THIS->object_data->database; string str = db->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } } /*! @endclass */ /*! @class QueryParser */ PIKECLASS QueryParser { CVAR XAPIAN_QUERYPARSER_OBJECT_DATA *object_data; /* QueryParser.void create() */ /*! @decl void create() *! *! *! */ PIKEFUN void create() { QueryParser * parser = new QueryParser(); THIS->object_data->parser = parser; } /*! @decl string get_corrected_query_string() *! */ PIKEFUN string get_corrected_query_string() { QueryParser * parser; parser = THIS->object_data->parser; string nstr = parser->get_corrected_query_string(); pop_n_elems(args); push_text(nstr.c_str()); } /* QueryParser.void set_stemmer(object stemmer) */ /*! @decl void set_stemmer(object stemmer) *! *! *! @param stemmer *! * ! *! */ PIKEFUN void set_stemmer(object stemmer) { QueryParser * parser; Stem * s; parser = THIS->object_data->parser; s = OBJ2_STEM(stemmer)->object_data->stem; parser->set_stemmer((const Stem)*s); pop_n_elems(args); } /* QueryParser.void set_stopper(object stopper) */ /*! @decl void set_stopper(object stopper) *! *! *! @param stopper *! * ! *! */ PIKEFUN void set_stopper(object stopper) { QueryParser * parser; Stopper * s; parser = THIS->object_data->parser; s = OBJ2_STOPPER(stopper)->object_data->stopper; parser->set_stopper((const Stopper*)s); pop_n_elems(args); } /* QueryParser.void set_database(object database) */ /*! @decl void set_database(object database) *! *! *! @param database *! *! *! */ PIKEFUN void set_database(object database) { QueryParser * parser; Database * d; parser = THIS->object_data->parser; d = OBJ2_DATABASE(database)->object_data->database; parser->set_database((const Database)*d); pop_n_elems(args); } /* QueryParser.void set_default_op(int op) */ /*! @decl void set_default_op(int op) *! *! *! @param op *! * ! *! */ PIKEFUN void set_default_op(int op) { QueryParser * parser; parser = THIS->object_data->parser; parser->set_default_op((Query::op)op); pop_n_elems(args); } /*! @decl void set_stemming_strategy(int strat) *! Set the stemming strategy. *! *! This controls how the query parser will apply the stemming algorithm. *! The default value is STEM_NONE. The possible values are: *! *! * STEM_NONE: Don't perform any stemming. *! *! * STEM_SOME: Search for stemmed forms of terms except for those *! which start with a capital letter, or are followed by certain *! characters (currently: (/@<>=*[{" ), or are used with operators which *! need positional information. Stemmed terms are prefixed with 'Z'. *! *! * STEM_ALL: Search for stemmed forms of all words (note: no 'Z' *! prefix is added). *! *! Note that the stemming algorithm is only applied to words in *! probabilistic fields - boolean filter terms are never stemmed. *! */ PIKEFUN void set_stemming_strategy(int strat) { QueryParser * parser; parser = THIS->object_data->parser; parser->set_stemming_strategy((Xapian::QueryParser::stem_strategy)strat); pop_n_elems(args); } /* QueryParser.object parse_query(string query, int flags) */ /*! @decl object parse_query(string query, int flags) *! *! *! @param query *! * ! *! @param flags *! * ! *! @returns *! *! */ PIKEFUN object parse_query(string query, int flags) { Query q; Query * q1; QueryParser *parser; struct object *o; parser = THIS->object_data->parser; string str((const char *)query->str, (size_t)query->len); q = parser->parse_query(str, flags); q1 = new Query(q); o = fast_clone_object(Query_program); if(!o) Pike_error("unable to clone the query program.\n"); if(!q1) Pike_error("unable to parse the query.\n"); OBJ2_QUERY(o)->object_data->query = q1; pop_n_elems(args); push_object(o); } /* QueryParser.void add_prefix(string field, string prefix) */ /*! @decl void add_prefix(string field, string prefix) *! *! *! @param field *! * ! *! @param prefix *! * ! *! */ PIKEFUN void add_prefix(string field, string prefix) { QueryParser *parser; parser = THIS->object_data->parser; string f((const char *)field->str, (size_t)field->len); string p((const char *)prefix->str, (size_t)prefix->len); parser->add_prefix(f, p); pop_n_elems(args); } /* QueryParser.void add_boolean_prefix(string field, string prefix) */ /*! @decl void add_boolean_prefix(string field, string prefix) *! *! *! @param field *! * ! *! @param prefix *! * ! *! */ PIKEFUN void add_boolean_prefix(string field, string prefix) { QueryParser *parser; parser = THIS->object_data->parser; string f((const char *)field->str, (size_t)field->len); string p((const char *)prefix->str, (size_t)prefix->len); parser->add_boolean_prefix(f, p); pop_n_elems(args); } /* QueryParser.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { QueryParser *parser; parser = THIS->object_data->parser; string str = parser->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { QueryParser *query; if(THIS && THIS->object_data && conversion_type == 'O') { query = THIS->object_data->parser; string str = query->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } INIT { XAPIAN_QUERYPARSER_OBJECT_DATA * dta = (XAPIAN_QUERYPARSER_OBJECT_DATA*)malloc(sizeof(XAPIAN_QUERYPARSER_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->parser = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { QueryParser *parser; parser = THIS->object_data->parser; if(parser) delete parser; free(THIS->object_data); } } EXTRA { QueryParser::feature_flag flag; int sflag; flag = QueryParser::FLAG_BOOLEAN; add_integer_constant("FLAG_BOOLEAN", flag, 0); flag = QueryParser::FLAG_PHRASE; add_integer_constant("FLAG_PHRASE", flag, 0); flag = QueryParser::FLAG_LOVEHATE; add_integer_constant("FLAG_LOVEHATE", flag, 0); flag = QueryParser::FLAG_BOOLEAN_ANY_CASE; add_integer_constant("FLAG_BOOLEAN_ANY_CASE", flag, 0); flag = QueryParser::FLAG_WILDCARD; add_integer_constant("FLAG_WILDCARD", flag, 0); flag = QueryParser::FLAG_SPELLING_CORRECTION; add_integer_constant("FLAG_SPELLING_CORRECTION", flag, 0); flag = QueryParser::FLAG_PURE_NOT; add_integer_constant("FLAG_PURE_NOT", flag, 0); flag = QueryParser::FLAG_PARTIAL; add_integer_constant("FLAG_PARTIAL", flag, 0); flag = QueryParser::FLAG_SYNONYM; add_integer_constant("FLAG_SYNONYM", flag, 0); flag = QueryParser::FLAG_AUTO_SYNONYMS; add_integer_constant("FLAG_AUTO_SYNONYMS", flag, 0); /* flag = QueryParser::FLAG_MULTIWORD_SYNONYMS; add_integer_constant("FLAG_MULTIWORD_SYNONYMS", flag, 0); */ sflag = QueryParser::STEM_NONE; add_integer_constant("STEM_NONE", sflag, 0); sflag = QueryParser::STEM_SOME; add_integer_constant("STEM_SOME", sflag, 0); sflag = QueryParser::STEM_ALL; add_integer_constant("STEM_ALL", sflag, 0); } } /*! @endclass */ /*! @class Enquire */ PIKECLASS Enquire { CVAR XAPIAN_ENQUIRE_OBJECT_DATA *object_data; /* Enquire.void create(object database) */ /*! @decl void create(object database) *! *! *! @param database *! * ! *! */ PIKEFUN void create(object database) { try { Database * db; db = OBJ2_DATABASE(database)->object_data->database; Enquire * enquire = new Enquire(*db); pop_n_elems(args); THIS->object_data->enquire = enquire; } catch(...) { Pike_error("an error occurred!\n"); } } /* Enquire.void set_weighting_scheme(object weight) */ /*! @decl void set_weighting_scheme(object weight) *! *! *! @param weight *! * ! *! */ PIKEFUN void set_weighting_scheme(object weight) { Enquire * e = THIS->object_data->enquire; Weight * w = (OBJ2_WEIGHT(weight)->object_data->weight); e->set_weighting_scheme(*w); pop_n_elems(args); } /* Enquire.void set_query(object query, int termcount) */ /*! @decl void set_query(object query, int termcount) *! *! *! @param query *! * ! *! @param termcount *! * ! *! */ PIKEFUN void set_query(object query, int termcount) { Query * q; Enquire *enquire; enquire = THIS->object_data->enquire; q = OBJ2_QUERY(query)->object_data->query; enquire->set_query(*q, (Xapian::termcount)termcount); pop_n_elems(args); } /* Enquire.void set_cutoff(int percent_cutoff, float weight_cutoff) */ /*! @decl void set_cutoff(int percent_cutoff, float weight_cutoff) *! *! *! @param percent_cutoff *! * ! *! @param weight_cutoff *! * ! *! */ PIKEFUN void set_cutoff(int percent_cutoff, float weight_cutoff) { Enquire *enquire; enquire = THIS->object_data->enquire; enquire->set_cutoff((percent)percent_cutoff, (weight)weight_cutoff); pop_n_elems(args); } /* Enquire.void set_docid_order(int docid_order) */ /*! @decl void set_docid_order(int docid_order) *! *! *! @param docid_order *! * ! *! */ PIKEFUN void set_docid_order(int docid_order) { Enquire *enquire; enquire = THIS->object_data->enquire; enquire->set_docid_order((Xapian::Enquire::docid_order)docid_order); pop_n_elems(args); } /* Enquire.void set_collapse_key(int collapse_key) */ /*! @decl void set_collapse_key(int collapse_key) *! *! *! @param collapse_key *! * ! *! */ PIKEFUN void set_collapse_key(int collapse_key) { Enquire *enquire; enquire = THIS->object_data->enquire; enquire->set_collapse_key((valueno)collapse_key); pop_n_elems(args); } /* Enquire.void set_sort_by_relevance_then_value(int sort_key, int ascending) */ /*! @decl void set_sort_by_relevance_then_value(int sort_key, int ascending) *! *! *! @param sort_key *! * ! *! @param ascending *! * ! *! */ PIKEFUN void set_sort_by_relevance_then_value(int sort_key, int ascending) { Enquire *enquire; enquire = THIS->object_data->enquire; enquire->set_sort_by_relevance_then_value((valueno)sort_key, ascending?true:false); pop_n_elems(args); } /* Enquire.void set_sort_by_value_then_relevance(int sort_key, int ascending) */ /*! @decl void set_sort_by_value_then_relevance(int sort_key, int ascending) *! *! *! @param sort_key *! * ! *! @param ascending *! * ! *! */ PIKEFUN void set_sort_by_value_then_relevance(int sort_key, int ascending) { Enquire *enquire; enquire = THIS->object_data->enquire; enquire->set_sort_by_value_then_relevance((valueno)sort_key, ascending?true:false); pop_n_elems(args); } /* Enquire.void set_sort_value(int sort_key, int ascending) */ /*! @decl void set_sort_value(int sort_key, int ascending) *! *! *! @param sort_key *! * ! *! @param ascending *! * ! *! */ PIKEFUN void set_sort_value(int sort_key, int ascending) { Enquire *enquire; enquire = THIS->object_data->enquire; enquire->set_sort_by_value((valueno)sort_key, ascending?true:false); pop_n_elems(args); } /* Enquire.void set_sort_by_relevence() */ /*! @decl void set_sort_by_relevence() *! *! *! */ PIKEFUN void set_sort_by_relevence() { Enquire *enquire; enquire = THIS->object_data->enquire; enquire->set_sort_by_relevance(); } /* Enquire.object get_query() */ /*! @decl object get_query() *! *! *! @returns *! *! */ PIKEFUN object get_query() { Enquire *enquire; Query q; Query * q2; struct object* r; enquire = THIS->object_data->enquire; q = enquire->get_query(); q2 = new Query(q); r = fast_clone_object(Query_program); OBJ2_QUERY(r)->object_data->query = q2; push_object(r); } /* Enquire.object get_mset(int first, int maxitems, object rset, function|void mdecider) */ /*! @decl object get_mset(int first, int maxitems, object rset, function|void mdecider) *! *! *! @param first *! * ! *! @param maxitems *! * ! *! @param rset *! * ! *! @returns *! *! */ PIKEFUN object get_mset(int first, int maxitems, object rset) { Enquire *enquire; enquire = THIS->object_data->enquire; MSet mset; MSet * mset1; struct object * o; RSet * rseto; rseto = OBJ2_RSET(rset)->object_data->rset; try { mset = enquire->get_mset((doccount)first, (doccount)maxitems, rseto, 0); } catch(InvalidArgumentError &e) { pop_n_elems(args); Pike_error("InvalidArgumentError\n"); } pop_n_elems(args); o = fast_clone_object(MSet_program); mset1 = new MSet(mset); OBJ2_MSET(o)->object_data->mset = mset1; push_object(o); } PIKEFUN object get_mset(int first, int maxitems, object rset, function mdecider) { Enquire *enquire; enquire = THIS->object_data->enquire; MSet mset; MSet * mset1; struct object * o; RSet * rseto; PikeMatchDeciderProxy * md; rseto = OBJ2_RSET(rset)->object_data->rset; md = new PikeMatchDeciderProxy(mdecider); try { mset = enquire->get_mset((doccount)first, (doccount)maxitems, rseto, md); } catch(InvalidArgumentError &e) { pop_n_elems(args); Pike_error("InvalidArgumentError\n"); } pop_n_elems(args); o = fast_clone_object(MSet_program); mset1 = new MSet(mset); OBJ2_MSET(o)->object_data->mset = mset1; push_object(o); } /* Enquire.object get_mset(int first, int maxitems, int checkatleast) */ /*! @decl object get_mset(int first, int maxitems, int checkatleast) *! *! *! @param first *! * ! *! @param maxitems *! * ! *! @param checkatleast *! * ! *! @returns *! *! */ PIKEFUN object get_mset(int first, int maxitems, int checkatleast) { Enquire *enquire; enquire = THIS->object_data->enquire; MSet mset; MSet * mset1; struct object * o; try { mset = enquire->get_mset((doccount)first, (doccount)maxitems, (doccount)checkatleast); } catch(InvalidArgumentError &e) { pop_n_elems(args); Pike_error("InvalidArgumentError\n"); } pop_n_elems(args); o = fast_clone_object(MSet_program); mset1 = new MSet(mset); OBJ2_MSET(o)->object_data->mset = mset1; push_object(o); } /* Enquire.object get_eset(int maxitems, object rset, function|void edecider) */ /*! @decl object get_eset(int maxitems, object rset, function|void edecider) *! *! *! @param maxitems *! * ! *! @param rset *! * ! *! @param edecider *! * ! *! @returns *! *! */ PIKEFUN object get_eset(int maxitems, object rset) { Enquire *enquire; enquire = THIS->object_data->enquire; ESet eset; ESet * eset1; RSet * rseto; struct object * o; rseto = OBJ2_RSET(rset)->object_data->rset; try { eset = enquire->get_eset((termcount)maxitems, *rseto, 0); } catch(InvalidArgumentError &e) { pop_n_elems(args); Pike_error("InvalidArgumentError\n"); } pop_n_elems(args); o = fast_clone_object(ESet_program); eset1 = new ESet(eset); OBJ2_ESET(o)->object_data->eset = eset1; push_object(o); } PIKEFUN object get_eset(int maxitems, object rset, function edecider) { Enquire *enquire; enquire = THIS->object_data->enquire; ESet eset; ESet * eset1; RSet * rseto; struct object * o; PikeExpandDeciderProxy * ed; ed = new PikeExpandDeciderProxy(edecider); rseto = OBJ2_RSET(rset)->object_data->rset; try { eset = enquire->get_eset((termcount)maxitems, *rseto, ed); } catch(InvalidArgumentError &e) { pop_n_elems(args); Pike_error("InvalidArgumentError\n"); } pop_n_elems(args); o = fast_clone_object(ESet_program); eset1 = new ESet(eset); OBJ2_ESET(o)->object_data->eset = eset1; push_object(o); } /* Enquire.object get_eset(int maxitems, object rset, int flags, float k, function|void edecider) */ /*! @decl object get_eset(int maxitems, object rset, int flags, float k, function|void edecider) *! *! *! @param maxitems *! * ! *! @param rset *! * ! *! @param flags *! * ! *! @param k *! * ! *! @param edecider *! * ! *! @returns *! *! */ PIKEFUN object get_eset(int maxitems, object rset, int flags, float k, function edecider) { Enquire *enquire; enquire = THIS->object_data->enquire; ESet eset; ESet * eset1; RSet * rseto; struct object * o; PikeExpandDeciderProxy * ed; ed = new PikeExpandDeciderProxy(edecider); rseto = OBJ2_RSET(rset)->object_data->rset; try { eset = enquire->get_eset((termcount)maxitems, *rseto, (int)flags, (double)k, ed); } catch(InvalidArgumentError &e) { pop_n_elems(args); Pike_error("InvalidArgumentError\n"); } pop_n_elems(args); o = fast_clone_object(ESet_program); eset1 = new ESet(eset); OBJ2_ESET(o)->object_data->eset = eset1; push_object(o); } PIKEFUN object get_eset(int maxitems, object rset, int flags, float k) { Enquire *enquire; enquire = THIS->object_data->enquire; ESet eset; ESet * eset1; RSet * rseto; struct object * o; rseto = OBJ2_RSET(rset)->object_data->rset; try { eset = enquire->get_eset((termcount)maxitems, *rseto, (int)flags, (double)k, 0); } catch(InvalidArgumentError &e) { pop_n_elems(args); Pike_error("InvalidArgumentError\n"); } pop_n_elems(args); o = fast_clone_object(ESet_program); eset1 = new ESet(eset); OBJ2_ESET(o)->object_data->eset = eset1; push_object(o); } /*! @decl object get_matching_terms(int docid) *! *! @returns *! a @[TermIterator] object which can also be passed to @[foreach]() */ PIKEFUN object get_matching_terms(int docid) { TermIterator ti; TermIterator * ti2; struct object * o; Enquire *enquire; enquire = THIS->object_data->enquire; ti = enquire->get_matching_terms_begin(docid); ti2 = new TermIterator(ti); o = fast_clone_object(TermIterator_program); OBJ2_TERMITERATOR(o)->object_data->termi = ti2; OBJ2_TERMITERATOR(o)->tie = new TermIterator(enquire->get_matching_terms_end(docid)); push_object(o); } /* Enquire.string get_description() */ /*! @decl string get_description() *! *! *! @returns *! *! */ PIKEFUN string get_description() { Enquire *enquire; enquire = THIS->object_data->enquire; string str = enquire->get_description(); push_text(str.c_str()); } PIKEFUN string _sprintf(int conversion_type, mapping params) { Enquire *enquire; if(THIS && THIS->object_data && conversion_type == 'O') { enquire = THIS->object_data->enquire; string str = enquire->get_description(); pop_n_elems(args); push_text(str.c_str()); } else { pop_n_elems(args); push_int(0); } } INIT { XAPIAN_ENQUIRE_OBJECT_DATA * dta = (XAPIAN_ENQUIRE_OBJECT_DATA*)malloc(sizeof(XAPIAN_ENQUIRE_OBJECT_DATA)); if (!dta) Pike_error("init_sample: Out of memory!\n"); dta->enquire = NULL; THIS->object_data = dta; } EXIT { if(THIS->object_data) { Enquire *enquire; enquire = THIS->object_data->enquire; // if(enquire) delete enquire; free(THIS->object_data); } } EXTRA { add_integer_constant("ASCENDING", Enquire::ASCENDING, 0); add_integer_constant("DESCENDING", Enquire::DESCENDING, 0); add_integer_constant("DONT_CARE", Enquire::DONT_CARE, 0); } } INIT { } EXIT { } EXTRA { /*! @decl constant DB_CREATE_OR_OPEN *! @decl constant DB_CREATE *! @decl constant DB_CREATE_OR_OVERWRITE *! @decl constant DB_OPEN *! @decl constant BAD_VALUENO */ add_integer_constant("DB_CREATE_OR_OPEN", DB_CREATE_OR_OPEN, 0); add_integer_constant("DB_CREATE", DB_CREATE, 0); add_integer_constant("DB_CREATE_OR_OVERWRITE", DB_CREATE_OR_OVERWRITE, 0); add_integer_constant("DB_OPEN", DB_OPEN, 0); add_integer_constant("BAD_VALUENO", BAD_VALUENO, 0); } /*! @endclass */ + +/*! @class TermGenerator +*/ +PIKECLASS TermGenerator +{ +CVAR XAPIAN_TERMGENERATOR_OBJECT_DATA *object_data; + + +PIKEFUN int set_flags(int flags, int mask) +{ + TermGenerator * termgenerator; + termgenerator = (TermGenerator*)THIS->object_data->termgenerator; + + TermGenerator::flags f; + TermGenerator::flags m; + + f = (TermGenerator::flags)flags; + m = (TermGenerator::flags)mask; + + termgenerator->set_flags(f, m); + + pop_n_elems(args); +} + +/* TermGenerator.void set_document(object document) */ +/*! @decl void set_document(object document) + *! + *! + *! @param document + *! +* ! + *! @returns + *! + *! + */ +PIKEFUN void set_document(object document) +{ + TermGenerator * termgenerator; + Document * doc; + docid id; + + struct Document_struct * od; + + termgenerator = (TermGenerator*)THIS->object_data->termgenerator; + od = OBJ2_DOCUMENT(document); + + if(!od) Pike_error("Not a Document!\n"); + + doc = od->object_data->document; + + try + { + termgenerator->set_document(*doc); + } + catch(Xapian::DatabaseCorruptError &e) + { + Pike_error("DatabaseCorruptError\n"); + } + catch(Xapian::DatabaseError &e) + { + Pike_error("DatabaseError\n"); + } + catch(Xapian::InvalidArgumentError &e) + { + //printf("%s\n",e.get_msg().c_str()); + Pike_error("InvalidArgumentError\n"); + } + pop_n_elems(args); +} + + PIKEFUN object get_document() + { + TermGenerator * termgenerator; + Document doc; + Document *doc2; + struct object * o; + try { + termgenerator = (TermGenerator*)THIS->object_data->termgenerator; + doc = termgenerator->get_document(); + doc2 = new Document(doc); + + o = fast_clone_object(Document_program); + OBJ2_DOCUMENT(o)->object_data->document = doc2; + + push_object(o); + } + catch(RangeError &e) + { + pop_n_elems(args); + Pike_error("RangeError\n"); + } + + } + +/* TermGenerator.void set_stemmer(object stemmer) */ +/*! @decl void set_stemmer(object stemmer) + *! + *! + *! @param stemmer + *! +* ! + *! + */ +PIKEFUN void set_stemmer(object stemmer) +{ + TermGenerator * termgenerator; + Stem * s; + + termgenerator = THIS->object_data->termgenerator; + s = OBJ2_STEM(stemmer)->object_data->stem; + termgenerator->set_stemmer((const Stem)*s); + + pop_n_elems(args); +} + +/* TermGenerator.void set_stopper(object stopper) */ +/*! @decl void set_stopper(object stopper) + *! + *! + *! @param stopper + *! +* ! + *! + */ +PIKEFUN void set_stopper(object stopper) +{ + TermGenerator * termgenerator; + Stopper * s; + + termgenerator = THIS->object_data->termgenerator; + s = OBJ2_STOPPER(stopper)->object_data->stopper; + termgenerator->set_stopper((const Stopper*)s); + + pop_n_elems(args); +} + +/* TermGenerator.void set_database(object database) */ +/*! @decl void set_database(object database) + *! + *! + *! @param database + *! + *! + *! + */ +PIKEFUN void set_database(object database) +{ + TermGenerator * termgenerator; + Database * d; + + termgenerator = THIS->object_data->termgenerator; + d = OBJ2_DATABASE(database)->object_data->database; + + termgenerator->set_database((const Xapian::WritableDatabase&)*d); + + pop_n_elems(args); +} + + + +INIT +{ + XAPIAN_TERMGENERATOR_OBJECT_DATA * dta = + (XAPIAN_TERMGENERATOR_OBJECT_DATA*)malloc(sizeof(XAPIAN_TERMGENERATOR_OBJECT_DATA)); + if (!dta) + Pike_error("init_sample: Out of memory!\n"); + + dta->termgenerator = NULL; + THIS->object_data = dta; +} + +/* Weight.void destroy() */ +/*! @decl void destroy() + *! + *! + *! + */ +PIKEFUN void destroy() +{ + + TermGenerator * termgenerator; + termgenerator = THIS->object_data->termgenerator; + + if(termgenerator) + { + delete termgenerator; + } + +} + +EXIT +{ + if(THIS->object_data) + { + + TermGenerator *termgenerator; + termgenerator = THIS->object_data->termgenerator; +// printf("shutting down!\n"); + free(THIS->object_data); + } +} + +} + +/*! @endclass +*/ + + /*! @endmodule */ /*! @endmodule */