xapian-core  1.4.22
api_replacedoc.cc
Go to the documentation of this file.
1 
4 /* Copyright 2009 Richard Boulton
5  * Copyright 2015,2016 Olly Betts
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_replacedoc.h"
26 
27 #include <string>
28 
29 using namespace std;
30 
31 #include <xapian.h>
32 #include "testsuite.h"
33 #include "testutils.h"
34 
35 #include "apitest.h"
36 #include "dbcheck.h"
37 
38 // Test that positionlists are updated correctly.
39 DEFINE_TESTCASE(poslistupdate1, positional && writable) {
41 
42  Xapian::Document doc;
43  doc.add_posting("pos", 2);
44  doc.add_posting("pos", 3);
45  db.add_document(doc);
46  db.commit();
47 
48  TEST_EQUAL(docterms_to_string(db, 1), "Term(pos, wdf=2, pos=[2, 3])");
49 
50  doc = db.get_document(1);
51  doc.add_term("pos2");
52  db.replace_document(1, doc);
53  db.commit();
55  "Term(pos, wdf=2, pos=[2, 3]), "
56  "Term(pos2, wdf=1)");
57 
58  doc = db.get_document(1);
59  doc.add_posting("pos3", 1);
60  doc.add_posting("pos3", 5);
61  db.replace_document(1, doc);
62  db.commit();
64  "Term(pos, wdf=2, pos=[2, 3]), "
65  "Term(pos2, wdf=1), "
66  "Term(pos3, wdf=2, pos=[1, 5])");
67 
68  doc = db.get_document(1);
69  doc.remove_term("pos");
70  db.replace_document(1, doc);
71  db.commit();
73  "Term(pos2, wdf=1), "
74  "Term(pos3, wdf=2, pos=[1, 5])");
75 
76  // Regression test: the old positionlist fragment used to be left lying
77  // around here.
78  Xapian::PositionIterator posit(db.positionlist_begin(1, "pos"));
79  TEST(posit == db.positionlist_end(1, "pos"));
80 
81  doc = db.get_document(1);
82  doc.remove_term("pos3");
83  db.replace_document(1, doc);
84  db.commit();
86  "Term(pos2, wdf=1)");
87 
88  // Regression test: the old positionlist fragment used to be left lying
89  // around here.
90  Xapian::PositionIterator posit2(db.positionlist_begin(1, "pos3"));
91  TEST(posit2 == db.positionlist_end(1, "pos3"));
92 
93  doc = db.get_document(1);
94  doc.add_term("pos");
95  db.replace_document(1, doc);
96  db.commit();
98  "Term(pos, wdf=1), "
99  "Term(pos2, wdf=1)");
100 }
101 
102 static Xapian::Document
104  Xapian::Document doc;
105  doc.add_term("z0", 0);
106  doc.add_term("z1", 1);
107  return doc;
108 }
109 
110 static string
112  return ", Term(z0, wdf=0), Term(z1, wdf=1)";
113 }
114 
117 DEFINE_TESTCASE(modtermwdf1, writable) {
119 
120  string bdt(basic_docterms());
121 
122  // Add a simple document.
123  Xapian::Document doc1(basic_doc());
124  doc1.add_term("takeaway", 1);
125  db.add_document(doc1);
126 
127  dbcheck(db, 1, 1);
128  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=1)" + bdt);
129 
130  // Modify the wdf of an existing document, checking stats before commit.
131  Xapian::Document doc2(basic_doc());
132  doc2.add_term("takeaway", 2);
133  db.replace_document(1, doc2);
134  dbcheck(db, 1, 1);
135  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
136 
137  // Remove a term, and then put it back again.
138  Xapian::Document doc0(basic_doc());
139  db.replace_document(1, doc0);
140  dbcheck(db, 1, 1);
141  TEST_EQUAL(docterms_to_string(db, 1), bdt.substr(2));
142  db.replace_document(1, doc1);
143  dbcheck(db, 1, 1);
144  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=1)" + bdt);
145 
146  // Remove a term, commit, then put it back, remove it, and put it back.
147  // This is to test the handling of items in the change cache.
148  db.replace_document(1, doc0);
149  db.commit();
150  db.replace_document(1, doc2);
151  db.replace_document(1, doc0);
152  db.replace_document(1, doc2);
153  db.commit();
154  dbcheck(db, 1, 1);
155  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
156 
157  // Remove a term, and then put it back again without checking stats.
158  db.replace_document(1, doc0);
159  db.replace_document(1, doc2);
160  dbcheck(db, 1, 1);
161  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
162 
163  // Modify a term, and then put it back again without checking stats.
164  db.replace_document(1, doc1);
165  db.replace_document(1, doc2);
166  dbcheck(db, 1, 1);
167  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
168 
169  // Modify the wdf of an existing document, checking stats after commit.
170  Xapian::Document doc3(basic_doc());
171  doc3.add_term("takeaway", 3);
172  db.replace_document(1, doc3);
173  db.commit();
174  dbcheck(db, 1, 1);
175  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=3)" + bdt);
176 
177  // Change a document, without changing its length.
178  Xapian::Document doc3_diff(basic_doc());
179  doc3_diff.add_term("takeaways", 3);
180  db.replace_document(1, doc3_diff);
181  db.commit();
182  dbcheck(db, 1, 1);
183  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaways, wdf=3)" + bdt);
184 
185  // Put it back.
186  db.replace_document(1, doc3);
187  dbcheck(db, 1, 1);
188  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=3)" + bdt);
189 
190  // Modify a document taken from the database.
191  Xapian::Document doc4(db.get_document(1));
192  Xapian::Document doc3a(db.get_document(1)); // need this one later
193  doc3a.termlist_count(); // Pull the document termlist into memory.
194  doc4.add_term("takeaway", 1);
195  db.replace_document(1, doc4);
196  dbcheck(db, 1, 1);
197  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=4)" + bdt);
198 
199  // Add a document which was previously added and then modified.
200  doc1.add_term("takeaway", 1);
201  db.replace_document(1, doc1);
202  dbcheck(db, 1, 1);
203  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
204 
205  // Add back a document which was taken from the database, but never modified.
206  db.replace_document(1, doc3a);
207  dbcheck(db, 1, 1);
208  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=3)" + bdt);
209 
210  // Add a position to the document.
211  Xapian::Document doc5(db.get_document(1));
212  doc5.add_posting("takeaway", 1, 2);
213  db.replace_document(1, doc5);
214  dbcheck(db, 1, 1);
215  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5, pos=[1])" + bdt);
216 
217  // Add a position without changing the wdf.
218  Xapian::Document doc5b(db.get_document(1));
219  doc5b.add_posting("takeaway", 2, 0);
220  db.replace_document(1, doc5b);
221  dbcheck(db, 1, 1);
222  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5, pos=[1, 2])" + bdt);
223 
224  // Delete a position without changing the wdf.
225  Xapian::Document doc5c(basic_doc());
226  doc5c.add_posting("takeaway", 2, 5);
227  db.replace_document(1, doc5c);
228  dbcheck(db, 1, 1);
229  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5, pos=[2])" + bdt);
230 
231  // Delete the other position without changing the wdf.
232  Xapian::Document doc5d(basic_doc());
233  doc5d.add_term("takeaway", 5);
234  db.replace_document(1, doc5d);
235  dbcheck(db, 1, 1);
236  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5)" + bdt);
237 
238  // Reduce the wdf to 0, but don't delete the term.
239  Xapian::Document doc0freq(basic_doc());
240  doc0freq.add_term("takeaway", 0);
241  db.replace_document(1, doc0freq);
242  dbcheck(db, 1, 1);
243  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=0)" + bdt);
244 
245  // Reduce the wdf to 0, and delete the term.
246  db.replace_document(1, doc0);
247  dbcheck(db, 1, 1);
248  TEST_EQUAL(docterms_to_string(db, 1), bdt.substr(2));
249 
250  // Delete the document.
251  db.delete_document(1);
252  dbcheck(db, 0, 1);
254  TEST_EQUAL(postlist_to_string(db, "takeaway"), "");
256  TEST_EQUAL(termstats_to_string(db, "takeaway"), "tf=0,cf=0");
257  TEST_EQUAL(db.get_doccount(), 0);
258  TEST_EQUAL(db.get_avlength(), 0);
259  TEST_EQUAL(db.get_lastdocid(), 1);
260 }
Xapian::Document get_document(Xapian::docid did) const
Get a document from the database, given its document id.
Definition: omdatabase.cc:490
Xapian::docid add_document(const Xapian::Document &document)
Add a new document to the database.
Definition: omdatabase.cc:902
PositionIterator positionlist_end(Xapian::docid, const std::string &) const
Corresponding end iterator to positionlist_begin().
Definition: database.h:252
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
Xapian::termcount termlist_count() const
The length of the termlist - i.e.
Definition: omdocument.cc:191
test database contents and consistency.
PositionIterator positionlist_begin(Xapian::docid did, const std::string &tname) const
An iterator pointing to the start of the position list for a given term in a given document...
Definition: omdatabase.cc:250
Xapian::WritableDatabase get_writable_database(const string &dbname)
Definition: apitest.cc:87
Xapian::docid get_lastdocid() const
Get the highest document id which has been used in the database.
Definition: omdatabase.cc:279
a generic test suite engine
void remove_term(const std::string &tname)
Remove a term and all postings associated with it.
Definition: omdocument.cc:177
STL namespace.
void replace_document(Xapian::docid did, const Xapian::Document &document)
Replace a given document in the database.
Definition: omdatabase.cc:952
Xapian::doccount get_doccount() const
Get the number of documents in the database.
Definition: omdatabase.cc:267
string docstats_to_string(const Xapian::Database &db, Xapian::docid did)
Convert statistics about a document to a string.
Definition: dbcheck.cc:105
test functionality of the Xapian API
Xapian::doclength get_avlength() const
Get the average length of the documents in the database.
Definition: omdatabase.cc:293
string docterms_to_string(const Xapian::Database &db, Xapian::docid did)
Convert the list of terms in a document to a string.
Definition: dbcheck.cc:82
string postlist_to_string(const Xapian::Database &db, const string &tname)
Convert the list of postings in a postlist to a string.
Definition: dbcheck.cc:55
static string basic_docterms()
string termstats_to_string(const Xapian::Database &db, const string &term)
Convert statistics about a term to a string.
Definition: dbcheck.cc:115
This class provides read/write access to a database.
Definition: database.h:785
Public interfaces for the Xapian library.
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
void commit()
Commit any pending modifications made to the database.
Definition: omdatabase.cc:857
Class for iterating over term positions.
Indicates an attempt to access a document not present in the database.
Definition: error.h:674
void add_posting(const std::string &tname, Xapian::termpos tpos, Xapian::termcount wdfinc=1)
Add an occurrence of a term at a particular position.
Definition: omdocument.cc:128
Xapian-specific test helper functions and macros.
DEFINE_TESTCASE(poslistupdate1, positional &&writable)
#define TEST_EQUAL(a, b)
Test for equality of two things.
Definition: testsuite.h:278
A handle representing a document in a Xapian database.
Definition: document.h:61
static Xapian::Document basic_doc()
void add_term(const std::string &tname, Xapian::termcount wdfinc=1)
Add a term to the document, without positional information.
Definition: omdocument.cc:140