/ Check-in [5a1eac24]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add new test file e_blobclose.test, containing tests for sqlite3_blob_close().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5a1eac2419b1462e6f21595a3fff26d9cc49d203
User & Date: dan 2014-11-11 12:20:35
Context
2014-11-11
14:59
Permit read operations to continue after a ROLLBACK as long as the schema does not change. check-in: b5df5ac0 user: drh tags: trunk
12:20
Add new test file e_blobclose.test, containing tests for sqlite3_blob_close(). check-in: 5a1eac24 user: dan tags: trunk
2014-11-10
19:16
New test cases for deleting content out from under a SELECT statement. check-in: 8289c3e9 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/sqlite.h.in.

  5750   5750   ** ^This function sets the database handle error code and message.
  5751   5751   */
  5752   5752   SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
  5753   5753   
  5754   5754   /*
  5755   5755   ** CAPI3REF: Close A BLOB Handle
  5756   5756   **
  5757         -** ^Closes an open [BLOB handle].
         5757  +** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
         5758  +** unconditionally.  Even if this routine returns an error code, the 
         5759  +** handle is still closed.)^
  5758   5760   **
  5759         -** ^Closing a BLOB shall cause the current transaction to commit
  5760         -** if there are no other BLOBs, no pending prepared statements, and the
  5761         -** database connection is in [autocommit mode].
  5762         -** ^If any writes were made to the BLOB, they might be held in cache
  5763         -** until the close operation if they will fit.
         5761  +** ^If the blob handle being closed was opened for read-write access, and if
         5762  +** the database is in auto-commit mode and there are no other open read-write
         5763  +** blob handles or active write statements, the current transaction is
         5764  +** committed. ^If an error occurs while committing the transaction, an error
         5765  +** code is returned and the transaction rolled back.
  5764   5766   **
  5765         -** ^(Closing the BLOB often forces the changes
  5766         -** out to disk and so if any I/O errors occur, they will likely occur
  5767         -** at the time when the BLOB is closed.  Any errors that occur during
  5768         -** closing are reported as a non-zero return value.)^
  5769         -**
  5770         -** ^(The BLOB is closed unconditionally.  Even if this routine returns
  5771         -** an error code, the BLOB is still closed.)^
  5772         -**
  5773         -** ^Calling this routine with a null pointer (such as would be returned
  5774         -** by a failed call to [sqlite3_blob_open()]) is a harmless no-op.
         5767  +** Calling this function with an argument that is not a NULL pointer or an
         5768  +** open blob handle results in undefined behaviour. ^Calling this routine 
         5769  +** with a null pointer (such as would be returned by a failed call to 
         5770  +** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
         5771  +** is passed a valid open blob handle, the values returned by the 
         5772  +** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
  5775   5773   */
  5776   5774   int sqlite3_blob_close(sqlite3_blob *);
  5777   5775   
  5778   5776   /*
  5779   5777   ** CAPI3REF: Return The Size Of An Open BLOB
  5780   5778   **
  5781   5779   ** ^Returns the size in bytes of the BLOB accessible via the 

Added test/e_blobclose.test.

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