000001 # 2014 October 30 000002 # 000003 # The author disclaims copyright to this source code. In place of 000004 # a legal notice, here is a blessing: 000005 # 000006 # May you do good and not evil. 000007 # May you find forgiveness for yourself and forgive others. 000008 # May you share freely, never taking more than you give. 000009 # 000010 #*********************************************************************** 000011 # 000012 000013 set testdir [file dirname $argv0] 000014 source $testdir/tester.tcl 000015 set testprefix e_blobclose 000016 000017 set dots [string repeat . 40] 000018 do_execsql_test 1.0 { 000019 CREATE TABLE x1(a INTEGER PRIMARY KEY, b DOTS); 000020 INSERT INTO x1 VALUES(-1, $dots); 000021 INSERT INTO x1 VALUES(-10, $dots); 000022 INSERT INTO x1 VALUES(-100, $dots); 000023 INSERT INTO x1 VALUES(-1000, $dots); 000024 INSERT INTO x1 VALUES(-10000, $dots); 000025 } 000026 000027 # EVIDENCE-OF: R-03145-46390 This function closes an open BLOB handle. 000028 # 000029 # It's not clear how to test that a blob handle really is closed. 000030 # Attempting to use a closed blob handle will likely crash the process. 000031 # Assume here that if the SHARED lock on the db file is released, 000032 # the blob handle has been closed. 000033 # 000034 do_execsql_test 1.1 { PRAGMA lock_status } {main unlocked temp closed} 000035 sqlite3_blob_open db main x1 b -1 0 B 000036 do_execsql_test 1.2 { PRAGMA lock_status } {main shared temp closed} 000037 sqlite3_blob_close $B 000038 do_execsql_test 1.3 { PRAGMA lock_status } {main unlocked temp closed} 000039 000040 000041 # EVIDENCE-OF: R-34027-00617 If the blob handle being closed was opened 000042 # for read-write access, and if the database is in auto-commit mode and 000043 # there are no other open read-write blob handles or active write 000044 # statements, the current transaction is committed. 000045 # 000046 # 2.1.*: Transaction is not committed if there are other open 000047 # read-write blob handles. 000048 # 000049 # 2.2.*: Transaction is not committed if not in auto-commit mode. 000050 # 000051 # 2.3.*: Active write statements. 000052 # 000053 do_test 2.1.1 { 000054 sqlite3_blob_open db main x1 b -100 1 B1 000055 sqlite3_blob_open db main x1 b -1000 1 B2 000056 sqlite3_blob_open db main x1 b -10000 1 B3 000057 sqlite3_blob_open db main x1 b -10000 0 B4 ;# B4 is read-only! 000058 execsql { PRAGMA lock_status } 000059 } {main reserved temp closed} 000060 do_test 2.1.2 { 000061 sqlite3_blob_close $B1 000062 execsql { PRAGMA lock_status } 000063 } {main reserved temp closed} 000064 do_test 2.1.3 { 000065 sqlite3_blob_close $B2 000066 execsql { PRAGMA lock_status } 000067 } {main reserved temp closed} 000068 do_test 2.1.4 { 000069 sqlite3_blob_close $B3 000070 execsql { PRAGMA lock_status } 000071 } {main shared temp closed} 000072 do_test 2.1.5 { 000073 sqlite3_blob_close $B4 000074 execsql { PRAGMA lock_status } 000075 } {main unlocked temp closed} 000076 000077 do_test 2.2.1 { 000078 sqlite3_blob_open db main x1 b -100 1 B1 000079 execsql { PRAGMA lock_status } 000080 } {main reserved temp closed} 000081 do_test 2.2.2 { 000082 execsql { BEGIN } 000083 sqlite3_blob_close $B1 000084 execsql { PRAGMA lock_status } 000085 } {main reserved temp closed} 000086 do_test 2.2.3 { 000087 execsql { COMMIT } 000088 execsql { PRAGMA lock_status } 000089 } {main unlocked temp closed} 000090 000091 proc val {} { 000092 sqlite3_blob_close $::B 000093 db eval { PRAGMA lock_status } 000094 } 000095 db func val val 000096 do_test 2.3.1 { 000097 sqlite3_blob_open db main x1 b -100 1 B 000098 execsql { PRAGMA lock_status } 000099 } {main reserved temp closed} 000100 do_test 2.3.2 { 000101 execsql { INSERT INTO x1 VALUES(15, val()) } 000102 execsql { PRAGMA lock_status } 000103 } {main unlocked temp closed} 000104 do_test 2.3.3 { 000105 execsql { SELECT * FROM x1 WHERE a = 15 } 000106 } {15 {main reserved temp closed}} 000107 000108 # A reader does not inhibit commit. 000109 do_test 2.3.4 { 000110 sqlite3_blob_open db main x1 b -100 1 B 000111 execsql { PRAGMA lock_status } 000112 } {main reserved temp closed} 000113 do_test 2.3.5 { 000114 execsql { SELECT a, val() FROM x1 LIMIT 1 } 000115 } {-10000 {main shared temp closed}} 000116 000117 000118 do_test 3.1 { 000119 sqlite3_blob_open db main x1 b -10 1 B 000120 execsql { 000121 INSERT INTO x1 VALUES(1, 'abc'); 000122 SELECT * FROM x1 WHERE a=1; 000123 } 000124 } {1 abc} 000125 do_test 3.2 { 000126 sqlite3_blob_write $B 0 "abcdefghij" 10 000127 execsql { SELECT * FROM x1 WHERE a=-10 } 000128 } {-10 abcdefghij..............................} 000129 000130 do_test 3.3 { 000131 sqlite3 db2 test.db 000132 execsql { BEGIN ; SELECT * FROM x1 } db2 000133 sqlite3_blob_close $B 000134 } {SQLITE_BUSY} 000135 000136 # EVIDENCE-OF: R-41959-38737 Otherwise, if this function is passed a 000137 # valid open blob handle, the values returned by the sqlite3_errcode() 000138 # and sqlite3_errmsg() functions are set before returning. 000139 # 000140 do_test 3.4 { 000141 list [sqlite3_errcode db] [sqlite3_errmsg db] 000142 } {SQLITE_BUSY {database is locked}} 000143 000144 # EVIDENCE-OF: R-37801-37633 The BLOB handle is closed unconditionally. 000145 # Even if this routine returns an error code, the handle is still 000146 # closed. 000147 # 000148 # Test that the lock has been released. Assume this means the handle 000149 # is closed, even though blob_close() returned SQLITE_BUSY. 000150 # 000151 do_execsql_test 3.4 { PRAGMA lock_status } {main unlocked temp closed} 000152 000153 # EVIDENCE-OF: R-35111-05628 If an error occurs while committing the 000154 # transaction, an error code is returned and the transaction rolled 000155 # back. 000156 # 000157 # Row 1 is removed (it was inserted this transaction) and row -10 000158 # is restored to its original state. Transaction has been rolled back. 000159 # 000160 do_execsql_test 3.5 { 000161 SELECT * FROM x1 WHERE a IN (1, -10); 000162 } {-10 ........................................} 000163 000164 # EVIDENCE-OF: R-25894-51060 Calling this routine with a null pointer 000165 # (such as would be returned by a failed call to sqlite3_blob_open()) is 000166 # a harmless no-op. 000167 # 000168 do_test 4.0 { sqlite3_blob_close 0 } {} 000169 000170 finish_test