xapian-core  1.4.21
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 #include <map>
29 
30 using namespace std;
31 
32 #include <xapian.h>
33 #include "testsuite.h"
34 #include "testutils.h"
35 
36 #include "apitest.h"
37 #include "dbcheck.h"
38 
39 // Test that positionlists are updated correctly.
40 DEFINE_TESTCASE(poslistupdate1, positional && writable) {
42 
43  Xapian::Document doc;
44  doc.add_posting("pos", 2);
45  doc.add_posting("pos", 3);
46  db.add_document(doc);
47  db.commit();
48 
49  TEST_EQUAL(docterms_to_string(db, 1), "Term(pos, wdf=2, pos=[2, 3])");
50 
51  doc = db.get_document(1);
52  doc.add_term("pos2");
53  db.replace_document(1, doc);
54  db.commit();
56  "Term(pos, wdf=2, pos=[2, 3]), "
57  "Term(pos2, wdf=1)");
58 
59  doc = db.get_document(1);
60  doc.add_posting("pos3", 1);
61  doc.add_posting("pos3", 5);
62  db.replace_document(1, doc);
63  db.commit();
65  "Term(pos, wdf=2, pos=[2, 3]), "
66  "Term(pos2, wdf=1), "
67  "Term(pos3, wdf=2, pos=[1, 5])");
68 
69  doc = db.get_document(1);
70  doc.remove_term("pos");
71  db.replace_document(1, doc);
72  db.commit();
74  "Term(pos2, wdf=1), "
75  "Term(pos3, wdf=2, pos=[1, 5])");
76 
77  // Regression test: the old positionlist fragment used to be left lying
78  // around here.
79  Xapian::PositionIterator posit(db.positionlist_begin(1, "pos"));
80  TEST(posit == db.positionlist_end(1, "pos"));
81 
82  doc = db.get_document(1);
83  doc.remove_term("pos3");
84  db.replace_document(1, doc);
85  db.commit();
87  "Term(pos2, wdf=1)");
88 
89  // Regression test: the old positionlist fragment used to be left lying
90  // around here.
91  Xapian::PositionIterator posit2(db.positionlist_begin(1, "pos3"));
92  TEST(posit2 == db.positionlist_end(1, "pos3"));
93 
94  doc = db.get_document(1);
95  doc.add_term("pos");
96  db.replace_document(1, doc);
97  db.commit();
99  "Term(pos, wdf=1), "
100  "Term(pos2, wdf=1)");
101 }
102 
103 static Xapian::Document
105  Xapian::Document doc;
106  doc.add_term("z0", 0);
107  doc.add_term("z1", 1);
108  return doc;
109 }
110 
111 static string
113  return ", Term(z0, wdf=0), Term(z1, wdf=1)";
114 }
115 
118 DEFINE_TESTCASE(modtermwdf1, writable) {
120 
121  string bdt(basic_docterms());
122 
123  // Add a simple document.
124  Xapian::Document doc1(basic_doc());
125  doc1.add_term("takeaway", 1);
126  db.add_document(doc1);
127 
128  dbcheck(db, 1, 1);
129  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=1)" + bdt);
130 
131  // Modify the wdf of an existing document, checking stats before commit.
132  Xapian::Document doc2(basic_doc());
133  doc2.add_term("takeaway", 2);
134  db.replace_document(1, doc2);
135  dbcheck(db, 1, 1);
136  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
137 
138  // Remove a term, and then put it back again.
139  Xapian::Document doc0(basic_doc());
140  db.replace_document(1, doc0);
141  dbcheck(db, 1, 1);
142  TEST_EQUAL(docterms_to_string(db, 1), bdt.substr(2));
143  db.replace_document(1, doc1);
144  dbcheck(db, 1, 1);
145  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=1)" + bdt);
146 
147  // Remove a term, commit, then put it back, remove it, and put it back.
148  // This is to test the handling of items in the change cache.
149  db.replace_document(1, doc0);
150  db.commit();
151  db.replace_document(1, doc2);
152  db.replace_document(1, doc0);
153  db.replace_document(1, doc2);
154  db.commit();
155  dbcheck(db, 1, 1);
156  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
157 
158  // Remove a term, and then put it back again without checking stats.
159  db.replace_document(1, doc0);
160  db.replace_document(1, doc2);
161  dbcheck(db, 1, 1);
162  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
163 
164  // Modify a term, and then put it back again without checking stats.
165  db.replace_document(1, doc1);
166  db.replace_document(1, doc2);
167  dbcheck(db, 1, 1);
168  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
169 
170  // Modify the wdf of an existing document, checking stats after commit.
171  Xapian::Document doc3(basic_doc());
172  doc3.add_term("takeaway", 3);
173  db.replace_document(1, doc3);
174  db.commit();
175  dbcheck(db, 1, 1);
176  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=3)" + bdt);
177 
178  // Change a document, without changing its length.
179  Xapian::Document doc3_diff(basic_doc());
180  doc3_diff.add_term("takeaways", 3);
181  db.replace_document(1, doc3_diff);
182  db.commit();
183  dbcheck(db, 1, 1);
184  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaways, wdf=3)" + bdt);
185 
186  // Put it back.
187  db.replace_document(1, doc3);
188  dbcheck(db, 1, 1);
189  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=3)" + bdt);
190 
191  // Modify a document taken from the database.
192  Xapian::Document doc4(db.get_document(1));
193  Xapian::Document doc3a(db.get_document(1)); // need this one later
194  doc3a.termlist_count(); // Pull the document termlist into memory.
195  doc4.add_term("takeaway", 1);
196  db.replace_document(1, doc4);
197  dbcheck(db, 1, 1);
198  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=4)" + bdt);
199 
200  // Add a document which was previously added and then modified.
201  doc1.add_term("takeaway", 1);
202  db.replace_document(1, doc1);
203  dbcheck(db, 1, 1);
204  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
205 
206  // Add back a document which was taken from the database, but never modified.
207  db.replace_document(1, doc3a);
208  dbcheck(db, 1, 1);
209  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=3)" + bdt);
210 
211  // Add a position to the document.
212  Xapian::Document doc5(db.get_document(1));
213  doc5.add_posting("takeaway", 1, 2);
214  db.replace_document(1, doc5);
215  dbcheck(db, 1, 1);
216  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5, pos=[1])" + bdt);
217 
218  // Add a position without changing the wdf.
219  Xapian::Document doc5b(db.get_document(1));
220  doc5b.add_posting("takeaway", 2, 0);
221  db.replace_document(1, doc5b);
222  dbcheck(db, 1, 1);
223  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5, pos=[1, 2])" + bdt);
224 
225  // Delete a position without changing the wdf.
226  Xapian::Document doc5c(basic_doc());
227  doc5c.add_posting("takeaway", 2, 5);
228  db.replace_document(1, doc5c);
229  dbcheck(db, 1, 1);
230  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5, pos=[2])" + bdt);
231 
232  // Delete the other position without changing the wdf.
233  Xapian::Document doc5d(basic_doc());
234  doc5d.add_term("takeaway", 5);
235  db.replace_document(1, doc5d);
236  dbcheck(db, 1, 1);
237  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5)" + bdt);
238 
239  // Reduce the wdf to 0, but don't delete the term.
240  Xapian::Document doc0freq(basic_doc());
241  doc0freq.add_term("takeaway", 0);
242  db.replace_document(1, doc0freq);
243  dbcheck(db, 1, 1);
244  TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=0)" + bdt);
245 
246  // Reduce the wdf to 0, and delete the term.
247  db.replace_document(1, doc0);
248  dbcheck(db, 1, 1);
249  TEST_EQUAL(docterms_to_string(db, 1), bdt.substr(2));
250 
251  // Delete the document.
252  db.delete_document(1);
253  dbcheck(db, 0, 1);
255  TEST_EQUAL(postlist_to_string(db, "takeaway"), "");
257  TEST_EQUAL(termstats_to_string(db, "takeaway"), "tf=0,cf=0");
258  TEST_EQUAL(db.get_doccount(), 0);
259  TEST_EQUAL(db.get_avlength(), 0);
260  TEST_EQUAL(db.get_lastdocid(), 1);
261 }
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