Codebase list libberkeleydb-perl / 818c966
Imported Upstream version 0.29 Marco d'Itri 9 years ago
13 changed file(s) with 701 addition(s) and 52 deletion(s). Raw diff Collapse all Expand all
11 package BerkeleyDB;
22
33
4 # Copyright (c) 1997-2005 Paul Marquess. All rights reserved.
4 # Copyright (c) 1997-2006 Paul Marquess. All rights reserved.
55 # This program is free software; you can redistribute it and/or
66 # modify it under the same terms as Perl itself.
77 #
1616 use vars qw($VERSION @ISA @EXPORT $AUTOLOAD
1717 $use_XSLoader);
1818
19 $VERSION = '0.27';
19 $VERSION = '0.29';
2020
2121 require Exporter;
2222 #require DynaLoader;
4343 $status = $db->status() ;
4444 $boolean = $db->byteswapped() ;
4545 $status = $db->truncate($count) ;
46 $status = $db->compact($start, $stop, $c_data, $flags, $end);
4647
4748 $bool = $env->cds_enabled();
4849 $bool = $db->cds_enabled();
14351436 Truncates the datatabase and returns the number or records deleted
14361437 in C<$count>.
14371438
1439 =head2 $status = $db->compact($start, $stop, $c_data, $flags, $end);
1440
1441 Compacts the database C<$db>.
1442
1443 All the parameters are optional - if only want to make use of some of them,
1444 use C<undef> for those you don't want. Trailing unusused parameters can be
1445 omitted. For example, if you only want to use the C<$c_data> parameter to
1446 set the C<compact_fillpercent>, write you code like this
1447
1448 my %hash;
1449 $hash{compact_fillpercent} = 50;
1450 $db->commit(undef, undef, \%hash);
1451
1452 The parameters operate identically to the C equivalent of this method.
1453 The C<$c_data> needs a bit of explanation - it must be a hash reference.
1454 The values of the following keys can be set before calling C<compact> and
1455 will affect the operation of the compaction.
1456
1457 =over 5
1458 =item * compact_fillpercent
1459 =item * compact_timeout
1460
1461 =back
1462
1463 The following keys, along with associated values, will be created in the
1464 hash reference if the C<compact> operation was successful.
1465
1466 =over 5
1467
1468 =item * compact_deadlock
1469 =item * compact_levels
1470 =item * compact_pages_free
1471 =item * compact_pages_examine
1472 =item * compact_pages_truncated
1473
1474 =back
1475
1476 You need to be running Berkeley DB 4.4 or better if you wan to make use of
1477 C<compact>.
1478
14381479 =head1 CURSORS
14391480
14401481 A cursor is used whenever you want to access the contents of a database
4343 $status = $db->status() ;
4444 $boolean = $db->byteswapped() ;
4545 $status = $db->truncate($count) ;
46 $status = $db->compact($start, $stop, $c_data, $flags, $end);
4647
4748 $bool = $env->cds_enabled();
4849 $bool = $db->cds_enabled();
12411242 Truncates the datatabase and returns the number or records deleted
12421243 in C<$count>.
12431244
1245 =head2 $status = $db->compact($start, $stop, $c_data, $flags, $end);
1246
1247 Compacts the database C<$db>.
1248
1249 All the parameters are optional - if only want to make use of some of them,
1250 use C<undef> for those you don't want. Trailing unusused parameters can be
1251 omitted. For example, if you only want to use the C<$c_data> parameter to
1252 set the C<compact_fillpercent>, write you code like this
1253
1254 my %hash;
1255 $hash{compact_fillpercent} = 50;
1256 $db->commit(undef, undef, \%hash);
1257
1258 The parameters operate identically to the C equivalent of this method.
1259 The C<$c_data> needs a bit of explanation - it must be a hash reference.
1260 The values of the following keys can be set before calling C<compact> and
1261 will affect the operation of the compaction.
1262
1263 =over 5
1264 =item * compact_fillpercent
1265 =item * compact_timeout
1266
1267 =back
1268
1269 The following keys, along with associated values, will be created in the
1270 hash reference if the C<compact> operation was successful.
1271
1272 =over 5
1273
1274 =item * compact_deadlock
1275 =item * compact_levels
1276 =item * compact_pages_free
1277 =item * compact_pages_examine
1278 =item * compact_pages_truncated
1279
1280 =back
1281
1282 You need to be running Berkeley DB 4.4 or better if you wan to make use of
1283 C<compact>.
1284
12441285 =head1 CURSORS
12451286
12461287 A cursor is used whenever you want to access the contents of a database
55
66 All comments/suggestions/problems are welcome
77
8 Copyright (c) 1997-2005 Paul Marquess. All rights reserved.
8 Copyright (c) 1997-2006 Paul Marquess. All rights reserved.
99 This program is free software; you can redistribute it and/or
1010 modify it under the same terms as Perl itself.
1111
126126
127127 #if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 4)
128128 # define AT_LEAST_DB_4_4
129 #endif
130
131 #if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 5)
132 # define AT_LEAST_DB_4_5
129133 #endif
130134
131135 #ifdef __cplusplus
343347 typedef DBT DBT_B ;
344348 typedef DBT DBTKEY_B ;
345349 typedef DBT DBTKEY_Br ;
350 typedef DBT DBTKEY_Bpr ;
346351 typedef DBT DBTVALUE ;
347352 typedef void * PV_or_NULL ;
348353 typedef PerlIO * IO_or_NULL ;
349354 typedef int DualType ;
355 typedef SV SVnull;
350356
351357 static void
352358 hash_delete(char * hash, char * key);
391397
392398 #define my_sv_setpvn(sv, d, s) (s ? sv_setpvn(sv, d, s) : sv_setpv(sv, "") )
393399
400 #define GetValue_iv(h,k) (((sv = readHash(h, k)) && sv != &PL_sv_undef) \
401 ? SvIV(sv) : 0)
394402 #define SetValue_iv(i, k) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) \
395403 i = SvIV(sv)
396404 #define SetValue_io(i, k) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) \
476484 { if (RETVAL == 0) \
477485 { \
478486 if (db->recno_or_queue || db->primary_recno_or_queue \
487 || (db->type == DB_BTREE && \
488 flagSet(DB_GET_RECNO))){ \
489 sv_setiv(arg, (I32)(*(I32*)name.data) - RECNO_BASE); \
490 } \
491 else { \
492 my_sv_setpvn(arg, name.data, name.size); \
493 } \
494 DBM_ckFilter(arg, filter_fetch_key, "filter_fetch_key") ; \
495 } \
496 }
497
498 #define OutputKey_Bpr(arg, name) \
499 { if (RETVAL == 0) \
500 { \
501 if (db->primary_recno_or_queue \
479502 || (db->type == DB_BTREE && \
480503 flagSet(DB_GET_RECNO))){ \
481504 sv_setiv(arg, (I32)(*(I32*)name.data) - RECNO_BASE); \
11421165
11431166 /* retrieve the secondary key */
11441167 DBT_clear(*skey);
1168
11451169 skey_ptr = SvPV(skey_SV, skey_len);
11461170 skey->flags = DB_DBT_APPMALLOC;
11471171 /* skey->size = SvCUR(skey_SV); */
11501174 skey->data = (char*)safemalloc(skey_len);
11511175 memcpy(skey->data, skey_ptr, skey_len);
11521176 Trace(("key is %d -- %.*s\n", skey->size, skey->size, skey->data));
1177
1178 FREETMPS ;
1179 LEAVE ;
1180
1181 return (retval) ;
1182 }
1183
1184 static int
1185 associate_cb_recno(DB_callback const DBT * pkey, const DBT * pdata, DBT * skey)
1186 {
1187 dSP ;
1188 char * pk_dat, * pd_dat ;
1189 /* char *sk_dat ; */
1190 int retval ;
1191 int count ;
1192 SV * skey_SV ;
1193 STRLEN skey_len;
1194 char * skey_ptr ;
1195 db_recno_t Value;
1196
1197 Trace(("In associate_cb_recno \n")) ;
1198 if (getCurrentDB->associated == NULL){
1199 Trace(("No Callback registered\n")) ;
1200 return EINVAL ;
1201 }
1202
1203 skey_SV = newSVpv("",0);
1204
1205
1206 pk_dat = (char*) pkey->data ;
1207 pd_dat = (char*) pdata->data ;
1208
1209 #ifndef newSVpvn
1210 /* As newSVpv will assume that the data pointer is a null terminated C
1211 string if the size parameter is 0, make sure that data points to an
1212 empty string if the length is 0
1213 */
1214 if (pkey->size == 0)
1215 pk_dat = "" ;
1216 if (pdata->size == 0)
1217 pd_dat = "" ;
1218 #endif
1219
1220 ENTER ;
1221 SAVETMPS;
1222
1223 PUSHMARK(SP) ;
1224 EXTEND(SP,2) ;
1225 PUSHs(sv_2mortal(newSVpvn(pk_dat,pkey->size)));
1226 PUSHs(sv_2mortal(newSVpvn(pd_dat,pdata->size)));
1227 PUSHs(sv_2mortal(skey_SV));
1228 PUTBACK ;
1229
1230 Trace(("calling associated cb\n"));
1231 count = perl_call_sv(getCurrentDB->associated, G_SCALAR);
1232 Trace(("called associated cb\n"));
1233
1234 SPAGAIN ;
1235
1236 if (count != 1)
1237 softCrash ("associate: expected 1 return value from prefix sub, got %d", count) ;
1238
1239 retval = POPi ;
1240
1241 PUTBACK ;
1242
1243 /* retrieve the secondary key */
1244 DBT_clear(*skey);
1245
1246 Value = GetRecnoKey(getCurrentDB, SvIV(skey_SV)) ;
1247 skey->flags = DB_DBT_APPMALLOC;
1248 skey->size = (int)sizeof(db_recno_t);
1249 skey->data = (char*)safemalloc(skey->size);
1250 memcpy(skey->data, &Value, skey->size);
11531251
11541252 FREETMPS ;
11551253 LEAVE ;
12211319 hv_store_iv(HV * hash, char * key, IV value)
12221320 {
12231321 hv_store(hash, key, strlen(key), newSViv(value), 0);
1322 }
1323
1324 #if 0
1325 static void
1326 hv_store_uv(HV * hash, char * key, UV value)
1327 {
1328 hv_store(hash, key, strlen(key), newSVuv(value), 0);
1329 }
1330 #endif
1331
1332 static void
1333 GetKey(BerkeleyDB_type * db, SV * sv, DBTKEY * key)
1334 {
1335 if (db->recno_or_queue) {
1336 Value = GetRecnoKey(db, SvIV(sv)) ;
1337 key->data = & Value;
1338 key->size = (int)sizeof(db_recno_t);
1339 }
1340 else {
1341 key->data = SvPV(sv, PL_na);
1342 key->size = (int)PL_na;
1343 }
12241344 }
12251345
12261346 static BerkeleyDB
29633083 #ifdef AT_LEAST_DB_3_3
29643084 RETVAL->associated = db->associated ;
29653085 RETVAL->secondary_db = db->secondary_db;
2966 RETVAL->primary_recno_or_queue = db->recno_or_queue ;
3086 RETVAL->primary_recno_or_queue = db->primary_recno_or_queue ;
29673087 #endif
29683088 RETVAL->prefix = db->prefix ;
29693089 RETVAL->hash = db->hash ;
30353155 #ifdef AT_LEAST_DB_3_3
30363156 RETVAL->associated = db->associated ;
30373157 RETVAL->secondary_db = db->secondary_db;
3038 RETVAL->primary_recno_or_queue = db->recno_or_queue ;
3158 RETVAL->primary_recno_or_queue = db->primary_recno_or_queue ;
30393159 #endif
30403160 RETVAL->prefix = db->prefix ;
30413161 RETVAL->hash = db->hash ;
32663386 u_int flags
32673387 BerkeleyDB::Common db
32683388 DBTKEY_B key
3269 DBTKEY_B pkey = NO_INIT
3389 DBTKEY_Bpr pkey = NO_INIT
32703390 DBT_OPT data
32713391 CODE:
32723392 #ifndef AT_LEAST_DB_3_3
34243544 secondary->primary_recno_or_queue = db->recno_or_queue ;
34253545 /* secondary->dbp->app_private = secondary->associated ; */
34263546 secondary->secondary_db = TRUE;
3427 RETVAL = db_associate(db, secondary, associate_cb, flags);
3547 if (secondary->recno_or_queue)
3548 RETVAL = db_associate(db, secondary, associate_cb_recno, flags);
3549 else
3550 RETVAL = db_associate(db, secondary, associate_cb, flags);
34283551 #endif
34293552 OUTPUT:
34303553 RETVAL
3554
3555 DualType
3556 compact(db, start=NULL, stop=NULL, c_data=NULL, flags=0, end=NULL)
3557 BerkeleyDB::Common db
3558 SVnull* start
3559 SVnull* stop
3560 SVnull* c_data
3561 u_int32_t flags
3562 SVnull* end
3563 INIT:
3564 DBTKEY end_key;
3565 CODE:
3566 {
3567 #ifndef AT_LEAST_DB_4_4
3568 softCrash("compact needs Berkeley DB 4.4 or later") ;
3569 #else
3570 DBTKEY start_key;
3571 DBTKEY stop_key;
3572 DBTKEY* start_p = NULL;
3573 DBTKEY* stop_p = NULL;
3574 DBTKEY* end_p = NULL;
3575 DB_COMPACT cmpt;
3576 DB_COMPACT* cmpt_p = NULL;
3577 SV * sv;
3578 HV* hash = NULL;
3579
3580 DBT_clear(start_key);
3581 DBT_clear(stop_key);
3582 DBT_clear(end_key);
3583 Zero(&cmpt, 1, DB_COMPACT) ;
3584 ckActive_Database(db->active) ;
3585 saveCurrentDB(db) ;
3586 if (start && SvOK(start)) {
3587 start_p = &start_key;
3588 DBM_ckFilter(start, filter_store_key, "filter_store_key");
3589 GetKey(db, start, start_p);
3590 }
3591 if (stop && SvOK(stop)) {
3592 stop_p = &stop_key;
3593 DBM_ckFilter(stop, filter_store_key, "filter_store_key");
3594 GetKey(db, stop, stop_p);
3595 }
3596 if (end) {
3597 end_p = &end_key;
3598 }
3599 if (c_data && SvOK(c_data)) {
3600 hash = (HV*) SvRV(c_data) ;
3601 cmpt_p = & cmpt;
3602 cmpt.compact_fillpercent = GetValue_iv(hash,"compact_fillpercent") ;
3603 cmpt.compact_timeout = (db_timeout_t) GetValue_iv(hash, "compact_timeout");
3604 }
3605 RETVAL = (db->dbp)->compact(db->dbp, db->txn, start_p, stop_p, cmpt_p, flags, end_p);
3606 if (RETVAL == 0 && hash) {
3607 hv_store_iv(hash, "compact_deadlock", cmpt.compact_deadlock) ;
3608 hv_store_iv(hash, "compact_levels", cmpt.compact_levels) ;
3609 hv_store_iv(hash, "compact_pages_free", cmpt.compact_pages_free) ;
3610 hv_store_iv(hash, "compact_pages_examine", cmpt.compact_pages_examine) ;
3611 hv_store_iv(hash, "compact_pages_truncated", cmpt.compact_pages_truncated) ;
3612 }
3613 #endif
3614 }
3615 OUTPUT:
3616 RETVAL
3617 end if (RETVAL == 0 && end) OutputValue_B(ST(5), end_key) ;
34313618
34323619
34333620 MODULE = BerkeleyDB::Cursor PACKAGE = BerkeleyDB::Cursor PREFIX = cu_
35443731 cu_c_get(db, key, data, flags=0)
35453732 int flags
35463733 BerkeleyDB::Cursor db
3547 DBTKEY_Br key
3734 DBTKEY_B key
35483735 DBT_B data
35493736 INIT:
35503737 Trace(("c_get db [%p] in [%p] flags [%d]\n", db->dbp, db, flags)) ;
35653752 int flags
35663753 BerkeleyDB::Cursor db
35673754 DBTKEY_B key
3568 DBTKEY_Br pkey = NO_INIT
3755 DBTKEY_Bpr pkey = NO_INIT
35693756 DBT_B data
35703757 CODE:
35713758 #ifndef AT_LEAST_DB_3_3
00 Revision history for Perl extension BerkeleyDB.
11
2 0.29 2nd July 2006
3
4 * Fixes for cursor get from secondary where primary os recno.
5
6 * Added db_compact
7
8 0.28 11th June 2006
9
10 * Fixes for secondary where primary is recno.
11
12 * GET_BOTH_RANGE wasn't working. It is now.
13
14 * Added FreeBSD hints to README - patch supplied by David Landgren
15 in #17675 from rt.cpan.org
16
217 0.27 1st Novemver 2005
318
419 * Added support for Berkeley DB 4.4
520
6 * Fixed decondary key issue with recno databases
21 * Fixed secondary key issue with recno databases
722
823 * Added libscan to Makefile.PL
924
2323 t/db-3.1.t
2424 t/db-3.2.t
2525 t/db-3.3.t
26 t/db-4.4.t
2627 t/destroy.t
2728 t/encrypt.t
2829 t/env.t
00 # http://module-build.sourceforge.net/META-spec.html
11 #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#
22 name: BerkeleyDB
3 version: 0.25
3 version: 0.29
44 version_from: BerkeleyDB.pm
55 installdirs: site
66 requires:
77
88 distribution_type: module
9 generated_by: ExtUtils::MakeMaker version 6.17
9 generated_by: ExtUtils::MakeMaker version 6.30
00 BerkeleyDB
11
2 Version 0.27
3
4 1st Nov 2005
5
6 Copyright (c) 1997-2005 Paul Marquess. All rights reserved. This
2 Version 0.29
3
4 2nd July 2006
5
6 Copyright (c) 1997-2006 Paul Marquess. All rights reserved. This
77 program is free software; you can redistribute it and/or modify
88 it under the same terms as Perl itself.
99
5757
5858 Step 1 : If you are running Solaris 2.5, 2.7 or HP-UX 10 read either
5959 the Solaris Notes or HP-UX Notes sections below.
60 If you are running Linux please read the Linux Notes section
60 If you are running Linux please read the Linux Notes section
6161 before proceeding.
62 If you are running FreeBSD read the FreeBSD Notes section
63 below.
64
6265
6366 Step 2 : Edit the file config.in to suit you local installation.
6467 Instructions are given in the file.
562565 3: Build and install the Berkeley DB distribution as usual.
563566
564567
568 FreeBSD Notes
569 -------------
570
571 On FreeBSD 4.x through 6.x, the default db.h is for version 1. The build
572 will fail with an error similar to:
573
574 BerkeleyDB.xs:74: #error db.h is from Berkeley DB 1.x - need at least
575 Berkeley DB 2.6.4
576
577 Later versions of Berkeley DB are usually installed from ports.
578 The available versions can be found by running a find(1) command:
579
580 % find /usr/local/include -name 'db.h'
581 /usr/local/include/db3/db.h
582 /usr/local/include/db4/db.h
583 /usr/local/include/db41/db.h
584 /usr/local/include/db42/db.h
585 /usr/local/include/db43/db.h
586
587 The desired version of the library must be specified on the command line or
588 via the config.in file. Make sure both values point to the same version:
589
590 INCLUDE = /usr/local/include/db43
591 LIB = /usr/local/lib/db43
592
593
594
565595
566596 FEEDBACK
567597 --------
1717
1818 umask(0);
1919
20 print "1..44\n";
20 print "1..130\n";
2121
2222 {
2323 # db->truncate
123123 ok 23, my $s_cursor = $secondary->db_cursor();
124124
125125 # c_get from primary
126 $k = 1;
127 ok 24, $p_cursor->c_get($k, $v, DB_FIRST) == 0;
126 $k = 'green';
127 ok 24, $p_cursor->c_get($k, $v, DB_SET) == 0;
128 ok 25, $k eq 'green';
129 ok 26, $v eq 'house';
128130
129131 # c_get from secondary
130 ok 25, $s_cursor->c_get($k, $v, DB_FIRST) == 0;
132 $k = 'sea';
133 ok 27, $s_cursor->c_get($k, $v, DB_SET) == 0;
134 ok 28, $k eq 'sea';
135 ok 29, $v eq 'sea';
131136
132137 # c_pget from primary database should fail
133138 $k = 1;
134 ok 26, $p_cursor->c_pget($k, $pk, $v, DB_FIRST) != 0;
139 ok 30, $p_cursor->c_pget($k, $pk, $v, DB_FIRST) != 0;
135140
136141 # c_pget from secondary database
137 ok 27, $s_cursor->c_pget($k, $pk, $v, DB_FIRST) == 0;
142 $k = 'flag';
143 ok 31, $s_cursor->c_pget($k, $pk, $v, DB_SET) == 0;
144 ok 32, $k eq 'flag';
145 ok 33, $pk eq 'red';
146 ok 34, $v eq 'flag';
138147
139148 # check put to secondary is illegal
140 ok 28, $secondary->db_put("tom", "dick") != 0;
141 ok 29, countRecords($secondary) == 3 ;
149 ok 35, $secondary->db_put("tom", "dick") != 0;
150 ok 36, countRecords($secondary) == 3 ;
142151
143152 # delete from primary
144 ok 30, $primary->db_del("green") == 0 ;
145 ok 31, countRecords($primary) == 2 ;
153 ok 37, $primary->db_del("green") == 0 ;
154 ok 38, countRecords($primary) == 2 ;
146155
147156 # check has been deleted in secondary
148 ok 32, $secondary->db_get("house", $v) != 0;
149 ok 33, countRecords($secondary) == 2 ;
157 ok 39, $secondary->db_get("house", $v) != 0;
158 ok 40, countRecords($secondary) == 2 ;
150159
151160 # delete from secondary
152 ok 34, $secondary->db_del('flag') == 0 ;
153 ok 35, countRecords($secondary) == 1 ;
161 ok 41, $secondary->db_del('flag') == 0 ;
162 ok 42, countRecords($secondary) == 1 ;
154163
155164
156165 # check deleted from primary
157 ok 36, $primary->db_get("red", $v) != 0;
158 ok 37, countRecords($primary) == 1 ;
166 ok 43, $primary->db_get("red", $v) != 0;
167 ok 44, countRecords($primary) == 1 ;
159168
160169 }
161170
186195 my ($k, $v, $pk) = ('','','');
187196
188197 # create primary database
189 ok 38, my $primary = new BerkeleyDB::Btree -Filename => $Dfile1,
198 ok 45, my $primary = new BerkeleyDB::Btree -Filename => $Dfile1,
190199 -Compare => sub { return $_[0] cmp $_[1]},
191200 -Flags => DB_CREATE ;
192201
193202 # create secondary database
194 ok 39, my $secondary = new BerkeleyDB::Btree -Filename => $Dfile2,
203 ok 46, my $secondary = new BerkeleyDB::Btree -Filename => $Dfile2,
195204 -Compare => sub { return $_[0] <=> $_[1]},
196205 -Property => DB_DUP,
197206 -Flags => DB_CREATE ;
198207
199208 # associate primary with secondary
200 ok 40, $primary->associate($secondary, \&sec_key2) == 0;
209 ok 47, $primary->associate($secondary, \&sec_key2) == 0;
201210
202211 # add data to the primary
203212 my %data = (
213222 #print "put [$r] $BerkeleyDB::Error\n";
214223 $ret += $r;
215224 }
216 ok 41, $ret == 0 ;
225 ok 48, $ret == 0 ;
217226 #print "ret $ret\n";
218227
219228 #print "Primary\n" ; dumpdb($primary) ;
220229 #print "Secondary\n" ; dumpdb($secondary) ;
221230
222231 # check the records in the secondary
223 ok 42, countRecords($secondary) == 4 ;
232 ok 49, countRecords($secondary) == 4 ;
224233
225234 my $p_data = joinkeys($primary, " ");
226235 #print "primary [$p_data]\n" ;
227 ok 43, $p_data eq join " ", sort { $a cmp $b } keys %data ;
236 ok 50, $p_data eq join " ", sort { $a cmp $b } keys %data ;
228237 my $s_data = joinkeys($secondary, " ");
229238 #print "secondary [$s_data]\n" ;
230 ok 44, $s_data eq join " ", sort { $a <=> $b } map { length } values %data ;
239 ok 51, $s_data eq join " ", sort { $a <=> $b } map { length } values %data ;
231240
232241 }
233242
243 {
244 # db->associate -- primary recno, secondary hash
245
246 sub sec_key3
247 {
248 #print "in sec_key\n";
249 my $pkey = shift ;
250 my $pdata = shift ;
251
252 $_[0] = $pdata ;
253 return 0;
254 }
255
256 my ($Dfile1, $Dfile2);
257 my $lex = new LexFile $Dfile1, $Dfile2 ;
258 my %hash ;
259 my $status;
260 my ($k, $v, $pk) = ('','','');
261
262 # create primary database
263 ok 52, my $primary = new BerkeleyDB::Recno -Filename => $Dfile1,
264 -Flags => DB_CREATE ;
265
266 # create secondary database
267 ok 53, my $secondary = new BerkeleyDB::Hash -Filename => $Dfile2,
268 -Flags => DB_CREATE ;
269
270 # associate primary with secondary
271 ok 54, $primary->associate($secondary, \&sec_key3) == 0;
272
273 # add data to the primary
274 my %data = (
275 0 => "flag",
276 1 => "house",
277 2 => "sea",
278 ) ;
279
280 my $ret = 0 ;
281 while (($k, $v) = each %data) {
282 my $r = $primary->db_put($k, $v) ;
283 #print "put $r $BerkeleyDB::Error\n";
284 $ret += $r;
285 }
286 ok 55, $ret == 0 ;
287
288 # check the records in the secondary
289 ok 56, countRecords($secondary) == 3 ;
290
291 ok 57, $secondary->db_get("flag", $v) == 0;
292 ok 58, $v eq "flag";
293
294 ok 59, $secondary->db_get("house", $v) == 0;
295 ok 60, $v eq "house";
296
297 ok 61, $secondary->db_get("sea", $v) == 0;
298 ok 62, $v eq "sea" ;
299
300 # pget to primary database is illegal
301 ok 63, $primary->db_pget(0, $pk, $v) != 0 ;
302
303 # pget to secondary database is ok
304 ok 64, $secondary->db_pget('house', $pk, $v) == 0 ;
305 ok 65, $pk == 1 ;
306 ok 66, $v eq 'house';
307
308 ok 67, my $p_cursor = $primary->db_cursor();
309 ok 68, my $s_cursor = $secondary->db_cursor();
310
311 # c_get from primary
312 $k = 1;
313 ok 69, $p_cursor->c_get($k, $v, DB_SET) == 0;
314 ok 70, $k == 1;
315 ok 71, $v eq 'house';
316
317 # c_get from secondary
318 $k = 'sea';
319 ok 72, $s_cursor->c_get($k, $v, DB_SET) == 0;
320 ok 73, $k eq 'sea'
321 or warn "# key [$k]\n";
322 ok 74, $v eq 'sea';
323
324 # c_pget from primary database should fail
325 $k = 1;
326 ok 75, $p_cursor->c_pget($k, $pk, $v, DB_FIRST) != 0;
327
328 # c_pget from secondary database
329 $k = 'sea';
330 ok 76, $s_cursor->c_pget($k, $pk, $v, DB_SET) == 0;
331 ok 77, $k eq 'sea' ;
332 ok 78, $pk == 2 ;
333 ok 79, $v eq 'sea';
334
335 # check put to secondary is illegal
336 ok 80, $secondary->db_put("tom", "dick") != 0;
337 ok 81, countRecords($secondary) == 3 ;
338
339 # delete from primary
340 ok 82, $primary->db_del(2) == 0 ;
341 ok 83, countRecords($primary) == 2 ;
342
343 # check has been deleted in secondary
344 ok 84, $secondary->db_get("sea", $v) != 0;
345 ok 85, countRecords($secondary) == 2 ;
346
347 # delete from secondary
348 ok 86, $secondary->db_del('flag') == 0 ;
349 ok 87, countRecords($secondary) == 1 ;
350
351
352 # check deleted from primary
353 ok 88, $primary->db_get(0, $v) != 0;
354 ok 89, countRecords($primary) == 1 ;
355
356 }
357
358 {
359 # db->associate -- primary hash, secondary recno
360
361 sub sec_key4
362 {
363 #print "in sec_key4\n";
364 my $pkey = shift ;
365 my $pdata = shift ;
366
367 $_[0] = length $pdata ;
368 return 0;
369 }
370
371 my ($Dfile1, $Dfile2);
372 my $lex = new LexFile $Dfile1, $Dfile2 ;
373 my %hash ;
374 my $status;
375 my ($k, $v, $pk) = ('','','');
376
377 # create primary database
378 ok 90, my $primary = new BerkeleyDB::Hash -Filename => $Dfile1,
379 -Flags => DB_CREATE ;
380
381 # create secondary database
382 ok 91, my $secondary = new BerkeleyDB::Recno -Filename => $Dfile2,
383 #-Property => DB_DUP,
384 -Flags => DB_CREATE ;
385
386 # associate primary with secondary
387 ok 92, $primary->associate($secondary, \&sec_key4) == 0;
388
389 # add data to the primary
390 my %data = (
391 "red" => "flag",
392 "green" => "house",
393 "blue" => "sea",
394 ) ;
395
396 my $ret = 0 ;
397 while (($k, $v) = each %data) {
398 my $r = $primary->db_put($k, $v) ;
399 #print "put $r $BerkeleyDB::Error\n";
400 $ret += $r;
401 }
402 ok 93, $ret == 0 ;
403
404 # check the records in the secondary
405 ok 94, countRecords($secondary) == 3 ;
406
407 ok 95, $secondary->db_get(0, $v) != 0;
408 ok 96, $secondary->db_get(1, $v) != 0;
409 ok 97, $secondary->db_get(2, $v) != 0;
410 ok 98, $secondary->db_get(3, $v) == 0;
411 ok 99, $v eq "sea";
412
413 ok 100, $secondary->db_get(4, $v) == 0;
414 ok 101, $v eq "flag";
415
416 ok 102, $secondary->db_get(5, $v) == 0;
417 ok 103, $v eq "house";
418
419 # pget to primary database is illegal
420 ok 104, $primary->db_pget(0, $pk, $v) != 0 ;
421
422 # pget to secondary database is ok
423 ok 105, $secondary->db_pget(4, $pk, $v) == 0 ;
424 ok 106, $pk eq 'red'
425 or warn "# $pk\n";;
426 ok 107, $v eq 'flag';
427
428 ok 108, my $p_cursor = $primary->db_cursor();
429 ok 109, my $s_cursor = $secondary->db_cursor();
430
431 # c_get from primary
432 $k = 'green';
433 ok 110, $p_cursor->c_get($k, $v, DB_SET) == 0;
434 ok 111, $k eq 'green';
435 ok 112, $v eq 'house';
436
437 # c_get from secondary
438 $k = 3;
439 ok 113, $s_cursor->c_get($k, $v, DB_SET) == 0;
440 ok 114, $k == 3 ;
441 ok 115, $v eq 'sea';
442
443 # c_pget from primary database should fail
444 $k = 1;
445 ok 116, $p_cursor->c_pget($k, $pk, $v, DB_SET) != 0;
446
447 # c_pget from secondary database
448 $k = 5;
449 ok 117, $s_cursor->c_pget($k, $pk, $v, DB_SET) == 0;
450 ok 118, $k == 5 ;
451 ok 119, $pk eq 'green';
452 ok 120, $v eq 'house';
453
454 # check put to secondary is illegal
455 ok 121, $secondary->db_put(77, "dick") != 0;
456 ok 122, countRecords($secondary) == 3 ;
457
458 # delete from primary
459 ok 123, $primary->db_del("green") == 0 ;
460 ok 124, countRecords($primary) == 2 ;
461
462 # check has been deleted in secondary
463 ok 125, $secondary->db_get(5, $v) != 0;
464 ok 126, countRecords($secondary) == 2 ;
465
466 # delete from secondary
467 ok 127, $secondary->db_del(4) == 0 ;
468 ok 128, countRecords($secondary) == 1 ;
469
470
471 # check deleted from primary
472 ok 129, $primary->db_get("red", $v) != 0;
473 ok 130, countRecords($primary) == 1 ;
474
475 }
0 #!./perl -w
1
2 use strict ;
3
4 use lib 't' ;
5 use BerkeleyDB;
6 use Test::More ;
7 use util (1);
8
9 plan(skip_all => "this needs Berkeley DB 4.4.x or better\n" )
10 if $BerkeleyDB::db_version < 4.4;
11
12 plan tests => 5;
13
14 {
15 title "Testing compact";
16
17 # db->db_compact
18
19 my $Dfile;
20 my $lex = new LexFile $Dfile ;
21 my ($k, $v) ;
22 ok my $db = new BerkeleyDB::Btree -Filename => $Dfile,
23 -Flags => DB_CREATE ;
24
25 # create some data
26 my %data = (
27 "red" => 2,
28 "green" => "house",
29 "blue" => "sea",
30 ) ;
31
32 my $ret = 0 ;
33 while (($k, $v) = each %data) {
34 $ret += $db->db_put($k, $v) ;
35 }
36 ok $ret == 0, " Created some data" ;
37
38 my $key;
39 my $end;
40 my %hash;
41 $hash{compact_filepercent} = 20;
42
43 ok $db->compact("red", "green", \%hash, 0, $end) == 0, " Compacted ok";
44
45 if (0)
46 {
47 diag "end at $end";
48 for my $key (sort keys %hash)
49 {
50 diag "[$key][$hash{$key}]\n";
51 }
52 }
53
54 ok $db->compact() == 0, " Compacted ok";
55 }
56
1313 print "1..0 # Skip: Data::Dumper is not installed on this system.\n";
1414 exit 0 ;
1515 }
16 if ($Data::Dumper::VERSION < 2.08) {
17 print "1..0 # Skip: Data::Dumper 2.08 or better required (found $Data::Dumper::VERSION).\n";
18 exit 0 ;
16 {
17 local ($^W) = 0 ;
18 if ($Data::Dumper::VERSION < 2.08) {
19 print "1..0 # Skip: Data::Dumper 2.08 or better required (found $Data::Dumper::VERSION).\n";
20 exit 0 ;
21 }
1922 }
2023 eval { require MLDBM ; };
2124 if ($@) {
6969
7070 sub new
7171 {
72 my $self = shift ;
72 my $self = shift ;
7373 #my @files = () ;
7474 foreach (@_)
7575 {
7676 $_ = $basename ;
77 unlink $basename ;
77 1 while unlink $basename ;
7878 push @files, $basename ;
7979 ++ $basename ;
8080 }
81 bless [ @files ], $self ;
81 bless [ @files ], $self ;
8282 }
8383
8484 sub DESTROY
8585 {
86 my $self = shift ;
87 #unlink @{ $self } ;
86 my $self = shift ;
87 chmod 0777, @{ $self } ;
88 for (@$self) { 1 while unlink $_ } ;
8889 }
8990
9091 END
77 #
88 #
99
10 SVnull* T_SV_NULL
1011 void * T_PV
1112 u_int T_U_INT
1213 u_int32_t T_U_INT
5354 DBTKEY T_dbtkeydatum
5455 DBTKEY_B T_dbtkeydatum_btree
5556 DBTKEY_Br T_dbtkeydatum_btree_r
57 DBTKEY_Bpr T_dbtkeydatum_btree_pr
5658 DBTYPE T_U_INT
5759 DualType T_DUAL
5860 BerkeleyDB_type * T_IV
8890 else
8991 croak(\"$var is not of type ${ntype}\")
9092
93 T_SV_NULL
94 if ($arg == NULL || $arg == &PL_sv_undef)
95 $var = NULL ;
96 else
97 $var = $arg ;
98
9199 T_HV_REF_NULL
92100 if ($arg == &PL_sv_undef)
93101 $var = NULL ;
214222 DBM_ckFilter(my_sv, filter_store_key, \"filter_store_key\");
215223 DBT_clear($var) ;
216224 SvGETMAGIC($arg) ;
217 if (db->recno_or_queue ||
225 if (db->recno_or_queue ||
226 (db->type == DB_BTREE && flagSet(DB_SET_RECNO))) {
227 Value = GetRecnoKey(db, SvIV(my_sv)) ;
228 $var.data = & Value;
229 $var.size = (int)sizeof(db_recno_t);
230 }
231 else {
232 $var.data = SvPV(my_sv, PL_na);
233 $var.size = (int)PL_na;
234 }
235 }
236
237 T_dbtkeydatum_btree_pr
238 {
239 SV* my_sv = $arg ;
240 DBM_ckFilter(my_sv, filter_store_key, \"filter_store_key\");
241 DBT_clear($var) ;
242 SvGETMAGIC($arg) ;
243 if (db->recno_or_queue ||
218244 (db->type == DB_BTREE && flagSet(DB_SET_RECNO))) {
219245 Value = GetRecnoKey(db, SvIV(my_sv)) ;
220246 $var.data = & Value;
241267
242268 T_dbtdatum_opt
243269 DBT_clear($var) ;
244 if (flagSet(DB_GET_BOTH)) {
270 if (flagSet(DB_GET_BOTH)|| flagSet(DB_GET_BOTH)) {
245271 SV* my_sv = $arg ;
246272 DBM_ckFilter(my_sv, filter_store_value, \"filter_store_value\");
247273 SvGETMAGIC($arg) ;
254280
255281 T_dbtdatum_btree
256282 DBT_clear($var) ;
257 if (flagSet(DB_GET_BOTH)) {
283 if (flagSet(DB_GET_BOTH)|| flagSet(DB_GET_BOTH)) {
258284 SV* my_sv = $arg ;
259285 DBM_ckFilter(my_sv, filter_store_value, \"filter_store_value\");
260286 SvGETMAGIC($arg) ;
268294
269295 OUTPUT
270296
297 T_SV_NULL
298 $arg = $var;
299
271300 T_RAW
272301 sv_setiv($arg, PTR2IV($var));
273302
296325 OutputKey_B($arg, $var)
297326 T_dbtkeydatum_btree_r
298327 OutputKey_Br($arg, $var)
328 T_dbtkeydatum_btree_pr
329 OutputKey_Bpr($arg, $var)
299330 T_dbtkeydatum
300331 OutputKey($arg, $var)
301332 T_dbtdatum