1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 1996-2009 Oracle.  All rights reserved.
4#
5# $Id$
6#
7# TEST	test003
8# TEST	Small keys/large data
9# TEST		Put/get per key
10# TEST		Dump file
11# TEST		Close, reopen
12# TEST		Dump file
13# TEST
14# TEST	Take the source files and dbtest executable and enter their names
15# TEST	as the key with their contents as data.  After all are entered,
16# TEST	retrieve all; compare output to original. Close file, reopen, do
17# TEST	retrieve and re-verify.
18proc test003 { method args} {
19	global names
20	source ./include.tcl
21
22	set args [convert_args $method $args]
23	set omethod [convert_method $method]
24
25	if {[is_fixed_length $method] == 1} {
26		puts "Test003 skipping for method $method"
27		return
28	}
29	puts "Test003: $method ($args) filename=key filecontents=data pairs"
30
31	# Create the database and open the dictionary
32	set limit 0
33	set txnenv 0
34	set eindex [lsearch -exact $args "-env"]
35	#
36	# If we are using an env, then testfile should just be the db name.
37	# Otherwise it is the test directory and the name.
38	if { $eindex == -1 } {
39		set testfile $testdir/test003.db
40		set env NULL
41	} else {
42		set testfile test003.db
43		incr eindex
44		set env [lindex $args $eindex]
45		set txnenv [is_txnenv $env]
46		if { $txnenv == 1 } {
47			append args " -auto_commit "
48			set limit 100
49		}
50		set testdir [get_home $env]
51	}
52	set t1 $testdir/t1
53	set t2 $testdir/t2
54	set t3 $testdir/t3
55	set t4 $testdir/t4
56
57	cleanup $testdir $env
58	set db [eval {berkdb_open \
59	     -create -mode 0644} $args $omethod $testfile]
60	error_check_good dbopen [is_valid_db $db] TRUE
61	set pflags ""
62	set gflags ""
63	set txn ""
64	if { [is_record_based $method] == 1 } {
65		set checkfunc test003_recno.check
66		append gflags "-recno"
67	} else {
68		set checkfunc test003.check
69	}
70
71	# Here is the loop where we put and get each key/data pair
72	set file_list [get_file_list]
73	set len [llength $file_list]
74	puts "\tTest003.a: put/get loop $len entries"
75	set count 0
76	foreach f $file_list {
77		if { [string compare [file type $f] "file"] != 0 } {
78			continue
79		}
80
81		if { [is_record_based $method] == 1 } {
82			set key [expr $count + 1]
83			set names([expr $count + 1]) $f
84		} else {
85			set key $f
86		}
87
88		# Should really catch errors
89		set fid [open $f r]
90		fconfigure $fid -translation binary
91		set data [read $fid]
92		close $fid
93		if { $txnenv == 1 } {
94			set t [$env txn]
95			error_check_good txn [is_valid_txn $t $env] TRUE
96			set txn "-txn $t"
97		}
98		set ret [eval {$db put} \
99		    $txn $pflags {$key [chop_data $method $data]}]
100		error_check_good put $ret 0
101		if { $txnenv == 1 } {
102			error_check_good txn [$t commit] 0
103		}
104
105		# Should really catch errors
106		set fid [open $t4 w]
107		fconfigure $fid -translation binary
108		if [catch {eval {$db get} $gflags {$key}} data] {
109			puts -nonewline $fid $data
110		} else {
111			# Data looks like {{key data}}
112			set key [lindex [lindex $data 0] 0]
113			set data [lindex [lindex $data 0] 1]
114			puts -nonewline $fid [pad_data $method $data]
115		}
116		close $fid
117
118		error_check_good \
119		    Test003:diff($f,$t4) [filecmp $f $t4] 0
120
121		incr count
122	}
123
124	# Now we will get each key from the DB and compare the results
125	# to the original.
126	puts "\tTest003.b: dump file"
127	if { $txnenv == 1 } {
128		set t [$env txn]
129		error_check_good txn [is_valid_txn $t $env] TRUE
130		set txn "-txn $t"
131	}
132	dump_bin_file $db $txn $t1 $checkfunc
133	if { $txnenv == 1 } {
134		error_check_good txn [$t commit] 0
135	}
136	error_check_good db_close [$db close] 0
137
138	# Now compare the keys to see if they match the entries in the
139	# current directory
140	if { [is_record_based $method] == 1 } {
141		set oid [open $t2 w]
142		for {set i 1} {$i <= $count} {set i [incr i]} {
143			puts $oid $i
144		}
145		close $oid
146		file rename -force $t1 $t3
147	} else {
148		set oid [open $t2.tmp w]
149		foreach f $file_list {
150			if { [string compare [file type $f] "file"] != 0 } {
151				continue
152			}
153			puts $oid $f
154		}
155		close $oid
156		filesort $t2.tmp $t2
157		fileremove $t2.tmp
158		filesort $t1 $t3
159	}
160
161	error_check_good \
162	    Test003:diff($t3,$t2) [filecmp $t3 $t2] 0
163
164	# Now, reopen the file and run the last test again.
165	puts "\tTest003.c: close, open, and dump file"
166	eval open_and_dump_file $testfile $env $t1 $checkfunc \
167	    dump_bin_file_direction "-first" "-next" $args
168
169	if { [is_record_based $method] == 1 } {
170		filesort $t1 $t3 -n
171	}
172
173	error_check_good \
174	    Test003:diff($t3,$t2) [filecmp $t3 $t2] 0
175
176	# Now, reopen the file and run the last test again in reverse direction.
177	puts "\tTest003.d: close, open, and dump file in reverse direction"
178	eval open_and_dump_file $testfile $env $t1 $checkfunc \
179	    dump_bin_file_direction "-last" "-prev" $args
180
181	if { [is_record_based $method] == 1 } {
182		filesort $t1 $t3 -n
183	}
184
185	error_check_good \
186	    Test003:diff($t3,$t2) [filecmp $t3 $t2] 0
187}
188
189# Check function for test003; key should be file name; data should be contents
190proc test003.check { binfile tmpfile } {
191	source ./include.tcl
192
193	error_check_good Test003:datamismatch($binfile,$tmpfile) \
194	    [filecmp $binfile $tmpfile] 0
195}
196proc test003_recno.check { binfile tmpfile } {
197	global names
198	source ./include.tcl
199
200	set fname $names($binfile)
201	error_check_good key"$binfile"_exists [info exists names($binfile)] 1
202	error_check_good Test003:datamismatch($fname,$tmpfile) \
203	    [filecmp $fname $tmpfile] 0
204}
205