blob: a5b244b13f32ad33af74950f9826ba920d98591b [file] [log] [blame]
danielk1977b4e9af92007-05-01 17:49:49 +00001# 2007 May 1
2#
3# The author disclaims copyright to this source code. In place of
4# a legal notice, here is a blessing:
5#
6# May you do good and not evil.
7# May you find forgiveness for yourself and forgive others.
8# May you share freely, never taking more than you give.
9#
10#***********************************************************************
11#
danielk197720713f32007-05-03 11:43:33 +000012# $Id: incrblob.test,v 1.3 2007/05/03 11:43:35 danielk1977 Exp $
13#
danielk1977b4e9af92007-05-01 17:49:49 +000014
15set testdir [file dirname $argv0]
16source $testdir/tester.tcl
17
18do_test incrblob-1.1 {
19 execsql {
20 CREATE TABLE blobs(k PRIMARY KEY, v BLOB);
21 INSERT INTO blobs VALUES('one', X'0102030405060708090A');
22 INSERT INTO blobs VALUES('two', X'0A090807060504030201');
23 }
24} {}
25
26do_test incrblob-1.2.1 {
27 set ::blob [db incrblob blobs v 1]
28} {incrblob_1}
29do_test incrblob-1.2.2 {
30 binary scan [read $::blob] c* data
31 set data
32} {1 2 3 4 5 6 7 8 9 10}
33do_test incrblob-1.2.3 {
34 seek $::blob 0
35 puts -nonewline $::blob "1234567890"
36 flush $::blob
37} {}
38do_test incrblob-1.2.4 {
39 seek $::blob 0
40 binary scan [read $::blob] c* data
41 set data
42} {49 50 51 52 53 54 55 56 57 48}
43do_test incrblob-1.2.5 {
44 close $::blob
45} {}
46do_test incrblob-1.2.6 {
47 execsql {
48 SELECT v FROM blobs WHERE rowid = 1;
49 }
50} {1234567890}
51
danielk1977d04417962007-05-02 13:16:30 +000052#--------------------------------------------------------------------
danielk197720713f32007-05-03 11:43:33 +000053# Test cases incrblob-1.3.X check that it is possible to read and write
danielk1977d04417962007-05-02 13:16:30 +000054# regions of a blob that lie on overflow pages.
danielk197720713f32007-05-03 11:43:33 +000055#
56do_test incrblob-1.3.1 {
danielk1977d04417962007-05-02 13:16:30 +000057 set ::str "[string repeat . 10000]"
58 execsql {
59 INSERT INTO blobs(rowid, k, v) VALUES(3, 'three', $::str);
60 }
61} {}
danielk1977b4e9af92007-05-01 17:49:49 +000062
danielk197720713f32007-05-03 11:43:33 +000063do_test incrblob-1.3.2 {
danielk1977d04417962007-05-02 13:16:30 +000064 set ::blob [db incrblob blobs v 3]
65 seek $::blob 8500
66 read $::blob 10
67} {..........}
danielk197720713f32007-05-03 11:43:33 +000068do_test incrblob-1.3.3 {
danielk1977d04417962007-05-02 13:16:30 +000069 seek $::blob 8500
70 puts -nonewline $::blob 1234567890
71} {}
danielk197720713f32007-05-03 11:43:33 +000072do_test incrblob-1.3.4 {
danielk1977d04417962007-05-02 13:16:30 +000073 seek $::blob 8496
74 read $::blob 10
75} {....123456}
danielk197720713f32007-05-03 11:43:33 +000076do_test incrblob-1.3.10 {
danielk1977d04417962007-05-02 13:16:30 +000077 close $::blob
78} {}
79
danielk1977b4e9af92007-05-01 17:49:49 +000080
danielk197720713f32007-05-03 11:43:33 +000081#------------------------------------------------------------------------
82# incrblob-2.*: Test seeking in an incremental blob can use ptrmap pages.
83#
84proc nRead {db} {
85 set bt [btree_from_db $db]
86 array set stats [btree_pager_stats $bt]
87 return $stats(read)
88}
89
90foreach AutoVacuumMode [list 0 1] {
91
92 db close
93 file delete -force test.db test.db-journal
94
95 sqlite3 db test.db
96 execsql "PRAGMA auto_vacuum = $AutoVacuumMode"
97
98 do_test incrblob-2.$AutoVacuumMode.1 {
99 set ::str [string repeat abcdefghij 2900]
100 execsql {
101 BEGIN;
102 CREATE TABLE blobs(k PRIMARY KEY, v BLOB);
103 DELETE FROM blobs;
104 INSERT INTO blobs VALUES('one', $::str || randstr(500,500));
105 COMMIT;
106 }
107 expr [file size test.db]/1024
108 } [expr 31 + $AutoVacuumMode]
109
110 do_test incrblob-2.$AutoVacuumMode.2 {
111 execsql {
112 PRAGMA auto_vacuum;
113 }
114 } $AutoVacuumMode
115
116 do_test incrblob-2.$AutoVacuumMode.3 {
117 # Open and close the db to make sure the page cache is empty.
118 db close
119 sqlite3 db test.db
120
121 # Read the last 20 bytes of the blob via a blob handle.
122 set ::blob [db incrblob blobs v 1]
123 seek $::blob -20 end
124 set ::fragment [read $::blob]
125 close $::blob
126
127 # If the database is not in auto-vacuum mode, the whole of
128 # the overflow-chain must be scanned. In auto-vacuum mode,
129 # sqlite uses the ptrmap pages to avoid reading the other pages.
130 #
131 nRead db
132 } [expr $AutoVacuumMode ? 4 : 30]
133
134 do_test incrblob-2.3 {
135 string range [db one {SELECT v FROM blobs}] end-19 end
136 } $::fragment
137}
138
139finish_test