143f4066eSdan# 2014 October 30 243f4066eSdan# 343f4066eSdan# The author disclaims copyright to this source code. In place of 443f4066eSdan# a legal notice, here is a blessing: 543f4066eSdan# 643f4066eSdan# May you do good and not evil. 743f4066eSdan# May you find forgiveness for yourself and forgive others. 843f4066eSdan# May you share freely, never taking more than you give. 943f4066eSdan# 1043f4066eSdan#*********************************************************************** 1143f4066eSdan# 1243f4066eSdan 1343f4066eSdanset testdir [file dirname $argv0] 1443f4066eSdansource $testdir/tester.tcl 1543f4066eSdanset testprefix e_blobclose 1643f4066eSdan 17*a32536b4Sdanifcapable !incrblob { 18*a32536b4Sdan finish_test 19*a32536b4Sdan return 20*a32536b4Sdan} 21*a32536b4Sdan 2243f4066eSdanset dots [string repeat . 40] 2343f4066eSdando_execsql_test 1.0 { 2443f4066eSdan CREATE TABLE x1(a INTEGER PRIMARY KEY, b DOTS); 2543f4066eSdan INSERT INTO x1 VALUES(-1, $dots); 2643f4066eSdan INSERT INTO x1 VALUES(-10, $dots); 2743f4066eSdan INSERT INTO x1 VALUES(-100, $dots); 2843f4066eSdan INSERT INTO x1 VALUES(-1000, $dots); 2943f4066eSdan INSERT INTO x1 VALUES(-10000, $dots); 3043f4066eSdan} 3143f4066eSdan 3243f4066eSdan# EVIDENCE-OF: R-03145-46390 This function closes an open BLOB handle. 3343f4066eSdan# 3443f4066eSdan# It's not clear how to test that a blob handle really is closed. 3543f4066eSdan# Attempting to use a closed blob handle will likely crash the process. 3643f4066eSdan# Assume here that if the SHARED lock on the db file is released, 3743f4066eSdan# the blob handle has been closed. 3843f4066eSdan# 3943f4066eSdando_execsql_test 1.1 { PRAGMA lock_status } {main unlocked temp closed} 4043f4066eSdansqlite3_blob_open db main x1 b -1 0 B 4143f4066eSdando_execsql_test 1.2 { PRAGMA lock_status } {main shared temp closed} 4243f4066eSdansqlite3_blob_close $B 4343f4066eSdando_execsql_test 1.3 { PRAGMA lock_status } {main unlocked temp closed} 4443f4066eSdan 4543f4066eSdan 4643f4066eSdan# EVIDENCE-OF: R-34027-00617 If the blob handle being closed was opened 4743f4066eSdan# for read-write access, and if the database is in auto-commit mode and 4843f4066eSdan# there are no other open read-write blob handles or active write 4943f4066eSdan# statements, the current transaction is committed. 5043f4066eSdan# 5143f4066eSdan# 2.1.*: Transaction is not committed if there are other open 5243f4066eSdan# read-write blob handles. 5343f4066eSdan# 5443f4066eSdan# 2.2.*: Transaction is not committed if not in auto-commit mode. 5543f4066eSdan# 5643f4066eSdan# 2.3.*: Active write statements. 5743f4066eSdan# 5843f4066eSdando_test 2.1.1 { 5943f4066eSdan sqlite3_blob_open db main x1 b -100 1 B1 6043f4066eSdan sqlite3_blob_open db main x1 b -1000 1 B2 6143f4066eSdan sqlite3_blob_open db main x1 b -10000 1 B3 6243f4066eSdan sqlite3_blob_open db main x1 b -10000 0 B4 ;# B4 is read-only! 6343f4066eSdan execsql { PRAGMA lock_status } 6443f4066eSdan} {main reserved temp closed} 6543f4066eSdando_test 2.1.2 { 6643f4066eSdan sqlite3_blob_close $B1 6743f4066eSdan execsql { PRAGMA lock_status } 6843f4066eSdan} {main reserved temp closed} 6943f4066eSdando_test 2.1.3 { 7043f4066eSdan sqlite3_blob_close $B2 7143f4066eSdan execsql { PRAGMA lock_status } 7243f4066eSdan} {main reserved temp closed} 7343f4066eSdando_test 2.1.4 { 7443f4066eSdan sqlite3_blob_close $B3 7543f4066eSdan execsql { PRAGMA lock_status } 7643f4066eSdan} {main shared temp closed} 7743f4066eSdando_test 2.1.5 { 7843f4066eSdan sqlite3_blob_close $B4 7943f4066eSdan execsql { PRAGMA lock_status } 8043f4066eSdan} {main unlocked temp closed} 8143f4066eSdan 8243f4066eSdando_test 2.2.1 { 8343f4066eSdan sqlite3_blob_open db main x1 b -100 1 B1 8443f4066eSdan execsql { PRAGMA lock_status } 8543f4066eSdan} {main reserved temp closed} 8643f4066eSdando_test 2.2.2 { 8743f4066eSdan execsql { BEGIN } 8843f4066eSdan sqlite3_blob_close $B1 8943f4066eSdan execsql { PRAGMA lock_status } 9043f4066eSdan} {main reserved temp closed} 9143f4066eSdando_test 2.2.3 { 9243f4066eSdan execsql { COMMIT } 9343f4066eSdan execsql { PRAGMA lock_status } 9443f4066eSdan} {main unlocked temp closed} 9543f4066eSdan 9643f4066eSdanproc val {} { 9743f4066eSdan sqlite3_blob_close $::B 9843f4066eSdan db eval { PRAGMA lock_status } 9943f4066eSdan} 10043f4066eSdandb func val val 10143f4066eSdando_test 2.3.1 { 10243f4066eSdan sqlite3_blob_open db main x1 b -100 1 B 10343f4066eSdan execsql { PRAGMA lock_status } 10443f4066eSdan} {main reserved temp closed} 10543f4066eSdando_test 2.3.2 { 10643f4066eSdan execsql { INSERT INTO x1 VALUES(15, val()) } 10743f4066eSdan execsql { PRAGMA lock_status } 10843f4066eSdan} {main unlocked temp closed} 10943f4066eSdando_test 2.3.3 { 11043f4066eSdan execsql { SELECT * FROM x1 WHERE a = 15 } 11143f4066eSdan} {15 {main reserved temp closed}} 11243f4066eSdan 11343f4066eSdan# A reader does not inhibit commit. 11443f4066eSdando_test 2.3.4 { 11543f4066eSdan sqlite3_blob_open db main x1 b -100 1 B 11643f4066eSdan execsql { PRAGMA lock_status } 11743f4066eSdan} {main reserved temp closed} 11843f4066eSdando_test 2.3.5 { 11943f4066eSdan execsql { SELECT a, val() FROM x1 LIMIT 1 } 12043f4066eSdan} {-10000 {main shared temp closed}} 12143f4066eSdan 12243f4066eSdan 12343f4066eSdando_test 3.1 { 12443f4066eSdan sqlite3_blob_open db main x1 b -10 1 B 12543f4066eSdan execsql { 12643f4066eSdan INSERT INTO x1 VALUES(1, 'abc'); 12743f4066eSdan SELECT * FROM x1 WHERE a=1; 12843f4066eSdan } 12943f4066eSdan} {1 abc} 13043f4066eSdando_test 3.2 { 13143f4066eSdan sqlite3_blob_write $B 0 "abcdefghij" 10 13243f4066eSdan execsql { SELECT * FROM x1 WHERE a=-10 } 13343f4066eSdan} {-10 abcdefghij..............................} 13443f4066eSdan 13543f4066eSdando_test 3.3 { 13643f4066eSdan sqlite3 db2 test.db 13743f4066eSdan execsql { BEGIN ; SELECT * FROM x1 } db2 13843f4066eSdan sqlite3_blob_close $B 13943f4066eSdan} {SQLITE_BUSY} 14043f4066eSdan 14143f4066eSdan# EVIDENCE-OF: R-41959-38737 Otherwise, if this function is passed a 14243f4066eSdan# valid open blob handle, the values returned by the sqlite3_errcode() 14343f4066eSdan# and sqlite3_errmsg() functions are set before returning. 14443f4066eSdan# 14543f4066eSdando_test 3.4 { 14643f4066eSdan list [sqlite3_errcode db] [sqlite3_errmsg db] 14743f4066eSdan} {SQLITE_BUSY {database is locked}} 14843f4066eSdan 14943f4066eSdan# EVIDENCE-OF: R-37801-37633 The BLOB handle is closed unconditionally. 15043f4066eSdan# Even if this routine returns an error code, the handle is still 15143f4066eSdan# closed. 15243f4066eSdan# 15343f4066eSdan# Test that the lock has been released. Assume this means the handle 15443f4066eSdan# is closed, even though blob_close() returned SQLITE_BUSY. 15543f4066eSdan# 15643f4066eSdando_execsql_test 3.4 { PRAGMA lock_status } {main unlocked temp closed} 15743f4066eSdan 15843f4066eSdan# EVIDENCE-OF: R-35111-05628 If an error occurs while committing the 15943f4066eSdan# transaction, an error code is returned and the transaction rolled 16043f4066eSdan# back. 16143f4066eSdan# 16243f4066eSdan# Row 1 is removed (it was inserted this transaction) and row -10 16343f4066eSdan# is restored to its original state. Transaction has been rolled back. 16443f4066eSdan# 16543f4066eSdando_execsql_test 3.5 { 16643f4066eSdan SELECT * FROM x1 WHERE a IN (1, -10); 16743f4066eSdan} {-10 ........................................} 16843f4066eSdan 16943f4066eSdan# EVIDENCE-OF: R-25894-51060 Calling this routine with a null pointer 17043f4066eSdan# (such as would be returned by a failed call to sqlite3_blob_open()) is 17143f4066eSdan# a harmless no-op. 17243f4066eSdan# 17343f4066eSdando_test 4.0 { sqlite3_blob_close 0 } {} 17443f4066eSdan 17543f4066eSdanfinish_test 176