| | 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 | } |