00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024
00025 #include "api_backend.h"
00026
00027 #define XAPIAN_DEPRECATED(X) X
00028 #include <xapian.h>
00029
00030 #include "str.h"
00031 #include "testsuite.h"
00032 #include "testutils.h"
00033 #include "utils.h"
00034
00035 #include "apitest.h"
00036
00037 #include "safefcntl.h"
00038 #include "safesysstat.h"
00039 #include "safeunistd.h"
00040
00041 using namespace std;
00042
00044 DEFINE_TESTCASE(lockfileumask1, brass || chert || flint) {
00045 #if !defined __WIN32__ && !defined __CYGWIN__ && !defined __EMX__
00046 mode_t old_umask = umask(022);
00047 try {
00048 Xapian::WritableDatabase db = get_named_writable_database("lockfileumask1");
00049
00050 string path = get_named_writable_database_path("lockfileumask1");
00051 path += "/flintlock";
00052
00053 struct stat statbuf;
00054 TEST(stat(path, &statbuf) == 0);
00055 TEST_EQUAL(statbuf.st_mode & 0777, 0644);
00056 } catch (...) {
00057 umask(old_umask);
00058 throw;
00059 }
00060
00061 umask(old_umask);
00062 #endif
00063
00064 return true;
00065 }
00066
00068 DEFINE_TESTCASE(totaldoclen1, writable) {
00069 Xapian::WritableDatabase db = get_writable_database();
00070 Xapian::Document doc;
00071 doc.add_posting("foo", 1, 2000000000);
00072 db.add_document(doc);
00073 db.add_document(doc);
00074 TEST_EQUAL(db.get_avlength(), 2000000000);
00075 db.commit();
00076 TEST_EQUAL(db.get_avlength(), 2000000000);
00077 if (get_dbtype() != "inmemory") {
00078
00079 Xapian::Database dbr = get_writable_database_as_database();
00080 TEST_EQUAL(dbr.get_avlength(), 2000000000);
00081 }
00082 return true;
00083 }
00084
00085 DEFINE_TESTCASE(dbstats1, backend) {
00086 Xapian::Database db = get_database("etext");
00087
00088
00089
00090 const Xapian::termcount min_len = 2;
00091 const Xapian::termcount max_len = 532;
00092 const Xapian::termcount max_wdf = 22;
00093
00094 if (get_dbtype().find("chert") != string::npos ||
00095 get_dbtype().find("brass") != string::npos) {
00096
00097 TEST_EQUAL(db.get_doclength_upper_bound(), max_len);
00098 TEST_EQUAL(db.get_doclength_lower_bound(), min_len);
00099 } else {
00100
00101 TEST_REL(db.get_doclength_upper_bound(),>=,max_len);
00102 TEST_REL(db.get_doclength_lower_bound(),<=,min_len);
00103 }
00104
00105 TEST_REL(db.get_wdf_upper_bound("the"),>=,max_wdf);
00106
00107 return true;
00108 }
00109
00111 DEFINE_TESTCASE(alldocspl3, backend) {
00112 Xapian::Database db = get_database(string());
00113
00114 TEST_EQUAL(db.get_termfreq(string()), 0);
00115 TEST_EQUAL(db.get_collection_freq(string()), 0);
00116 TEST(db.postlist_begin(string()) == db.postlist_end(string()));
00117
00118 return true;
00119 }
00120
00122 DEFINE_TESTCASE(modifiedpostlist1, writable) {
00123 Xapian::WritableDatabase db = get_writable_database();
00124 Xapian::Document a, b;
00125 Xapian::Enquire enq(db);
00126
00127 a.add_term("T");
00128 enq.set_query(Xapian::Query("T"));
00129
00130 db.replace_document(2, a);
00131 db.commit();
00132 db.replace_document(1, a);
00133 db.replace_document(1, b);
00134
00135 mset_expect_order(enq.get_mset(0, 2), 2);
00136
00137 return true;
00138 }
00139
00141 DEFINE_TESTCASE(doclenaftercommit1, writable) {
00142 Xapian::WritableDatabase db = get_writable_database();
00143 TEST_EXCEPTION(Xapian::DocNotFoundError, db.get_doclength(1));
00144 db.replace_document(1, Xapian::Document());
00145 db.commit();
00146 TEST_EQUAL(db.get_doclength(1), 0);;
00147 return true;
00148 }
00149
00150 DEFINE_TESTCASE(valuesaftercommit1, writable) {
00151 Xapian::WritableDatabase db = get_writable_database();
00152 Xapian::Document doc;
00153 doc.add_value(0, "value");
00154 db.replace_document(2, doc);
00155 db.commit();
00156 db.replace_document(1, doc);
00157 db.replace_document(3, doc);
00158 TEST_EQUAL(db.get_document(3).get_value(0), "value");
00159 db.commit();
00160 TEST_EQUAL(db.get_document(3).get_value(0), "value");
00161 return true;
00162 }
00163
00164 DEFINE_TESTCASE(lockfilefd0or1, brass || chert || flint) {
00165 #if !defined __WIN32__ && !defined __CYGWIN__ && !defined __EMX__
00166 int old_stdin = dup(0);
00167 int old_stdout = dup(1);
00168 try {
00169
00170 close(0);
00171 {
00172 Xapian::WritableDatabase db = get_writable_database();
00173 TEST_EXCEPTION(Xapian::DatabaseLockError,
00174 (void)get_writable_database_again());
00175 }
00176
00177 close(1);
00178 {
00179 Xapian::WritableDatabase db = get_writable_database();
00180 TEST_EXCEPTION(Xapian::DatabaseLockError,
00181 (void)get_writable_database_again());
00182 }
00183
00184 dup2(old_stdin, 0);
00185 {
00186 Xapian::WritableDatabase db = get_writable_database();
00187 TEST_EXCEPTION(Xapian::DatabaseLockError,
00188 (void)get_writable_database_again());
00189 }
00190 } catch (...) {
00191 dup2(old_stdin, 0);
00192 dup2(old_stdout, 1);
00193 close(old_stdin);
00194 close(old_stdout);
00195 throw;
00196 }
00197
00198 dup2(old_stdout, 1);
00199 close(old_stdin);
00200 close(old_stdout);
00201 #endif
00202
00203 return true;
00204 }
00205
00207 DEFINE_TESTCASE(lockfilealreadyopen1, brass || chert) {
00208 string path = get_named_writable_database_path("lockfilealreadyopen1");
00209 int fd = ::open((path + "/flintlock").c_str(), O_RDONLY);
00210 try {
00211 Xapian::WritableDatabase db(path, Xapian::DB_CREATE_OR_OPEN);
00212 TEST_EXCEPTION(Xapian::DatabaseLockError,
00213 Xapian::WritableDatabase db2(path, Xapian::DB_CREATE_OR_OPEN)
00214 );
00215 } catch (...) {
00216 close(fd);
00217 throw;
00218 }
00219 close(fd);
00220
00221 return true;
00222 }
00223
00224 struct MyMatchDecider : public Xapian::MatchDecider {
00225 mutable bool called;
00226
00227 MyMatchDecider() : called(false) { }
00228
00229 bool operator()(const Xapian::Document &) const {
00230 called = true;
00231 return true;
00232 }
00233 };
00234
00236 DEFINE_TESTCASE(matchdecider4, remote) {
00237 Xapian::Database db(get_database("apitest_simpledata"));
00238 Xapian::Enquire enquire(db);
00239 enquire.set_query(Xapian::Query("paragraph"));
00240
00241 MyMatchDecider mdecider, mspyold;
00242 Xapian::MSet mset;
00243
00244 TEST_EXCEPTION(Xapian::UnimplementedError,
00245 mset = enquire.get_mset(0, 10, NULL, &mdecider));
00246 TEST(!mdecider.called);
00247
00248 TEST_EXCEPTION(Xapian::UnimplementedError,
00249 mset = enquire.get_mset(0, 10, 0, NULL, NULL, &mspyold));
00250 TEST(!mspyold.called);
00251
00252 TEST_EXCEPTION(Xapian::UnimplementedError,
00253 mset = enquire.get_mset(0, 10, 0, NULL, &mdecider, &mspyold));
00254 TEST(!mdecider.called);
00255 TEST(!mspyold.called);
00256
00257 return true;
00258 }
00259
00263 DEFINE_TESTCASE(replacedoc7, writable && !inmemory && !remote) {
00264
00265
00266
00267
00268
00269 Xapian::WritableDatabase db(get_writable_database());
00270 Xapian::Document doc;
00271 doc.set_data("fish");
00272 doc.add_term("Hlocalhost");
00273 doc.add_posting("hello", 1);
00274 doc.add_posting("world", 2);
00275 doc.add_value(1, "myvalue");
00276 db.add_document(doc);
00277 db.commit();
00278
00279
00280
00281
00282
00283 doc.add_term("XREV2");
00284 db.add_document(doc);
00285
00286 for (int i = 0; i < 10000; ++i) {
00287 doc = db.get_document(1);
00288 db.replace_document(1, doc);
00289 }
00290
00291 Xapian::Database rodb(get_writable_database_as_database());
00292 TEST_EQUAL(rodb.get_doccount(), 1);
00293
00294 db.flush();
00295 rodb.reopen();
00296
00297 TEST_EQUAL(rodb.get_doccount(), 2);
00298 return true;
00299 }
00300
00305 DEFINE_TESTCASE(replacedoc8, writable) {
00306 Xapian::WritableDatabase db(get_writable_database());
00307 {
00308 Xapian::Document doc;
00309 doc.set_data("fish");
00310 doc.add_term("takeaway");
00311 db.add_document(doc);
00312 }
00313 db.delete_document(1);
00314 {
00315 Xapian::Document doc;
00316 doc.set_data("chips");
00317 doc.add_term("takeaway", 2);
00318 db.replace_document(1, doc);
00319 }
00320 db.flush();
00321 TEST_EQUAL(db.get_collection_freq("takeaway"), 2);
00322 Xapian::PostingIterator p = db.postlist_begin("takeaway");
00323 TEST(p != db.postlist_end("takeaway"));
00324 TEST_EQUAL(p.get_wdf(), 2);
00325 return true;
00326 }
00327
00329 DEFINE_TESTCASE(databasemodified1, writable && !inmemory && !remote) {
00330
00331
00332
00333
00334 Xapian::WritableDatabase db(get_writable_database());
00335 Xapian::Document doc;
00336 doc.set_data("cargo");
00337 doc.add_term("abc");
00338 doc.add_term("def");
00339 doc.add_term("ghi");
00340 const int N = 500;
00341 for (int i = 0; i < N; ++i) {
00342 db.add_document(doc);
00343 }
00344 db.commit();
00345
00346 Xapian::Database rodb(get_writable_database_as_database());
00347 db.add_document(doc);
00348 db.commit();
00349
00350 db.add_document(doc);
00351 db.commit();
00352
00353 db.add_document(doc);
00354 try {
00355 TEST_EQUAL(*rodb.termlist_begin(N - 1), "abc");
00356 return false;
00357 } catch (const Xapian::DatabaseModifiedError &) {
00358 }
00359
00360 try {
00361 Xapian::Enquire enq(rodb);
00362 enq.set_query(Xapian::Query("abc"));
00363 Xapian::MSet mset = enq.get_mset(0, 10);
00364 return false;
00365 } catch (const Xapian::DatabaseModifiedError &) {
00366 }
00367
00368 return true;
00369 }
00370
00372 DEFINE_TESTCASE(qpmemoryleak1, writable && !inmemory) {
00373
00374 Xapian::WritableDatabase wdb(get_writable_database());
00375 Xapian::Document doc;
00376
00377 doc.add_term("foo");
00378 for (int i = 100; i < 120; ++i) {
00379 doc.add_term(str(i));
00380 }
00381
00382 for (int j = 0; j < 50; ++j) {
00383 wdb.add_document(doc);
00384 }
00385 wdb.commit();
00386
00387 Xapian::Database database(get_writable_database_as_database());
00388 Xapian::QueryParser queryparser;
00389 queryparser.set_database(database);
00390 TEST_EXCEPTION(Xapian::DatabaseModifiedError,
00391 for (int k = 0; k < 3; ++k) {
00392 wdb.add_document(doc);
00393 wdb.commit();
00394 (void)queryparser.parse_query("1", queryparser.FLAG_PARTIAL);
00395 }
00396 );
00397
00398 return true;
00399 }
00400
00401 static void
00402 make_msize1_db(Xapian::WritableDatabase &db, const string &)
00403 {
00404 const char * value0 =
00405 "ABBCDEFGHIJKLMMNOPQQRSTTUUVVWXYZZaabcdefghhijjkllmnopqrsttuvwxyz";
00406 const char * value1 =
00407 "EMLEMMMMMMMNMMLMELEDNLEDMLMLDMLMLMLMEDGFHPOPBAHJIQJNGRKCGF";
00408 while (*value0) {
00409 Xapian::Document doc;
00410 doc.add_value(0, string(1, *value0++));
00411 if (*value1) {
00412 doc.add_value(1, string(1, *value1++));
00413 doc.add_term("K1");
00414 }
00415 db.add_document(doc);
00416 }
00417 }
00418
00420 DEFINE_TESTCASE(msize1, generated) {
00421 Xapian::Database db = get_database("msize1", make_msize1_db);
00422 Xapian::Enquire enq(db);
00423 enq.set_sort_by_value(1, false);
00424 enq.set_collapse_key(0);
00425 enq.set_query(Xapian::Query("K1"));
00426
00427 Xapian::MSet mset = enq.get_mset(0, 10, 1000);
00428 Xapian::doccount lb = mset.get_matches_lower_bound();
00429 Xapian::doccount ub = mset.get_matches_upper_bound();
00430 Xapian::doccount est = mset.get_matches_estimated();
00431 TEST_EQUAL(lb, ub);
00432 TEST_EQUAL(lb, est);
00433
00434 Xapian::MSet mset2 = enq.get_mset(50, 10, 1000);
00435 Xapian::doccount lb2 = mset2.get_matches_lower_bound();
00436 Xapian::doccount ub2 = mset2.get_matches_upper_bound();
00437 Xapian::doccount est2 = mset2.get_matches_estimated();
00438 TEST_EQUAL(lb2, ub2);
00439 TEST_EQUAL(lb2, est2);
00440 TEST_EQUAL(est, est2);
00441
00442 Xapian::MSet mset3 = enq.get_mset(0, 60);
00443 Xapian::doccount lb3 = mset3.get_matches_lower_bound();
00444 Xapian::doccount ub3 = mset3.get_matches_upper_bound();
00445 Xapian::doccount est3 = mset3.get_matches_estimated();
00446 TEST_EQUAL(lb3, ub3);
00447 TEST_EQUAL(lb3, est3);
00448 TEST_EQUAL(est, est3);
00449
00450 return true;
00451 }
00452
00453 static void
00454 make_msize2_db(Xapian::WritableDatabase &db, const string &)
00455 {
00456 const char * value0 = "AAABCDEEFGHIIJJKLLMNNOOPPQQRSTTUVWXYZ";
00457 const char * value1 = "MLEMNMLMLMEDEDEMLEMLMLMLPOAHGF";
00458 while (*value0) {
00459 Xapian::Document doc;
00460 doc.add_value(0, string(1, *value0++));
00461 if (*value1) {
00462 doc.add_value(1, string(1, *value1++));
00463 doc.add_term("K1");
00464 }
00465 db.add_document(doc);
00466 }
00467 }
00468
00470 DEFINE_TESTCASE(msize2, generated) {
00471 Xapian::Database db = get_database("msize2", make_msize2_db);
00472 Xapian::Enquire enq(db);
00473 enq.set_sort_by_value(1, false);
00474 enq.set_collapse_key(0);
00475 enq.set_query(Xapian::Query("K1"));
00476
00477 Xapian::MSet mset = enq.get_mset(0, 10, 1000);
00478 Xapian::doccount lb = mset.get_matches_lower_bound();
00479 Xapian::doccount ub = mset.get_matches_upper_bound();
00480 Xapian::doccount est = mset.get_matches_estimated();
00481 TEST_EQUAL(lb, ub);
00482 TEST_EQUAL(lb, est);
00483
00484 Xapian::MSet mset2 = enq.get_mset(50, 10, 1000);
00485 Xapian::doccount lb2 = mset2.get_matches_lower_bound();
00486 Xapian::doccount ub2 = mset2.get_matches_upper_bound();
00487 Xapian::doccount est2 = mset2.get_matches_estimated();
00488 TEST_EQUAL(lb2, ub2);
00489 TEST_EQUAL(lb2, est2);
00490 TEST_EQUAL(est, est2);
00491
00492 Xapian::MSet mset3 = enq.get_mset(0, 60);
00493 Xapian::doccount lb3 = mset3.get_matches_lower_bound();
00494 Xapian::doccount ub3 = mset3.get_matches_upper_bound();
00495 Xapian::doccount est3 = mset3.get_matches_estimated();
00496 TEST_EQUAL(lb3, ub3);
00497 TEST_EQUAL(lb3, est3);
00498 TEST_EQUAL(est, est3);
00499
00500 return true;
00501 }
00502
00503 static void
00504 make_xordecay1_db(Xapian::WritableDatabase &db, const string &)
00505 {
00506 for (int n = 1; n != 50; ++n) {
00507 Xapian::Document doc;
00508 for (int i = 1; i != 50; ++i) {
00509 if (n % i == 0)
00510 doc.add_term("N" + str(i));
00511 }
00512 db.add_document(doc);
00513 }
00514 }
00515
00517 DEFINE_TESTCASE(xordecay1, generated) {
00518 Xapian::Database db = get_database("xordecay1", make_xordecay1_db);
00519 Xapian::Enquire enq(db);
00520 enq.set_query(Xapian::Query(Xapian::Query::OP_XOR,
00521 Xapian::Query("N10"),
00522 Xapian::Query(Xapian::Query::OP_OR,
00523 Xapian::Query("N2"),
00524 Xapian::Query("N3"))));
00525 Xapian::MSet mset1 = enq.get_mset(0, 1);
00526 Xapian::MSet msetall = enq.get_mset(0, db.get_doccount());
00527
00528 TEST(mset_range_is_same(mset1, 0, msetall, 0, mset1.size()));
00529 return true;
00530 }
00531
00532 static void
00533 make_ordecay_db(Xapian::WritableDatabase &db, const string &)
00534 {
00535 const char * p = "VJ=QC]LUNTaARLI;715RR^];A4O=P4ZG<2CS4EM^^VS[A6QENR";
00536 for (int d = 0; p[d]; ++d) {
00537 int l = int(p[d] - '0');
00538 Xapian::Document doc;
00539 for (int n = 1; n < l; ++n) {
00540 doc.add_term("N" + str(n));
00541 if (n % (d + 1) == 0) {
00542 doc.add_term("M" + str(n));
00543 }
00544 }
00545 db.add_document(doc);
00546 }
00547 }
00548
00550 DEFINE_TESTCASE(ordecay1, generated) {
00551 Xapian::Database db = get_database("ordecay", make_ordecay_db);
00552 Xapian::Enquire enq(db);
00553 enq.set_query(Xapian::Query(Xapian::Query::OP_OR,
00554 Xapian::Query("N20"),
00555 Xapian::Query("N21")));
00556
00557 Xapian::MSet msetall = enq.get_mset(0, db.get_doccount());
00558 for (unsigned int i = 1; i < msetall.size(); ++i) {
00559 Xapian::MSet submset = enq.get_mset(0, i);
00560 TEST(mset_range_is_same(submset, 0, msetall, 0, submset.size()));
00561 }
00562 return true;
00563 }
00564
00568 DEFINE_TESTCASE(ordecay2, generated) {
00569 Xapian::Database db = get_database("ordecay", make_ordecay_db);
00570 Xapian::Enquire enq(db);
00571 std::vector<Xapian::Query> q;
00572 q.push_back(Xapian::Query("M20"));
00573 q.push_back(Xapian::Query("N21"));
00574 q.push_back(Xapian::Query("N22"));
00575 enq.set_query(Xapian::Query(Xapian::Query::OP_OR,
00576 Xapian::Query("N25"),
00577 Xapian::Query(Xapian::Query::OP_AND,
00578 q.begin(),
00579 q.end())));
00580
00581 Xapian::MSet msetall = enq.get_mset(0, db.get_doccount());
00582 for (unsigned int i = 1; i < msetall.size(); ++i) {
00583 Xapian::MSet submset = enq.get_mset(0, i);
00584 TEST(mset_range_is_same(submset, 0, msetall, 0, submset.size()));
00585 }
00586 return true;
00587 }
00588
00589 static void
00590 make_orcheck_db(Xapian::WritableDatabase &db, const string &)
00591 {
00592 static const int t1[6] = {2, 4, 6, 8, 10, 0};
00593 static const int t2[11] = {6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 0};
00594 static const int t3[11] = {3, 7, 8, 11, 12, 13, 14, 15, 16, 17, 0};
00595
00596 for (unsigned i = 1; i <= 17; ++i) {
00597 Xapian::Document doc;
00598 db.replace_document(i, doc);
00599 }
00600 for (const int * p = t1; *p != 0; ++p) {
00601 Xapian::Document doc(db.get_document(*p));
00602 doc.add_term("T1");
00603 db.replace_document(*p, doc);
00604 }
00605 for (const int * p = t2; *p != 0; ++p) {
00606 Xapian::Document doc(db.get_document(*p));
00607 doc.add_term("T2");
00608 if (*p < 17) {
00609 doc.add_term("T2_lowfreq");
00610 }
00611 doc.add_value(2, "1");
00612 db.replace_document(*p, doc);
00613 }
00614 for (const int * p = t3; *p != 0; ++p) {
00615 Xapian::Document doc(db.get_document(*p));
00616 doc.add_term("T3");
00617 if (*p < 17) {
00618 doc.add_term("T3_lowfreq");
00619 }
00620 doc.add_value(3, "1");
00621 db.replace_document(*p, doc);
00622 }
00623 }
00624
00628 DEFINE_TESTCASE(orcheck1, generated) {
00629 Xapian::Database db = get_database("orcheck1", make_orcheck_db);
00630 Xapian::Enquire enq(db);
00631 Xapian::Query q1("T1");
00632 Xapian::Query q2("T2");
00633 Xapian::Query q2l("T2_lowfreq");
00634 Xapian::Query q3("T3");
00635 Xapian::Query q3l("T3_lowfreq");
00636 Xapian::Query v2(Xapian::Query::OP_VALUE_RANGE, 2, "0", "2");
00637 Xapian::Query v3(Xapian::Query::OP_VALUE_RANGE, 3, "0", "2");
00638
00639 tout << "Checking q2 OR q3\n";
00640 enq.set_query(Xapian::Query(Xapian::Query::OP_AND, q1,
00641 Xapian::Query(Xapian::Query::OP_OR, q2, q3)));
00642 mset_expect_order(enq.get_mset(0, db.get_doccount()), 8, 6);
00643
00644 tout << "Checking q2l OR q3\n";
00645 enq.set_query(Xapian::Query(Xapian::Query::OP_AND, q1,
00646 Xapian::Query(Xapian::Query::OP_OR, q2l, q3)));
00647 mset_expect_order(enq.get_mset(0, db.get_doccount()), 8, 6);
00648
00649 tout << "Checking q2 OR q3l\n";
00650 enq.set_query(Xapian::Query(Xapian::Query::OP_AND, q1,
00651 Xapian::Query(Xapian::Query::OP_OR, q2, q3l)));
00652 mset_expect_order(enq.get_mset(0, db.get_doccount()), 8, 6);
00653
00654 tout << "Checking v2 OR q3\n";
00655 enq.set_query(Xapian::Query(Xapian::Query::OP_AND, q1,
00656 Xapian::Query(Xapian::Query::OP_OR, v2, q3)));
00657 mset_expect_order(enq.get_mset(0, db.get_doccount()), 8, 6);
00658
00659 tout << "Checking q2 OR v3\n";
00660 enq.set_query(Xapian::Query(Xapian::Query::OP_AND, q1,
00661 Xapian::Query(Xapian::Query::OP_OR, q2, v3)));
00662
00663
00664 mset_expect_order(enq.get_mset(0, db.get_doccount()), 6, 8);
00665
00666 return true;
00667 }
00668
00673 DEFINE_TESTCASE(failedreplace1, brass || chert || flint) {
00674 Xapian::WritableDatabase db(get_writable_database());
00675 Xapian::Document doc;
00676 doc.add_term("foo");
00677 db.add_document(doc);
00678 Xapian::docid did = db.add_document(doc);
00679 doc.add_term("abc");
00680 doc.add_term(string(1000, 'm'));
00681 doc.add_term("xyz");
00682 TEST_EXCEPTION(Xapian::InvalidArgumentError, db.replace_document(did, doc));
00683 db.commit();
00684 TEST_EQUAL(db.get_doccount(), 0);
00685 TEST_EQUAL(db.get_termfreq("foo"), 0);
00686 return true;
00687 }
00688
00689 DEFINE_TESTCASE(failedreplace2, brass || chert || flint) {
00690 Xapian::WritableDatabase db(get_writable_database("apitest_simpledata"));
00691 db.commit();
00692 Xapian::doccount db_size = db.get_doccount();
00693 Xapian::Document doc;
00694 doc.set_data("wibble");
00695 doc.add_term("foo");
00696 doc.add_value(0, "seven");
00697 db.add_document(doc);
00698 Xapian::docid did = db.add_document(doc);
00699 doc.add_term("abc");
00700 doc.add_term(string(1000, 'm'));
00701 doc.add_term("xyz");
00702 doc.add_value(0, "six");
00703 TEST_EXCEPTION(Xapian::InvalidArgumentError, db.replace_document(did, doc));
00704 db.commit();
00705 TEST_EQUAL(db.get_doccount(), db_size);
00706 TEST_EQUAL(db.get_termfreq("foo"), 0);
00707 return true;
00708 }
00709
00711 DEFINE_TESTCASE(phrase3, positional) {
00712 Xapian::Database db = get_database("apitest_phrase");
00713
00714 const char * phrase_words[] = { "phrase", "near" };
00715 Xapian::Query q(Xapian::Query::OP_NEAR, phrase_words, phrase_words + 2, 12);
00716 q = Xapian::Query(Xapian::Query::OP_AND_MAYBE, Xapian::Query("pad"), q);
00717
00718 Xapian::Enquire enquire(db);
00719 enquire.set_query(q);
00720 Xapian::MSet mset = enquire.get_mset(0, 5);
00721
00722 return true;
00723 }
00724
00726
00727 DEFINE_TESTCASE(msetfirst2, backend) {
00728 Xapian::Database db(get_database("apitest_simpledata"));
00729 Xapian::Enquire enquire(db);
00730 enquire.set_query(Xapian::Query("paragraph"));
00731 Xapian::MSet mset;
00732
00733 mset = enquire.get_mset(0xfffffff0, 1);
00734 TEST_EQUAL(mset.get_firstitem(), 0xfffffff0);
00735
00736 mset = enquire.get_mset(1, 0xfffffff0);
00737 TEST_EQUAL(mset.get_firstitem(), 1);
00738
00739
00740 enquire.set_query(Xapian::Query::MatchNothing);
00741 mset = enquire.get_mset(1, 1);
00742 TEST_EQUAL(mset.get_firstitem(), 1);
00743 return true;
00744 }
00745
00746 DEFINE_TESTCASE(bm25weight2, backend) {
00747 Xapian::Database db(get_database("etext"));
00748 Xapian::Enquire enquire(db);
00749 enquire.set_query(Xapian::Query("the"));
00750 enquire.set_weighting_scheme(Xapian::BM25Weight(0, 0, 0, 0, 1));
00751 Xapian::MSet mset = enquire.get_mset(0, 100);
00752 TEST_REL(mset.size(),>=,2);
00753 Xapian::weight weight0 = mset[0].get_weight();
00754 for (size_t i = 1; i != mset.size(); ++i) {
00755 TEST_EQUAL(weight0, mset[i].get_weight());
00756 }
00757 return true;
00758 }
00759
00760 DEFINE_TESTCASE(tradweight2, backend) {
00761 Xapian::Database db(get_database("etext"));
00762 Xapian::Enquire enquire(db);
00763 enquire.set_query(Xapian::Query("the"));
00764 enquire.set_weighting_scheme(Xapian::TradWeight(0));
00765 Xapian::MSet mset = enquire.get_mset(0, 100);
00766 TEST_REL(mset.size(),>=,2);
00767 Xapian::weight weight0 = mset[0].get_weight();
00768 for (size_t i = 1; i != mset.size(); ++i) {
00769 TEST_EQUAL(weight0, mset[i].get_weight());
00770 }
00771 return true;
00772 }
00773
00774
00775 DEFINE_TESTCASE(emptydb1, backend) {
00776 Xapian::Database db(get_database(string()));
00777 static const Xapian::Query::op ops[] = {
00778 Xapian::Query::OP_AND,
00779 Xapian::Query::OP_OR,
00780 Xapian::Query::OP_AND_NOT,
00781 Xapian::Query::OP_XOR,
00782 Xapian::Query::OP_AND_MAYBE,
00783 Xapian::Query::OP_FILTER,
00784 Xapian::Query::OP_NEAR,
00785 Xapian::Query::OP_PHRASE,
00786 Xapian::Query::OP_ELITE_SET
00787 };
00788 const Xapian::Query::op * p;
00789 for (p = ops; p - ops != sizeof(ops) / sizeof(*ops); ++p) {
00790 tout << *p << endl;
00791 Xapian::Enquire enquire(db);
00792 Xapian::Query query(*p, Xapian::Query("a"), Xapian::Query("b"));
00793 enquire.set_query(query);
00794 Xapian::MSet mset = enquire.get_mset(0, 10);
00795 TEST_EQUAL(mset.get_matches_estimated(), 0);
00796 TEST_EQUAL(mset.get_matches_upper_bound(), 0);
00797 TEST_EQUAL(mset.get_matches_lower_bound(), 0);
00798 }
00799 return true;
00800 }
00801
00803
00804 DEFINE_TESTCASE(stubdb7, !backend) {
00805 TEST_EXCEPTION(Xapian::DatabaseOpeningError,
00806 Xapian::Auto::open_stub("nosuchdirectory"));
00807 TEST_EXCEPTION(Xapian::DatabaseOpeningError,
00808 Xapian::Auto::open_stub("nosuchdirectory", Xapian::DB_OPEN));
00809 return true;
00810 }
00811
00813
00814
00815 DEFINE_TESTCASE(msetweights1, backend) {
00816 Xapian::Database db = get_database("apitest_simpledata");
00817 Xapian::Enquire enq(db);
00818 Xapian::Query q(Xapian::Query::OP_OR,
00819 Xapian::Query("paragraph"),
00820 Xapian::Query("word"));
00821 enq.set_query(q);
00822
00823
00824 Xapian::MSet mset = enq.get_mset(0, 4);
00825
00826 static const struct { Xapian::docid did; double wt; } expected[] = {
00827 { 2, 1.2058248004573934864 },
00828 { 4, 0.81127876655507624726 },
00829 { 1, 0.17309550762546158098 },
00830 { 3, 0.14609528172558261527 }
00831 };
00832
00833 TEST_EQUAL(mset.size(), sizeof(expected) / sizeof(expected[0]));
00834 for (size_t i = 0; i < mset.size(); ++i) {
00835 TEST_EQUAL(*mset[i], expected[i].did);
00836 TEST_EQUAL_DOUBLE(mset[i].get_weight(), expected[i].wt);
00837 }
00838
00839
00840
00841 enq.set_query(Xapian::Query("one"));
00842 mset = enq.get_mset(0, 3);
00843
00844 static const struct { Xapian::docid did; double wt; } expected2[] = {
00845 { 6, 0.73354729848273669823 },
00846 { 2, 0.45626501034348893038 }
00847 };
00848
00849 TEST_EQUAL(mset.size(), sizeof(expected2) / sizeof(expected2[0]));
00850 for (size_t i = 0; i < mset.size(); ++i) {
00851 TEST_EQUAL(*mset[i], expected2[i].did);
00852 TEST_EQUAL_DOUBLE(mset[i].get_weight(), expected2[i].wt);
00853 }
00854
00855 return true;
00856 }