| 198 | |
| 199 | static void write_stub(const string & stubpath, const string & contents) { |
| 200 | int fd = open(stubpath.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666); |
| 201 | TEST_EQUAL(write(fd, contents.c_str(), contents.size()), (ssize_t)contents.size()); |
| 202 | close(fd); |
| 203 | } |
| 204 | |
| 205 | // Test of reopen of a database which has been replaced underneath the reader. |
| 206 | DEFINE_TESTCASE(reopen1, flint || chert || brass) { |
| 207 | // Create a directory with a XAPIANDB file pointing to a sub database. |
| 208 | string topdbdir = get_named_writable_database_path("reopen1"); |
| 209 | mkdir(topdbdir.c_str(), 0755); |
| 210 | string stubpath = topdbdir + "/XAPIANDB"; |
| 211 | string subdb1path = topdbdir + "/db1"; |
| 212 | string subdb2path = topdbdir + "/db2"; |
| 213 | |
| 214 | write_stub(stubpath, "auto db1"); |
| 215 | |
| 216 | // Make the sub database, and add document to it. |
| 217 | { |
| 218 | Xapian::WritableDatabase db(get_named_writable_database("reopen1/db1")); |
| 219 | for (int i = 0; i != 1000; ++i) { |
| 220 | Xapian::Document doc1; |
| 221 | doc1.add_term("hello"); |
| 222 | db.add_document(doc1); |
| 223 | } |
| 224 | db.commit(); |
| 225 | db.close(); |
| 226 | } |
| 227 | |
| 228 | // Open the database through the stub directory, through the stub, and |
| 229 | // directly. |
| 230 | Xapian::Database db1(topdbdir); |
| 231 | Xapian::Database db2(stubpath); |
| 232 | Xapian::Database db3(subdb1path); |
| 233 | dbcheck(db1, 1000, 1000); |
| 234 | dbcheck(db2, 1000, 1000); |
| 235 | dbcheck(db3, 1000, 1000); |
| 236 | check_equal_dbs(topdbdir, stubpath); |
| 237 | check_equal_dbs(topdbdir, subdb1path); |
| 238 | |
| 239 | // Delete the old database. |
| 240 | rm_rf(subdb1path); |
| 241 | |
| 242 | // Make a new database in the original location. |
| 243 | { |
| 244 | Xapian::WritableDatabase db(get_named_writable_database("reopen1/db1")); |
| 245 | Xapian::Document doc1; |
| 246 | doc1.add_term("hola"); |
| 247 | doc1.add_term("hello"); |
| 248 | db.add_document(doc1); |
| 249 | db.commit(); |
| 250 | db.add_document(doc1); |
| 251 | db.commit(); |
| 252 | db.delete_document(1); |
| 253 | db.commit(); |
| 254 | db.close(); |
| 255 | } |
| 256 | |
| 257 | // Reopen the database and check. |
| 258 | db1.reopen(); |
| 259 | db2.reopen(); |
| 260 | db3.reopen(); |
| 261 | dbcheck(db1, 1, 2); |
| 262 | dbcheck(db2, 1, 2); |
| 263 | dbcheck(db3, 1, 2); |
| 264 | check_equal_dbs(topdbdir, stubpath); |
| 265 | check_equal_dbs(topdbdir, subdb1path); |
| 266 | |
| 267 | return true; |
| 268 | } |
| 269 | |
| 270 | // Test of reopen of a database opened through a stub path. |
| 271 | DEFINE_TESTCASE(reopen2, flint || chert || brass) { |
| 272 | // Create a directory with a XAPIANDB file pointing to a sub database. |
| 273 | string topdbdir = get_named_writable_database_path("reopen2"); |
| 274 | mkdir(topdbdir.c_str(), 0755); |
| 275 | string stubpath = topdbdir + "/XAPIANDB"; |
| 276 | string subdb1path = topdbdir + "/db1"; |
| 277 | string subdb2path = topdbdir + "/db2"; |
| 278 | |
| 279 | write_stub(stubpath, "auto db1"); |
| 280 | |
| 281 | // Make the sub database, and add document to it. |
| 282 | { |
| 283 | Xapian::WritableDatabase db(get_named_writable_database("reopen2/db1")); |
| 284 | Xapian::Document doc1; |
| 285 | doc1.add_term("hello"); |
| 286 | db.add_document(doc1); |
| 287 | db.commit(); |
| 288 | db.close(); |
| 289 | } |
| 290 | |
| 291 | // Open the database through the stub directory, through the stub, and |
| 292 | // directly. |
| 293 | Xapian::Database db1(topdbdir); |
| 294 | Xapian::Database db2(stubpath); |
| 295 | Xapian::Database db3(subdb1path); |
| 296 | dbcheck(db1, 1, 1); |
| 297 | dbcheck(db2, 1, 1); |
| 298 | dbcheck(db3, 1, 1); |
| 299 | check_equal_dbs(topdbdir, stubpath); |
| 300 | check_equal_dbs(topdbdir, subdb1path); |
| 301 | |
| 302 | // Make a new database, and change the stub to point to it. |
| 303 | { |
| 304 | Xapian::WritableDatabase db(get_named_writable_database("reopen2/db2")); |
| 305 | Xapian::Document doc1; |
| 306 | doc1.add_term("world"); |
| 307 | db.add_document(doc1); |
| 308 | db.commit(); |
| 309 | db.close(); |
| 310 | } |
| 311 | write_stub(stubpath, "auto db2"); |
| 312 | |
| 313 | // Delete the old database. |
| 314 | rm_rf(subdb1path); |
| 315 | |
| 316 | // Reopen the database and check. |
| 317 | db1.reopen(); |
| 318 | db2.reopen(); |
| 319 | db3.reopen(); |
| 320 | dbcheck(db1, 1, 1); |
| 321 | dbcheck(db2, 1, 1); |
| 322 | dbcheck(db3, 1, 1); |
| 323 | check_equal_dbs(topdbdir, stubpath); |
| 324 | check_equal_dbs(topdbdir, subdb2path); |
| 325 | |
| 326 | // Make a new database in the original location. |
| 327 | rm_rf(subdb1path); |
| 328 | { |
| 329 | Xapian::WritableDatabase db(get_named_writable_database("reopen2/db1")); |
| 330 | Xapian::Document doc1; |
| 331 | doc1.add_term("hola"); |
| 332 | doc1.add_term("hello"); |
| 333 | db.add_document(doc1); |
| 334 | db.commit(); |
| 335 | db.add_document(doc1); |
| 336 | db.commit(); |
| 337 | db.delete_document(1); |
| 338 | db.commit(); |
| 339 | db.close(); |
| 340 | } |
| 341 | |
| 342 | // Reopen the database and check. |
| 343 | db1.reopen(); |
| 344 | db2.reopen(); |
| 345 | db3.reopen(); |
| 346 | dbcheck(db1, 1, 2); |
| 347 | dbcheck(db2, 1, 2); |
| 348 | dbcheck(db3, 1, 2); |
| 349 | check_equal_dbs(topdbdir, stubpath); |
| 350 | check_equal_dbs(topdbdir, subdb2path); |
| 351 | |
| 352 | return true; |
| 353 | } |