File: DB_File.html

package info (click to toggle)
perl-doc-html 5.26.0-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 39,400 kB
  • sloc: xml: 36; makefile: 7
file content (1237 lines) | stat: -rw-r--r-- 154,435 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>DB_File - perldoc.perl.org</title>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta http-equiv="Content-Language" content="en-gb">
  <link rel="search" type="application/opensearchdescription+xml" title="Search perldoc.perl.org" href="/static/search.xml"/>
  <link href="static/css-20100830.css" rel="stylesheet" rev="stylesheet" type="text/css" media="screen">
  <link href="static/exploreperl.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>

<body onLoad="perldoc.startup();" onPageShow="if (event.persisted) perldoc.startup();">
    <div id="page">
      
      <div id="header">
	<div id="homepage_link">
	  <a href="index.html"></a>
	</div>
	<div id="strapline">
	  Perl Programming Documentation
	</div>
	<div id="download_link" class="download">
	  <a href="http://www.perl.org/get.html">Download Perl</a>
	</div>
	<div id="explore_link" class="download">
	  <a id="explore_anchor" href="#">Explore</a>
	</div>
      </div>
      
      <div id="body">
        <div id="left_column">
          <div class="side_group">
            
	    <div class="side_panel doc_panel">
              <p>Manual</p>
              <ul>
                <li><a href="index-overview.html">Overview</a>
                <li><a href="index-tutorials.html">Tutorials</a>
                <li><a href="index-faq.html">FAQs</a>
                <li><a href="index-history.html">History / Changes</a>
                <li><a href="index-licence.html">License</a>
              </ul>
            </div>
            <div class="side_panel doc_panel">
              <p>Reference</p>
              <ul>
                <li><a href="index-language.html">Language</a>
                <li><a href="index-functions.html">Functions</a>
                <li><a href="perlop.html">Operators</a>
                <li><a href="perlvar.html">Special Variables</a>
                <li><a href="index-pragmas.html">Pragmas</a>
                <li><a href="index-utilities.html">Utilities</a>
                <li><a href="index-internals.html">Internals</a>
                <li><a href="index-platforms.html">Platform Specific</a>
              </ul>
            </div>
            <div class="side_panel doc_panel">
              <p>Modules</p>
              <ul>
		<li>
		
                
                  
		    
		  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		
                  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		
                  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		    
		  
		
                  
		
                  
		
                  
		    
		  
		
                  
		
                  
		
		
                    <a href="index-modules-A.html">A</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-B.html">B</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-C.html">C</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-D.html">D</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-E.html">E</a>
                    
                      
                        <li>
                      
                    
                
                    <a href="index-modules-F.html">F</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-G.html">G</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-H.html">H</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-I.html">I</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-L.html">L</a>
                    
                      
                        <li>
                      
                    
                
                    <a href="index-modules-M.html">M</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-N.html">N</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-O.html">O</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-P.html">P</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-S.html">S</a>
                    
                      
                        <li>
                      
                    
                
                    <a href="index-modules-T.html">T</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-U.html">U</a>
                    
                      
                        &bull;
                      
                    
                
                    <a href="index-modules-X.html">X</a>
                    
                
              </ul>
            </div>
            
	      <div class="side_panel doc_panel">
		<p>Tools</p>
		<ul>
		  <li><a href="preferences.html">Preferences</a>
		</ul>
	      </div>
            
          </div>
        </div>
        <div id="centre_column">
          <div id="content_header">
            <div id="title_bar">
              <div id="page_name">
                <h1>DB_File</h1>
              </div>
              <div id="perl_version">
                Perl 5 version 26.0 documentation
              </div>
              <div class="page_links" id="page_links_top">
                <a href="#" onClick="toolbar.goToTop();return false;">Go to top</a>
		
              </div>
	      <div class="page_links" id="page_links_bottom">
		
                  <a href="#" id="page_index_toggle">Show page index</a> &bull;
		
                <a href="#" id="recent_pages_toggle">Show recent pages</a>		
	      </div>
	      <div id="search_form">
		<form action="search.html" method="GET" id="search">
		  <input type="text" name="q" id="search_box" alt="Search">
		</form>
	      </div>
            </div>
            <div id="breadcrumbs">
                
    <a href="index.html">Home</a> &gt;
    
      
        <a href="index-modules-D.html">Core modules (D)</a> &gt;
      
    
    DB_File
  

            </div>
          </div>
          <div id="content_body">
	    <!--[if lt IE 7]>
 <div class="noscript">
   <p>
     <strong>It looks like you're using Internet Explorer 6. This is a very old
     browser which does not offer full support for modern websites.</strong>
   </p>
   <p>
     Unfortunately this means that this website will not work on
     your computer.
   </p>
   <p>
     Don't miss out though! To view the site (and get a better experience from
     many other websites), simply upgrade to
     <a href="http://www.microsoft.com/windows/Internet-explorer/default.aspx">Internet
Explorer 8</a>
     or download an alternative browser such as
     <a href="http://www.mozilla.com/en-US/firefox/firefox.html">Firefox</a>,
     <a href="http://www.apple.com/safari/download/">Safari</a>, or
     <a href="http://www.google.co.uk/chrome">Google Chrome</a>.
   </p>
   <p>
     All of these browsers are free. If you're using a PC at work, you may
     need to contact your IT administrator.
   </p>
 </div>
<![endif]-->
	    <noscript>
	      <div class="noscript">
	      <p>
                <strong>Please note: Many features of this site require JavaScript. You appear to have JavaScript disabled,
	        or are running a non-JavaScript capable web browser.</strong>
	      </p>
	      <p>
		To get the best experience, please enable JavaScript or download a modern web browser such as <a href="http://www.microsoft.com/windows/Internet-explorer/default.aspx">Internet Explorer 8</a>, <a href="http://www.mozilla.com/en-US/firefox/firefox.html">Firefox</a>, <a href="http://www.apple.com/safari/download/">Safari</a>, or <a href="http://www.google.co.uk/chrome">Google Chrome</a>.
              </p>
	      </div>
	    </noscript>

	    <div id="recent_pages" class="hud_container">
	      <div id="recent_pages_header" class="hud_header">
		<div id="recent_pages_close" class="hud_close"><a href="#" onClick="recentPages.hide();return false;"></a></div>
		<div id="recent_pages_title" class="hud_title"><span class="hud_span_top">Recently read</span></div>
		<div id="recent_pages_topright" class="hud_topright"></div>
	      </div>
	      <div id="recent_pages_content" class="hud_content">
	      </div>
	      <div id="recent_pages_footer" class="hud_footer">
		<div id="recent_pages_bottomleft" class="hud_bottomleft"></div>
		<div id="recent_pages_bottom" class="hud_bottom"><span class="hud_span_bottom"></span></div>
		<div id="recent_pages_resize" class="hud_resize"></div>
	      </div>
	    </div>
  
	    <div id="from_search"></div>
            <h1>DB_File</h1>


  <!--    -->
