@@ -82,6 +82,15 @@ static char *make_basedir(const char * const *reldirs)
82
82
CU_ASSERT_EQUAL(r, CYRUSDB_OK); \
83
83
CU_ASSERT_PTR_NOT_NULL(txn);
84
84
85
+ #define CANDELETE (key , keylen ) \
86
+ r = cyrusdb_delete(db, key, keylen, &txn, 1); \
87
+ CU_ASSERT_EQUAL(r, CYRUSDB_OK); \
88
+ CU_ASSERT_PTR_NOT_NULL(txn);
89
+
90
+ #define ISCONSISTENT () \
91
+ r = cyrusdb_consistent(db); \
92
+ CU_ASSERT_EQUAL(r, CYRUSDB_OK);
93
+
85
94
#define BADDATA ((const char *)0xdeadbeef)
86
95
#define BADLEN ((int)0xcafebabe)
87
96
@@ -150,6 +159,18 @@ static char *make_basedir(const char * const *reldirs)
150
159
CU_ASSERT_NOT_EQUAL(_datalen, BADLEN); \
151
160
}
152
161
162
+ #define CANNOTFETCH_NOTXN (key , keylen , experror ) \
163
+ { \
164
+ const char *_data = BADDATA; \
165
+ size_t _datalen = BADLEN; \
166
+ r = cyrusdb_fetch(db, key, keylen, &_data, &_datalen, NULL); \
167
+ CU_ASSERT_EQUAL(r, experror); \
168
+ CU_ASSERT_PTR_NULL(_data); \
169
+ CU_ASSERT_PTR_NOT_EQUAL(_data, BADDATA); \
170
+ CU_ASSERT_EQUAL(_datalen, 0); \
171
+ CU_ASSERT_NOT_EQUAL(_datalen, BADLEN); \
172
+ }
173
+
153
174
#define CANNOTFETCHNEXT (key , keylen , experror ) \
154
175
{ \
155
176
r = cyrusdb_fetchnext(db, key, keylen, NULL, 0, NULL, 0, &txn); \
@@ -329,6 +350,63 @@ static void test_multiopen(void)
329
350
CU_ASSERT_EQUAL (fexists (filename ), 0 );
330
351
}
331
352
353
+ static void test_read_and_delete (void )
354
+ {
355
+ struct db * db = NULL ;
356
+ struct txn * txn = NULL ;
357
+ int r ;
358
+ /* data courtesy hipsteripsum.me */
359
+ static const char KEY1 [] = "mustache" ;
360
+ static const char DATA1 [] = "blog lomo" ;
361
+ static const char KEY2 [] = "cred" ;
362
+ static const char DATA2 [] = "beard ethical" ;
363
+ static const char KEY3 [] = "leggings" ;
364
+ static const char DATA3 [] = "tumblr salvia" ;
365
+ static const char KEY3CHILD [] = "leggings.biodiesel" ;
366
+ static const char KEY4 [] = "occupy" ;
367
+ static const char DATA4 [] = "etsy tote bag" ;
368
+
369
+ if (skiptest ()) return ;
370
+
371
+ CU_ASSERT_EQUAL (fexists (filename ), - ENOENT );
372
+
373
+ /* open() with _CREATE succeeds and creates the db */
374
+ r = cyrusdb_open (backend , filename , CYRUSDB_CREATE , & db );
375
+ CU_ASSERT_EQUAL (r , CYRUSDB_OK );
376
+ CU_ASSERT_PTR_NOT_NULL (db );
377
+ CU_ASSERT_EQUAL (fexists (filename ), 0 );
378
+
379
+ /* 1st txn starts */
380
+ CANSTORE (KEY1 , strlen (KEY1 ), DATA1 , strlen (DATA1 ));
381
+ CANSTORE (KEY2 , strlen (KEY2 ), DATA2 , strlen (DATA2 ));
382
+ CANSTORE (KEY3 , strlen (KEY3 ), DATA3 , strlen (DATA3 ));
383
+ CANSTORE (KEY4 , strlen (KEY4 ), DATA4 , strlen (DATA4 ));
384
+ CANCOMMIT ();
385
+ ISCONSISTENT ();
386
+ /* 1st txn ends */
387
+
388
+ /* 2nd txn starts - try to fetch the immediately preceding value */
389
+ CANNOTFETCH (KEY3CHILD , strlen (KEY3CHILD ), CYRUSDB_NOTFOUND );
390
+ CANFETCH (KEY3 , strlen (KEY3 ), DATA3 , strlen (DATA3 ));
391
+ CANDELETE (KEY3 , strlen (KEY3 ));
392
+ CANFETCH (KEY1 , strlen (KEY1 ), DATA1 , strlen (DATA1 ));
393
+ CANDELETE (KEY1 , strlen (KEY1 ));
394
+ CANCOMMIT ();
395
+ ISCONSISTENT ();
396
+
397
+ /* what is left? */
398
+ CANNOTFETCH_NOTXN (KEY1 , strlen (KEY1 ), CYRUSDB_NOTFOUND );
399
+ CANFETCH_NOTXN (KEY2 , strlen (KEY2 ), DATA2 , strlen (DATA2 ));
400
+ CANNOTFETCH_NOTXN (KEY3 , strlen (KEY3 ), CYRUSDB_NOTFOUND );
401
+ CANFETCH_NOTXN (KEY4 , strlen (KEY4 ), DATA4 , strlen (DATA4 ));
402
+ ISCONSISTENT ();
403
+
404
+ /* closing succeeds and leaves the file in place */
405
+ r = cyrusdb_close (db );
406
+ CU_ASSERT_EQUAL (r , CYRUSDB_OK );
407
+ CU_ASSERT_EQUAL (fexists (filename ), 0 );
408
+ }
409
+
332
410
static void test_opentwo (void )
333
411
{
334
412
struct db * db1 = NULL ;
0 commit comments