xapian-core  1.4.20
api_compact.cc
Go to the documentation of this file.
1 
4 /* Copyright (C) 2009,2010,2011,2012,2013,2015,2016,2017,2018,2019 Olly Betts
5  * Copyright (C) 2010 Richard Boulton
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20  * USA
21  */
22 
23 #include <config.h>
24 
25 #include "api_compact.h"
26 
27 #include <xapian.h>
28 
29 #include "apitest.h"
30 #include "dbcheck.h"
31 #include "filetests.h"
32 #include "msvcignoreinvalidparam.h"
33 #include "str.h"
34 #include "testsuite.h"
35 #include "testutils.h"
36 
37 #include <cerrno>
38 #include <cstdlib>
39 #include <fstream>
40 
41 #include <sys/types.h>
42 #include "safesysstat.h"
43 #include "safefcntl.h"
44 #include "safeunistd.h"
45 
46 #include "unixcmds.h"
47 
48 using namespace std;
49 
50 static void
52 {
53  // Need non-const pointer for strtoul(), but data isn't modified.
54  char * p = const_cast<char *>(s.c_str());
55 
56  while (*p) {
57  bool del = (*p == '!');
58  if (del) ++p;
59  Xapian::docid first = strtoul(p, &p, 10);
60  Xapian::docid last = first;
61  if (*p == '-') {
62  last = strtoul(p + 1, &p, 10);
63  }
64  if (*p && *p != ' ') {
65  tout << p - s.c_str() << endl;
66  FAIL_TEST("Bad sparse db spec (expected space): " << s);
67  }
68  if (first > last) {
69  FAIL_TEST("Bad sparse db spec (first > last): " << s);
70  }
71 
72  do {
73  if (del) {
74  db.delete_document(first);
75  } else {
76  Xapian::Document doc;
77  string id = str(first);
78  doc.set_data(id);
79  doc.add_term("Q" + str(first));
80  doc.add_term(string(first % 7 + 1, char((first % 26) + 'a')));
81  db.replace_document(first, doc);
82  }
83  } while (first++ < last);
84 
85  if (*p == '\0') break;
86  ++p;
87  }
88 
89  db.commit();
90 }
91 
92 static void
93 check_sparse_uid_terms(const string & path)
94 {
95  Xapian::Database db(path);
97  for (t = db.allterms_begin("Q"); t != db.allterms_end("Q"); ++t) {
98  Xapian::docid did = atoi((*t).c_str() + 1);
100  TEST_EQUAL(*p, did);
101  }
102 }
103 
104 // With multi the docids in the shards change the behaviour.
105 DEFINE_TESTCASE(compactnorenumber1, compact && generated && !multi) {
106  string a = get_database_path("compactnorenumber1a", make_sparse_db,
107  "5-7 24 76 987 1023-1027 9999 !9999");
108  string a_uuid;
109  {
110  Xapian::Database db(a);
111  a_uuid = db.get_uuid();
112  }
113  string b = get_database_path("compactnorenumber1b", make_sparse_db,
114  "1027-1030");
115  string c = get_database_path("compactnorenumber1c", make_sparse_db,
116  "1028-1040");
117  string d = get_database_path("compactnorenumber1d", make_sparse_db,
118  "3000 999999 !999999");
119 
120  string out = get_compaction_output_path("compactnorenumber1out");
121 
122  rm_rf(out);
123  {
124  Xapian::Database db(a);
126  }
127 
129 
130  {
131  TEST(!dir_exists(out + "/donor"));
132  Xapian::Database db(out);
133  // xapian-compact should change the UUID of the database, but didn't
134  // prior to 1.0.18/1.1.4.
135  string out_uuid = db.get_uuid();
136  TEST_NOT_EQUAL(a_uuid, out_uuid);
137  TEST_EQUAL(out_uuid.size(), 36);
138  TEST_NOT_EQUAL(out_uuid, "00000000-0000-0000-0000-000000000000");
139 
140  // White box test - ensure that the donor database is removed.
141  TEST(!dir_exists(out + "/donor"));
142  }
143 
144  rm_rf(out);
145  {
146  Xapian::Database db;
150  }
152  {
153  // Check that xapian-compact is producing a consistent database. Also,
154  // regression test - xapian 1.1.4 set lastdocid to 0 in the output
155  // database.
156  Xapian::Database outdb(out);
157  dbcheck(outdb, 24, 9999);
158  }
159 
160  rm_rf(out);
161  {
162  Xapian::Database db;
167  }
169 
170  rm_rf(out);
171  {
172  Xapian::Database db;
177  }
179 
180  // Should fail.
181  rm_rf(out);
182  {
183  Xapian::Database db;
188  );
189  }
190 
191  // Should fail.
192  rm_rf(out);
193  {
194  Xapian::Database db;
199  );
200  }
201 
202  // Should fail.
203  rm_rf(out);
204  {
205  Xapian::Database db;
211  );
212  }
213 
214  // Should fail.
215  rm_rf(out);
216  {
217  Xapian::Database db;
223  );
224  }
225 
226  // Should fail.
227  rm_rf(out);
228  {
229  Xapian::Database db;
235  );
236  }
237 }
238 
239 // Test use of compact to merge two databases.
240 DEFINE_TESTCASE(compactmerge1, compact) {
241  string indbpath = get_database_path("apitest_simpledata");
242  string outdbpath = get_compaction_output_path("compactmerge1out");
243  rm_rf(outdbpath);
244 
245  const string& dbtype = get_dbtype();
246  bool singlefile = startswith(dbtype, "singlefile_");
247  {
248  Xapian::Database db;
249  db.add_database(Xapian::Database(indbpath));
250  db.add_database(Xapian::Database(indbpath));
251  if (singlefile) {
252  db.compact(outdbpath, Xapian::DBCOMPACT_SINGLE_FILE);
253  } else {
254  db.compact(outdbpath);
255  }
256  }
257 
258  Xapian::Database indb(get_database("apitest_simpledata"));
259  Xapian::Database outdb(outdbpath);
260 
261  TEST_EQUAL(indb.get_doccount() * 2, outdb.get_doccount());
262  dbcheck(outdb, outdb.get_doccount(), outdb.get_doccount());
263 
264  if (singlefile) {
265  // Check we actually got a single file out.
266  TEST(file_exists(outdbpath));
267  TEST_EQUAL(Xapian::Database::check(outdbpath, 0, &tout), 0);
268  } else if (startswith(dbtype, "multi_")) {
269  // Can't check tables for a sharded DB.
270  TEST_EQUAL(Xapian::Database::check(outdbpath, 0, &tout), 0);
271  } else {
272  // Check we got a directory out, not a file.
273  TEST(dir_exists(outdbpath));
274  static const char* const suffixes[] = {
275  "", "/postlist", "/termlist.", nullptr
276  };
277  for (auto s : suffixes) {
278  string suffix;
279  if (s) {
280  suffix = s;
281  } else {
282  if (get_dbtype() == "chert") {
283  suffix = "/record.DB";
284  } else {
285  suffix = "/docdata." + dbtype;
286  }
287  }
288  tout.str(string());
289  tout << "Trying suffix '" << suffix << "'" << endl;
290  string arg = outdbpath;
291  arg += suffix;
293  }
294  }
295 }
296 
297 static void
299 {
300  int count = 10000;
301 
302  Xapian::Document doc;
303  doc.add_term("a");
304  while (count) {
305  db.add_document(doc);
306  --count;
307  }
308 
309  db.commit();
310 }
311 
312 // Test use of compact on a database which has multiple chunks for a term.
313 // This is a regression test for ticket #427
314 DEFINE_TESTCASE(compactmultichunks1, compact && generated) {
315  string indbpath = get_database_path("compactmultichunks1in",
316  make_multichunk_db, "");
317  string outdbpath = get_compaction_output_path("compactmultichunks1out");
318  rm_rf(outdbpath);
319 
320  {
321  Xapian::Database db(indbpath);
322  db.compact(outdbpath);
323  }
324 
325  Xapian::Database indb(indbpath);
326  Xapian::Database outdb(outdbpath);
327 
328  TEST_EQUAL(indb.get_doccount(), outdb.get_doccount());
329  dbcheck(outdb, outdb.get_doccount(), outdb.get_doccount());
330 }
331 
332 // Test compacting from a stub database directory.
333 DEFINE_TESTCASE(compactstub1, compact) {
334  const char * stubpath = ".stub/compactstub1";
335  const char * stubpathfile = ".stub/compactstub1/XAPIANDB";
336  mkdir(".stub", 0755);
337  mkdir(stubpath, 0755);
338  ofstream stub(stubpathfile);
339  TEST(stub.is_open());
340  stub << "auto ../../" << get_database_path("apitest_simpledata") << endl;
341  stub << "auto ../../" << get_database_path("apitest_simpledata2") << endl;
342  stub.close();
343 
344  string outdbpath = get_compaction_output_path("compactstub1out");
345  rm_rf(outdbpath);
346 
347  {
348  Xapian::Database db(stubpath);
349  db.compact(outdbpath);
350  }
351 
352  Xapian::Database indb(stubpath);
353  Xapian::Database outdb(outdbpath);
354 
355  TEST_EQUAL(indb.get_doccount(), outdb.get_doccount());
356  dbcheck(outdb, outdb.get_doccount(), outdb.get_doccount());
357 }
358 
359 // Test compacting from a stub database file.
360 DEFINE_TESTCASE(compactstub2, compact) {
361  const char * stubpath = ".stub/compactstub2";
362  mkdir(".stub", 0755);
363  ofstream stub(stubpath);
364  TEST(stub.is_open());
365  stub << "auto ../" << get_database_path("apitest_simpledata") << endl;
366  stub << "auto ../" << get_database_path("apitest_simpledata2") << endl;
367  stub.close();
368 
369  string outdbpath = get_compaction_output_path("compactstub2out");
370  rm_rf(outdbpath);
371 
372  {
373  Xapian::Database db(stubpath);
374  db.compact(outdbpath);
375  }
376 
377  Xapian::Database indb(stubpath);
378  Xapian::Database outdb(outdbpath);
379 
380  TEST_EQUAL(indb.get_doccount(), outdb.get_doccount());
381  dbcheck(outdb, outdb.get_doccount(), outdb.get_doccount());
382 }
383 
384 // Test compacting a stub database file to itself.
385 DEFINE_TESTCASE(compactstub3, compact) {
386  const char * stubpath = ".stub/compactstub3";
387  mkdir(".stub", 0755);
388  ofstream stub(stubpath);
389  TEST(stub.is_open());
390  stub << "auto ../" << get_database_path("apitest_simpledata") << endl;
391  stub << "auto ../" << get_database_path("apitest_simpledata2") << endl;
392  stub.close();
393 
394  Xapian::doccount in_docs;
395  {
396  Xapian::Database indb(stubpath);
397  in_docs = indb.get_doccount();
398  indb.compact(stubpath);
399  }
400 
401  Xapian::Database outdb(stubpath);
402 
403  TEST_EQUAL(in_docs, outdb.get_doccount());
404  dbcheck(outdb, outdb.get_doccount(), outdb.get_doccount());
405 }
406 
407 // Test compacting a stub database directory to itself.
408 DEFINE_TESTCASE(compactstub4, compact) {
409  const char * stubpath = ".stub/compactstub4";
410  const char * stubpathfile = ".stub/compactstub4/XAPIANDB";
411  mkdir(".stub", 0755);
412  mkdir(stubpath, 0755);
413  ofstream stub(stubpathfile);
414  TEST(stub.is_open());
415  stub << "auto ../../" << get_database_path("apitest_simpledata") << endl;
416  stub << "auto ../../" << get_database_path("apitest_simpledata2") << endl;
417  stub.close();
418 
419  Xapian::doccount in_docs;
420  {
421  Xapian::Database indb(stubpath);
422  in_docs = indb.get_doccount();
423  indb.compact(stubpath);
424  }
425 
426  Xapian::Database outdb(stubpath);
427 
428  TEST_EQUAL(in_docs, outdb.get_doccount());
429  dbcheck(outdb, outdb.get_doccount(), outdb.get_doccount());
430 }
431 
432 static void
434 {
435  Xapian::Document doc;
436  doc.add_term("foo");
437  db.add_document(doc);
438  db.add_spelling("foo");
439  db.add_synonym("bar", "pub");
440  db.add_synonym("foobar", "foo");
441 
442  db.commit();
443 }
444 
445 static void
447 {
448  Xapian::Document doc;
449  doc.add_term("foo");
450  db.add_document(doc);
451 
452  db.commit();
453 }
454 
455 DEFINE_TESTCASE(compactmissingtables1, compact && generated) {
456  string a = get_database_path("compactmissingtables1a",
458  string b = get_database_path("compactmissingtables1b",
460 
461  string out = get_compaction_output_path("compactmissingtables1out");
462  rm_rf(out);
463 
464  {
465  Xapian::Database db;
468  db.compact(out);
469  }
470 
471  {
472  Xapian::Database db(out);
475  // FIXME: arrange for input b to not have a termlist table.
476 // TEST_EXCEPTION(Xapian::FeatureUnavailableError, db.termlist_begin(1));
477  }
478 }
479 
480 static void
482 {
483  Xapian::Document doc;
484  doc.add_term("bar");
485  db.add_document(doc);
486  db.add_spelling("bar");
487  db.add_synonym("bar", "baa");
488  db.add_synonym("barfoo", "barbar");
489  db.add_synonym("foofoo", "barfoo");
490 
491  db.commit();
492 }
493 
495 DEFINE_TESTCASE(compactmergesynonym1, compact && generated) {
496  string a = get_database_path("compactmergesynonym1a",
498  string b = get_database_path("compactmergesynonym1b",
500 
501  string out = get_compaction_output_path("compactmergesynonym1out");
502  rm_rf(out);
503 
504  {
505  Xapian::Database db;
508  db.compact(out);
509  }
510 
511  {
512  Xapian::Database db(out);
513 
515  TEST_NOT_EQUAL(i, db.spellings_end());
516  TEST_EQUAL(*i, "bar");
517  ++i;
518  TEST_NOT_EQUAL(i, db.spellings_end());
519  TEST_EQUAL(*i, "foo");
520  ++i;
521  TEST_EQUAL(i, db.spellings_end());
522 
523  i = db.synonym_keys_begin();
525  TEST_EQUAL(*i, "bar");
526  ++i;
528  TEST_EQUAL(*i, "barfoo");
529  ++i;
531  TEST_EQUAL(*i, "foobar");
532  ++i;
534  TEST_EQUAL(*i, "foofoo");
535  ++i;
536  TEST_EQUAL(i, db.synonym_keys_end());
537  }
538 }
539 
540 DEFINE_TESTCASE(compactempty1, compact) {
541  string empty_dbpath = get_database_path(string());
542  string outdbpath = get_compaction_output_path("compactempty1out");
543  rm_rf(outdbpath);
544 
545  {
546  // Compacting an empty database tried to divide by zero in 1.3.0.
547  Xapian::Database db;
548  db.add_database(Xapian::Database(empty_dbpath));
549  db.compact(outdbpath);
550 
551  Xapian::Database outdb(outdbpath);
552  TEST_EQUAL(outdb.get_doccount(), 0);
553  dbcheck(outdb, 0, 0);
554  }
555 
556  {
557  // Check compacting two empty databases together.
558  Xapian::Database db;
559  db.add_database(Xapian::Database(empty_dbpath));
560  db.add_database(Xapian::Database(empty_dbpath));
561  db.compact(outdbpath);
562 
563  Xapian::Database outdb(outdbpath);
564  TEST_EQUAL(outdb.get_doccount(), 0);
565  dbcheck(outdb, 0, 0);
566  }
567 }
568 
569 DEFINE_TESTCASE(compactmultipass1, compact && generated) {
570  string outdbpath = get_compaction_output_path("compactmultipass1");
571  rm_rf(outdbpath);
572 
573  string a = get_database_path("compactnorenumber1a", make_sparse_db,
574  "5-7 24 76 987 1023-1027 9999 !9999");
575  string b = get_database_path("compactnorenumber1b", make_sparse_db,
576  "1027-1030");
577  string c = get_database_path("compactnorenumber1c", make_sparse_db,
578  "1028-1040");
579  string d = get_database_path("compactnorenumber1d", make_sparse_db,
580  "3000 999999 !999999");
581 
582  {
583  Xapian::Database db;
588  db.compact(outdbpath, Xapian::DBCOMPACT_MULTIPASS);
589  }
590 
591  Xapian::Database outdb(outdbpath);
592  dbcheck(outdb, 29, 1041);
593 }
594 
595 // Test compacting to an fd.
596 // Chert doesn't support single file databases.
597 DEFINE_TESTCASE(compacttofd1, compact && !chert) {
598  Xapian::Database indb(get_database("apitest_simpledata"));
599  string outdbpath = get_compaction_output_path("compacttofd1out");
600  rm_rf(outdbpath);
601 
602  int fd = open(outdbpath.c_str(), O_CREAT|O_RDWR|O_BINARY, 0666);
603  TEST(fd != -1);
604  indb.compact(fd);
605 
606  // Confirm that the fd was closed by Xapian. Set errno first to workaround
607  // a bug in Wine's msvcrt.dll which fails to set errno in this case:
608  // https://bugs.winehq.org/show_bug.cgi?id=43902
609  errno = EBADF;
610  {
611  MSVCIgnoreInvalidParameter invalid_fd_in_close_is_expected;
612  TEST(close(fd) == -1);
613  TEST_EQUAL(errno, EBADF);
614  }
615 
616  Xapian::Database outdb(outdbpath);
617 
618  TEST_EQUAL(indb.get_doccount(), outdb.get_doccount());
619  dbcheck(outdb, outdb.get_doccount(), outdb.get_doccount());
620 }
621 
622 // Test compacting to an fd at at offset.
623 // Chert doesn't support single file databases.
624 DEFINE_TESTCASE(compacttofd2, compact && !chert) {
625  Xapian::Database indb(get_database("apitest_simpledata"));
626  string outdbpath = get_compaction_output_path("compacttofd2out");
627  rm_rf(outdbpath);
628 
629  int fd = open(outdbpath.c_str(), O_CREAT|O_RDWR|O_BINARY, 0666);
630  TEST(fd != -1);
631  TEST(lseek(fd, 8192, SEEK_SET) == 8192);
632  indb.compact(fd);
633 
634  // Confirm that the fd was closed by Xapian. Set errno first to workaround
635  // a bug in Wine's msvcrt.dll which fails to set errno in this case:
636  // https://bugs.winehq.org/show_bug.cgi?id=43902
637  errno = EBADF;
638  {
639  MSVCIgnoreInvalidParameter invalid_fd_in_close_is_expected;
640  TEST(close(fd) == -1);
641  TEST_EQUAL(errno, EBADF);
642  }
643 
644  fd = open(outdbpath.c_str(), O_RDONLY|O_BINARY, 0666);
645  TEST(fd != -1);
646 
647  // Test that the database wasn't just written to the start of the file.
648  char buf[8192];
649  size_t n = sizeof(buf);
650  while (n) {
651  ssize_t c = read(fd, buf, n);
652  TEST(c > 0);
653  for (const char * p = buf; p != buf + c; ++p) {
654  TEST(*p == 0);
655  }
656  n -= c;
657  }
658 
659  TEST(lseek(fd, 8192, SEEK_SET) == 8192);
660  Xapian::Database outdb(fd);
661 
662  TEST_EQUAL(indb.get_doccount(), outdb.get_doccount());
663  dbcheck(outdb, outdb.get_doccount(), outdb.get_doccount());
664 }
665 
666 // Regression test for bug fixed in 1.3.5. If you compact a WritableDatabase
667 // with uncommitted changes, you get an inconsistent output.
668 //
669 // Chert doesn't support single file databases.
670 DEFINE_TESTCASE(compactsingle1, compact && writable && !chert) {
672  Xapian::Document doc;
673  doc.add_term("foo");
674  doc.add_term("bar");
675  doc.add_term("baz");
676  db.add_document(doc);
677  // Include a zero-length document as a regression test for a
678  // Database::check() bug fixed in 1.4.7 (and introduced in 1.4.6). Test it
679  // here so we also have test coverage for compaction for such a document.
680  Xapian::Document doc2;
681  doc2.add_boolean_term("Kfoo");
682  db.add_document(doc2);
683  // Also test a completely empty document.
685 
686  string output = get_compaction_output_path("compactsingle1-out");
687  // In 1.3.4, we would hang if the output file already existed, so check
688  // that works.
689  touch(output);
690 
693 
694  // Check the file wasn't removed by the failed attempt.
695  TEST(file_exists(output));
696 
697  db.commit();
699  db.close();
700 
701  TEST_EQUAL(Xapian::Database::check(output, 0, &tout), 0);
702 
703  TEST_EQUAL(Xapian::Database(output).get_doccount(), 3);
704 }
705 
706 // Regression test for bug fixed in 1.4.6. Same as above, except not with
707 // a single file database!
708 DEFINE_TESTCASE(compact1, compact && writable) {
710  Xapian::Document doc;
711  doc.add_term("foo");
712  doc.add_term("bar");
713  doc.add_term("baz");
714  db.add_document(doc);
715  // Include a zero-length document as a regression test for a
716  // Database::check() bug fixed in 1.4.7 (and introduced in 1.4.6). Test it
717  // here so we also have test coverage for compaction for such a document.
718  Xapian::Document doc2;
719  doc2.add_boolean_term("Kfoo");
720  db.add_document(doc2);
721  // Also test a completely empty document.
723 
724  string output = get_compaction_output_path("compact1-out");
725  rm_rf(output);
726 
728  db.compact(output));
729 
730  db.commit();
731  db.compact(output);
732  db.close();
733 
734  TEST_EQUAL(Xapian::Database::check(output, 0, &tout), 0);
735 
736  TEST_EQUAL(Xapian::Database(output).get_doccount(), 3);
737 }
int close(FD &fd)
Definition: fd.h:63
Xapian::docid add_document(const Xapian::Document &document)
Add a new document to the database.
Definition: omdatabase.cc:902
static size_t check(const std::string &path, int opts=0, std::ostream *out=NULL)
Check the integrity of a database or database table.
Definition: database.h:560
void dbcheck(const Xapian::Database &db, Xapian::doccount expected_doccount, Xapian::docid expected_lastdocid)
Check consistency of database and statistics.
Definition: dbcheck.cc:126
#define TEST(a)
Test a condition, without an additional explanation for failure.
Definition: testsuite.h:275
This class is used to access a database, or a group of databases.
Definition: database.h:68
Work around MSVC&#39;s unhelpful non-standard invalid parameter handling.
test database contents and consistency.
static void make_missing_tables(Xapian::WritableDatabase &db, const string &)
Definition: api_compact.cc:446
InvalidOperationError indicates the API was used in an invalid way.
Definition: error.h:283
TermIterator allterms_end(const std::string &=std::string()) const
Corresponding end iterator to allterms_begin(prefix).
Definition: database.h:265
Xapian::WritableDatabase get_writable_database(const string &dbname)
Definition: apitest.cc:87
#define O_BINARY
Definition: safefcntl.h:81
a generic test suite engine
C++ function versions of useful Unix commands.
WritableDatabase open()
Construct a WritableDatabase object for a new, empty InMemory database.
Definition: dbfactory.h:104
STL namespace.
Convert types to std::string.
Utility functions for testing files.
void replace_document(Xapian::docid did, const Xapian::Document &document)
Replace a given document in the database.
Definition: omdatabase.cc:952
const int DBCOMPACT_NO_RENUMBER
Use the same document ids in the output as in the input(s).
Definition: constants.h:256
Xapian::doccount get_doccount() const
Get the number of documents in the database.
Definition: omdatabase.cc:267
include <sys/stat.h> with portability enhancements
test functionality of the Xapian API
void rm_rf(const string &filename)
Remove a directory and contents, just like the Unix "rm -rf" command.
Definition: unixcmds.cc:111
static void make_all_tables2(Xapian::WritableDatabase &db, const string &)
Definition: api_compact.cc:481
Class for iterating over a list of terms.
Definition: termiterator.h:41
Class for iterating over a list of terms.
#define TEST_NOT_EQUAL(a, b)
Test for non-equality of two things.
Definition: testsuite.h:305
string get_database_path(const string &dbname)
Definition: apitest.cc:72
This class provides read/write access to a database.
Definition: database.h:785
Xapian::TermIterator spellings_begin() const
An iterator which returns all the spelling correction targets.
Definition: omdatabase.cc:704
static void make_all_tables(Xapian::WritableDatabase &db, const string &)
Definition: api_compact.cc:433
std::ostringstream tout
The debug printing stream.
Definition: testsuite.cc:103
Public interfaces for the Xapian library.
Xapian::TermIterator synonym_keys_begin(const std::string &prefix=std::string()) const
An iterator which returns all terms which have synonyms.
Definition: omdatabase.cc:740
static void make_multichunk_db(Xapian::WritableDatabase &db, const string &)
Definition: api_compact.cc:298
void delete_document(Xapian::docid did)
Delete a document from the database.
Definition: omdatabase.cc:925
#define TEST_EXCEPTION(TYPE, CODE)
Check that CODE throws exactly Xapian exception TYPE.
Definition: testutils.h:109
Xapian::TermIterator synonym_keys_end(const std::string &=std::string()) const
Corresponding end iterator to synonym_keys_begin(prefix).
Definition: database.h:455
std::string get_dbtype()
Definition: apitest.cc:42
string str(int value)
Convert int to std::string.
Definition: str.cc:90
void commit()
Commit any pending modifications made to the database.
Definition: omdatabase.cc:857
DEFINE_TESTCASE(compactnorenumber1, compact &&generated &&!multi)
Definition: api_compact.cc:105
bool startswith(const std::string &s, char pfx)
Definition: stringutils.h:46
TermIterator allterms_begin(const std::string &prefix=std::string()) const
An iterator which runs across all terms with a given prefix.
Definition: omdatabase.cc:223
void compact(const std::string &output, unsigned flags=0, int block_size=0)
Produce a compact version of this database.
Definition: database.h:623
bool dir_exists(const char *path)
Test if a directory exists.
Definition: filetests.h:136
void add_database(const Database &database)
Add an existing database (or group of databases) to those accessed by this object.
Definition: omdatabase.cc:148
std::string get_compaction_output_path(const std::string &name)
Definition: apitest.cc:105
#define FAIL_TEST(MSG)
Fail the current testcase with message MSG.
Definition: testsuite.h:68
Xapian::Database get_database(const string &dbname)
Definition: apitest.cc:48
unsigned XAPIAN_DOCID_BASE_TYPE doccount
A count of documents.
Definition: types.h:38
Xapian-specific test helper functions and macros.
const int DBCOMPACT_MULTIPASS
If merging more than 3 databases, merge the postlists in multiple passes.
Definition: constants.h:262
<unistd.h>, but with compat.
void add_boolean_term(const std::string &term)
Add a boolean filter term to the document.
Definition: document.h:191
Xapian::TermIterator spellings_end() const
Corresponding end iterator to spellings_begin().
Definition: database.h:432
void add_synonym(const std::string &term, const std::string &synonym) const
Add a synonym for a term.
Definition: omdatabase.cc:1028
unsigned XAPIAN_DOCID_BASE_TYPE docid
A unique identifier for a document.
Definition: types.h:52
static void check_sparse_uid_terms(const string &path)
Definition: api_compact.cc:93
#define TEST_EQUAL(a, b)
Test for equality of two things.
Definition: testsuite.h:278
const int DBCOMPACT_SINGLE_FILE
Produce a single-file database.
Definition: constants.h:268
void set_data(const std::string &data)
Set data stored in the document.
Definition: omdocument.cc:78
bool file_exists(const char *path)
Test if a file exists.
Definition: filetests.h:39
virtual void close()
Close the database.
Definition: omdatabase.cc:138
include <fcntl.h>, but working around broken platforms.
A handle representing a document in a Xapian database.
Definition: document.h:61
std::string get_uuid() const
Get a UUID for the database.
Definition: omdatabase.cc:776
void add_spelling(const std::string &word, Xapian::termcount freqinc=1) const
Add a word to the spelling dictionary.
Definition: omdatabase.cc:1004
PostingIterator postlist_begin(const std::string &tname) const
An iterator pointing to the start of the postlist for a given term.
Definition: omdatabase.cc:162
void touch(const string &filename)
Touch a file, just like the Unix "touch" command.
Definition: unixcmds.cc:155
void add_term(const std::string &tname, Xapian::termcount wdfinc=1)
Add a term to the document, without positional information.
Definition: omdocument.cc:140
static void make_sparse_db(Xapian::WritableDatabase &db, const string &s)
Definition: api_compact.cc:51