/* * Copyright (C) 2005 Network Applied Communication Laboratory Co., Ltd. * * This file is part of Rast. * See the file COPYING for redistribution information. * */ #include #include #include #include "rast/ruby.h" #include "rast/config.h" #include "rast/text_index.h" #include "rast/filter.h" #include "rast/local_db.h" #include "rast/query.h" #include "rast/merger.h" static VALUE cTerm, cTermFrequency, cCandidate, cQueryResult; static VALUE cResult, cResultTerm, cResultItem; static VALUE cProperty, cDocument; static void document_free(rast_document_t *doc) { if (doc) { rast_document_abort(doc); } } static rast_document_t * get_document(VALUE self) { if (TYPE(self) != T_DATA || RDATA(self)->dfree != (RUBY_DATA_FUNC) document_free) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Rast::Document)", rb_obj_classname(self)); } return (rast_document_t *) DATA_PTR(self); } static VALUE document_doc_id(VALUE self) { rast_document_t *doc; rast_doc_id_t doc_id; doc = get_document(self); if (doc == NULL) { rb_raise(rb_eTypeError, "bad operation %s already aborted", rb_obj_classname(self)); } rast_rb_raise_error(rast_document_get_doc_id(doc, &doc_id)); return INT2NUM(doc_id); } static VALUE document_add_text(VALUE self, VALUE vtext) { rast_document_t *doc; char *text; int nbytes; SafeStringValue(vtext); text = RSTRING(vtext)->ptr; nbytes = RSTRING(vtext)->len; doc = get_document(self); if (doc == NULL) { rb_raise(rb_eTypeError, "bad operation %s already aborted", rb_obj_classname(self)); } rast_rb_raise_error(rast_document_add_text(doc, text, nbytes)); return Qnil; } static VALUE document_set_property(VALUE self, VALUE vname, VALUE vvalue) { rast_db_t *db; rast_document_t *doc; char *name; int num_properties, i; const rast_property_t *properties; SafeStringValue(vname); name = StringValuePtr(vname); doc = get_document(self); if (doc == NULL) { rb_raise(rb_eTypeError, "bad operation %s already aborted", rb_obj_classname(self)); } db = rast_document_get_db(doc); properties = rast_db_properties(db, &num_properties); for (i = 0; i < num_properties; i++) { if (strcmp(properties[i].name, name) == 0) { rast_value_t value; rast_value_set_type(&value, properties[i].type); switch (properties[i].type) { case RAST_TYPE_STRING: Check_Type(vvalue, T_STRING); rast_value_set_string(&value, StringValuePtr(vvalue)); break; case RAST_TYPE_DATE: if (TYPE(vvalue) != T_STRING) { vvalue = rb_funcall(vvalue, rb_intern("strftime"), 1, rb_str_new2("%F")); } rast_value_set_date(&value, StringValuePtr(vvalue)); break; case RAST_TYPE_DATETIME: if (TYPE(vvalue) != T_STRING) { vvalue = rb_funcall(vvalue, rb_intern("strftime"), 1, rb_str_new2("%FT%T")); } rast_value_set_datetime(&value, StringValuePtr(vvalue)); break; case RAST_TYPE_UINT: Check_Type(vvalue, T_FIXNUM); rast_value_set_uint(&value, NUM2INT(vvalue)); break; default: rb_raise(rast_rb_eError, "unknown property type"); } rast_rb_raise_error(rast_document_set_property(doc, name, &value)); break; } } return Qnil; } static VALUE document_commit(VALUE self) { rast_document_t *doc; doc = get_document(self); rast_rb_raise_error(rast_document_commit(doc)); DATA_PTR(self) = NULL; return Qnil; } static VALUE document_abort(VALUE self) { rast_document_t *doc; doc = get_document(self); rast_rb_raise_error(rast_document_abort(doc)); DATA_PTR(self) = NULL; return Qnil; } typedef struct { rast_filter_chain_t *chain; VALUE vdoc; VALUE vpool; } filter_chain_data_t; static rast_filter_chain_t * get_chain(VALUE vchain) { return ((filter_chain_data_t *) DATA_PTR(vchain))->chain; } static void filter_chain_mark(filter_chain_data_t *data) { if (data == NULL) { return; } rb_gc_mark(data->vdoc); rb_gc_mark(data->vpool); } static VALUE filter_chain_alloc(VALUE klass) { return Data_Wrap_Struct(klass, filter_chain_mark, NULL, NULL); } static VALUE filter_chain_initialize(int argc, VALUE *argv, VALUE self) { rast_document_t *doc; rast_filter_chain_t *chain; apr_pool_t *pool; VALUE vdoc, vtext_filters, vpool; const char **text_filters = NULL; int num_text_filters = 0, i; filter_chain_data_t *data; rast_error_t *error; rb_scan_args(argc, argv, "11", &vdoc, &vtext_filters); pool = rast_rb_pool_new(&vpool); if (!NIL_P(vtext_filters)) { Check_Type(vtext_filters, T_ARRAY); num_text_filters = RARRAY(vtext_filters)->len; text_filters = (const char **) apr_palloc(pool, sizeof(char *) * num_text_filters); for (i = 0; i < num_text_filters; i++) { VALUE str = RARRAY(vtext_filters)->ptr[i]; SafeStringValue(str); text_filters[i] = StringValuePtr(str); } } doc = get_document(vdoc); error = rast_filter_chain_create(&chain, doc, text_filters, num_text_filters, pool); rast_rb_raise_error(error); data = (filter_chain_data_t *) apr_palloc(pool, sizeof(filter_chain_data_t)); data->chain = chain; data->vdoc = vdoc; data->vpool = vpool; DATA_PTR(self) = data; return Qnil; } static VALUE filter_chain_invoke(int argc, VALUE *argv, VALUE self) { rast_filter_chain_t *chain = get_chain(self); apr_bucket_brigade *brigade; const char *mime_type, *filename; VALUE vbrigade, vmime_type, vfilename; rast_error_t *error; rb_scan_args(argc, argv, "21", &vbrigade, &vmime_type, &vfilename); brigade = rast_rb_get_brigade(vbrigade); mime_type = rast_rb_get_safe_string_ptr(vmime_type); filename = rast_rb_get_safe_string_ptr(vfilename); error = rast_filter_chain_invoke(chain, brigade, mime_type, filename); rast_rb_raise_error(error); return Qnil; } static rast_property_t * get_properties(apr_pool_t *pool, VALUE vproperties, int *num_properties) { rast_property_t *properties; int i; Check_Type(vproperties, T_ARRAY); properties = (rast_property_t *) apr_palloc(pool, sizeof(rast_property_t) * RARRAY(vproperties)->len); for (i = 0; i < RARRAY(vproperties)->len; i++) { VALUE vproperty = RARRAY(vproperties)->ptr[i]; rast_property_t *property = properties + i; Check_Type(vproperty, T_HASH); property->name = rast_rb_hash_get_string(pool, vproperty, "name"); property->type = rast_rb_hash_get_property_type(vproperty, "type"); property->flags = 0; if (rast_rb_hash_get_bool(vproperty, "search")) { property->flags |= RAST_PROPERTY_FLAG_SEARCH; } if (rast_rb_hash_get_bool(vproperty, "text_search")) { property->flags |= RAST_PROPERTY_FLAG_TEXT_SEARCH; } if (rast_rb_hash_get_bool(vproperty, "full_text_search")) { property->flags |= RAST_PROPERTY_FLAG_FULL_TEXT_SEARCH; } if (rast_rb_hash_get_bool(vproperty, "unique")) { property->flags |= RAST_PROPERTY_FLAG_UNIQUE; } if (rast_rb_hash_get_bool(vproperty, "omit_property")) { property->flags |= RAST_PROPERTY_FLAG_OMIT; } } *num_properties = RARRAY(vproperties)->len; return properties; } static VALUE process_db_s_create(VALUE self, VALUE vname, VALUE voptions, rast_error_t *(*create)(const char *name, rast_db_create_option_t *options, apr_pool_t *pool)) { VALUE vpool; apr_pool_t *pool; VALUE properties; char *name; rast_db_create_option_t *options; pool = rast_rb_pool_new(&vpool); SafeStringValue(vname); name = RSTRING(vname)->ptr; options = rast_db_create_option_create(pool); Check_Type(voptions, T_HASH); rast_rb_get_int_option(voptions, "byte_order", (int *) &options->byte_order); rast_rb_get_int_option(voptions, "pos_block_size", (int *) &options->pos_block_size); rast_rb_get_string_option(voptions, "encoding", &options->encoding); rast_rb_get_bool_option(voptions, "preserve_text", &options->preserve_text); properties = rb_hash_aref(voptions, rb_str_new2("properties")); options->properties = get_properties(pool, properties, &options->num_properties); rast_rb_raise_error(create(name, options, pool)); return Qnil; } static VALUE local_db_s_create(VALUE self, VALUE vname, VALUE voptions) { return process_db_s_create(self, vname, voptions, rast_local_db_create); } static VALUE db_alloc(VALUE klass) { return Data_Wrap_Struct(klass, NULL, rast_rb_db_free, NULL); } static VALUE db_initialize(int argc, VALUE *argv, VALUE self) { return rast_rb_process_db_initialize(argc, argv, self, rast_db_open); } static VALUE local_db_initialize(int argc, VALUE *argv, VALUE self) { return rast_rb_process_db_initialize(argc, argv, self, rast_local_db_open); } static VALUE db_close(VALUE self) { rast_rb_db_data_t *data; Data_Get_Struct(self, rast_rb_db_data_t, data); rast_rb_raise_error(rast_db_close(data->db)); data->closed = 1; return Qnil; } static VALUE db_s_create(VALUE self, VALUE vname, VALUE voptions) { return process_db_s_create(self, vname, voptions, rast_db_create); } static VALUE process_db_s_optimize(int argc, VALUE *argv, VALUE self, rast_error_t *(*optimize)(const char *, const rast_db_optimize_option_t *, apr_pool_t *)) { VALUE vpool, vname, voptions; apr_pool_t *pool; char *name; rast_db_optimize_option_t *options; pool = rast_rb_pool_new(&vpool); options = rast_db_optimize_option_create(pool); if (rb_scan_args(argc, argv, "11", &vname, &voptions) == 2) { Check_Type(voptions, T_HASH); rast_rb_get_bool_option(voptions, "squeeze_doc_id", &options->squeeze_doc_id); } SafeStringValue(vname); name = RSTRING(vname)->ptr; rast_rb_raise_error(optimize(name, options, pool)); return Qnil; } static VALUE db_s_optimize(int argc, VALUE *argv, VALUE self) { return process_db_s_optimize(argc, argv, self, rast_db_optimize); } static VALUE db_s_open(int argc, VALUE *argv, VALUE self) { VALUE db = rb_class_new_instance(argc, argv, self); if (rb_block_given_p()) { return rb_ensure(rb_yield, db, db_close, db); } return db; } static VALUE db_byte_order(VALUE self) { rast_db_t *db; rast_byte_order_e byte_order; db = rast_rb_get_db(self); byte_order = rast_db_byte_order(db); if (byte_order == RAST_UNKNOWN_ENDIAN) { rb_raise(rast_rb_eRastError, "unknown endian"); } return INT2NUM(byte_order); } static VALUE db_encoding(VALUE self) { rast_db_t *db; const char *encoding; db = rast_rb_get_db(self); encoding = rast_db_encoding(db); if (encoding == NULL) { rb_raise(rast_rb_eRastError, "unknown encoding"); } return rb_tainted_str_new2(encoding); } static VALUE db_properties(VALUE self) { rast_db_t *db; const rast_property_t *properties; VALUE result; int i, num_properties; db = rast_rb_get_db(self); properties = rast_db_properties(db, &num_properties); result = rb_ary_new(); for (i = 0; i < num_properties; i++) { const rast_property_t *property = properties + i; VALUE val, search, text_search, full_text_search, unique; VALUE omit_property; search = property->flags & RAST_PROPERTY_FLAG_SEARCH ? Qtrue : Qfalse; text_search = property->flags & RAST_PROPERTY_FLAG_TEXT_SEARCH ? Qtrue : Qfalse; full_text_search = property->flags & RAST_PROPERTY_FLAG_FULL_TEXT_SEARCH ? Qtrue : Qfalse; unique = property->flags & RAST_PROPERTY_FLAG_UNIQUE ? Qtrue : Qfalse; omit_property = property->flags & RAST_PROPERTY_FLAG_OMIT ? Qtrue : Qfalse; val = rb_funcall(cProperty, rb_intern("new"), 7, rb_tainted_str_new2(property->name), INT2NUM(property->type), search, text_search, full_text_search, unique, omit_property); rb_ary_push(result, val); } return result; } static VALUE db_sync_threshold_chars(VALUE self) { rast_db_t *db = rast_rb_get_db(self); int sync_threshold_chars; sync_threshold_chars = rast_db_sync_threshold_chars(db); if (sync_threshold_chars == -1) { rb_raise(rast_rb_eRastError, "unknown sync_threshold_chars"); } return INT2NUM(sync_threshold_chars); } static rast_value_t * get_property_values(VALUE vproperty_values, rast_db_t *db, apr_pool_t *pool) { const rast_property_t *properties; rast_value_t *property_values; int i, num_properties; properties = rast_db_properties(db, &num_properties); property_values = (rast_value_t *) apr_palloc(pool, sizeof(rast_value_t) * num_properties); for (i = 0; i < num_properties; i++) { const rast_property_t *property = properties + i; VALUE value; value = rb_hash_aref(vproperty_values, rb_str_new2(property->name)); switch (property->type) { case RAST_TYPE_STRING: Check_Type(value, T_STRING); rast_value_set_string(property_values + i, StringValuePtr(value)); break; case RAST_TYPE_DATE: if (TYPE(value) != T_STRING) { value = rb_funcall(value, rb_intern("strftime"), 1, rb_str_new2("%F")); } rast_value_set_date(property_values + i, StringValuePtr(value)); break; case RAST_TYPE_DATETIME: if (TYPE(value) != T_STRING) { value = rb_funcall(value, rb_intern("strftime"), 1, rb_str_new2("%FT%T")); } rast_value_set_datetime(property_values + i, StringValuePtr(value)); break; case RAST_TYPE_UINT: Check_Type(value, T_FIXNUM); rast_value_set_uint(property_values + i, NUM2INT(value)); break; default: rb_raise(rast_rb_eError, "unknown property type"); }; } return property_values; } static VALUE db_register(VALUE self, VALUE text, VALUE vproperty_values) { rast_db_t *db; rast_value_t *property_values; rast_doc_id_t doc_id; rast_error_t *error; apr_pool_t *pool; VALUE vpool; pool = rast_rb_pool_new(&vpool); db = rast_rb_get_db(self); property_values = get_property_values(vproperty_values, db, pool); StringValue(text); error = rast_db_register(db, RSTRING(text)->ptr, RSTRING(text)->len, property_values, &doc_id); rast_rb_raise_error(error); return INT2NUM(doc_id); } static VALUE document_new(rast_document_t *doc) { VALUE obj; obj = Data_Wrap_Struct(cDocument, NULL, document_free, NULL); DATA_PTR(obj) = doc; return obj; } static VALUE db_create_document(VALUE self) { rast_document_t *doc; rast_rb_raise_error(rast_db_create_document(rast_rb_get_db(self), &doc)); return document_new(doc); } const char * get_year_month_day(const char *s, int *year, int *month, int *day) { const char *p = s; *year = atoi(p); p = strchr(p, '-'); if (p == NULL) { *month = 1; *day = 1; return NULL; } p++; *month = atoi(p); p = strchr(p, '-'); if (p == NULL) { *day = 1; return NULL; } p++; *day = atoi(p); return p; } static VALUE get_date(const char *s) { int year, month, day; if (*s == '\0') { return Qnil; } if (get_year_month_day(s, &year, &month, &day) == NULL) { /* todo: parse error */ return Qnil; } return rb_funcall(rast_rb_cDate, rb_intern("new"), 3, INT2NUM(year), INT2NUM(month), INT2NUM(day)); } static VALUE get_date_time(const char *s) { int year, month, day; int hour = 0, minute = 0, second = 0; const char *p; if (*s == '\0') { return Qnil; } p = get_year_month_day(s, &year, &month, &day); if (p == NULL) { /* todo: parse error */ return Qnil; } p = strchr(p, 'T'); if (p != NULL) { p++; hour = atoi(p); p = strchr(p, ':'); if (p != NULL) { p++; minute = atoi(p); p = strchr(p, ':'); if (p != NULL) { p++; second = atoi(p); } } } return rb_funcall(rast_rb_cDateTime, rb_intern("new"), 6, INT2NUM(year), INT2NUM(month), INT2NUM(day), INT2NUM(hour), INT2NUM(minute), INT2NUM(second)); } static VALUE result_new(rast_result_t *result, int num_properties, const char **db_properties, int parse_date) { VALUE terms, term, items, vitem, properties; VALUE property_value_class = Qnil, *symbols; int i, j; terms = rb_ary_new(); for (i = 0; i < result->num_terms; i++) { term = rb_funcall(cResultTerm, rb_intern("new"), 2, rb_tainted_str_new2(result->terms[i].term), INT2NUM(result->terms[i].doc_count)); rb_ary_push(terms, term); } symbols = ALLOCA_N(VALUE, num_properties); for (i = 0; i < num_properties; i++) { symbols[i] = ID2SYM(rb_intern(db_properties[i])); } if (num_properties > 0) { property_value_class = rb_funcall2(rb_cStruct, rb_intern("new"), num_properties, symbols); } items = rb_ary_new(); for (i = 0; i < result->num_items; i++) { rast_result_item_t *item = result->items[i]; if (num_properties > 0) { properties = rb_funcall(property_value_class, rb_intern("new"), 0); } else { properties = Qnil; } vitem = rb_funcall(cResultItem, rb_intern("new"), 5, INT2NUM(item->doc_id), INT2NUM(item->db_index), INT2NUM(item->score), rb_tainted_str_new(item->summary, item->summary_nbytes), properties); for (j = 0; j < num_properties; j++) { rast_value_t *value = item->properties + j; VALUE vvalue; switch (value->type) { case RAST_TYPE_STRING: vvalue = rb_tainted_str_new2(rast_value_string(value)); break; case RAST_TYPE_DATE: if (parse_date) { vvalue = get_date(rast_value_date(value)); } else { vvalue = rb_tainted_str_new2(rast_value_date(value)); } break; case RAST_TYPE_DATETIME: if (parse_date) { vvalue = get_date_time(rast_value_datetime(value)); } else { vvalue = rb_tainted_str_new2(rast_value_datetime(value)); } break; case RAST_TYPE_UINT: vvalue = INT2NUM(rast_value_uint(value)); break; default: vvalue = Qnil; } (void) rb_funcall(properties, rb_intern("[]="), 2, INT2NUM(j), vvalue); } rb_ary_push(items, vitem); } return rb_funcall(cResult, rb_intern("new"), 5, INT2NUM(result->num_indices), INT2NUM(result->num_docs), INT2NUM(result->hit_count), terms, items); } static VALUE db_sync(VALUE self) { rast_db_t *db; db = rast_rb_get_db(self); rast_rb_raise_error(rast_db_sync(db)); return Qnil; } static VALUE db_search(int argc, VALUE *argv, VALUE self) { VALUE query, voptions, properties; rast_db_t *db; rast_error_t *error; rast_search_option_t *options; rast_result_t *result; int i, parse_date = 0; apr_pool_t *pool; VALUE vpool, value; pool = rast_rb_pool_new(&vpool); db = rast_rb_get_db(self); options = rast_search_option_create(pool); if (rb_scan_args(argc, argv, "11", &query, &voptions) == 2) { VALUE terms; Check_Type(voptions, T_HASH); rast_rb_get_bool_option(voptions, "parse_date", &parse_date); rast_rb_get_int_option(voptions, "start_no", (int *) &options->start_no); rast_rb_get_int_option(voptions, "num_items", &options->num_items); options->need_summary = rast_rb_hash_get_bool(voptions, "need_summary"); rast_rb_get_int_option(voptions, "summary_nchars", (int *) &options->summary_nchars); rast_rb_get_int_option(voptions, "sort_order", (int *) &options->sort_order); value = rb_hash_aref(voptions, rb_str_new2("sort_property")); if (!NIL_P(value)) { options->sort_property = apr_pstrdup(pool, StringValuePtr(value)); } rast_rb_get_int_option(voptions, "sort_method", (int *) &options->sort_method); rast_rb_get_int_option(voptions, "score_method", (int *) &options->score_method); rast_rb_get_int_option(voptions, "all_num_docs", (int *) &options->all_num_docs); terms = rb_hash_aref(voptions, rb_str_new2("terms")); if (!NIL_P(terms)) { Check_Type(terms, T_ARRAY); options->num_terms = RARRAY(terms)->len; options->terms = (int *) apr_palloc(pool, sizeof(int) * options->num_terms); for (i = 0; i < options->num_terms; i++) { options->terms[i] = NUM2INT(RARRAY(terms)->ptr[i]); } } properties = rb_hash_aref(voptions, rb_str_new2("properties")); if (!NIL_P(properties)) { int properties_len = sizeof(char *) * RARRAY(properties)->len; Check_Type(properties, T_ARRAY); options->properties = (const char **) apr_palloc(pool, properties_len); for (i = 0; i < RARRAY(properties)->len; i++) { options->properties[i] = StringValuePtr(RARRAY(properties)->ptr[i]); } options->num_properties = RARRAY(properties)->len; } } error = rast_db_search(db, StringValuePtr(query), options, &result, pool); rast_rb_raise_error(error); return result_new(result, options->num_properties, options->properties, parse_date); } static VALUE db_delete(VALUE self, VALUE vdoc_id) { rast_doc_id_t doc_id; rast_db_t *db; doc_id = (rast_doc_id_t) NUM2INT(vdoc_id); db = rast_rb_get_db(self); rast_rb_raise_error(rast_db_delete(db, doc_id)); return Qnil; } static VALUE db_update(VALUE self, VALUE vdoc_id, VALUE text, VALUE vproperty_values) { rast_db_t *db; rast_doc_id_t doc_id, new_doc_id; rast_value_t *property_values; rast_error_t *error; apr_pool_t *pool; VALUE vpool; doc_id = (rast_doc_id_t) NUM2INT(vdoc_id); pool = rast_rb_pool_new(&vpool); db = rast_rb_get_db(self); property_values = get_property_values(vproperty_values, db, pool); StringValue(text); error = rast_db_update(db, doc_id, RSTRING(text)->ptr, RSTRING(text)->len, property_values, &new_doc_id); rast_rb_raise_error(error); return INT2NUM(new_doc_id); } static VALUE db_get_text(VALUE self, VALUE doc_id) { rast_db_t *db; apr_pool_t *pool; VALUE vpool; char *s; rast_size_t len; pool = rast_rb_pool_new(&vpool); db = rast_rb_get_db(self); rast_rb_raise_error(rast_db_get_text(db, NUM2INT(doc_id), &s, &len, pool)); return rb_tainted_str_new(s, len); } static VALUE merger_initialize(int argc, VALUE *argv, VALUE self) { VALUE vdbs; rast_error_t *error; apr_pool_t *pool; rast_rb_db_data_t *data; rast_db_t *db; int i, num_dbs; rast_db_t **dbs; rb_scan_args(argc, argv, "10", &vdbs); rast_rb_pool_create_ex(&pool, NULL, NULL); Check_Type(vdbs, T_ARRAY); num_dbs = RARRAY(vdbs)->len; dbs = (rast_db_t **) apr_palloc(pool, sizeof(rast_db_t *) * num_dbs); for (i = 0; i < num_dbs; i++) { dbs[i] = rast_rb_get_db(RARRAY(vdbs)->ptr[i]); } error = rast_merger_open(&db, dbs, num_dbs, pool); if (error != RAST_OK) { apr_pool_destroy(pool); rast_rb_raise_error(error); } data = ALLOC(rast_rb_db_data_t); data->db = db; data->pool = pool; data->closed = 0; DATA_PTR(self) = data; return Qnil; } void Init_rast() { VALUE cDB, cLocalDB, cMerger; VALUE cFilterChain; apr_initialize(); atexit(apr_terminate); rast_initialize(); atexit(rast_finalize); rast_rb_initialize(); rb_define_const(rast_rb_mRast, "RESULT_ALL_ITEMS", INT2NUM(RAST_RESULT_ALL_ITEMS)); rb_define_const(rast_rb_mRast, "NATIVE_ENDIAN", INT2NUM(RAST_NATIVE_ENDIAN)); rb_define_const(rast_rb_mRast, "LITTLE_ENDIAN", INT2NUM(RAST_LITTLE_ENDIAN)); rb_define_const(rast_rb_mRast, "BIG_ENDIAN", INT2NUM(RAST_BIG_ENDIAN)); cTerm = rb_funcall(rb_cStruct, rb_intern("new"), 2, ID2SYM(rb_intern("term")), ID2SYM(rb_intern("doc_count"))); rb_define_const(rast_rb_mRast, "Term", cTerm); cTermFrequency = rb_funcall(rb_cStruct, rb_intern("new"), 2, ID2SYM(rb_intern("count")), ID2SYM(rb_intern("pos"))); rb_define_const(rast_rb_mRast, "TermFrequency", cTermFrequency); cCandidate = rb_funcall(rb_cStruct, rb_intern("new"), 2, ID2SYM(rb_intern("doc_id")), ID2SYM(rb_intern("terms"))); rb_define_const(rast_rb_mRast, "Candidate", cCandidate); cQueryResult = rb_funcall(rb_cStruct, rb_intern("new"), 2, ID2SYM(rb_intern("terms")), ID2SYM(rb_intern("candidates"))); rb_define_const(rast_rb_mRast, "QueryResult", cQueryResult); cResultTerm = rb_funcall(rb_cStruct, rb_intern("new"), 2, ID2SYM(rb_intern("term")), ID2SYM(rb_intern("doc_count"))); rb_define_const(rast_rb_mRast, "ResultTerm", cResultTerm); cResultItem = rb_funcall(rb_cStruct, rb_intern("new"), 5, ID2SYM(rb_intern("doc_id")), ID2SYM(rb_intern("db_index")), ID2SYM(rb_intern("score")), ID2SYM(rb_intern("summary")), ID2SYM(rb_intern("properties"))); rb_define_const(rast_rb_mRast, "ResultItem", cResultItem); cResult = rb_funcall(rb_cStruct, rb_intern("new"), 5, ID2SYM(rb_intern("num_indices")), ID2SYM(rb_intern("num_docs")), ID2SYM(rb_intern("hit_count")), ID2SYM(rb_intern("terms")), ID2SYM(rb_intern("items"))); rb_define_const(rast_rb_mRast, "Result", cResult); cProperty = rb_funcall(rb_cStruct, rb_intern("new"), 7, ID2SYM(rb_intern("name")), ID2SYM(rb_intern("type")), ID2SYM(rb_intern("search")), ID2SYM(rb_intern("text_search")), ID2SYM(rb_intern("full_text_search")), ID2SYM(rb_intern("unique")), ID2SYM(rb_intern("omit_property"))); rb_define_const(rast_rb_mRast, "Property", cProperty); rb_define_const(rast_rb_mRast, "PROPERTY_TYPE_STRING", INT2NUM(RAST_TYPE_STRING)); rb_define_const(rast_rb_mRast, "PROPERTY_TYPE_UINT", INT2NUM(RAST_TYPE_UINT)); rb_define_const(rast_rb_mRast, "PROPERTY_TYPE_DATE", INT2NUM(RAST_TYPE_DATE)); rb_define_const(rast_rb_mRast, "PROPERTY_TYPE_DATETIME", INT2NUM(RAST_TYPE_DATETIME)); rb_define_const(rast_rb_mRast, "SORT_METHOD_SCORE", INT2NUM(RAST_SORT_METHOD_SCORE)); rb_define_const(rast_rb_mRast, "SORT_METHOD_PROPERTY", INT2NUM(RAST_SORT_METHOD_PROPERTY)); rb_define_const(rast_rb_mRast, "SORT_ORDER_DEFAULT", INT2NUM(RAST_SORT_ORDER_DEFAULT)); rb_define_const(rast_rb_mRast, "SORT_ORDER_ASCENDING", INT2NUM(RAST_SORT_ORDER_ASCENDING)); rb_define_const(rast_rb_mRast, "SORT_ORDER_DESCENDING", INT2NUM(RAST_SORT_ORDER_DESCENDING)); rb_define_const(rast_rb_mRast, "SCORE_METHOD_NONE", INT2NUM(RAST_SCORE_METHOD_NONE)); rb_define_const(rast_rb_mRast, "SCORE_METHOD_TFIDF", INT2NUM(RAST_SCORE_METHOD_TFIDF)); cDB = rb_define_class_under(rast_rb_mRast, "DB", rb_cObject); rb_define_alloc_func(cDB, db_alloc); rb_define_const(cDB, "RDWR", INT2NUM(RAST_DB_RDWR)); rb_define_const(cDB, "RDONLY", INT2NUM(RAST_DB_RDONLY)); rb_define_singleton_method(cDB, "create", db_s_create, 2); rb_define_singleton_method(cDB, "optimize", db_s_optimize, -1); rb_define_singleton_method(cDB, "open", db_s_open, -1); rb_define_method(cDB, "initialize", db_initialize, -1); rb_define_method(cDB, "sync", db_sync, 0); rb_define_method(cDB, "close", db_close, 0); rb_define_method(cDB, "register", db_register, 2); rb_define_method(cDB, "create_document", db_create_document, 0); rb_define_method(cDB, "search", db_search, -1); rb_define_method(cDB, "delete", db_delete, 1); rb_define_method(cDB, "update", db_update, 3); rb_define_method(cDB, "get_text", db_get_text, 1); rb_define_method(cDB, "byte_order", db_byte_order, 0); rb_define_method(cDB, "encoding", db_encoding, 0); rb_define_method(cDB, "properties", db_properties, 0); rb_define_method(cDB, "sync_threshold_chars", db_sync_threshold_chars, 0); cLocalDB = rb_define_class_under(rast_rb_mRast, "LocalDB", cDB); rb_define_singleton_method(cLocalDB, "create", local_db_s_create, 2); rb_define_method(cLocalDB, "initialize", local_db_initialize, -1); cMerger = rb_define_class_under(rast_rb_mRast, "Merger", cDB); rb_define_method(cMerger, "initialize", merger_initialize, -1); cDocument = rb_define_class_under(rast_rb_mRast, "Document", rb_cObject); rb_define_method(cDocument, "doc_id", document_doc_id, 0); rb_define_method(cDocument, "add_text", document_add_text, 1); rb_define_method(cDocument, "set_property", document_set_property, 2); rb_define_method(cDocument, "commit", document_commit, 0); rb_define_method(cDocument, "abort", document_abort, 0); cFilterChain = rb_define_class_under(rast_rb_mRast, "FilterChain", rb_cObject); rb_define_alloc_func(cFilterChain, filter_chain_alloc); rb_define_method(cFilterChain, "initialize", filter_chain_initialize, -1); rb_define_method(cFilterChain, "invoke", filter_chain_invoke, -1); } /* vim: set filetype=c sw=4 expandtab : */