xref: /sqlite-3.40.0/test/e_blobclose.test (revision a32536b4)
1# 2014 October 30
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#
12
13set testdir [file dirname $argv0]
14source $testdir/tester.tcl
15set testprefix e_blobclose
16
17ifcapable !incrblob {
18  finish_test
19  return
20}
21
22set dots [string repeat . 40]
23do_execsql_test 1.0 {
24  CREATE TABLE x1(a INTEGER PRIMARY KEY, b DOTS);
25  INSERT INTO x1 VALUES(-1, $dots);
26  INSERT INTO x1 VALUES(-10, $dots);
27  INSERT INTO x1 VALUES(-100, $dots);
28  INSERT INTO x1 VALUES(-1000, $dots);
29  INSERT INTO x1 VALUES(-10000, $dots);
30}
31
32# EVIDENCE-OF: R-03145-46390 This function closes an open BLOB handle.
33#
34#   It's not clear how to test that a blob handle really is closed.
35#   Attempting to use a closed blob handle will likely crash the process.
36#   Assume here that if the SHARED lock on the db file is released,
37#   the blob handle has been closed.
38#
39do_execsql_test 1.1 { PRAGMA lock_status } {main unlocked temp closed}
40sqlite3_blob_open db main x1 b -1 0 B
41do_execsql_test 1.2 { PRAGMA lock_status } {main shared temp closed}
42sqlite3_blob_close $B
43do_execsql_test 1.3 { PRAGMA lock_status } {main unlocked temp closed}
44
45
46# EVIDENCE-OF: R-34027-00617 If the blob handle being closed was opened
47# for read-write access, and if the database is in auto-commit mode and
48# there are no other open read-write blob handles or active write
49# statements, the current transaction is committed.
50#
51#   2.1.*: Transaction is not committed if there are other open
52#          read-write blob handles.
53#
54#   2.2.*: Transaction is not committed if not in auto-commit mode.
55#
56#   2.3.*: Active write statements.
57#
58do_test 2.1.1 {
59  sqlite3_blob_open db main x1 b -100 1 B1
60  sqlite3_blob_open db main x1 b -1000 1 B2
61  sqlite3_blob_open db main x1 b -10000 1 B3
62  sqlite3_blob_open db main x1 b -10000 0 B4      ;# B4 is read-only!
63  execsql { PRAGMA lock_status }
64} {main reserved temp closed}
65do_test 2.1.2 {
66  sqlite3_blob_close $B1
67  execsql { PRAGMA lock_status }
68} {main reserved temp closed}
69do_test 2.1.3 {
70  sqlite3_blob_close $B2
71  execsql { PRAGMA lock_status }
72} {main reserved temp closed}
73do_test 2.1.4 {
74  sqlite3_blob_close $B3
75  execsql { PRAGMA lock_status }
76} {main shared temp closed}
77do_test 2.1.5 {
78  sqlite3_blob_close $B4
79  execsql { PRAGMA lock_status }
80} {main unlocked temp closed}
81
82do_test 2.2.1 {
83  sqlite3_blob_open db main x1 b -100 1 B1
84  execsql { PRAGMA lock_status }
85} {main reserved temp closed}
86do_test 2.2.2 {
87  execsql { BEGIN }
88  sqlite3_blob_close $B1
89  execsql { PRAGMA lock_status }
90} {main reserved temp closed}
91do_test 2.2.3 {
92  execsql { COMMIT }
93  execsql { PRAGMA lock_status }
94} {main unlocked temp closed}
95
96proc val {} {
97  sqlite3_blob_close $::B
98  db eval { PRAGMA lock_status }
99}
100db func val val
101do_test 2.3.1 {
102  sqlite3_blob_open db main x1 b -100 1 B
103  execsql { PRAGMA lock_status }
104} {main reserved temp closed}
105do_test 2.3.2 {
106  execsql { INSERT INTO x1 VALUES(15, val()) }
107  execsql { PRAGMA lock_status }
108} {main unlocked temp closed}
109do_test 2.3.3 {
110  execsql { SELECT * FROM x1 WHERE a = 15 }
111} {15 {main reserved temp closed}}
112
113# A reader does not inhibit commit.
114do_test 2.3.4 {
115  sqlite3_blob_open db main x1 b -100 1 B
116  execsql { PRAGMA lock_status }
117} {main reserved temp closed}
118do_test 2.3.5 {
119  execsql { SELECT a, val() FROM x1 LIMIT 1 }
120} {-10000 {main shared temp closed}}
121
122
123do_test 3.1 {
124  sqlite3_blob_open db main x1 b -10 1 B
125  execsql {
126    INSERT INTO x1 VALUES(1, 'abc');
127    SELECT * FROM x1 WHERE a=1;
128  }
129} {1 abc}
130do_test 3.2 {
131  sqlite3_blob_write $B 0 "abcdefghij" 10
132  execsql { SELECT * FROM x1 WHERE a=-10 }
133} {-10 abcdefghij..............................}
134
135do_test 3.3 {
136  sqlite3 db2 test.db
137  execsql { BEGIN ; SELECT * FROM x1 } db2
138  sqlite3_blob_close $B
139} {SQLITE_BUSY}
140
141# EVIDENCE-OF: R-41959-38737 Otherwise, if this function is passed a
142# valid open blob handle, the values returned by the sqlite3_errcode()
143# and sqlite3_errmsg() functions are set before returning.
144#
145do_test 3.4 {
146  list [sqlite3_errcode db] [sqlite3_errmsg db]
147} {SQLITE_BUSY {database is locked}}
148
149# EVIDENCE-OF: R-37801-37633 The BLOB handle is closed unconditionally.
150# Even if this routine returns an error code, the handle is still
151# closed.
152#
153#   Test that the lock has been released. Assume this means the handle
154#   is closed, even though blob_close() returned SQLITE_BUSY.
155#
156do_execsql_test 3.4 { PRAGMA lock_status } {main unlocked temp closed}
157
158# EVIDENCE-OF: R-35111-05628 If an error occurs while committing the
159# transaction, an error code is returned and the transaction rolled
160# back.
161#
162#   Row 1 is removed (it was inserted this transaction) and row -10
163#   is restored to its original state. Transaction has been rolled back.
164#
165do_execsql_test 3.5 {
166  SELECT * FROM x1 WHERE a IN (1, -10);
167} {-10 ........................................}
168
169# EVIDENCE-OF: R-25894-51060 Calling this routine with a null pointer
170# (such as would be returned by a failed call to sqlite3_blob_open()) is
171# a harmless no-op.
172#
173do_test 4.0 { sqlite3_blob_close 0 } {}
174
175finish_test
176