Update for 1.4.20
[xapian.git] / xapian-core / tests / api_replacedoc.cc
blob7fa4c7c8d6b6632b7eaa3dd37a181a28d2ddafdf
1 /** @file
2 * @brief tests of document replacing.
3 */
4 /* Copyright 2009 Richard Boulton
5 * Copyright 2015,2016 Olly Betts
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.
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.
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
23 #include <config.h>
25 #include "api_replacedoc.h"
27 #include <string>
28 #include <map>
30 using namespace std;
32 #include <xapian.h>
33 #include "testsuite.h"
34 #include "testutils.h"
36 #include "apitest.h"
37 #include "dbcheck.h"
39 // Test that positionlists are updated correctly.
40 DEFINE_TESTCASE(poslistupdate1, positional && writable) {
41 Xapian::WritableDatabase db = get_writable_database();
43 Xapian::Document doc;
44 doc.add_posting("pos", 2);
45 doc.add_posting("pos", 3);
46 db.add_document(doc);
47 db.commit();
49 TEST_EQUAL(docterms_to_string(db, 1), "Term(pos, wdf=2, pos=[2, 3])");
51 doc = db.get_document(1);
52 doc.add_term("pos2");
53 db.replace_document(1, doc);
54 db.commit();
55 TEST_EQUAL(docterms_to_string(db, 1),
56 "Term(pos, wdf=2, pos=[2, 3]), "
57 "Term(pos2, wdf=1)");
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();
64 TEST_EQUAL(docterms_to_string(db, 1),
65 "Term(pos, wdf=2, pos=[2, 3]), "
66 "Term(pos2, wdf=1), "
67 "Term(pos3, wdf=2, pos=[1, 5])");
69 doc = db.get_document(1);
70 doc.remove_term("pos");
71 db.replace_document(1, doc);
72 db.commit();
73 TEST_EQUAL(docterms_to_string(db, 1),
74 "Term(pos2, wdf=1), "
75 "Term(pos3, wdf=2, pos=[1, 5])");
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"));
82 doc = db.get_document(1);
83 doc.remove_term("pos3");
84 db.replace_document(1, doc);
85 db.commit();
86 TEST_EQUAL(docterms_to_string(db, 1),
87 "Term(pos2, wdf=1)");
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"));
94 doc = db.get_document(1);
95 doc.add_term("pos");
96 db.replace_document(1, doc);
97 db.commit();
98 TEST_EQUAL(docterms_to_string(db, 1),
99 "Term(pos, wdf=1), "
100 "Term(pos2, wdf=1)");
103 static Xapian::Document
104 basic_doc() {
105 Xapian::Document doc;
106 doc.add_term("z0", 0);
107 doc.add_term("z1", 1);
108 return doc;
111 static string
112 basic_docterms() {
113 return ", Term(z0, wdf=0), Term(z1, wdf=1)";
116 /** Check that changing the wdf of a term in a document works.
118 DEFINE_TESTCASE(modtermwdf1, writable) {
119 Xapian::WritableDatabase db(get_writable_database());
121 string bdt(basic_docterms());
123 // Add a simple document.
124 Xapian::Document doc1(basic_doc());
125 doc1.add_term("takeaway", 1);
126 db.add_document(doc1);
128 dbcheck(db, 1, 1);
129 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=1)" + bdt);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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));
251 // Delete the document.
252 db.delete_document(1);
253 dbcheck(db, 0, 1);
254 TEST_EXCEPTION(Xapian::DocNotFoundError, docterms_to_string(db, 1));
255 TEST_EQUAL(postlist_to_string(db, "takeaway"), "");
256 TEST_EXCEPTION(Xapian::DocNotFoundError, docstats_to_string(db, 1));
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);