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