
Contents of /Public_Xapian-1.4/xapian.ccmod:
/*! @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(const 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
*!
*! @note
*! this function is wide-string aware.
*!
*/
PIKEFUN string `()(string word)
{
Stem *stem;
string foo;
ref_push_string(word);
f_string_to_utf8(1);
const string str((const char *)Pike_sp[-1].u.string->str, (size_t) Pike_sp[-1].u.string->len);
stem = THIS->object_data->stem;
foo = (*stem)(str);
pop_n_elems(args+1);
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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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);
try
{
Database * db = new Database(str);
THIS->object_data->database = db;
pop_n_elems(args);
}
catch(const DatabaseLockError& e)
{
pop_n_elems(args);
Pike_error("DatabaseLockError\n");
}
catch(const DatabaseOpeningError& e)
{
pop_n_elems(args);
Pike_error("DatabaseOpeningError\n");
}
catch(const InvalidArgumentError& e)
{
pop_n_elems(args);
Pike_error("InvalidArgumentError\n");
}
catch(...){
pop_n_elems(args);
Pike_error("an error occurred while opening the database.\n");
}
}
/* 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(const 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(const DatabaseLockError& e)
{
pop_n_elems(args);
Pike_error("DatabaseLockError\n");
}
catch(const DatabaseOpeningError &e)
{
pop_n_elems(args);
Pike_error("DatabaseOpeningError\n");
}
catch(const InvalidArgumentError &e)
{
pop_n_elems(args);
Pike_error("InvalidArgumentError\n");
}
catch(...){
pop_n_elems(args);
Pike_error("an error occurred while opening the database.\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
*! a plain text query string
* !
*! @param flags
*!
* !
*! @returns
*! a @[Query] object
*!
*! @note
*! this function is wide-string aware
*/
PIKEFUN object parse_query(string query, int flags)
{
Query q;
Query * q1;
QueryParser *parser;
struct object *o;
parser = THIS->object_data->parser;
ref_push_string(query);
f_string_to_utf8(1);
string str((const char *)Pike_sp[-1].u.string->str, (size_t) Pike_sp[-1].u.string->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+1);
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 void create()
{
TermGenerator * termgenerator;
termgenerator = new TermGenerator();
THIS->object_data->termgenerator = termgenerator;
}
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;
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);
}
/*!
*!
*! @decl object get_document()
*!
*/
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);
}
/*!
*! @decl void set_termpos(int termpos)
*!
*/
PIKEFUN void set_termpos(int termpos)
{
TermGenerator * termgenerator;
termgenerator = THIS->object_data->termgenerator;
termgenerator->set_termpos((Xapian::termcount)termpos);
pop_n_elems(args);
}
/*!
*! @decl int get_termpos()
*!
*/
PIKEFUN int get_termpos()
{
TermGenerator * termgenerator;
termgenerator = THIS->object_data->termgenerator;
Xapian::termcount termpos;
termpos = termgenerator->get_termpos();
push_int((int)termpos);
}
/*!
*! @decl void index_text(string text, int weight, string prefix)
*!
*! @note
*! this function is wide-string aware.
*/
PIKEFUN void index_text(string text, int weight, string prefix)
{
TermGenerator * termgenerator;
ref_push_string(text);
f_string_to_utf8(1);
Xapian::Utf8Iterator * text_iter = new Xapian::Utf8Iterator((const char *)Pike_sp[-1].u.string->str, (size_t) Pike_sp[-1].u.string->len);
string prefix_str((const char *)prefix->str, (size_t)prefix->len);
termgenerator = THIS->object_data->termgenerator;
termgenerator->index_text(*text_iter, (Xapian::termcount) weight, prefix_str);
pop_n_elems(args+1);
}
/*!
*! @decl void index_text_without_positions(string text, int weight, string prefix)
*!
*! @note
*! this function is wide-string aware.
*/
PIKEFUN void index_text_without_positions(string text, int weight, string prefix)
{
TermGenerator * termgenerator;
ref_push_string(text);
f_string_to_utf8(1);
Xapian::Utf8Iterator * text_iter = new Xapian::Utf8Iterator((const char *)Pike_sp[-1].u.string->str, (size_t) Pike_sp[-1].u.string->len);
string prefix_str((const char *)prefix->str, (size_t)prefix->len);
termgenerator = THIS->object_data->termgenerator;
termgenerator->index_text_without_positions(*text_iter, (Xapian::termcount) weight, prefix_str);
pop_n_elems(args+1);
}
/* Stopper.string get_description() */
/*! @decl string get_description()
*!
*!
*! @returns
*!
*!
*/
PIKEFUN string get_description()
{
TermGenerator * termgenerator;
termgenerator = THIS->object_data->termgenerator;
string str = termgenerator->get_description();
push_text(str.c_str());
}
PIKEFUN string _sprintf(int conversion_type, mapping params)
{
TermGenerator * termgenerator;
if(THIS && THIS->object_data && conversion_type == 'O')
{
termgenerator = THIS->object_data->termgenerator;
string str = termgenerator->get_description();
pop_n_elems(args);
push_text(str.c_str());
}
else
{
pop_n_elems(args);
push_int(0);
}
}
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;
}
}
EXTRA
{
/*! @decl constant OP_AND
*! Return iff both subqueries are satisfied.
*/
add_integer_constant("FLAG_SPELLING", TermGenerator::FLAG_SPELLING, 0);
}
EXIT
{
if(THIS->object_data)
{
TermGenerator *termgenerator;
termgenerator = THIS->object_data->termgenerator;
// printf("shutting down!\n");
free(THIS->object_data);
}
}
}
/*! @endclass
*/
/*! @endmodule
*/
/*! @endmodule
*/