Support: quest -f cjk_ngram
[xapian.git] / xapian-core / tests / api_replacedoc.cc
blob5ea35cac94ed2c5cdca79456e6414a9d6498aedb
1 /* api_replacedoc.cc: tests of document replacing.
3 * Copyright 2009 Richard Boulton
4 * Copyright 2015 Olly Betts
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 * USA
22 #include <config.h>
24 #include "api_replacedoc.h"
26 #include <string>
27 #include <map>
29 using namespace std;
31 #include <xapian.h>
32 #include "testsuite.h"
33 #include "testutils.h"
35 #include "apitest.h"
36 #include "dbcheck.h"
38 // Test that positionlists are updated correctly.
39 DEFINE_TESTCASE(poslistupdate1, positional && writable) {
40 Xapian::WritableDatabase db = get_writable_database();
42 Xapian::Document doc;
43 doc.add_posting("pos", 2);
44 doc.add_posting("pos", 3);
45 db.add_document(doc);
46 db.flush();
48 TEST_EQUAL(docterms_to_string(db, 1), "Term(pos, wdf=2, pos=[2, 3])");
50 doc = db.get_document(1);
51 doc.add_term("pos2");
52 db.replace_document(1, doc);
53 db.flush();
54 TEST_EQUAL(docterms_to_string(db, 1),
55 "Term(pos, wdf=2, pos=[2, 3]), "
56 "Term(pos2, wdf=1)");
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.flush();
63 TEST_EQUAL(docterms_to_string(db, 1),
64 "Term(pos, wdf=2, pos=[2, 3]), "
65 "Term(pos2, wdf=1), "
66 "Term(pos3, wdf=2, pos=[1, 5])");
68 doc = db.get_document(1);
69 doc.remove_term("pos");
70 db.replace_document(1, doc);
71 db.flush();
72 TEST_EQUAL(docterms_to_string(db, 1),
73 "Term(pos2, wdf=1), "
74 "Term(pos3, wdf=2, pos=[1, 5])");
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"));
81 doc = db.get_document(1);
82 doc.remove_term("pos3");
83 db.replace_document(1, doc);
84 db.flush();
85 TEST_EQUAL(docterms_to_string(db, 1),
86 "Term(pos2, wdf=1)");
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"));
93 doc = db.get_document(1);
94 doc.add_term("pos");
95 db.replace_document(1, doc);
96 db.flush();
97 TEST_EQUAL(docterms_to_string(db, 1),
98 "Term(pos, wdf=1), "
99 "Term(pos2, wdf=1)");
101 return true;
104 static Xapian::Document
105 basic_doc() {
106 Xapian::Document doc;
107 doc.add_term("z0", 0);
108 doc.add_term("z1", 1);
109 return doc;
112 static string
113 basic_docterms() {
114 return ", Term(z0, wdf=0), Term(z1, wdf=1)";
117 /** Check that changing the wdf of a term in a document works.
119 DEFINE_TESTCASE(modtermwdf1, writable) {
120 Xapian::WritableDatabase db(get_writable_database());
122 string bdt(basic_docterms());
124 // Add a simple document.
125 Xapian::Document doc1(basic_doc());
126 doc1.add_term("takeaway", 1);
127 db.add_document(doc1);
129 dbcheck(db, 1, 1);
130 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=1)" + bdt);
132 // Modify the wdf of an existing document, checking stats before flush.
133 Xapian::Document doc2(basic_doc());
134 doc2.add_term("takeaway", 2);
135 db.replace_document(1, doc2);
136 dbcheck(db, 1, 1);
137 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
139 // Remove a term, and then put it back again.
140 Xapian::Document doc0(basic_doc());
141 db.replace_document(1, doc0);
142 dbcheck(db, 1, 1);
143 TEST_EQUAL(docterms_to_string(db, 1), bdt.substr(2));
144 db.replace_document(1, doc1);
145 dbcheck(db, 1, 1);
146 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=1)" + bdt);
148 // Remove a term, flush, then put it back, remove it, and put it back.
149 // This is to test the handling of items in the change cache.
150 db.replace_document(1, doc0);
151 db.flush();
152 db.replace_document(1, doc2);
153 db.replace_document(1, doc0);
154 db.replace_document(1, doc2);
155 db.flush();
156 dbcheck(db, 1, 1);
157 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
159 // Remove a term, and then put it back again without checking stats.
160 db.replace_document(1, doc0);
161 db.replace_document(1, doc2);
162 dbcheck(db, 1, 1);
163 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
165 // Modify a term, and then put it back again without checking stats.
166 db.replace_document(1, doc1);
167 db.replace_document(1, doc2);
168 dbcheck(db, 1, 1);
169 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
171 // Modify the wdf of an existing document, checking stats after flush.
172 Xapian::Document doc3(basic_doc());
173 doc3.add_term("takeaway", 3);
174 db.replace_document(1, doc3);
175 db.flush();
176 dbcheck(db, 1, 1);
177 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=3)" + bdt);
179 // Change a document, without changing its length.
180 Xapian::Document doc3_diff(basic_doc());
181 doc3_diff.add_term("takeaways", 3);
182 db.replace_document(1, doc3_diff);
183 db.flush();
184 dbcheck(db, 1, 1);
185 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaways, wdf=3)" + bdt);
187 // Put it back.
188 db.replace_document(1, doc3);
189 dbcheck(db, 1, 1);
190 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=3)" + bdt);
192 // Modify a document taken from the database.
193 Xapian::Document doc4(db.get_document(1));
194 Xapian::Document doc3a(db.get_document(1)); // need this one later
195 doc3a.termlist_count(); // Pull the document termlist into memory.
196 doc4.add_term("takeaway", 1);
197 db.replace_document(1, doc4);
198 dbcheck(db, 1, 1);
199 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=4)" + bdt);
201 // Add a document which was previously added and then modified.
202 doc1.add_term("takeaway", 1);
203 db.replace_document(1, doc1);
204 dbcheck(db, 1, 1);
205 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=2)" + bdt);
207 // Add back a document which was taken from the database, but never modified.
208 db.replace_document(1, doc3a);
209 dbcheck(db, 1, 1);
210 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=3)" + bdt);
212 // Add a position to the document.
213 Xapian::Document doc5(db.get_document(1));
214 doc5.add_posting("takeaway", 1, 2);
215 db.replace_document(1, doc5);
216 dbcheck(db, 1, 1);
217 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5, pos=[1])" + bdt);
219 // Add a position without changing the wdf.
220 Xapian::Document doc5b(db.get_document(1));
221 doc5b.add_posting("takeaway", 2, 0);
222 db.replace_document(1, doc5b);
223 dbcheck(db, 1, 1);
224 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5, pos=[1, 2])" + bdt);
226 // Delete a position without changing the wdf.
227 Xapian::Document doc5c(basic_doc());
228 doc5c.add_posting("takeaway", 2, 5);
229 db.replace_document(1, doc5c);
230 dbcheck(db, 1, 1);
231 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5, pos=[2])" + bdt);
233 // Delete the other position without changing the wdf.
234 Xapian::Document doc5d(basic_doc());
235 doc5d.add_term("takeaway", 5);
236 db.replace_document(1, doc5d);
237 dbcheck(db, 1, 1);
238 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=5)" + bdt);
240 // Reduce the wdf to 0, but don't delete the term.
241 Xapian::Document doc0freq(basic_doc());
242 doc0freq.add_term("takeaway", 0);
243 db.replace_document(1, doc0freq);
244 dbcheck(db, 1, 1);
245 TEST_EQUAL(docterms_to_string(db, 1), "Term(takeaway, wdf=0)" + bdt);
247 // Reduce the wdf to 0, and delete the term.
248 db.replace_document(1, doc0);
249 dbcheck(db, 1, 1);
250 TEST_EQUAL(docterms_to_string(db, 1), bdt.substr(2));
252 // Delete the document.
253 db.delete_document(1);
254 dbcheck(db, 0, 1);
255 TEST_EXCEPTION(Xapian::DocNotFoundError, docterms_to_string(db, 1));
256 TEST_EQUAL(postlist_to_string(db, "takeaway"), "");
257 TEST_EXCEPTION(Xapian::DocNotFoundError, docstats_to_string(db, 1));
258 TEST_EQUAL(termstats_to_string(db, "takeaway"), "tf=0,cf=0");
259 TEST_EQUAL(db.get_doccount(), 0);
260 TEST_EQUAL(db.get_avlength(), 0);
261 TEST_EQUAL(db.get_lastdocid(), 1);
263 return true;