<ul><li><a href="#NAME">NAME</a><li><a href="#SYNOPSIS">SYNOPSIS</a><li><a href="#DESCRIPTION">DESCRIPTION</a><ul><li><a href="#Using-DB_File-with-Berkeley-DB-version-2-or-greater">Using DB_File with Berkeley DB version 2 or greater</a><li><a href="#Interface-to-Berkeley-DB">Interface to Berkeley DB</a><li><a href="#Opening-a-Berkeley-DB-Database-File">Opening a Berkeley DB Database File</a><li><a href="#Default-Parameters">Default Parameters</a><li><a href="#In-Memory-Databases">In Memory Databases</a></ul><li><a href="#DB_HASH">DB_HASH</a><ul><li><a href="#A-Simple-Example">A Simple Example</a></ul><li><a href="#DB_BTREE">DB_BTREE</a><ul><li><a href="#Changing-the-BTREE-sort-order">Changing the BTREE sort order</a><li><a href="#Handling-Duplicate-Keys">Handling Duplicate Keys</a><li><a href="#The-get_dup()-Method">The get_dup() Method</a><li><a href="#The-find_dup()-Method">The find_dup() Method</a><li><a href="#The-del_dup()-Method">The del_dup() Method</a><li><a href="#Matching-Partial-Keys">Matching Partial Keys</a></ul><li><a href="#DB_RECNO">DB_RECNO</a><ul><li><a href="#The-'bval'-Option">The 'bval' Option</a><li><a href="#A-Simple-Example">A Simple Example</a><li><a href="#Extra-RECNO-Methods">Extra RECNO Methods</a><li><a href="#Another-Example">Another Example</a></ul><li><a href="#THE-API-INTERFACE">THE API INTERFACE</a><li><a href="#DBM-FILTERS">DBM FILTERS</a><ul><li><a href="#DBM-Filter-Low-level-API">DBM Filter Low-level API</a><li><a href="#The-Filter">The Filter</a><li><a href="#An-Example----the-NULL-termination-problem.">An Example -- the NULL termination problem.</a><li><a href="#Another-Example----Key-is-a-C-int.">Another Example -- Key is a C int.</a></ul><li><a href="#HINTS-AND-TIPS">HINTS AND TIPS</a><ul><li><a href="#Locking%3a-The-Trouble-with-fd">Locking: The Trouble with fd</a><li><a href="#Safe-ways-to-lock-a-database">Safe ways to lock a database</a><li><a href="#Sharing-Databases-With-C-Applications">Sharing Databases With C Applications</a><li><a href="#The-untie()-Gotcha">The untie() Gotcha</a></ul><li><a href="#COMMON-QUESTIONS">COMMON QUESTIONS</a><ul><li><a href="#Why-is-there-Perl-source-in-my-database%3f">Why is there Perl source in my database?</a><li><a href="#How-do-I-store-complex-data-structures-with-DB_File%3f">How do I store complex data structures with DB_File?</a><li><a href="#What-does-%22wide-character-in-subroutine-entry%22-mean%3f">What does "wide character in subroutine entry" mean?</a><li><a href="#What-does-%22Invalid-Argument%22-mean%3f">What does "Invalid Argument" mean?</a><li><a href="#What-does-%22Bareword-'DB_File'-not-allowed%22-mean%3f">What does "Bareword 'DB_File' not allowed" mean?</a></ul><li><a href="#REFERENCES">REFERENCES</a><li><a href="#HISTORY">HISTORY</a><li><a href="#BUGS">BUGS</a><li><a href="#AVAILABILITY">AVAILABILITY</a><li><a href="#COPYRIGHT">COPYRIGHT</a><li><a href="#SEE-ALSO">SEE ALSO</a><li><a href="#AUTHOR">AUTHOR</a></ul><a name="NAME"></a><h1>NAME</h1>
<p>DB_File - Perl5 access to Berkeley DB version 1.x</p>
<a name="SYNOPSIS"></a><h1>SYNOPSIS</h1>
<pre class="verbatim"><ol><li> <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span><span class="sc">;</span></li><li></li><li> <span class="s">[</span><span class="i">$X</span> =<span class="s">]</span> <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%hash</span><span class="cm">,</span>  <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="s">[</span><span class="i">$filename</span><span class="cm">,</span> <span class="i">$flags</span><span class="cm">,</span> <span class="i">$mode</span><span class="cm">,</span> <span class="i">$DB_HASH</span><span class="s">]</span> <span class="sc">;</span></li><li> <span class="s">[</span><span class="i">$X</span> =<span class="s">]</span> <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%hash</span><span class="cm">,</span>  <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="i">$flags</span><span class="cm">,</span> <span class="i">$mode</span><span class="cm">,</span> <span class="i">$DB_BTREE</span> <span class="sc">;</span></li><li> <span class="s">[</span><span class="i">$X</span> =<span class="s">]</span> <a class="l_k" href="functions/tie.html">tie</a> <span class="i">@array</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="i">$flags</span><span class="cm">,</span> <span class="i">$mode</span><span class="cm">,</span> <span class="i">$DB_RECNO</span> <span class="sc">;</span></li><li></li><li> <span class="i">$status</span> = <span class="i">$X</span><span class="i">-&gt;del</span><span class="s">(</span><span class="i">$key</span> [<span class="cm">,</span> <span class="i">$flags</span>]<span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">$status</span> = <span class="i">$X</span><span class="i">-&gt;put</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span> [<span class="cm">,</span> <span class="i">$flags</span>]<span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">$status</span> = <span class="i">$X</span><span class="i">-&gt;get</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span> [<span class="cm">,</span> <span class="i">$flags</span>]<span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">$status</span> = <span class="i">$X</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="i">$flags</span><span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">$status</span> = <span class="i">$X</span><span class="i">-&gt;sync</span><span class="s">(</span><span class="s">[</span><span class="i">$flags</span><span class="s">]</span><span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">$status</span> = <span class="i">$X</span><span class="i">-&gt;fd</span> <span class="sc">;</span></li><li></li><li> <span class="c"># BTREE only</span></li><li> <span class="i">$count</span> = <span class="i">$X</span><span class="i">-&gt;get_dup</span><span class="s">(</span><span class="i">$key</span><span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">@list</span>  = <span class="i">$X</span><span class="i">-&gt;get_dup</span><span class="s">(</span><span class="i">$key</span><span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">%list</span>  = <span class="i">$X</span><span class="i">-&gt;get_dup</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="n">1</span><span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">$status</span> = <span class="i">$X</span><span class="i">-&gt;find_dup</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">$status</span> = <span class="i">$X</span><span class="i">-&gt;del_dup</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li> <span class="c"># RECNO only</span></li><li> <span class="i">$a</span> = <span class="i">$X</span><span class="i">-&gt;length</span><span class="sc">;</span></li><li> <span class="i">$a</span> = <span class="i">$X</span><span class="i">-&gt;pop</span> <span class="sc">;</span></li><li> <span class="i">$X</span><span class="i">-&gt;push</span><span class="s">(</span><span class="w">list</span><span class="s">)</span><span class="sc">;</span></li><li> <span class="i">$a</span> = <span class="i">$X</span><span class="i">-&gt;shift</span><span class="sc">;</span></li><li> <span class="i">$X</span><span class="i">-&gt;unshift</span><span class="s">(</span><span class="w">list</span><span class="s">)</span><span class="sc">;</span></li><li> <span class="i">@r</span> = <span class="i">$X</span><span class="i">-&gt;splice</span><span class="s">(</span><span class="w">offset</span><span class="cm">,</span> <a class="l_k" href="functions/length.html">length</a><span class="cm">,</span> <span class="w">elements</span><span class="s">)</span><span class="sc">;</span></li><li></li><li> <span class="c"># DBM Filters</span></li><li> <span class="i">$old_filter</span> = <span class="i">$db</span><span class="i">-&gt;filter_store_key</span>  <span class="s">(</span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> ... <span class="s">}</span> <span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">$old_filter</span> = <span class="i">$db</span><span class="i">-&gt;filter_store_value</span><span class="s">(</span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> ... <span class="s">}</span> <span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">$old_filter</span> = <span class="i">$db</span><span class="i">-&gt;filter_fetch_key</span>  <span class="s">(</span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> ... <span class="s">}</span> <span class="s">)</span> <span class="sc">;</span></li><li> <span class="i">$old_filter</span> = <span class="i">$db</span><span class="i">-&gt;filter_fetch_value</span><span class="s">(</span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> ... <span class="s">}</span> <span class="s">)</span> <span class="sc">;</span></li><li></li><li> <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%hash</span> <span class="sc">;</span></li><li> <a class="l_k" href="functions/untie.html">untie</a> <span class="i">@array</span> <span class="sc">;</span></li></ol></pre><a name="DESCRIPTION"></a><h1>DESCRIPTION</h1>
<p><b>DB_File</b> is a module which allows Perl programs to make use of the
facilities provided by Berkeley DB version 1.x (if you have a newer
version of DB, see <a href="#Using-DB_File-with-Berkeley-DB-version-2-or-greater">Using DB_File with Berkeley DB version 2 or greater</a>).
It is assumed that you have a copy of the Berkeley DB manual pages at
hand when reading this documentation. The interface defined here
mirrors the Berkeley DB interface closely.</p>
<p>Berkeley DB is a C library which provides a consistent interface to a
number of database formats.  <b>DB_File</b> provides an interface to all
three of the database types currently supported by Berkeley DB.</p>
<p>The file types are:</p>
<ul>
<li><a name="*DB_HASH*"></a><b><b>DB_HASH</b></b>
<p>This database type allows arbitrary key/value pairs to be stored in data
files. This is equivalent to the functionality provided by other
hashing packages like DBM, NDBM, ODBM, GDBM, and SDBM. Remember though,
the files created using DB_HASH are not compatible with any of the
other packages mentioned.</p>
<p>A default hashing algorithm, which will be adequate for most
applications, is built into Berkeley DB. If you do need to use your own
hashing algorithm it is possible to write your own in Perl and have
<b>DB_File</b> use it instead.</p>
</li>
<li><a name="*DB_BTREE*"></a><b><b>DB_BTREE</b></b>
<p>The btree format allows arbitrary key/value pairs to be stored in a
sorted, balanced binary tree.</p>
<p>As with the DB_HASH format, it is possible to provide a user defined
Perl routine to perform the comparison of keys. By default, though, the
keys are stored in lexical order.</p>
</li>
<li><a name="*DB_RECNO*"></a><b><b>DB_RECNO</b></b>
<p>DB_RECNO allows both fixed-length and variable-length flat text files
to be manipulated using the same key/value pair interface as in DB_HASH
and DB_BTREE.  In this case the key will consist of a record (line)
number.</p>
</li>
</ul>
<a name="Using-DB_File-with-Berkeley-DB-version-2-or-greater"></a><h2>Using DB_File with Berkeley DB version 2 or greater</h2>
<p>Although <b>DB_File</b> is intended to be used with Berkeley DB version 1,
it can also be used with version 2, 3 or 4. In this case the interface is
limited to the functionality provided by Berkeley DB 1.x. Anywhere the
version 2 or greater interface differs, <b>DB_File</b> arranges for it to work
like version 1. This feature allows <b>DB_File</b> scripts that were built
with version 1 to be migrated to version 2 or greater without any changes.</p>
<p>If you want to make use of the new features available in Berkeley DB
2.x or greater, use the Perl module <b>BerkeleyDB</b> instead.</p>
<p><b>Note:</b> The database file format has changed multiple times in Berkeley
DB version 2, 3 and 4. If you cannot recreate your databases, you
must dump any existing databases with either the <code class="inline"><span class="w">db_dump</span></code>
 or the
<code class="inline"><span class="w">db_dump185</span></code>
 utility that comes with Berkeley DB.
Once you have rebuilt DB_File to use Berkeley DB version 2 or greater,
your databases can be recreated using <code class="inline"><span class="w">db_load</span></code>
. Refer to the Berkeley DB
documentation for further details.</p>
<p>Please read <a href="#COPYRIGHT">COPYRIGHT</a> before using version 2.x or greater of Berkeley
DB with DB_File.</p>
<a name="Interface-to-Berkeley-DB"></a><h2>Interface to Berkeley DB</h2>
<p><b>DB_File</b> allows access to Berkeley DB files using the tie() mechanism
in Perl 5 (for full details, see <a href="functions/tie.html">tie()</a>). This facility
allows <b>DB_File</b> to access Berkeley DB files using either an
associative array (for DB_HASH &amp; DB_BTREE file types) or an ordinary
array (for the DB_RECNO file type).</p>
<p>In addition to the tie() interface, it is also possible to access most
of the functions provided in the Berkeley DB API directly.
See <a href="#THE-API-INTERFACE">THE API INTERFACE</a>.</p>
<a name="Opening-a-Berkeley-DB-Database-File"></a><h2>Opening a Berkeley DB Database File</h2>
<p>Berkeley DB uses the function dbopen() to open or create a database.
Here is the C prototype for dbopen():</p>
<pre class="verbatim"><ol><li>      <span class="w">DB</span>*</li><li>      <span class="w">dbopen</span> <span class="s">(</span><span class="w">const</span> <span class="w">char</span> * <span class="w">file</span><span class="cm">,</span> <a class="l_k" href="functions/int.html">int</a> <span class="w">flags</span><span class="cm">,</span> <a class="l_k" href="functions/int.html">int</a> <span class="w">mode</span><span class="cm">,</span> </li><li>              <span class="w">DBTYPE</span> <span class="w">type</span><span class="cm">,</span> <span class="w">const</span> <span class="w">void</span> * <span class="w">openinfo</span><span class="s">)</span></li></ol></pre><p>The parameter <code class="inline"><span class="w">type</span></code>
 is an enumeration which specifies which of the 3
interface methods (DB_HASH, DB_BTREE or DB_RECNO) is to be used.
Depending on which of these is actually chosen, the final parameter,
<i>openinfo</i> points to a data structure which allows tailoring of the
specific interface method.</p>
<p>This interface is handled slightly differently in <b>DB_File</b>. Here is
an equivalent call using <b>DB_File</b>:</p>
<pre class="verbatim"><ol><li>        <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%array</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="i">$flags</span><span class="cm">,</span> <span class="i">$mode</span><span class="cm">,</span> <span class="i">$DB_HASH</span> <span class="sc">;</span></li></ol></pre><p>The <code class="inline"><span class="w">filename</span></code>
, <code class="inline"><span class="w">flags</span></code>
 and <code class="inline"><span class="w">mode</span></code>
 parameters are the direct
equivalent of their dbopen() counterparts. The final parameter $DB_HASH
performs the function of both the <code class="inline"><span class="w">type</span></code>
 and <code class="inline"><span class="w">openinfo</span></code>
 parameters in
dbopen().</p>
<p>In the example above $DB_HASH is actually a pre-defined reference to a
hash object. <b>DB_File</b> has three of these pre-defined references.
Apart from $DB_HASH, there is also $DB_BTREE and $DB_RECNO.</p>
<p>The keys allowed in each of these pre-defined references is limited to
the names used in the equivalent C structure. So, for example, the
$DB_HASH reference will only allow keys called <code class="inline"><span class="w">bsize</span></code>
, <code class="inline"><span class="w">cachesize</span></code>
,
<code class="inline"><span class="w">ffactor</span></code>
, <code class="inline"><span class="w">hash</span></code>
, <code class="inline"><span class="w">lorder</span></code>
 and <code class="inline"><span class="w">nelem</span></code>
.</p>
<p>To change one of these elements, just assign to it like this:</p>
<pre class="verbatim"><ol><li>	<span class="i">$DB_HASH</span>-&gt;{<span class="q">&#39;cachesize&#39;</span>} = <span class="n">10000</span> <span class="sc">;</span></li></ol></pre><p>The three predefined variables $DB_HASH, $DB_BTREE and $DB_RECNO are
usually adequate for most applications.  If you do need to create extra
instances of these objects, constructors are available for each file
type.</p>
<p>Here are examples of the constructors and the valid options available
for DB_HASH, DB_BTREE and DB_RECNO respectively.</p>
<pre class="verbatim"><ol><li>     <span class="i">$a</span> = <span class="w">new</span> <span class="w">DB_File::HASHINFO</span> <span class="sc">;</span></li><li>     <span class="i">$a</span>-&gt;{<span class="q">&#39;bsize&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$a</span>-&gt;{<span class="q">&#39;cachesize&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$a</span>-&gt;{<span class="q">&#39;ffactor&#39;</span>}<span class="sc">;</span></li><li>     <span class="i">$a</span>-&gt;{<span class="q">&#39;hash&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$a</span>-&gt;{<span class="q">&#39;lorder&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$a</span>-&gt;{<span class="q">&#39;nelem&#39;</span>} <span class="sc">;</span></li><li></li><li>     <span class="i">$b</span> = <span class="w">new</span> <span class="w">DB_File::BTREEINFO</span> <span class="sc">;</span></li><li>     <span class="i">$b</span>-&gt;{<span class="q">&#39;flags&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$b</span>-&gt;{<span class="q">&#39;cachesize&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$b</span>-&gt;{<span class="q">&#39;maxkeypage&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$b</span>-&gt;{<span class="q">&#39;minkeypage&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$b</span>-&gt;{<span class="q">&#39;psize&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$b</span>-&gt;{<span class="q">&#39;compare&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$b</span>-&gt;{<span class="q">&#39;prefix&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$b</span>-&gt;{<span class="q">&#39;lorder&#39;</span>} <span class="sc">;</span></li><li></li><li>     <span class="i">$c</span> = <span class="w">new</span> <span class="w">DB_File::RECNOINFO</span> <span class="sc">;</span></li><li>     <span class="i">$c</span>-&gt;{<span class="q">&#39;bval&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$c</span>-&gt;{<span class="q">&#39;cachesize&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$c</span>-&gt;{<span class="q">&#39;psize&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$c</span>-&gt;{<span class="q">&#39;flags&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$c</span>-&gt;{<span class="q">&#39;lorder&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$c</span>-&gt;{<span class="q">&#39;reclen&#39;</span>} <span class="sc">;</span></li><li>     <span class="i">$c</span>-&gt;{<span class="q">&#39;bfname&#39;</span>} <span class="sc">;</span></li></ol></pre><p>The values stored in the hashes above are mostly the direct equivalent
of their C counterpart. Like their C counterparts, all are set to a
default values - that means you don't have to set <i>all</i> of the
values when you only want to change one. Here is an example:</p>
<pre class="verbatim"><ol><li>     <span class="i">$a</span> = <span class="w">new</span> <span class="w">DB_File::HASHINFO</span> <span class="sc">;</span></li><li>     <span class="i">$a</span>-&gt;{<span class="q">&#39;cachesize&#39;</span>} =  <span class="n">12345</span> <span class="sc">;</span></li><li>     <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%y</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="q">&quot;filename&quot;</span><span class="cm">,</span> <span class="i">$flags</span><span class="cm">,</span> <span class="n">0777</span><span class="cm">,</span> <span class="i">$a</span> <span class="sc">;</span></li></ol></pre><p>A few of the options need extra discussion here. When used, the C
equivalent of the keys <code class="inline"><span class="w">hash</span></code>
, <code class="inline"><span class="w">compare</span></code>
 and <code class="inline"><span class="w">prefix</span></code>
 store pointers
to C functions. In <b>DB_File</b> these keys are used to store references
to Perl subs. Below are templates for each of the subs:</p>
<pre class="verbatim"><ol><li><a name="hash"></a>    sub <span class="m">hash</span></li><li>    <span class="s">{</span></li><li>        <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$data</span><span class="s">)</span> = <span class="i">@_</span> <span class="sc">;</span></li><li>        ...</li><li>        <span class="c"># return the hash value for $data</span></li><li>	<a class="l_k" href="functions/return.html">return</a> <span class="i">$hash</span> <span class="sc">;</span></li><li>    <span class="s">}</span></li><li></li><li><a name="compare"></a>    sub <span class="m">compare</span></li><li>    <span class="s">{</span></li><li>	<a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$key2</span><span class="s">)</span> = <span class="i">@_</span> <span class="sc">;</span></li><li>        ...</li><li>        <span class="c"># return  0 if $key1 eq $key2</span></li><li>        <span class="c">#        -1 if $key1 lt $key2</span></li><li>        <span class="c">#         1 if $key1 gt $key2</span></li><li>        <a class="l_k" href="functions/return.html">return</a> <span class="s">(</span><span class="n">-1</span> <span class="cm">,</span> <span class="n">0</span> or <span class="n">1</span><span class="s">)</span> <span class="sc">;</span></li><li>    <span class="s">}</span></li><li></li><li><a name="prefix"></a>    sub <span class="m">prefix</span></li><li>    <span class="s">{</span></li><li>	<a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$key2</span><span class="s">)</span> = <span class="i">@_</span> <span class="sc">;</span></li><li>        ...</li><li>        <span class="c"># return number of bytes of $key2 which are </span></li><li>        <span class="c"># necessary to determine that it is greater than $key1</span></li><li>        <a class="l_k" href="functions/return.html">return</a> <span class="i">$bytes</span> <span class="sc">;</span></li><li>    <span class="s">}</span></li></ol></pre><p>See <a href="#Changing-the-BTREE-sort-order">Changing the BTREE sort order</a> for an example of using the
<code class="inline"><span class="w">compare</span></code>
 template.</p>
<p>If you are using the DB_RECNO interface and you intend making use of
<code class="inline"><span class="w">bval</span></code>
, you should check out <a href="#The-'bval'-Option">The 'bval' Option</a>.</p>
<a name="Default-Parameters"></a><h2>Default Parameters</h2>
<p>It is possible to omit some or all of the final 4 parameters in the
call to <code class="inline"><a class="l_k" href="functions/tie.html">tie</a></code> and let them take default values. As DB_HASH is the most
common file format used, the call:</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%A</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="q">&quot;filename&quot;</span> <span class="sc">;</span></li></ol></pre><p>is equivalent to:</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%A</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="q">&quot;filename&quot;</span><span class="cm">,</span> <span class="w">O_CREAT</span>|<span class="w">O_RDWR</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_HASH</span> <span class="sc">;</span></li></ol></pre><p>It is also possible to omit the filename parameter as well, so the
call:</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%A</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span> <span class="sc">;</span></li></ol></pre><p>is equivalent to:</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%A</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <a class="l_k" href="functions/undef.html">undef</a><span class="cm">,</span> <span class="w">O_CREAT</span>|<span class="w">O_RDWR</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_HASH</span> <span class="sc">;</span></li></ol></pre><p>See <a href="#In-Memory-Databases">In Memory Databases</a> for a discussion on the use of <code class="inline"><a class="l_k" href="functions/undef.html">undef</a></code>
in place of a filename.</p>
<a name="In-Memory-Databases"></a><h2>In Memory Databases</h2>
<p>Berkeley DB allows the creation of in-memory databases by using NULL
(that is, a <code class="inline">(char *)0</code> in C) in place of the filename.  <b>DB_File</b>
uses <code class="inline"><a class="l_k" href="functions/undef.html">undef</a></code> instead of NULL to provide this functionality.</p>
<a name="DB_HASH"></a><h1>DB_HASH</h1>
<p>The DB_HASH file format is probably the most commonly used of the three
file formats that <b>DB_File</b> supports. It is also very straightforward
to use.</p>
<a name="A-Simple-Example"></a><h2>A Simple Example</h2>
<p>This example shows how to create a database, add key/value pairs to the
database, delete keys/value pairs and finally how to enumerate the
contents of the database.</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/our.html">our</a> <span class="s">(</span><span class="i">%h</span><span class="cm">,</span> <span class="i">$k</span><span class="cm">,</span> <span class="i">$v</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/unlink.html">unlink</a> <span class="q">&quot;fruit&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%h</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="q">&quot;fruit&quot;</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_HASH</span> </li><li>        or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open file &#39;fruit&#39;: $!\n&quot;</span><span class="sc">;</span></li><li></li><li>    <span class="c"># Add a few key/value pairs to the file</span></li><li>    <span class="i">$h</span>{<span class="q">&quot;apple&quot;</span>} = <span class="q">&quot;red&quot;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&quot;orange&quot;</span>} = <span class="q">&quot;orange&quot;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&quot;banana&quot;</span>} = <span class="q">&quot;yellow&quot;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&quot;tomato&quot;</span>} = <span class="q">&quot;red&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Check for existence of a key</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Banana Exists\n\n&quot;</span> if <span class="i">$h</span>{<span class="q">&quot;banana&quot;</span>} <span class="sc">;</span></li><li></li><li>    <span class="c"># Delete a key/value pair.</span></li><li>    <a class="l_k" href="functions/delete.html">delete</a> <span class="i">$h</span>{<span class="q">&quot;apple&quot;</span>} <span class="sc">;</span></li><li></li><li>    <span class="c"># print the contents of the file</span></li><li>    while <span class="s">(</span><span class="s">(</span><span class="i">$k</span><span class="cm">,</span> <span class="i">$v</span><span class="s">)</span> = <a class="l_k" href="functions/each.html">each</a> <span class="i">%h</span><span class="s">)</span></li><li>      <span class="s">{</span> <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;$k -&gt; $v\n&quot;</span> <span class="s">}</span></li><li></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%h</span> <span class="sc">;</span></li></ol></pre><p>here is the output:</p>
<pre class="verbatim"><ol><li>    <span class="w">Banana</span> <span class="w">Exists</span></li><li></li><li>    <span class="w">orange</span> <span class="w">-&gt; orange</span></li><li>    <span class="w">tomato</span> <span class="w">-&gt; red</span></li><li>    <span class="w">banana</span> <span class="w">-&gt; yellow</span></li></ol></pre><p>Note that the like ordinary associative arrays, the order of the keys
retrieved is in an apparently random order.</p>
<a name="DB_BTREE"></a><h1>DB_BTREE</h1>
<p>The DB_BTREE format is useful when you want to store data in a given
order. By default the keys will be stored in lexical order, but as you
will see from the example shown in the next section, it is very easy to
define your own sorting function.</p>
<a name="Changing-the-BTREE-sort-order"></a><h2>Changing the BTREE sort order</h2>
<p>This script shows how to override the default sorting algorithm that
BTREE uses. Instead of using the normal lexical ordering, a case
insensitive compare function will be used.</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">%h</span> <span class="sc">;</span></li><li></li><li><a name="Compare"></a>    sub <span class="m">Compare</span></li><li>    <span class="s">{</span></li><li>        <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$key1</span><span class="cm">,</span> <span class="i">$key2</span><span class="s">)</span> = <span class="i">@_</span> <span class="sc">;</span></li><li>        <span class="q">&quot;\L$key1&quot;</span> cmp <span class="q">&quot;\L$key2&quot;</span> <span class="sc">;</span></li><li>    <span class="s">}</span></li><li></li><li>    <span class="c"># specify the Perl sub that will do the comparison</span></li><li>    <span class="i">$DB_BTREE</span>-&gt;{<span class="q">&#39;compare&#39;</span>} = \<span class="i">&amp;Compare</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/unlink.html">unlink</a> <span class="q">&quot;tree&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%h</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="q">&quot;tree&quot;</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_BTREE</span> </li><li>        or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open file &#39;tree&#39;: $!\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Add a key/value pair to the file</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Wall&#39;</span>} = <span class="q">&#39;Larry&#39;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Smith&#39;</span>} = <span class="q">&#39;John&#39;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;mouse&#39;</span>} = <span class="q">&#39;mickey&#39;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;duck&#39;</span>}  = <span class="q">&#39;donald&#39;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Delete</span></li><li>    <a class="l_k" href="functions/delete.html">delete</a> <span class="i">$h</span>{<span class="q">&quot;duck&quot;</span>} <span class="sc">;</span></li><li></li><li>    <span class="c"># Cycle through the keys printing them in order.</span></li><li>    <span class="c"># Note it is not necessary to sort the keys as</span></li><li>    <span class="c"># the btree will have kept them in order automatically.</span></li><li>    foreach <span class="s">(</span><a class="l_k" href="functions/keys.html">keys</a> <span class="i">%h</span><span class="s">)</span></li><li>      <span class="s">{</span> <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;$_\n&quot;</span> <span class="s">}</span></li><li></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%h</span> <span class="sc">;</span></li></ol></pre><p>Here is the output from the code above.</p>
<pre class="verbatim"><ol><li>    <span class="w">mouse</span></li><li>    <span class="w">Smith</span></li><li>    <span class="w">Wall</span></li></ol></pre><p>There are a few point to bear in mind if you want to change the
ordering in a BTREE database:</p>
<dl>
<dt>1.</dt><dd>
<p>The new compare function must be specified when you create the database.</p>
</dd>
<dt>2.</dt><dd>
<p>You cannot change the ordering once the database has been created. Thus
you must use the same compare function every time you access the
database.</p>
</dd>
<dt>3</dt><dd>
<p>Duplicate keys are entirely defined by the comparison function.
In the case-insensitive example above, the keys: 'KEY' and 'key'
would be considered duplicates, and assigning to the second one
would overwrite the first. If duplicates are allowed for (with the
R_DUP flag discussed below), only a single copy of duplicate keys
is stored in the database --- so (again with example above) assigning
three values to the keys: 'KEY', 'Key', and 'key' would leave just
the first key: 'KEY' in the database with three values. For some
situations this results in information loss, so care should be taken
to provide fully qualified comparison functions when necessary.
For example, the above comparison routine could be modified to
additionally compare case-sensitively if two keys are equal in the
case insensitive comparison:</p>
<pre class="verbatim"><ol><li><a name="compare"></a>    sub <span class="m">compare</span> <span class="s">{</span></li><li>        <a class="l_k" href="functions/my.html">my</a><span class="s">(</span><span class="i">$key1</span><span class="cm">,</span> <span class="i">$key2</span><span class="s">)</span> = <span class="i">@_</span><span class="sc">;</span></li><li>        <a class="l_k" href="functions/lc.html">lc</a> <span class="i">$key1</span> cmp <a class="l_k" href="functions/lc.html">lc</a> <span class="i">$key2</span> ||</li><li>        <span class="i">$key1</span> cmp <span class="i">$key2</span><span class="sc">;</span></li><li>    <span class="s">}</span></li></ol></pre><p>And now you will only have duplicates when the keys themselves
are truly the same. (note: in versions of the db library prior to
about November 1996, such duplicate keys were retained so it was
possible to recover the original keys in sets of keys that
compared as equal).</p>
</dd>
</dl>
<a name="Handling-Duplicate-Keys"></a><h2>Handling Duplicate Keys</h2>
<p>The BTREE file type optionally allows a single key to be associated
with an arbitrary number of values. This option is enabled by setting
the flags element of <code class="inline"><span class="i">$DB_BTREE</span></code>
 to R_DUP when creating the database.</p>
<p>There are some difficulties in using the tied hash interface if you
want to manipulate a BTREE database with duplicate keys. Consider this
code:</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$filename</span><span class="cm">,</span> <span class="i">%h</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$filename</span> = <span class="q">&quot;tree&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/unlink.html">unlink</a> <span class="i">$filename</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Enable duplicate records</span></li><li>    <span class="i">$DB_BTREE</span>-&gt;{<span class="q">&#39;flags&#39;</span>} = <span class="w">R_DUP</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%h</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_BTREE</span> </li><li>	or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open $filename: $!\n&quot;</span><span class="sc">;</span></li><li></li><li>    <span class="c"># Add some key/value pairs to the file</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Wall&#39;</span>} = <span class="q">&#39;Larry&#39;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Wall&#39;</span>} = <span class="q">&#39;Brick&#39;</span> <span class="sc">;</span> <span class="c"># Note the duplicate key</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Wall&#39;</span>} = <span class="q">&#39;Brick&#39;</span> <span class="sc">;</span> <span class="c"># Note the duplicate key and value</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Smith&#39;</span>} = <span class="q">&#39;John&#39;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;mouse&#39;</span>} = <span class="q">&#39;mickey&#39;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># iterate through the associative array</span></li><li>    <span class="c"># and print each key/value pair.</span></li><li>    foreach <span class="s">(</span><a class="l_k" href="functions/sort.html">sort</a> <a class="l_k" href="functions/keys.html">keys</a> <span class="i">%h</span><span class="s">)</span></li><li>      <span class="s">{</span> <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;$_  -&gt; $h{$_}\n&quot;</span> <span class="s">}</span></li><li></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%h</span> <span class="sc">;</span></li></ol></pre><p>Here is the output:</p>
<pre class="verbatim"><ol><li>    <span class="w">Smith</span>   <span class="w">-&gt; John</span></li><li>    <span class="w">Wall</span>    <span class="w">-&gt; Larry</span></li><li>    <span class="w">Wall</span>    <span class="w">-&gt; Larry</span></li><li>    <span class="w">Wall</span>    <span class="w">-&gt; Larry</span></li><li>    <span class="w">mouse</span>   <span class="w">-&gt; mickey</span></li></ol></pre><p>As you can see 3 records have been successfully created with key <code class="inline"><span class="w">Wall</span></code>

- the only thing is, when they are retrieved from the database they
<i>seem</i> to have the same value, namely <code class="inline"><span class="w">Larry</span></code>
. The problem is caused
by the way that the associative array interface works. Basically, when
the associative array interface is used to fetch the value associated
with a given key, it will only ever retrieve the first value.</p>
<p>Although it may not be immediately obvious from the code above, the
associative array interface can be used to write values with duplicate
keys, but it cannot be used to read them back from the database.</p>
<p>The way to get around this problem is to use the Berkeley DB API method
called <code class="inline"><span class="w">seq</span></code>
.  This method allows sequential access to key/value
pairs. See <a href="#THE-API-INTERFACE">THE API INTERFACE</a> for details of both the <code class="inline"><span class="w">seq</span></code>
 method
and the API in general.</p>
<p>Here is the script above rewritten using the <code class="inline"><span class="w">seq</span></code>
 API method.</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$filename</span><span class="cm">,</span> <span class="i">$x</span><span class="cm">,</span> <span class="i">%h</span><span class="cm">,</span> <span class="i">$status</span><span class="cm">,</span> <span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$filename</span> = <span class="q">&quot;tree&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/unlink.html">unlink</a> <span class="i">$filename</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Enable duplicate records</span></li><li>    <span class="i">$DB_BTREE</span>-&gt;{<span class="q">&#39;flags&#39;</span>} = <span class="w">R_DUP</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$x</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%h</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_BTREE</span> </li><li>	or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open $filename: $!\n&quot;</span><span class="sc">;</span></li><li></li><li>    <span class="c"># Add some key/value pairs to the file</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Wall&#39;</span>} = <span class="q">&#39;Larry&#39;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Wall&#39;</span>} = <span class="q">&#39;Brick&#39;</span> <span class="sc">;</span> <span class="c"># Note the duplicate key</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Wall&#39;</span>} = <span class="q">&#39;Brick&#39;</span> <span class="sc">;</span> <span class="c"># Note the duplicate key and value</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Smith&#39;</span>} = <span class="q">&#39;John&#39;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;mouse&#39;</span>} = <span class="q">&#39;mickey&#39;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># iterate through the btree using seq</span></li><li>    <span class="c"># and print each key/value pair.</span></li><li>    <span class="i">$key</span> = <span class="i">$value</span> = <span class="n">0</span> <span class="sc">;</span></li><li>    for <span class="s">(</span><span class="i">$status</span> = <span class="i">$x</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="w">R_FIRST</span><span class="s">)</span> <span class="sc">;</span></li><li>         <span class="i">$status</span> == <span class="n">0</span> <span class="sc">;</span></li><li>         <span class="i">$status</span> = <span class="i">$x</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="w">R_NEXT</span><span class="s">)</span> <span class="s">)</span></li><li>      <span class="s">{</span>  <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;$key -&gt; $value\n&quot;</span> <span class="s">}</span></li><li></li><li>    <a class="l_k" href="functions/undef.html">undef</a> <span class="i">$x</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%h</span> <span class="sc">;</span></li></ol></pre><p>that prints:</p>
<pre class="verbatim"><ol><li>    <span class="w">Smith</span>   <span class="w">-&gt; John</span></li><li>    <span class="w">Wall</span>    <span class="w">-&gt; Brick</span></li><li>    <span class="w">Wall</span>    <span class="w">-&gt; Brick</span></li><li>    <span class="w">Wall</span>    <span class="w">-&gt; Larry</span></li><li>    <span class="w">mouse</span>   <span class="w">-&gt; mickey</span></li></ol></pre><p>This time we have got all the key/value pairs, including the multiple
values associated with the key <code class="inline"><span class="w">Wall</span></code>
.</p>
<p>To make life easier when dealing with duplicate keys, <b>DB_File</b> comes with 
a few utility methods.</p>
<a name="The-get_dup()-Method"></a><h2>The get_dup() Method</h2>
<p>The <code class="inline"><span class="w">get_dup</span></code>
 method assists in
reading duplicate values from BTREE databases. The method can take the
following forms:</p>
<pre class="verbatim"><ol><li>    <span class="i">$count</span> = <span class="i">$x</span><span class="i">-&gt;get_dup</span><span class="s">(</span><span class="i">$key</span><span class="s">)</span> <span class="sc">;</span></li><li>    <span class="i">@list</span>  = <span class="i">$x</span><span class="i">-&gt;get_dup</span><span class="s">(</span><span class="i">$key</span><span class="s">)</span> <span class="sc">;</span></li><li>    <span class="i">%list</span>  = <span class="i">$x</span><span class="i">-&gt;get_dup</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="n">1</span><span class="s">)</span> <span class="sc">;</span></li></ol></pre><p>In a scalar context the method returns the number of values associated
with the key, <code class="inline"><span class="i">$key</span></code>
.</p>
<p>In list context, it returns all the values which match <code class="inline"><span class="i">$key</span></code>
. Note
that the values will be returned in an apparently random order.</p>
<p>In list context, if the second parameter is present and evaluates
TRUE, the method returns an associative array. The keys of the
associative array correspond to the values that matched in the BTREE
and the values of the array are a count of the number of times that
particular value occurred in the BTREE.</p>
<p>So assuming the database created above, we can use <code class="inline"><span class="w">get_dup</span></code>
 like
this:</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$filename</span><span class="cm">,</span> <span class="i">$x</span><span class="cm">,</span> <span class="i">%h</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$filename</span> = <span class="q">&quot;tree&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Enable duplicate records</span></li><li>    <span class="i">$DB_BTREE</span>-&gt;{<span class="q">&#39;flags&#39;</span>} = <span class="w">R_DUP</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$x</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%h</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_BTREE</span> </li><li>	or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open $filename: $!\n&quot;</span><span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$cnt</span>  = <span class="i">$x</span><span class="i">-&gt;get_dup</span><span class="s">(</span><span class="q">&quot;Wall&quot;</span><span class="s">)</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Wall occurred $cnt times\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">%hash</span> = <span class="i">$x</span><span class="i">-&gt;get_dup</span><span class="s">(</span><span class="q">&quot;Wall&quot;</span><span class="cm">,</span> <span class="n">1</span><span class="s">)</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Larry is there\n&quot;</span> if <span class="i">$hash</span>{<span class="q">&#39;Larry&#39;</span>} <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;There are $hash{&#39;Brick&#39;} Brick Walls\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">@list</span> = <a class="l_k" href="functions/sort.html">sort</a> <span class="i">$x</span><span class="i">-&gt;get_dup</span><span class="s">(</span><span class="q">&quot;Wall&quot;</span><span class="s">)</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Wall =&gt;	[@list]\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="i">@list</span> = <span class="i">$x</span><span class="i">-&gt;get_dup</span><span class="s">(</span><span class="q">&quot;Smith&quot;</span><span class="s">)</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Smith =&gt;	[@list]\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="i">@list</span> = <span class="i">$x</span><span class="i">-&gt;get_dup</span><span class="s">(</span><span class="q">&quot;Dog&quot;</span><span class="s">)</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Dog =&gt;	[@list]\n&quot;</span> <span class="sc">;</span></li></ol></pre><p>and it will print:</p>
<pre class="verbatim"><ol><li>    Wall occurred 3 times</li><li>    Larry is there</li><li>    There are 2 Brick Walls</li><li>    Wall =&gt;	[Brick Brick Larry]</li><li>    Smith =&gt;	[John]</li><li>    Dog =&gt;	[]</li></ol></pre><a name="The-find_dup()-Method"></a><h2>The find_dup() Method</h2>
<pre class="verbatim"><ol><li>    <span class="i">$status</span> = <span class="i">$X</span><span class="i">-&gt;find_dup</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="s">)</span> <span class="sc">;</span></li></ol></pre><p>This method checks for the existence of a specific key/value pair. If the
pair exists, the cursor is left pointing to the pair and the method 
returns 0. Otherwise the method returns a non-zero value.</p>
<p>Assuming the database from the previous example:</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$filename</span><span class="cm">,</span> <span class="i">$x</span><span class="cm">,</span> <span class="i">%h</span><span class="cm">,</span> <span class="i">$found</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$filename</span> = <span class="q">&quot;tree&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Enable duplicate records</span></li><li>    <span class="i">$DB_BTREE</span>-&gt;{<span class="q">&#39;flags&#39;</span>} = <span class="w">R_DUP</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$x</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%h</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_BTREE</span> </li><li>	or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open $filename: $!\n&quot;</span><span class="sc">;</span></li><li></li><li>    <span class="i">$found</span> = <span class="s">(</span> <span class="i">$x</span><span class="i">-&gt;find_dup</span><span class="s">(</span><span class="q">&quot;Wall&quot;</span><span class="cm">,</span> <span class="q">&quot;Larry&quot;</span><span class="s">)</span> == <span class="n">0</span> ? <span class="q">&quot;&quot;</span> <span class="co">:</span> <span class="q">&quot;not&quot;</span><span class="s">)</span> <span class="sc">;</span> </li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Larry Wall is $found there\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$found</span> = <span class="s">(</span> <span class="i">$x</span><span class="i">-&gt;find_dup</span><span class="s">(</span><span class="q">&quot;Wall&quot;</span><span class="cm">,</span> <span class="q">&quot;Harry&quot;</span><span class="s">)</span> == <span class="n">0</span> ? <span class="q">&quot;&quot;</span> <span class="co">:</span> <span class="q">&quot;not&quot;</span><span class="s">)</span> <span class="sc">;</span> </li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Harry Wall is $found there\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/undef.html">undef</a> <span class="i">$x</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%h</span> <span class="sc">;</span></li></ol></pre><p>prints this</p>
<pre class="verbatim"><ol><li>    <span class="w">Larry</span> <span class="w">Wall</span> <span class="w">is</span>  <span class="w">there</span></li><li>    <span class="w">Harry</span> <span class="w">Wall</span> <span class="w">is</span> not <span class="w">there</span></li></ol></pre><a name="The-del_dup()-Method"></a><h2>The del_dup() Method</h2>
<pre class="verbatim"><ol><li>    <span class="i">$status</span> = <span class="i">$X</span><span class="i">-&gt;del_dup</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="s">)</span> <span class="sc">;</span></li></ol></pre><p>This method deletes a specific key/value pair. It returns
0 if they exist and have been deleted successfully.
Otherwise the method returns a non-zero value.</p>
<p>Again assuming the existence of the <code class="inline"><span class="w">tree</span></code>
 database</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$filename</span><span class="cm">,</span> <span class="i">$x</span><span class="cm">,</span> <span class="i">%h</span><span class="cm">,</span> <span class="i">$found</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$filename</span> = <span class="q">&quot;tree&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Enable duplicate records</span></li><li>    <span class="i">$DB_BTREE</span>-&gt;{<span class="q">&#39;flags&#39;</span>} = <span class="w">R_DUP</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$x</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%h</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_BTREE</span> </li><li>	or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open $filename: $!\n&quot;</span><span class="sc">;</span></li><li></li><li>    <span class="i">$x</span><span class="i">-&gt;del_dup</span><span class="s">(</span><span class="q">&quot;Wall&quot;</span><span class="cm">,</span> <span class="q">&quot;Larry&quot;</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$found</span> = <span class="s">(</span> <span class="i">$x</span><span class="i">-&gt;find_dup</span><span class="s">(</span><span class="q">&quot;Wall&quot;</span><span class="cm">,</span> <span class="q">&quot;Larry&quot;</span><span class="s">)</span> == <span class="n">0</span> ? <span class="q">&quot;&quot;</span> <span class="co">:</span> <span class="q">&quot;not&quot;</span><span class="s">)</span> <span class="sc">;</span> </li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Larry Wall is $found there\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/undef.html">undef</a> <span class="i">$x</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%h</span> <span class="sc">;</span></li></ol></pre><p>prints this</p>
<pre class="verbatim"><ol><li>    <span class="w">Larry</span> <span class="w">Wall</span> <span class="w">is</span> not <span class="w">there</span></li></ol></pre><a name="Matching-Partial-Keys"></a><h2>Matching Partial Keys</h2>
<p>The BTREE interface has a feature which allows partial keys to be
matched. This functionality is <i>only</i> available when the <code class="inline"><span class="w">seq</span></code>
 method
is used along with the R_CURSOR flag.</p>
<pre class="verbatim"><ol><li>    <span class="i">$x</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="w">R_CURSOR</span><span class="s">)</span> <span class="sc">;</span></li></ol></pre><p>Here is the relevant quote from the dbopen man page where it defines
the use of the R_CURSOR flag with seq:</p>
<pre class="verbatim"><ol><li>    <span class="w">Note</span><span class="cm">,</span> for <span class="w">the</span> <span class="w">DB_BTREE</span> <span class="w">access</span> <span class="w">method</span><span class="cm">,</span> <span class="w">the</span> <span class="w">returned</span> <span class="w">key</span> <span class="w">is</span> not</li><li>    <span class="w">necessarily</span> <span class="w">an</span> <span class="w">exact</span> <span class="w">match</span> for <span class="w">the</span> <span class="w">specified</span> <span class="w">key</span>. <span class="w">The</span> <span class="w">returned</span> <span class="w">key</span></li><li>    <span class="w">is</span> <span class="w">the</span> <span class="w">smallest</span> <span class="w">key</span> <span class="w">greater</span> <span class="w">than</span> or <span class="w">equal</span> <span class="w">to</span> <span class="w">the</span> <span class="w">specified</span> <span class="w">key</span><span class="cm">,</span></li><li>    <span class="w">permitting</span> <span class="w">partial</span> <span class="w">key</span> <span class="w">matches</span> and <span class="w">range</span> <span class="w">searches</span>.</li></ol></pre><p>In the example script below, the <code class="inline"><span class="w">match</span></code>
 sub uses this feature to find
and print the first matching key/value pair given a partial key.</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">Fcntl</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$filename</span><span class="cm">,</span> <span class="i">$x</span><span class="cm">,</span> <span class="i">%h</span><span class="cm">,</span> <span class="i">$st</span><span class="cm">,</span> <span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li><a name="match"></a>    sub <span class="m">match</span></li><li>    <span class="s">{</span></li><li>        <a class="l_k" href="functions/my.html">my</a> <span class="i">$key</span> = <a class="l_k" href="functions/shift.html">shift</a> <span class="sc">;</span></li><li>        <a class="l_k" href="functions/my.html">my</a> <span class="i">$value</span> = <span class="n">0</span><span class="sc">;</span></li><li>        <a class="l_k" href="functions/my.html">my</a> <span class="i">$orig_key</span> = <span class="i">$key</span> <span class="sc">;</span></li><li>        <span class="i">$x</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="w">R_CURSOR</span><span class="s">)</span> <span class="sc">;</span></li><li>        <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;$orig_key\t-&gt; $key\t-&gt; $value\n&quot;</span> <span class="sc">;</span></li><li>    <span class="s">}</span></li><li></li><li>    <span class="i">$filename</span> = <span class="q">&quot;tree&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/unlink.html">unlink</a> <span class="i">$filename</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$x</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%h</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_BTREE</span></li><li>        or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open $filename: $!\n&quot;</span><span class="sc">;</span></li><li></li><li>    <span class="c"># Add some key/value pairs to the file</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;mouse&#39;</span>} = <span class="q">&#39;mickey&#39;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Wall&#39;</span>} = <span class="q">&#39;Larry&#39;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>{<span class="q">&#39;Walls&#39;</span>} = <span class="q">&#39;Brick&#39;</span> <span class="sc">;</span> </li><li>    <span class="i">$h</span>{<span class="q">&#39;Smith&#39;</span>} = <span class="q">&#39;John&#39;</span> <span class="sc">;</span></li><li></li><li></li><li>    <span class="i">$key</span> = <span class="i">$value</span> = <span class="n">0</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;IN ORDER\n&quot;</span> <span class="sc">;</span></li><li>    for <span class="s">(</span><span class="i">$st</span> = <span class="i">$x</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="w">R_FIRST</span><span class="s">)</span> <span class="sc">;</span></li><li>	 <span class="i">$st</span> == <span class="n">0</span> <span class="sc">;</span></li><li>         <span class="i">$st</span> = <span class="i">$x</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="w">R_NEXT</span><span class="s">)</span> <span class="s">)</span></li><li></li><li>      <span class="s">{</span>  <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;$key	-&gt; $value\n&quot;</span> <span class="s">}</span></li><li></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;\nPARTIAL MATCH\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="i">match</span> <span class="q">&quot;Wa&quot;</span> <span class="sc">;</span></li><li>    <span class="i">match</span> <span class="q">&quot;A&quot;</span> <span class="sc">;</span></li><li>    <span class="i">match</span> <span class="q">&quot;a&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/undef.html">undef</a> <span class="i">$x</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%h</span> <span class="sc">;</span></li></ol></pre><p>Here is the output:</p>
<pre class="verbatim"><ol><li>    <span class="w">IN</span> <span class="w">ORDER</span></li><li>    <span class="w">Smith</span> <span class="w">-&gt; John</span></li><li>    <span class="w">Wall</span>  <span class="w">-&gt; Larry</span></li><li>    <span class="w">Walls</span> <span class="w">-&gt; Brick</span></li><li>    <span class="w">mouse</span> <span class="w">-&gt; mickey</span></li><li></li><li>    <span class="w">PARTIAL</span> <span class="w">MATCH</span></li><li>    <span class="w">Wa</span> <span class="w">-&gt; Wall</span>  <span class="w">-&gt; Larry</span></li><li>    <span class="w">A</span>  <span class="w">-&gt; Smith</span> <span class="w">-&gt; John</span></li><li>    <span class="w">a</span>  <span class="w">-&gt; mouse</span> <span class="w">-&gt; mickey</span></li></ol></pre><a name="DB_RECNO"></a><h1>DB_RECNO</h1>
<p>DB_RECNO provides an interface to flat text files. Both variable and
fixed length records are supported.</p>
<p>In order to make RECNO more compatible with Perl, the array offset for
all RECNO arrays begins at 0 rather than 1 as in Berkeley DB.</p>
<p>As with normal Perl arrays, a RECNO array can be accessed using
negative indexes. The index -1 refers to the last element of the array,
-2 the second last, and so on. Attempting to access an element before
the start of the array will raise a fatal run-time error.</p>
<a name="The-'bval'-Option"></a><h2>The 'bval' Option</h2>
<p>The operation of the bval option warrants some discussion. Here is the
definition of bval from the Berkeley DB 1.85 recno manual page:</p>
<pre class="verbatim"><ol><li>    The delimiting byte to be used to mark  the  end  of  a</li><li>    record for variable-length records, and the pad charac-</li><li>    ter for fixed-length records.  If no  value  is  speci-</li><li>    fied,  newlines  (``\n'')  are  used to mark the end of</li><li>    variable-length records and  fixed-length  records  are</li><li>    padded with spaces.</li></ol></pre><p>The second sentence is wrong. In actual fact bval will only default to
<code class="inline"><span class="q">&quot;\n&quot;</span></code>
 when the openinfo parameter in dbopen is NULL. If a non-NULL
openinfo parameter is used at all, the value that happens to be in bval
will be used. That means you always have to specify bval when making
use of any of the options in the openinfo parameter. This documentation
error will be fixed in the next release of Berkeley DB.</p>
<p>That clarifies the situation with regards Berkeley DB itself. What
about <b>DB_File</b>? Well, the behavior defined in the quote above is
quite useful, so <b>DB_File</b> conforms to it.</p>
<p>That means that you can specify other options (e.g. cachesize) and
still have bval default to <code class="inline"><span class="q">&quot;\n&quot;</span></code>
 for variable length records, and
space for fixed length records.</p>
<p>Also note that the bval option only allows you to specify a single byte
as a delimiter.</p>
<a name="A-Simple-Example"></a><h2>A Simple Example</h2>
<p>Here is a simple example that uses RECNO (if you are using a version 
of Perl earlier than 5.004_57 this example won't work -- see 
<a href="#Extra-RECNO-Methods">Extra RECNO Methods</a> for a workaround).</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$filename</span> = <span class="q">&quot;text&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/unlink.html">unlink</a> <span class="i">$filename</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">@h</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">@h</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_RECNO</span> </li><li>        or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open file &#39;text&#39;: $!\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Add a few key/value pairs to the file</span></li><li>    <span class="i">$h</span>[<span class="n">0</span>] = <span class="q">&quot;orange&quot;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>[<span class="n">1</span>] = <span class="q">&quot;blue&quot;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>[<span class="n">2</span>] = <span class="q">&quot;yellow&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/push.html">push</a> <span class="i">@h</span><span class="cm">,</span> <span class="q">&quot;green&quot;</span><span class="cm">,</span> <span class="q">&quot;black&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$elements</span> = <a class="l_k" href="functions/scalar.html">scalar</a> <span class="i">@h</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;The array contains $elements entries\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$last</span> = <a class="l_k" href="functions/pop.html">pop</a> <span class="i">@h</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;popped $last\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/unshift.html">unshift</a> <span class="i">@h</span><span class="cm">,</span> <span class="q">&quot;white&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$first</span> = <a class="l_k" href="functions/shift.html">shift</a> <span class="i">@h</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;shifted $first\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Check for existence of a key</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Element 1 Exists with value $h[1]\n&quot;</span> if <span class="i">$h</span>[<span class="n">1</span>] <span class="sc">;</span></li><li></li><li>    <span class="c"># use a negative index</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;The last element is $h[-1]\n&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;The 2nd last element is $h[-2]\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">@h</span> <span class="sc">;</span></li></ol></pre><p>Here is the output from the script:</p>
<pre class="verbatim"><ol><li>    The array contains 5 entries</li><li>    popped black</li><li>    shifted white</li><li>    Element 1 Exists with value blue</li><li>    The last element is green</li><li>    The 2nd last element is yellow</li></ol></pre><a name="Extra-RECNO-Methods"></a><h2>Extra RECNO Methods</h2>
<p>If you are using a version of Perl earlier than 5.004_57, the tied
array interface is quite limited. In the example script above
<code class="inline"><a class="l_k" href="functions/push.html">push</a></code>, <code class="inline"><a class="l_k" href="functions/pop.html">pop</a></code>, <code class="inline"><a class="l_k" href="functions/shift.html">shift</a></code>, <code class="inline"><a class="l_k" href="functions/unshift.html">unshift</a></code>
or determining the array length will not work with a tied array.</p>
<p>To make the interface more useful for older versions of Perl, a number
of methods are supplied with <b>DB_File</b> to simulate the missing array
operations. All these methods are accessed via the object returned from
the tie call.</p>
<p>Here are the methods:</p>
<ul>
<li><a name="*%24X-%3epush(list)-%3b*"></a><b><b>$X-&gt;push(list) ;</b></b>
<p>Pushes the elements of <code class="inline"><span class="w">list</span></code>
 to the end of the array.</p>
</li>
<li><a name="*%24value-%3d-%24X-%3epop-%3b*"></a><b><b>$value = $X-&gt;pop ;</b></b>
<p>Removes and returns the last element of the array.</p>
</li>
<li><a name="*%24X-%3eshift*"></a><b><b>$X-&gt;shift</b></b>
<p>Removes and returns the first element of the array.</p>
</li>
<li><a name="*%24X-%3eunshift(list)-%3b*"></a><b><b>$X-&gt;unshift(list) ;</b></b>
<p>Pushes the elements of <code class="inline"><span class="w">list</span></code>
 to the start of the array.</p>
</li>
<li><a name="*%24X-%3elength*"></a><b><b>$X-&gt;length</b></b>
<p>Returns the number of elements in the array.</p>
</li>
<li><a name="*%24X-%3esplice(offset%2c-length%2c-elements)%3b*"></a><b><b>$X-&gt;splice(offset, length, elements);</b></b>
<p>Returns a splice of the array.</p>
</li>
</ul>
<a name="Another-Example"></a><h2>Another Example</h2>
<p>Here is a more complete example that makes use of some of the methods
described above. It also makes use of the API interface directly (see 
<a href="#THE-API-INTERFACE">THE API INTERFACE</a>).</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">@h</span><span class="cm">,</span> <span class="i">$H</span><span class="cm">,</span> <span class="i">$file</span><span class="cm">,</span> <span class="i">$i</span><span class="s">)</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">Fcntl</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$file</span> = <span class="q">&quot;text&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/unlink.html">unlink</a> <span class="i">$file</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$H</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">@h</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="i">$file</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_RECNO</span> </li><li>        or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open file $file: $!\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># first create a text file to play with</span></li><li>    <span class="i">$h</span>[<span class="n">0</span>] = <span class="q">&quot;zero&quot;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>[<span class="n">1</span>] = <span class="q">&quot;one&quot;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>[<span class="n">2</span>] = <span class="q">&quot;two&quot;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>[<span class="n">3</span>] = <span class="q">&quot;three&quot;</span> <span class="sc">;</span></li><li>    <span class="i">$h</span>[<span class="n">4</span>] = <span class="q">&quot;four&quot;</span> <span class="sc">;</span></li><li></li><li></li><li>    <span class="c"># Print the records in order.</span></li><li>    <span class="c">#</span></li><li>    <span class="c"># The length method is needed here because evaluating a tied</span></li><li>    <span class="c"># array in a scalar context does not return the number of</span></li><li>    <span class="c"># elements in the array.  </span></li><li></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;\nORIGINAL\n&quot;</span> <span class="sc">;</span></li><li>    foreach <span class="i">$i</span> <span class="s">(</span><span class="n">0</span> .. <span class="i">$H</span><span class="i">-&gt;length</span> - <span class="n">1</span><span class="s">)</span> <span class="s">{</span></li><li>        <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;$i: $h[$i]\n&quot;</span> <span class="sc">;</span></li><li>    <span class="s">}</span></li><li></li><li>    <span class="c"># use the push &amp; pop methods</span></li><li>    <span class="i">$a</span> = <span class="i">$H</span><span class="i">-&gt;pop</span> <span class="sc">;</span></li><li>    <span class="i">$H</span><span class="i">-&gt;push</span><span class="s">(</span><span class="q">&quot;last&quot;</span><span class="s">)</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;\nThe last record was [$a]\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># and the shift &amp; unshift methods</span></li><li>    <span class="i">$a</span> = <span class="i">$H</span><span class="i">-&gt;shift</span> <span class="sc">;</span></li><li>    <span class="i">$H</span><span class="i">-&gt;unshift</span><span class="s">(</span><span class="q">&quot;first&quot;</span><span class="s">)</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;The first record was [$a]\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Use the API to add a new record after record 2.</span></li><li>    <span class="i">$i</span> = <span class="n">2</span> <span class="sc">;</span></li><li>    <span class="i">$H</span><span class="i">-&gt;put</span><span class="s">(</span><span class="i">$i</span><span class="cm">,</span> <span class="q">&quot;Newbie&quot;</span><span class="cm">,</span> <span class="w">R_IAFTER</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># and a new record before record 1.</span></li><li>    <span class="i">$i</span> = <span class="n">1</span> <span class="sc">;</span></li><li>    <span class="i">$H</span><span class="i">-&gt;put</span><span class="s">(</span><span class="i">$i</span><span class="cm">,</span> <span class="q">&quot;New One&quot;</span><span class="cm">,</span> <span class="w">R_IBEFORE</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># delete record 3</span></li><li>    <span class="i">$H</span><span class="i">-&gt;del</span><span class="s">(</span><span class="n">3</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># now print the records in reverse order</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;\nREVERSE\n&quot;</span> <span class="sc">;</span></li><li>    for <span class="s">(</span><span class="i">$i</span> = <span class="i">$H</span><span class="i">-&gt;length</span> - <span class="n">1</span> <span class="sc">;</span> <span class="i">$i</span> &gt;= <span class="n">0</span> <span class="sc">;</span> -- <span class="i">$i</span><span class="s">)</span></li><li>      <span class="s">{</span> <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;$i: $h[$i]\n&quot;</span> <span class="s">}</span></li><li></li><li>    <span class="c"># same again, but use the API functions instead</span></li><li>    <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;\nREVERSE again\n&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$s</span><span class="cm">,</span> <span class="i">$k</span><span class="cm">,</span> <span class="i">$v</span><span class="s">)</span>  = <span class="s">(</span><span class="n">0</span><span class="cm">,</span> <span class="n">0</span><span class="cm">,</span> <span class="n">0</span><span class="s">)</span> <span class="sc">;</span></li><li>    for <span class="s">(</span><span class="i">$s</span> = <span class="i">$H</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$k</span><span class="cm">,</span> <span class="i">$v</span><span class="cm">,</span> <span class="w">R_LAST</span><span class="s">)</span> <span class="sc">;</span> </li><li>             <span class="i">$s</span> == <span class="n">0</span> <span class="sc">;</span> </li><li>             <span class="i">$s</span> = <span class="i">$H</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$k</span><span class="cm">,</span> <span class="i">$v</span><span class="cm">,</span> <span class="w">R_PREV</span><span class="s">)</span><span class="s">)</span></li><li>      <span class="s">{</span> <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;$k: $v\n&quot;</span> <span class="s">}</span></li><li></li><li>    <a class="l_k" href="functions/undef.html">undef</a> <span class="i">$H</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">@h</span> <span class="sc">;</span></li></ol></pre><p>and this is what it outputs:</p>
<pre class="verbatim"><ol><li>    ORIGINAL</li><li>    0: zero</li><li>    1: one</li><li>    2: two</li><li>    3: three</li><li>    4: four</li><li></li><li>    The last record was [four]</li><li>    The first record was [zero]</li><li></li><li>    REVERSE</li><li>    5: last</li><li>    4: three</li><li>    3: Newbie</li><li>    2: one</li><li>    1: New One</li><li>    0: first</li><li></li><li>    REVERSE again</li><li>    5: last</li><li>    4: three</li><li>    3: Newbie</li><li>    2: one</li><li>    1: New One</li><li>    0: first</li></ol></pre><p>Notes:</p>
<dl>
<dt>1.</dt><dd>
<p>Rather than iterating through the array, <code class="inline"><span class="i">@h</span></code>
 like this:</p>
<pre class="verbatim"><ol><li>    foreach <span class="i">$i</span> <span class="s">(</span><span class="i">@h</span><span class="s">)</span></li></ol></pre><p>it is necessary to use either this:</p>
<pre class="verbatim"><ol><li>    foreach <span class="i">$i</span> <span class="s">(</span><span class="n">0</span> .. <span class="i">$H</span><span class="i">-&gt;length</span> - <span class="n">1</span><span class="s">)</span></li></ol></pre><p>or this:</p>
<pre class="verbatim"><ol><li>    for <span class="s">(</span><span class="i">$a</span> = <span class="i">$H</span><span class="i">-&gt;get</span><span class="s">(</span><span class="i">$k</span><span class="cm">,</span> <span class="i">$v</span><span class="cm">,</span> <span class="w">R_FIRST</span><span class="s">)</span> <span class="sc">;</span></li><li>         <span class="i">$a</span> == <span class="n">0</span> <span class="sc">;</span></li><li>         <span class="i">$a</span> = <span class="i">$H</span><span class="i">-&gt;get</span><span class="s">(</span><span class="i">$k</span><span class="cm">,</span> <span class="i">$v</span><span class="cm">,</span> <span class="w">R_NEXT</span><span class="s">)</span> <span class="s">)</span></li></ol></pre></dd>
<dt>2.</dt><dd>
<p>Notice that both times the <code class="inline"><span class="w">put</span></code>
 method was used the record index was
specified using a variable, <code class="inline"><span class="i">$i</span></code>
, rather than the literal value
itself. This is because <code class="inline"><span class="w">put</span></code>
 will return the record number of the
inserted line via that parameter.</p>
</dd>
</dl>
<a name="THE-API-INTERFACE"></a><h1>THE API INTERFACE</h1>
<p>As well as accessing Berkeley DB using a tied hash or array, it is also
possible to make direct use of most of the API functions defined in the
Berkeley DB documentation.</p>
<p>To do this you need to store a copy of the object returned from the tie.</p>
<pre class="verbatim"><ol><li>	<span class="i">$db</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%hash</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="q">&quot;filename&quot;</span> <span class="sc">;</span></li></ol></pre><p>Once you have done that, you can access the Berkeley DB API functions
as <b>DB_File</b> methods directly like this:</p>
<pre class="verbatim"><ol><li>	<span class="i">$db</span><span class="i">-&gt;put</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="w">R_NOOVERWRITE</span><span class="s">)</span> <span class="sc">;</span></li></ol></pre><p><b>Important:</b> If you have saved a copy of the object returned from
<code class="inline"><a class="l_k" href="functions/tie.html">tie</a></code>, the underlying database file will <i>not</i> be closed until both
the tied variable is untied and all copies of the saved object are
destroyed.</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li>    <span class="i">$db</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%hash</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="q">&quot;filename&quot;</span> </li><li>        or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot tie filename: $!&quot;</span> <span class="sc">;</span></li><li>    ...</li><li>    <a class="l_k" href="functions/undef.html">undef</a> <span class="i">$db</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%hash</span> <span class="sc">;</span></li></ol></pre><p>See <a href="#The-untie()-Gotcha">The untie() Gotcha</a> for more details.</p>
<p>All the functions defined in <a href="http://search.cpan.org/perldoc/dbopen">dbopen</a> are available except for
close() and dbopen() itself. The <b>DB_File</b> method interface to the
supported functions have been implemented to mirror the way Berkeley DB
works whenever possible. In particular note that:</p>
<ul>
<li>
<p>The methods return a status value. All return 0 on success.
All return -1 to signify an error and set <code class="inline"><span class="i">$!</span></code>
 to the exact
error code. The return code 1 generally (but not always) means that the
key specified did not exist in the database.</p>
<p>Other return codes are defined. See below and in the Berkeley DB
documentation for details. The Berkeley DB documentation should be used
as the definitive source.</p>
</li>
<li>
<p>Whenever a Berkeley DB function returns data via one of its parameters,
the equivalent <b>DB_File</b> method does exactly the same.</p>
</li>
<li>
<p>If you are careful, it is possible to mix API calls with the tied
hash/array interface in the same piece of code. Although only a few of
the methods used to implement the tied interface currently make use of
the cursor, you should always assume that the cursor has been changed
any time the tied hash/array interface is used. As an example, this
code will probably not do what you expect:</p>
<pre class="verbatim"><ol><li>    <span class="i">$X</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%x</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0777</span><span class="cm">,</span> <span class="i">$DB_BTREE</span></li><li>        or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot tie $filename: $!&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Get the first key/value pair and set  the cursor</span></li><li>    <span class="i">$X</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="w">R_FIRST</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># this line will modify the cursor</span></li><li>    <span class="i">$count</span> = <a class="l_k" href="functions/scalar.html">scalar</a> <a class="l_k" href="functions/keys.html">keys</a> <span class="i">%x</span> <span class="sc">;</span> </li><li></li><li>    <span class="c"># Get the second key/value pair.</span></li><li>    <span class="c"># oops, it didn&#39;t, it got the last key/value pair!</span></li><li>    <span class="i">$X</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="w">R_NEXT</span><span class="s">)</span> <span class="sc">;</span></li></ol></pre><p>The code above can be rearranged to get around the problem, like this:</p>
<pre class="verbatim"><ol><li>    <span class="i">$X</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%x</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0777</span><span class="cm">,</span> <span class="i">$DB_BTREE</span></li><li>        or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot tie $filename: $!&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># this line will modify the cursor</span></li><li>    <span class="i">$count</span> = <a class="l_k" href="functions/scalar.html">scalar</a> <a class="l_k" href="functions/keys.html">keys</a> <span class="i">%x</span> <span class="sc">;</span> </li><li></li><li>    <span class="c"># Get the first key/value pair and set  the cursor</span></li><li>    <span class="i">$X</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="w">R_FIRST</span><span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Get the second key/value pair.</span></li><li>    <span class="c"># worked this time.</span></li><li>    <span class="i">$X</span><span class="i">-&gt;seq</span><span class="s">(</span><span class="i">$key</span><span class="cm">,</span> <span class="i">$value</span><span class="cm">,</span> <span class="w">R_NEXT</span><span class="s">)</span> <span class="sc">;</span></li></ol></pre></li>
</ul>
<p>All the constants defined in <a href="http://search.cpan.org/perldoc/dbopen">dbopen</a> for use in the flags parameters
in the methods defined below are also available. Refer to the Berkeley
DB documentation for the precise meaning of the flags values.</p>
<p>Below is a list of the methods available.</p>
<ul>
<li><a name="*%24status-%3d-%24X-%3eget(%24key%2c-%24value-%5b%2c-%24flags%5d)-%3b*"></a><b><b>$status = $X-&gt;get($key, $value [, $flags]) ;</b></b>
<p>Given a key (<code class="inline"><span class="i">$key</span></code>
) this method reads the value associated with it
from the database. The value read from the database is returned in the
<code class="inline"><span class="i">$value</span></code>
 parameter.</p>
<p>If the key does not exist the method returns 1.</p>
<p>No flags are currently defined for this method.</p>
</li>
<li><a name="*%24status-%3d-%24X-%3eput(%24key%2c-%24value-%5b%2c-%24flags%5d)-%3b*"></a><b><b>$status = $X-&gt;put($key, $value [, $flags]) ;</b></b>
<p>Stores the key/value pair in the database.</p>
<p>If you use either the R_IAFTER or R_IBEFORE flags, the <code class="inline"><span class="i">$key</span></code>
 parameter
will have the record number of the inserted key/value pair set.</p>
<p>Valid flags are R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE and
R_SETCURSOR.</p>
</li>
<li><a name="*%24status-%3d-%24X-%3edel(%24key-%5b%2c-%24flags%5d)-%3b*"></a><b><b>$status = $X-&gt;del($key [, $flags]) ;</b></b>
<p>Removes all key/value pairs with key <code class="inline"><span class="i">$key</span></code>
 from the database.</p>
<p>A return code of 1 means that the requested key was not in the
database.</p>
<p>R_CURSOR is the only valid flag at present.</p>
</li>
<li><a name="*%24status-%3d-%24X-%3efd-%3b*"></a><b><b>$status = $X-&gt;fd ;</b></b>
<p>Returns the file descriptor for the underlying database.</p>
<p>See <a href="#Locking%3a-The-Trouble-with-fd">Locking: The Trouble with fd</a> for an explanation for why you should
not use <code class="inline"><span class="w">fd</span></code>
 to lock your database.</p>
</li>
<li><a name="*%24status-%3d-%24X-%3eseq(%24key%2c-%24value%2c-%24flags)-%3b*"></a><b><b>$status = $X-&gt;seq($key, $value, $flags) ;</b></b>
<p>This interface allows sequential retrieval from the database. See
<a href="http://search.cpan.org/perldoc/dbopen">dbopen</a> for full details.</p>
<p>Both the <code class="inline"><span class="i">$key</span></code>
 and <code class="inline"><span class="i">$value</span></code>
 parameters will be set to the key/value
pair read from the database.</p>
<p>The flags parameter is mandatory. The valid flag values are R_CURSOR,
R_FIRST, R_LAST, R_NEXT and R_PREV.</p>
</li>
<li><a name="*%24status-%3d-%24X-%3esync(%5b%24flags%5d)-%3b*"></a><b><b>$status = $X-&gt;sync([$flags]) ;</b></b>
<p>Flushes any cached buffers to disk.</p>
<p>R_RECNOSYNC is the only valid flag at present.</p>
</li>
</ul>
<a name="DBM-FILTERS"></a><h1>DBM FILTERS</h1>
<p>A DBM Filter is a piece of code that is be used when you <i>always</i> want to
make the same transformation to all keys and/or values in a DBM database.
An example is when you need to encode your data in UTF-8 before writing to
the database and then decode the UTF-8 when reading from the database file.</p>
<p>There are two ways to use a DBM Filter.</p>
<dl>
<dt>1.</dt><dd>
<p>Using the low-level API defined below.</p>
</dd>
<dt>2.</dt><dd>
<p>Using the <a href="DBM_Filter.html">DBM_Filter</a> module. 
This module hides the complexity of the API defined below and comes
with a number of "canned" filters that cover some of the common use-cases.</p>
</dd>
</dl>
<p>Use of the <a href="DBM_Filter.html">DBM_Filter</a> module is recommended.</p>
<a name="DBM-Filter-Low-level-API"></a><h2>DBM Filter Low-level API</h2>
<p>There are four methods associated with DBM Filters. All work identically,
and each is used to install (or uninstall) a single DBM Filter. Each
expects a single parameter, namely a reference to a sub. The only
difference between them is the place that the filter is installed.</p>
<p>To summarise:</p>
<ul>
<li><a name="*filter_store_key*"></a><b><b>filter_store_key</b></b>
<p>If a filter has been installed with this method, it will be invoked
every time you write a key to a DBM database.</p>
</li>
<li><a name="*filter_store_value*"></a><b><b>filter_store_value</b></b>
<p>If a filter has been installed with this method, it will be invoked
every time you write a value to a DBM database.</p>
</li>
<li><a name="*filter_fetch_key*"></a><b><b>filter_fetch_key</b></b>
<p>If a filter has been installed with this method, it will be invoked
every time you read a key from a DBM database.</p>
</li>
<li><a name="*filter_fetch_value*"></a><b><b>filter_fetch_value</b></b>
<p>If a filter has been installed with this method, it will be invoked
every time you read a value from a DBM database.</p>
</li>
</ul>
<p>You can use any combination of the methods, from none, to all four.</p>
<p>All filter methods return the existing filter, if present, or <code class="inline"><a class="l_k" href="functions/undef.html">undef</a></code>
in not.</p>
<p>To delete a filter pass <code class="inline"><a class="l_k" href="functions/undef.html">undef</a></code> to it.</p>
<a name="The-Filter"></a><h2>The Filter</h2>
<p>When each filter is called by Perl, a local copy of <code class="inline"><span class="i">$_</span></code>
 will contain
the key or value to be filtered. Filtering is achieved by modifying
the contents of <code class="inline"><span class="i">$_</span></code>
. The return code from the filter is ignored.</p>
<a name="An-Example----the-NULL-termination-problem."></a><h2>An Example -- the NULL termination problem.</h2>
<p>Consider the following scenario. You have a DBM database
that you need to share with a third-party C application. The C application
assumes that <i>all</i> keys and values are NULL terminated. Unfortunately
when Perl writes to DBM databases it doesn't use NULL termination, so
your Perl application will have to manage NULL termination itself. When
you write to the database you will have to use something like this:</p>
<pre class="verbatim"><ol><li>    <span class="i">$hash</span>{<span class="q">&quot;$key\0&quot;</span>} = <span class="q">&quot;$value\0&quot;</span> <span class="sc">;</span></li></ol></pre><p>Similarly the NULL needs to be taken into account when you are considering
the length of existing keys/values.</p>
<p>It would be much better if you could ignore the NULL terminations issue
in the main application code and have a mechanism that automatically
added the terminating NULL to all keys and values whenever you write to
the database and have them removed when you read from the database. As I'm
sure you have already guessed, this is a problem that DBM Filters can
fix very easily.</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">%hash</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$filename</span> = <span class="q">&quot;filt&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/unlink.html">unlink</a> <span class="i">$filename</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$db</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%hash</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_CREAT</span>|<span class="w">O_RDWR</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_HASH</span> </li><li>      or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open $filename: $!\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="c"># Install DBM Filters</span></li><li>    <span class="i">$db</span><span class="i">-&gt;filter_fetch_key</span>  <span class="s">(</span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="q">s/\0$//</span>    <span class="s">}</span> <span class="s">)</span> <span class="sc">;</span></li><li>    <span class="i">$db</span><span class="i">-&gt;filter_store_key</span>  <span class="s">(</span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="i">$_</span> .= <span class="q">&quot;\0&quot;</span> <span class="s">}</span> <span class="s">)</span> <span class="sc">;</span></li><li>    <span class="i">$db</span><span class="i">-&gt;filter_fetch_value</span><span class="s">(</span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="q">s/\0$//</span>    <span class="s">}</span> <span class="s">)</span> <span class="sc">;</span></li><li>    <span class="i">$db</span><span class="i">-&gt;filter_store_value</span><span class="s">(</span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="i">$_</span> .= <span class="q">&quot;\0&quot;</span> <span class="s">}</span> <span class="s">)</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$hash</span>{<span class="q">&quot;abc&quot;</span>} = <span class="q">&quot;def&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$a</span> = <span class="i">$hash</span>{<span class="q">&quot;ABC&quot;</span>} <span class="sc">;</span></li><li>    <span class="c"># ...</span></li><li>    <a class="l_k" href="functions/undef.html">undef</a> <span class="i">$db</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%hash</span> <span class="sc">;</span></li></ol></pre><p>Hopefully the contents of each of the filters should be
self-explanatory. Both "fetch" filters remove the terminating NULL,
and both "store" filters add a terminating NULL.</p>
<a name="Another-Example----Key-is-a-C-int."></a><h2>Another Example -- Key is a C int.</h2>
<p>Here is another real-life example. By default, whenever Perl writes to
a DBM database it always writes the key and value as strings. So when
you use this:</p>
<pre class="verbatim"><ol><li>    <span class="i">$hash</span>{<span class="n">12345</span>} = <span class="q">&quot;something&quot;</span> <span class="sc">;</span></li></ol></pre><p>the key 12345 will get stored in the DBM database as the 5 byte string
"12345". If you actually want the key to be stored in the DBM database
as a C int, you will have to use <code class="inline"><a class="l_k" href="functions/pack.html">pack</a></code> when writing, and <code class="inline"><a class="l_k" href="functions/unpack.html">unpack</a></code>
when reading.</p>
<p>Here is a DBM Filter that does it:</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">%hash</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$filename</span> = <span class="q">&quot;filt&quot;</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/unlink.html">unlink</a> <span class="i">$filename</span> <span class="sc">;</span></li><li></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$db</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%hash</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_CREAT</span>|<span class="w">O_RDWR</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_HASH</span> </li><li>      or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open $filename: $!\n&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$db</span><span class="i">-&gt;filter_fetch_key</span>  <span class="s">(</span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="i">$_</span> = <a class="l_k" href="functions/unpack.html">unpack</a><span class="s">(</span><span class="q">&quot;i&quot;</span><span class="cm">,</span> <span class="i">$_</span><span class="s">)</span> <span class="s">}</span> <span class="s">)</span> <span class="sc">;</span></li><li>    <span class="i">$db</span><span class="i">-&gt;filter_store_key</span>  <span class="s">(</span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="i">$_</span> = <a class="l_k" href="functions/pack.html">pack</a> <span class="s">(</span><span class="q">&quot;i&quot;</span><span class="cm">,</span> <span class="i">$_</span><span class="s">)</span> <span class="s">}</span> <span class="s">)</span> <span class="sc">;</span></li><li>    <span class="i">$hash</span>{<span class="n">123</span>} = <span class="q">&quot;def&quot;</span> <span class="sc">;</span></li><li>    <span class="c"># ...</span></li><li>    <a class="l_k" href="functions/undef.html">undef</a> <span class="i">$db</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%hash</span> <span class="sc">;</span></li></ol></pre><p>This time only two filters have been used -- we only need to manipulate
the contents of the key, so it wasn't necessary to install any value
filters.</p>
<a name="HINTS-AND-TIPS"></a><h1>HINTS AND TIPS</h1>
<a name="Locking%3a-The-Trouble-with-fd"></a><h2>Locking: The Trouble with fd</h2>
<p>Until version 1.72 of this module, the recommended technique for locking
<b>DB_File</b> databases was to flock the filehandle returned from the "fd"
function. Unfortunately this technique has been shown to be fundamentally
flawed (Kudos to David Harris for tracking this down). Use it at your own
peril!</p>
<p>The locking technique went like this.</p>
<pre class="verbatim"><ol><li>    <span class="i">$db</span> = <a class="l_k" href="functions/tie.html">tie</a><span class="s">(</span><span class="i">%db</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="q">&#39;foo.db&#39;</span><span class="cm">,</span> <span class="w">O_CREAT</span>|<span class="w">O_RDWR</span><span class="cm">,</span> <span class="n">0644</span><span class="s">)</span></li><li>        || <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;dbcreat foo.db $!&quot;</span><span class="sc">;</span></li><li>    <span class="i">$fd</span> = <span class="i">$db</span><span class="i">-&gt;fd</span><span class="sc">;</span></li><li>    <a class="l_k" href="functions/open.html">open</a><span class="s">(</span><span class="w">DB_FH</span><span class="cm">,</span> <span class="q">&quot;+&lt;&amp;=$fd&quot;</span><span class="s">)</span> || <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;dup $!&quot;</span><span class="sc">;</span></li><li>    <a class="l_k" href="functions/flock.html">flock</a> <span class="s">(</span><span class="w">DB_FH</span><span class="cm">,</span> <span class="w">LOCK_EX</span><span class="s">)</span> || <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;flock: $!&quot;</span><span class="sc">;</span></li><li>    ...</li><li>    <span class="i">$db</span>{<span class="q">&quot;Tom&quot;</span>} = <span class="q">&quot;Jerry&quot;</span> <span class="sc">;</span></li><li>    ...</li><li>    <a class="l_k" href="functions/flock.html">flock</a><span class="s">(</span><span class="w">DB_FH</span><span class="cm">,</span> <span class="w">LOCK_UN</span><span class="s">)</span><span class="sc">;</span></li><li>    <a class="l_k" href="functions/undef.html">undef</a> <span class="i">$db</span><span class="sc">;</span></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%db</span><span class="sc">;</span></li><li>    <a class="l_k" href="functions/close.html">close</a><span class="s">(</span><span class="w">DB_FH</span><span class="s">)</span><span class="sc">;</span></li></ol></pre><p>In simple terms, this is what happens:</p>
<dl>
<dt>1.</dt><dd>
<p>Use "tie" to open the database.</p>
</dd>
<dt>2.</dt><dd>
<p>Lock the database with fd &amp; flock.</p>
</dd>
<dt>3.</dt><dd>
<p>Read &amp; Write to the database.</p>
</dd>
<dt>4.</dt><dd>
<p>Unlock and close the database.</p>
</dd>
</dl>
<p>Here is the crux of the problem. A side-effect of opening the <b>DB_File</b>
database in step 2 is that an initial block from the database will get
read from disk and cached in memory.</p>
<p>To see why this is a problem, consider what can happen when two processes,
say "A" and "B", both want to update the same <b>DB_File</b> database
using the locking steps outlined above. Assume process "A" has already
opened the database and has a write lock, but it hasn't actually updated
the database yet (it has finished step 2, but not started step 3 yet). Now
process "B" tries to open the same database - step 1 will succeed,
but it will block on step 2 until process "A" releases the lock. The
important thing to notice here is that at this point in time both
processes will have cached identical initial blocks from the database.</p>
<p>Now process "A" updates the database and happens to change some of the
data held in the initial buffer. Process "A" terminates, flushing
all cached data to disk and releasing the database lock. At this point
the database on disk will correctly reflect the changes made by process
"A".</p>
<p>With the lock released, process "B" can now continue. It also updates the
database and unfortunately it too modifies the data that was in its
initial buffer. Once that data gets flushed to disk it will overwrite
some/all of the changes process "A" made to the database.</p>
<p>The result of this scenario is at best a database that doesn't contain
what you expect. At worst the database will corrupt.</p>
<p>The above won't happen every time competing process update the same
<b>DB_File</b> database, but it does illustrate why the technique should
not be used.</p>
<a name="Safe-ways-to-lock-a-database"></a><h2>Safe ways to lock a database</h2>
<p>Starting with version 2.x, Berkeley DB  has internal support for locking.
The companion module to this one, <b>BerkeleyDB</b>, provides an interface
to this locking functionality. If you are serious about locking
Berkeley DB databases, I strongly recommend using <b>BerkeleyDB</b>.</p>
<p>If using <b>BerkeleyDB</b> isn't an option, there are a number of modules
available on CPAN that can be used to implement locking. Each one
implements locking differently and has different goals in mind. It is
therefore worth knowing the difference, so that you can pick the right
one for your application. Here are the three locking wrappers:</p>
<ul>
<li><a name="*Tie%3a%3aDB_Lock*"></a><b><b>Tie::DB_Lock</b></b>
<p>A <b>DB_File</b> wrapper which creates copies of the database file for
read access, so that you have a kind of a multiversioning concurrent read
system. However, updates are still serial. Use for databases where reads
may be lengthy and consistency problems may occur.</p>
</li>
<li><a name="*Tie%3a%3aDB_LockFile*"></a><b><b>Tie::DB_LockFile</b></b>
<p>A <b>DB_File</b> wrapper that has the ability to lock and unlock the database
while it is being used. Avoids the tie-before-flock problem by simply
re-tie-ing the database when you get or drop a lock.  Because of the
flexibility in dropping and re-acquiring the lock in the middle of a
session, this can be massaged into a system that will work with long
updates and/or reads if the application follows the hints in the POD
documentation.</p>
</li>
<li><a name="*DB_File%3a%3aLock*"></a><b><b>DB_File::Lock</b></b>
<p>An extremely lightweight <b>DB_File</b> wrapper that simply flocks a lockfile
before tie-ing the database and drops the lock after the untie. Allows
one to use the same lockfile for multiple databases to avoid deadlock
problems, if desired. Use for databases where updates are reads are
quick and simple flock locking semantics are enough.</p>
</li>
</ul>
<a name="Sharing-Databases-With-C-Applications"></a><h2>Sharing Databases With C Applications</h2>
<p>There is no technical reason why a Berkeley DB database cannot be
shared by both a Perl and a C application.</p>
<p>The vast majority of problems that are reported in this area boil down
to the fact that C strings are NULL terminated, whilst Perl strings are
not. See <a href="#DBM-FILTERS">DBM FILTERS</a> for a generic way to work around this problem.</p>
<p>Here is a real example. Netscape 2.0 keeps a record of the locations you
visit along with the time you last visited them in a DB_HASH database.
This is usually stored in the file <i>~/.netscape/history.db</i>. The key
field in the database is the location string and the value field is the
time the location was last visited stored as a 4 byte binary value.</p>
<p>If you haven't already guessed, the location string is stored with a
terminating NULL. This means you need to be careful when accessing the
database.</p>
<p>Here is a snippet of code that is loosely based on Tom Christiansen's
<i>ggh</i> script (available from your nearest CPAN archive in
<i>authors/id/TOMC/scripts/nshist.gz</i>).</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">Fcntl</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$dotdir</span><span class="cm">,</span> <span class="i">$HISTORY</span><span class="cm">,</span> <span class="i">%hist_db</span><span class="cm">,</span> <span class="i">$href</span><span class="cm">,</span> <span class="i">$binary_time</span><span class="cm">,</span> <span class="i">$date</span><span class="s">)</span> <span class="sc">;</span></li><li>    <span class="i">$dotdir</span> = <span class="i">$ENV</span>{<span class="w">HOME</span>} || <span class="i">$ENV</span>{<span class="w">LOGNAME</span>}<span class="sc">;</span></li><li></li><li>    <span class="i">$HISTORY</span> = <span class="q">&quot;$dotdir/.netscape/history.db&quot;</span><span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%hist_db</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="i">$HISTORY</span></li><li>        or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot open $HISTORY: $!\n&quot;</span> <span class="sc">;</span><span class="sc">;</span></li><li></li><li>    <span class="c"># Dump the complete database</span></li><li>    while <span class="s">(</span> <span class="s">(</span><span class="i">$href</span><span class="cm">,</span> <span class="i">$binary_time</span><span class="s">)</span> = <a class="l_k" href="functions/each.html">each</a> <span class="i">%hist_db</span> <span class="s">)</span> <span class="s">{</span></li><li></li><li>        <span class="c"># remove the terminating NULL</span></li><li>        <span class="i">$href</span> =~ <span class="q">s/\x00$//</span> <span class="sc">;</span></li><li></li><li>        <span class="c"># convert the binary time into a user friendly string</span></li><li>        <span class="i">$date</span> = <a class="l_k" href="functions/localtime.html">localtime</a> <a class="l_k" href="functions/unpack.html">unpack</a><span class="s">(</span><span class="q">&quot;V&quot;</span><span class="cm">,</span> <span class="i">$binary_time</span><span class="s">)</span><span class="sc">;</span></li><li>        <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;$date $href\n&quot;</span> <span class="sc">;</span></li><li>    <span class="s">}</span></li><li></li><li>    <span class="c"># check for the existence of a specific key</span></li><li>    <span class="c"># remember to add the NULL</span></li><li>    if <span class="s">(</span> <span class="i">$binary_time</span> = <span class="i">$hist_db</span>{<span class="q">&quot;<a href="http://mox.perl.com/">http://mox.perl.com/</a>\x00&quot;</span>} <span class="s">)</span> <span class="s">{</span></li><li>        <span class="i">$date</span> = <a class="l_k" href="functions/localtime.html">localtime</a> <a class="l_k" href="functions/unpack.html">unpack</a><span class="s">(</span><span class="q">&quot;V&quot;</span><span class="cm">,</span> <span class="i">$binary_time</span><span class="s">)</span> <span class="sc">;</span></li><li>        <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Last visited mox.perl.com on $date\n&quot;</span> <span class="sc">;</span></li><li>    <span class="s">}</span></li><li>    else <span class="s">{</span></li><li>        <a class="l_k" href="functions/print.html">print</a> <span class="q">&quot;Never visited mox.perl.com\n&quot;</span></li><li>    <span class="s">}</span></li><li></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%hist_db</span> <span class="sc">;</span></li></ol></pre><a name="The-untie()-Gotcha"></a><h2>The untie() Gotcha</h2>
<p>If you make use of the Berkeley DB API, it is <i>very</i> strongly
recommended that you read <a href="perltie.html#The-untie-Gotcha">The untie Gotcha in perltie</a>.</p>
<p>Even if you don't currently make use of the API interface, it is still
worth reading it.</p>
<p>Here is an example which illustrates the problem from a <b>DB_File</b>
perspective:</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">Fcntl</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">%x</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$X</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$X</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%x</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="q">&#39;tst.fil&#39;</span> <span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_TRUNC</span></li><li>        or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot tie first time: $!&quot;</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$x</span>{<span class="n">123</span>} = <span class="n">456</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%x</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%x</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="q">&#39;tst.fil&#39;</span> <span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span></li><li>        or <a class="l_k" href="functions/die.html">die</a> <span class="q">&quot;Cannot tie second time: $!&quot;</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%x</span> <span class="sc">;</span></li></ol></pre><p>When run, the script will produce this error message:</p>
<pre class="verbatim"><ol><li>    Cannot tie second time: Invalid argument at bad.file line 14.</li></ol></pre><p>Although the error message above refers to the second tie() statement
in the script, the source of the problem is really with the untie()
statement that precedes it.</p>
<p>Having read <a href="perltie.html">perltie</a> you will probably have already guessed that the
error is caused by the extra copy of the tied object stored in <code class="inline"><span class="i">$X</span></code>
.
If you haven't, then the problem boils down to the fact that the
<b>DB_File</b> destructor, DESTROY, will not be called until <i>all</i>
references to the tied object are destroyed. Both the tied variable,
<code class="inline"><span class="i">%x</span></code>
, and <code class="inline"><span class="i">$X</span></code>
 above hold a reference to the object. The call to
untie() will destroy the first, but <code class="inline"><span class="i">$X</span></code>
 still holds a valid
reference, so the destructor will not get called and the database file
<i>tst.fil</i> will remain open. The fact that Berkeley DB then reports the
attempt to open a database that is already open via the catch-all
"Invalid argument" doesn't help.</p>
<p>If you run the script with the <code class="inline">-w</code>
 flag the error message becomes:</p>
<pre class="verbatim"><ol><li>    untie attempted while 1 inner references still exist at bad.file line 12.</li><li>    Cannot tie second time: Invalid argument at bad.file line 14.</li></ol></pre><p>which pinpoints the real problem. Finally the script can now be
modified to fix the original problem by destroying the API object
before the untie:</p>
<pre class="verbatim"><ol><li>    ...</li><li>    <span class="i">$x</span>{<span class="n">123</span>} = <span class="n">456</span> <span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/undef.html">undef</a> <span class="i">$X</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/untie.html">untie</a> <span class="i">%x</span> <span class="sc">;</span></li><li></li><li>    <span class="i">$X</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%x</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="q">&#39;tst.fil&#39;</span> <span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span></li><li>    ...</li></ol></pre><a name="COMMON-QUESTIONS"></a><h1>COMMON QUESTIONS</h1>
<a name="Why-is-there-Perl-source-in-my-database%3f"></a><h2>Why is there Perl source in my database?</h2>
<p>If you look at the contents of a database file created by DB_File,
there can sometimes be part of a Perl script included in it.</p>
<p>This happens because Berkeley DB uses dynamic memory to allocate
buffers which will subsequently be written to the database file. Being
dynamic, the memory could have been used for anything before DB
malloced it. As Berkeley DB doesn't clear the memory once it has been
allocated, the unused portions will contain random junk. In the case
where a Perl script gets written to the database, the random junk will
correspond to an area of dynamic memory that happened to be used during
the compilation of the script.</p>
<p>Unless you don't like the possibility of there being part of your Perl
scripts embedded in a database file, this is nothing to worry about.</p>
<a name="How-do-I-store-complex-data-structures-with-DB_File%3f"></a><h2>How do I store complex data structures with DB_File?</h2>
<p>Although <b>DB_File</b> cannot do this directly, there is a module which
can layer transparently over <b>DB_File</b> to accomplish this feat.</p>
<p>Check out the MLDBM module, available on CPAN in the directory
<i>modules/by-module/MLDBM</i>.</p>
<a name="What-does-%22wide-character-in-subroutine-entry%22-mean%3f"></a><h2>What does "wide character in subroutine entry" mean?</h2>
<p>You will usually get this message if you are working with UTF-8 data and
want to read/write it from/to a Berkeley DB database file.</p>
<p>The easist way to deal with this issue is to use the pre-defined "utf8"
<b>DBM_Filter</b> (see <a href="DBM_Filter.html">DBM_Filter</a>) that was designed to deal with this
situation.</p>
<p>The example below shows what you need if <i>both</i> the key and value are
expected to be in UTF-8.</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span><span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DBM_Filter</span><span class="sc">;</span> </li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$db</span> = <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%h</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="q">&#39;/tmp/try.db&#39;</span><span class="cm">,</span> <span class="w">O_CREAT</span>|<span class="w">O_RDWR</span><span class="cm">,</span> <span class="n">0666</span><span class="cm">,</span> <span class="i">$DB_BTREE</span><span class="sc">;</span> </li><li>    <span class="i">$db</span><span class="i">-&gt;Filter_Key_Push</span><span class="s">(</span><span class="q">&#39;utf8&#39;</span><span class="s">)</span><span class="sc">;</span></li><li>    <span class="i">$db</span><span class="i">-&gt;Filter_Value_Push</span><span class="s">(</span><span class="q">&#39;utf8&#39;</span><span class="s">)</span><span class="sc">;</span></li><li></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$key</span> = <span class="q">&quot;\N{LATIN SMALL LETTER A WITH ACUTE}&quot;</span><span class="sc">;</span></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">$value</span> = <span class="q">&quot;\N{LATIN SMALL LETTER E WITH ACUTE}&quot;</span><span class="sc">;</span></li><li>    <span class="i">$h</span>{ <span class="i">$key</span> } = <span class="i">$value</span><span class="sc">;</span></li></ol></pre><a name="What-does-%22Invalid-Argument%22-mean%3f"></a><h2>What does "Invalid Argument" mean?</h2>
<p>You will get this error message when one of the parameters in the
<code class="inline"><a class="l_k" href="functions/tie.html">tie</a></code> call is wrong. Unfortunately there are quite a few parameters to
get wrong, so it can be difficult to figure out which one it is.</p>
<p>Here are a couple of possibilities:</p>
<dl>
<dt>1.</dt><dd>
<p>Attempting to reopen a database without closing it.</p>
</dd>
<dt>2.</dt><dd>
<p>Using the O_WRONLY flag.</p>
</dd>
</dl>
<a name="What-does-%22Bareword-'DB_File'-not-allowed%22-mean%3f"></a><h2>What does "Bareword 'DB_File' not allowed" mean?</h2>
<p>You will encounter this particular error message when you have the
<code class="inline"><span class="w">strict</span> <span class="q">&#39;subs&#39;</span></code>
 pragma (or the full strict pragma) in your script.
Consider this script:</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">warnings</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/my.html">my</a> <span class="i">%x</span> <span class="sc">;</span></li><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%x</span><span class="cm">,</span> <span class="w">DB_File</span><span class="cm">,</span> <span class="q">&quot;filename&quot;</span> <span class="sc">;</span></li></ol></pre><p>Running it produces the error in question:</p>
<pre class="verbatim"><ol><li>    Bareword "DB_File" not allowed while "strict subs" in use</li></ol></pre><p>To get around the error, place the word <code class="inline"><span class="w">DB_File</span></code>
 in either single or
double quotes, like this:</p>
<pre class="verbatim"><ol><li>    <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%x</span><span class="cm">,</span> <span class="q">&quot;DB_File&quot;</span><span class="cm">,</span> <span class="q">&quot;filename&quot;</span> <span class="sc">;</span></li></ol></pre><p>Although it might seem like a real pain, it is really worth the effort
of having a <code class="inline"><a class="l_k" href="functions/use.html">use</a> <span class="w">strict</span></code>
 in all your scripts.</p>
<a name="REFERENCES"></a><h1>REFERENCES</h1>
<p>Articles that are either about <b>DB_File</b> or make use of it.</p>
<dl>
<dt>1.</dt><dd>
<p><i>Full-Text Searching in Perl</i>, Tim Kientzle (tkientzle@ddj.com),
Dr. Dobb's Journal, Issue 295, January 1999, pp 34-41</p>
</dd>
</dl>
<a name="HISTORY"></a><h1>HISTORY</h1>
<p>Moved to the Changes file.</p>
<a name="BUGS"></a><h1>BUGS</h1>
<p>Some older versions of Berkeley DB had problems with fixed length
records using the RECNO file format. This problem has been fixed since
version 1.85 of Berkeley DB.</p>
<p>I am sure there are bugs in the code. If you do find any, or can
suggest any enhancements, I would welcome your comments.</p>
<a name="AVAILABILITY"></a><h1>AVAILABILITY</h1>
<p><b>DB_File</b> comes with the standard Perl source distribution. Look in
the directory <i>ext/DB_File</i>. Given the amount of time between releases
of Perl the version that ships with Perl is quite likely to be out of
date, so the most recent version can always be found on CPAN (see
<a href="perlmodlib.html#CPAN">CPAN in perlmodlib</a> for details), in the directory
<i>modules/by-module/DB_File</i>.</p>
<p>This version of <b>DB_File</b> will work with either version 1.x, 2.x or
3.x of Berkeley DB, but is limited to the functionality provided by
version 1.</p>
<p>The official web site for Berkeley DB is <i><a href="http://www.oracle.com/technology/products/berkeley-db/db/index.html">http://www.oracle.com/technology/products/berkeley-db/db/index.html</a></i>.
All versions of Berkeley DB are available there.</p>
<p>Alternatively, Berkeley DB version 1 is available at your nearest CPAN
archive in <i>src/misc/db.1.85.tar.gz</i>.</p>
<a name="COPYRIGHT"></a><h1>COPYRIGHT</h1>
<p>Copyright (c) 1995-2016 Paul Marquess. All rights reserved. This program
is free software; you can redistribute it and/or modify it under the
same terms as Perl itself.</p>
<p>Although <b>DB_File</b> is covered by the Perl license, the library it
makes use of, namely Berkeley DB, is not. Berkeley DB has its own
copyright and its own license. Please take the time to read it.</p>
<p>Here are a few words taken from the Berkeley DB FAQ (at
<i><a href="http://www.oracle.com/technology/products/berkeley-db/db/index.html">http://www.oracle.com/technology/products/berkeley-db/db/index.html</a></i>) regarding the license:</p>
<pre class="verbatim"><ol><li>    Do I have to license DB to use it in Perl scripts? </li><li></li><li>    No. The Berkeley DB license requires that software that uses</li><li>    Berkeley DB be freely redistributable. In the case of Perl, that</li><li>    software is Perl, and not your scripts. Any Perl scripts that you</li><li>    write are your property, including scripts that make use of</li><li>    Berkeley DB. Neither the Perl license nor the Berkeley DB license</li><li>    place any restriction on what you may do with them.</li></ol></pre><p>If you are in any doubt about the license situation, contact either the
Berkeley DB authors or the author of DB_File. See <a href="#AUTHOR">AUTHOR</a> for details.</p>
<a name="SEE-ALSO"></a><h1>SEE ALSO</h1>
<p><a href="perl.html">perl</a>, <i>dbopen(3)</i>, <i>hash(3)</i>, <i>recno(3)</i>, <i>btree(3)</i>,
<a href="perldbmfilter.html">perldbmfilter</a>, <a href="DBM_Filter.html">DBM_Filter</a></p>
<a name="AUTHOR"></a><h1>AUTHOR</h1>
<p>The DB_File interface was written by Paul Marquess
&lt;pmqs@cpan.org&gt;.</p>




  <div id="page_index" class="hud_container">
    <div id="page_index_header" class="hud_header">
      <div id="page_index_close" class="hud_close"><a href="#" onClick="pageIndex.hide();return false;"></a></div>
      <div id="page_index_title" class="hud_title"><span class="hud_span_top">Page index</span></div>
      <div id="page_index_topright" class="hud_topright"></div>
    </div>
    <div id="page_index_content" class="hud_content">
      <ul><li><a href="#NAME">NAME</a><li><a href="#SYNOPSIS">SYNOPSIS</a><li><a href="#DESCRIPTION">DESCRIPTION</a><ul><li><a href="#Using-DB_File-with-Berkeley-DB-version-2-or-greater">Using DB_File with Berkeley DB version 2 or greater</a><li><a href="#Interface-to-Berkeley-DB">Interface to Berkeley DB</a><li><a href="#Opening-a-Berkeley-DB-Database-File">Opening a Berkeley DB Database File</a><li><a href="#Default-Parameters">Default Parameters</a><li><a href="#In-Memory-Databases">In Memory Databases</a></ul><li><a href="#DB_HASH">DB_HASH</a><ul><li><a href="#A-Simple-Example">A Simple Example</a></ul><li><a href="#DB_BTREE">DB_BTREE</a><ul><li><a href="#Changing-the-BTREE-sort-order">Changing the BTREE sort order</a><li><a href="#Handling-Duplicate-Keys">Handling Duplicate Keys</a><li><a href="#The-get_dup()-Method">The get_dup() Method</a><li><a href="#The-find_dup()-Method">The find_dup() Method</a><li><a href="#The-del_dup()-Method">The del_dup() Method</a><li><a href="#Matching-Partial-Keys">Matching Partial Keys</a></ul><li><a href="#DB_RECNO">DB_RECNO</a><ul><li><a href="#The-'bval'-Option">The 'bval' Option</a><li><a href="#A-Simple-Example">A Simple Example</a><li><a href="#Extra-RECNO-Methods">Extra RECNO Methods</a><li><a href="#Another-Example">Another Example</a></ul><li><a href="#THE-API-INTERFACE">THE API INTERFACE</a><li><a href="#DBM-FILTERS">DBM FILTERS</a><ul><li><a href="#DBM-Filter-Low-level-API">DBM Filter Low-level API</a><li><a href="#The-Filter">The Filter</a><li><a href="#An-Example----the-NULL-termination-problem.">An Example -- the NULL termination problem.</a><li><a href="#Another-Example----Key-is-a-C-int.">Another Example -- Key is a C int.</a></ul><li><a href="#HINTS-AND-TIPS">HINTS AND TIPS</a><ul><li><a href="#Locking%3a-The-Trouble-with-fd">Locking: The Trouble with fd</a><li><a href="#Safe-ways-to-lock-a-database">Safe ways to lock a database</a><li><a href="#Sharing-Databases-With-C-Applications">Sharing Databases With C Applications</a><li><a href="#The-untie()-Gotcha">The untie() Gotcha</a></ul><li><a href="#COMMON-QUESTIONS">COMMON QUESTIONS</a><ul><li><a href="#Why-is-there-Perl-source-in-my-database%3f">Why is there Perl source in my database?</a><li><a href="#How-do-I-store-complex-data-structures-with-DB_File%3f">How do I store complex data structures with DB_File?</a><li><a href="#What-does-%22wide-character-in-subroutine-entry%22-mean%3f">What does "wide character in subroutine entry" mean?</a><li><a href="#What-does-%22Invalid-Argument%22-mean%3f">What does "Invalid Argument" mean?</a><li><a href="#What-does-%22Bareword-'DB_File'-not-allowed%22-mean%3f">What does "Bareword 'DB_File' not allowed" mean?</a></ul><li><a href="#REFERENCES">REFERENCES</a><li><a href="#HISTORY">HISTORY</a><li><a href="#BUGS">BUGS</a><li><a href="#AVAILABILITY">AVAILABILITY</a><li><a href="#COPYRIGHT">COPYRIGHT</a><li><a href="#SEE-ALSO">SEE ALSO</a><li><a href="#AUTHOR">AUTHOR</a></ul>
    </div>
    <div id="page_index_footer" class="hud_footer">
      <div id="page_index_bottomleft" class="hud_bottomleft"></div>
      <div id="page_index_bottom" class="hud_bottom"><span class="hud_span_bottom"></span></div>
      <div id="page_index_resize" class="hud_resize"></div>
    </div>
  </div>


	    &nbsp;
          </div>
          <div id="content_footer">
          </div>
        </div>
        <div class="clear"></div>
      </div>
      
    <div id="footer">
      <div id="footer_content">
        <div id="footer_strapline">
          perldoc.perl.org - Official documentation for the Perl programming language
        </div>
        <div id="footer_links">
          <div id="address">
            <p class="name">Contact details</p>
            <p class="address">
	      Site maintained by <a href="mailto:jj@jonallen.info">Jon Allen (JJ)</a><br>
	    </p>
            <p class="contact">
              Documentation maintained by the <a href="http://lists.cpan.org/showlist.cgi?name=perl5-porters">Perl 5 Porters</a>
            </p>
          </div>
          <ul class="f1">
            <li>Manual
              <ul class="f2">
                <li><a href="index-overview.html">Overview</a>
                <li><a href="index-tutorials.html">Tutorials</a>
                <li><a href="index-faq.html">FAQs</a>
                <li><a href="index-history.html">Changes</a>
              </ul>
            <li>Reference
              <ul class="f2">
                <li><a href="index-language.html">Language</a>
                <li><a href="index-functions.html">Functions</a>
                <li><a href="perlop.html">Operators</a>
                <li><a href="perlvar.html">Variables</a>
              </ul>
            <li>Modules
              <ul class="f2">
                <li><a href="index-modules-A.html">Modules</a>
                <li><a href="index-pragmas.html">Pragmas</a>
                <li><a href="index-utilities.html">Utilities</a>
              </ul>
            <li>Misc
              <ul class="f2">
                <li><a href="index-licence.html">License</a>
                <li><a href="index-internals.html">Internals</a>
                <li><a href="index-platforms.html">Platforms</a>
              </ul>          </ul>
          <div class="clear"></div>
        </div>
      </div>
      <div id="footer_end">
      </div>
    </div>
      
    </div>
      <script language="JavaScript" type="text/javascript" src="static/exploreperl.js"></script>
      <script language="JavaScript" src="static/combined-20100403.js" type="text/javascript"></script>
<script language="JavaScript" type="text/javascript">
  perldoc.setPath(0);
  perldoc.pageName    = 'DB_File';
  perldoc.pageAddress = 'DB_File.html';
  perldoc.contentPage = 1;
  explorePerl.render();
  explorePerl.addEvents('explore_anchor');
</script>
    
  </body>
</html>