Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Structural coverage tests for vdbeblob.c. Including experimental new API sqlite3_blob_reopen(). |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | experimental |
Files: | files | file ages | folders |
SHA1: |
97c6b2616ddcce2337778c6ee88a973c |
User & Date: | dan 2010-10-26 18:42:52.000 |
Context
2010-10-27
| ||
10:55 | In fts4, store the total number of bytes of for all records in the table in the %_stat table. (check-in: 941647d121 user: dan tags: experimental) | |
2010-10-26
| ||
18:42 | Structural coverage tests for vdbeblob.c. Including experimental new API sqlite3_blob_reopen(). (check-in: 97c6b2616d user: dan tags: experimental) | |
11:56 | Add missing header comments for changes related to the experimental sqlite3_blob_reopen() API. (check-in: d1cc5c93f0 user: dan tags: experimental) | |
Changes
Changes to src/test1.c.
︙ | ︙ | |||
1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 | Tcl_SetObjResult(interp, pRet); return TCL_OK; } #endif #ifndef SQLITE_OMIT_INCRBLOB /* ** sqlite3_blob_read CHANNEL OFFSET N ** ** This command is used to test the sqlite3_blob_read() in ways that ** the Tcl channel interface does not. The first argument should ** be the name of a valid channel created by the [incrblob] method | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 | Tcl_SetObjResult(interp, pRet); return TCL_OK; } #endif #ifndef SQLITE_OMIT_INCRBLOB static int blobHandleFromObj( Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3_blob **ppBlob ){ char *z; int n; z = Tcl_GetStringFromObj(pObj, &n); if( n==0 ){ *ppBlob = 0; }else{ int notUsed; Tcl_Channel channel; ClientData instanceData; channel = Tcl_GetChannel(interp, z, ¬Used); if( !channel ) return TCL_ERROR; Tcl_Flush(channel); Tcl_Seek(channel, 0, SEEK_SET); instanceData = Tcl_GetChannelInstanceData(channel); *ppBlob = *((sqlite3_blob **)instanceData); } return TCL_OK; } /* ** sqlite3_blob_bytes CHANNEL */ static int test_blob_bytes( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ sqlite3_blob *pBlob; int nByte; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL"); return TCL_ERROR; } if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; nByte = sqlite3_blob_bytes(pBlob); Tcl_SetObjResult(interp, Tcl_NewIntObj(nByte)); return TCL_OK; } /* ** sqlite3_blob_close CHANNEL */ static int test_blob_close( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ sqlite3_blob *pBlob; int nByte; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL"); return TCL_ERROR; } if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; sqlite3_blob_close(pBlob); return TCL_OK; } /* ** sqlite3_blob_read CHANNEL OFFSET N ** ** This command is used to test the sqlite3_blob_read() in ways that ** the Tcl channel interface does not. The first argument should ** be the name of a valid channel created by the [incrblob] method |
︙ | ︙ | |||
1607 1608 1609 1610 1611 1612 1613 | */ static int test_blob_read( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ | < < < < | | < < < < | 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 | */ static int test_blob_read( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ sqlite3_blob *pBlob; int nByte; int iOffset; unsigned char *zBuf; int rc; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET N"); return TCL_ERROR; } if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) || TCL_OK!=Tcl_GetIntFromObj(interp, objv[3], &nByte) ){ return TCL_ERROR; } zBuf = (unsigned char *)Tcl_Alloc(nByte); rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset); if( rc==SQLITE_OK ){ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zBuf, nByte)); }else{ Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); } |
︙ | ︙ | |||
1665 1666 1667 1668 1669 1670 1671 | */ static int test_blob_write( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ | < < < | | < < < < < < | | < < < < < < < < < < < < | 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 | */ static int test_blob_write( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ sqlite3_blob *pBlob; int iOffset; int rc; unsigned char *zBuf; int nBuf; if( objc!=4 && objc!=5 ){ Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA ?NDATA?"); return TCL_ERROR; } if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){ return TCL_ERROR; } zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf); if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){ return TCL_ERROR; } rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); } return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); } static int test_blob_reopen( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ Tcl_WideInt iRowid; sqlite3_blob *pBlob; int rc; unsigned char *zBuf; int nBuf; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL ROWID"); return TCL_ERROR; } if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; if( Tcl_GetWideIntFromObj(interp, objv[2], &iRowid) ) return TCL_ERROR; rc = sqlite3_blob_reopen(pBlob, iRowid); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); } return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); |
︙ | ︙ | |||
5367 5368 5369 5370 5371 5372 5373 | { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0}, #endif { "sqlite3_libversion_number", test_libversion_number, 0 }, #ifdef SQLITE_ENABLE_COLUMN_METADATA { "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, #endif #ifndef SQLITE_OMIT_INCRBLOB | | | > > | 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 | { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0}, #endif { "sqlite3_libversion_number", test_libversion_number, 0 }, #ifdef SQLITE_ENABLE_COLUMN_METADATA { "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, #endif #ifndef SQLITE_OMIT_INCRBLOB { "sqlite3_blob_read", test_blob_read, 0 }, { "sqlite3_blob_write", test_blob_write, 0 }, { "sqlite3_blob_reopen", test_blob_reopen, 0 }, { "sqlite3_blob_bytes", test_blob_bytes, 0 }, { "sqlite3_blob_close", test_blob_close, 0 }, #endif { "pcache_stats", test_pcache_stats, 0 }, #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY { "sqlite3_unlock_notify", test_unlock_notify, 0 }, #endif { "sqlite3_wal_checkpoint", test_wal_checkpoint, 0 }, { "test_sqlite3_log", test_sqlite3_log, 0 }, |
︙ | ︙ |
Changes to src/vdbeblob.c.
︙ | ︙ | |||
146 147 148 149 150 151 152 | {OP_Column, 0, 0, 1}, /* 7 */ {OP_ResultRow, 1, 0, 0}, /* 8 */ {OP_Goto, 0, 5, 0}, /* 9 */ {OP_Close, 0, 0, 0}, /* 10 */ {OP_Halt, 0, 0, 0}, /* 11 */ }; | < | | > < < | < > > | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | {OP_Column, 0, 0, 1}, /* 7 */ {OP_ResultRow, 1, 0, 0}, /* 8 */ {OP_Goto, 0, 5, 0}, /* 9 */ {OP_Close, 0, 0, 0}, /* 10 */ {OP_Halt, 0, 0, 0}, /* 11 */ }; int rc = SQLITE_OK; char *zErr = 0; Table *pTab; Parse *pParse = 0; Incrblob *pBlob = 0; flags = !!flags; /* flags = (flags ? 1 : 0); */ *ppBlob = 0; sqlite3_mutex_enter(db->mutex); pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); if( !pBlob ) goto blob_open_out; pParse = sqlite3StackAllocRaw(db, sizeof(*pParse)); if( !pParse ) goto blob_open_out; do { memset(pParse, 0, sizeof(Parse)); pParse->db = db; sqlite3DbFree(db, zErr); zErr = 0; sqlite3BtreeEnterAll(db); pTab = sqlite3LocateTable(pParse, 0, zTable, zDb); if( pTab && IsVirtual(pTab) ){ pTab = 0; sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable); } |
︙ | ︙ | |||
193 194 195 196 197 198 199 | } rc = SQLITE_ERROR; sqlite3BtreeLeaveAll(db); goto blob_open_out; } /* Now search pTab for the exact column. */ | | | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | } rc = SQLITE_ERROR; sqlite3BtreeLeaveAll(db); goto blob_open_out; } /* Now search pTab for the exact column. */ for(iCol=0; iCol<pTab->nCol; iCol++) { if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ break; } } if( iCol==pTab->nCol ){ sqlite3DbFree(db, zErr); zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn); |
︙ | ︙ | |||
247 248 249 250 251 252 253 | zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault); rc = SQLITE_ERROR; sqlite3BtreeLeaveAll(db); goto blob_open_out; } } | | > | > > > | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault); rc = SQLITE_ERROR; sqlite3BtreeLeaveAll(db); goto blob_open_out; } } pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(db); assert( pBlob->pStmt || db->mallocFailed ); if( pBlob->pStmt ){ Vdbe *v = (Vdbe *)pBlob->pStmt; int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob); /* Configure the OP_Transaction */ sqlite3VdbeChangeP1(v, 0, iDb); sqlite3VdbeChangeP2(v, 0, flags); /* Configure the OP_VerifyCookie */ sqlite3VdbeChangeP1(v, 1, iDb); |
︙ | ︙ | |||
294 295 296 297 298 299 300 | sqlite3VdbeChangeP2(v, 7, pTab->nCol); if( !db->mallocFailed ){ sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0); } } pBlob->flags = flags; | < < < | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | sqlite3VdbeChangeP2(v, 7, pTab->nCol); if( !db->mallocFailed ){ sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0); } } pBlob->flags = flags; pBlob->iCol = iCol; pBlob->db = db; sqlite3BtreeLeaveAll(db); if( db->mallocFailed ){ goto blob_open_out; } sqlite3_bind_int64(pBlob->pStmt, 1, iRow); rc = blobSeekToRow(pBlob, iRow, &zErr); } while( (++nAttempt)<5 && rc==SQLITE_SCHEMA ); blob_open_out: if( rc==SQLITE_OK && db->mallocFailed==0 ){ *ppBlob = (sqlite3_blob *)pBlob; }else{ if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); sqlite3DbFree(db, pBlob); } sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr); sqlite3DbFree(db, zErr); sqlite3StackFree(db, pParse); rc = sqlite3ApiExit(db, rc); |
︙ | ︙ |
Added test/incrblob3.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | # 2010 October 20 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # set testdir [file dirname $argv0] source $testdir/tester.tcl sqlite3 db test.db sqlite3_db_config_lookaside db 0 0 0 do_execsql_test incrblob3-1.1 { CREATE TABLE blobs(k INTEGER PRIMARY KEY, v BLOB); INSERT INTO blobs VALUES(1, zeroblob(100)); INSERT INTO blobs VALUES(2, zeroblob(100)); } {} # Test the sqlite3_blob_reopen()/read()/write() functions. # do_test incrblob3-1.2 { set ::blob [db incrblob blobs v 1] puts $::blob "hello world" } {} do_test incrblob3-1.3 { sqlite3_blob_reopen $::blob 2 puts $::blob "world hello" } {} do_test incrblob3-1.4 { sqlite3_blob_reopen $::blob 1 gets $::blob } {hello world} do_test incrblob3-1.5 { sqlite3_blob_reopen $::blob 2 gets $::blob } {world hello} do_test incrblob3-1.6 { close $::blob } {} # Test some error conditions. # # incrblob3-2.1: Attempting to reopen a row that does not exist. # incrblob3-2.2: Attempting to reopen a row that does not contain a blob # or text value. # do_test incrblob3-2.1.1 { set ::blob [db incrblob blobs v 1] list [catch {sqlite3_blob_reopen $::blob 3} msg] $msg } {1 SQLITE_ERROR} do_test incrblob3-2.1.2 { list [sqlite3_errcode db] [sqlite3_errmsg db] } {SQLITE_ERROR {no such rowid: 3}} do_test incrblob3-2.1.3 { list [catch {sqlite3_blob_reopen $::blob 1} msg] $msg } {1 SQLITE_ABORT} do_test incrblob3-2.1.4 { close $::blob } {} do_execsql_test incrblob3-2.2.1 { INSERT INTO blobs VALUES(3, 42); INSERT INTO blobs VALUES(4, 54.4); INSERT INTO blobs VALUES(5, NULL); } foreach {tn rowid type} { 1 3 integer 2 4 real 3 5 null } { do_test incrblob3-2.2.$tn.1 { set ::blob [db incrblob blobs v 1] list [catch {sqlite3_blob_reopen $::blob $rowid} msg] $msg } {1 SQLITE_ERROR} do_test incrblob3-2.2.$tn.2 { list [sqlite3_errcode db] [sqlite3_errmsg db] } "SQLITE_ERROR {cannot open value of type $type}" do_test incrblob3-2.2.$tn.3 { list [catch {sqlite3_blob_reopen $::blob 1} msg] $msg } {1 SQLITE_ABORT} do_test incrblob3-2.2.$tn.4 { list [catch {sqlite3_blob_read $::blob 0 10} msg] $msg } {1 SQLITE_ABORT} do_test incrblob3-2.2.$tn.5 { list [catch {sqlite3_blob_write $::blob 0 "abcd"} msg] $msg } {1 SQLITE_ABORT} do_test incrblob3-2.2.$tn.4 { close $::blob } {} } # Test that passing NULL to sqlite3_blob_XXX() APIs returns SQLITE_MISUSE. # # incrblob3-3.1: sqlite3_blob_reopen() # incrblob3-3.2: sqlite3_blob_read() # incrblob3-3.3: sqlite3_blob_write() # incrblob3-3.4: sqlite3_blob_bytes() # do_test incrblob3-3.1 { list [catch {sqlite3_blob_reopen {} 3} msg] $msg } {1 SQLITE_MISUSE} do_test incrblob3-3.2 { list [catch {sqlite3_blob_read {} 0 10} msg] $msg } {1 SQLITE_MISUSE} do_test incrblob3-3.3 { list [catch {sqlite3_blob_write {} 0 "abcd"} msg] $msg } {1 SQLITE_MISUSE} do_test incrblob3-3.4 { sqlite3_blob_bytes {} } {0} do_test incrblob3-3.5 { sqlite3_blob_close {} } {} # Test out-of-range reading and writing # do_test incrblob3-4.1 { set ::blob [db incrblob blobs v 1] sqlite3_blob_bytes $::blob } {100} do_test incrblob3-4.2 { list [catch { sqlite3_blob_read $::blob -1 10 } msg] $msg } {1 SQLITE_ERROR} do_test incrblob3-4.3 { list [catch { sqlite3_blob_read $::blob 0 -10 } msg] $msg } {1 SQLITE_ERROR} do_test incrblob3-4.4 { list [catch { sqlite3_blob_read $::blob 95 10 } msg] $msg } {1 SQLITE_ERROR} do_test incrblob3-4.5 { list [catch { sqlite3_blob_write $::blob -1 "abcdefghij" 10 } msg] $msg } {1 SQLITE_ERROR} do_test incrblob3-4.6 { list [catch { sqlite3_blob_write $::blob 0 "abcdefghij" -10 } msg] $msg } {1 SQLITE_ERROR} do_test incrblob3-4.7 { list [catch { sqlite3_blob_write $::blob 95 "abcdefghij" } msg] $msg } {1 SQLITE_ERROR} do_test incrblob3-4.8 { close $::blob } {} # Test that modifying the row a blob handle points to aborts the blob. # do_test incrblob3-5.1 { set ::blob [db incrblob blobs v 1] sqlite3_blob_bytes $::blob } {100} do_test incrblob3-5.2 { execsql { UPDATE blobs SET v = '123456789012345678901234567890' WHERE k = 1 } list [catch { sqlite3_blob_read $::blob 0 10 } msg] $msg } {1 SQLITE_ABORT} # Test various errors that can occur in sqlite3_blob_open(): # # 1. Trying to open a virtual table column. # 2. Trying to open a view column. # 3. Trying to open a column that does not exist. # 4. Trying to open a read/write handle on an indexed column. # 5. Trying to open a read/write handle on the child key of an FK constraint. # ifcapable fts3 { do_test incrblob3-6.1 { execsql { CREATE VIRTUAL TABLE ft USING fts3; INSERT INTO ft VALUES('rules to open a column to which'); } list [catch { db incrblob ft content 1 } msg] $msg } {1 {cannot open virtual table: ft}} } ifcapable view { do_test incrblob3-6.2 { execsql { CREATE VIEW v1 AS SELECT * FROM blobs } list [catch { db incrblob v1 content 1 } msg] $msg } {1 {cannot open view: v1}} } do_test incrblob3-6.3 { list [catch { db incrblob blobs content 1 } msg] $msg } {1 {no such column: "content"}} do_test incrblob3-6.4.1 { execsql { CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(b); INSERT INTO t1 VALUES(zeroblob(100), zeroblob(100)); } list [catch { db incrblob t1 b 1 } msg] $msg } {1 {cannot open indexed column for writing}} do_test incrblob3-6.4.2 { set ::blob [db incrblob t1 a 1] close $::blob } {} do_test incrblob3-6.4.3 { set ::blob [db incrblob -readonly t1 b 1] close $::blob } {} do_test incrblob3-6.5.1 { execsql { CREATE TABLE p1(a PRIMARY KEY); CREATE TABLE c1(a, b REFERENCES p1); PRAGMA foreign_keys = 1; INSERT INTO p1 VALUES(zeroblob(100)); INSERT INTO c1 VALUES(zeroblob(100), zeroblob(100)); } list [catch { db incrblob c1 b 1 } msg] $msg } {1 {cannot open foreign key column for writing}} do_test incrblob3-6.5.2 { set ::blob [db incrblob c1 a 1] close $::blob } {} do_test incrblob3-6.5.3 { set ::blob [db incrblob -readonly c1 b 1] close $::blob } {} do_test incrblob3-6.5.4 { execsql { PRAGMA foreign_keys = 0 } set ::blob [db incrblob c1 b 1] close $::blob } {} # Test that sqlite3_blob_open() handles transient and persistent schema # errors correctly. # do_test incrblob3-7.1 { sqlite3 db2 test.db sqlite3_db_config_lookaside db2 0 0 0 execsql { CREATE TABLE t2(x) } db2 set ::blob [db incrblob blobs v 1] close $::blob } {} db2 close testvfs tvfs -default 1 tvfs filter xAccess tvfs script access_method proc access_method {args} { set schemacookie [hexio_get_int [hexio_read test.db 40 4]] incr schemacookie hexio_write test.db 40 [hexio_render_int32 $schemacookie] set dbversion [hexio_get_int [hexio_read test.db 24 4]] incr dbversion hexio_write test.db 24 [hexio_render_int32 $dbversion] return "" } do_test incrblob3-7.2 { sqlite3 db test.db sqlite3_db_config_lookaside db 0 0 0 list [catch {db incrblob blobs v 1} msg] $msg } {1 {database schema has changed}} db close tvfs delete finish_test |
Added test/incrblobfault.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | # 2010 October 26 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix incrblobfault do_execsql_test 1.0 { CREATE TABLE blob(x INTEGER PRIMARY KEY, v BLOB); INSERT INTO blob VALUES(1, 'hello world'); INSERT INTO blob VALUES(2, 'world hello'); INSERT INTO blob SELECT NULL, v FROM blob; INSERT INTO blob SELECT NULL, v FROM blob; INSERT INTO blob SELECT NULL, v FROM blob; INSERT INTO blob SELECT NULL, v FROM blob; INSERT INTO blob SELECT NULL, v FROM blob; INSERT INTO blob SELECT NULL, v FROM blob; INSERT INTO blob SELECT NULL, v FROM blob; INSERT INTO blob SELECT NULL, v FROM blob; INSERT INTO blob SELECT NULL, v FROM blob; INSERT INTO blob SELECT NULL, v FROM blob; } do_faultsim_test 1 -prep { sqlite3 db test.db set ::blob [db incrblob blob v 1] } -body { if {[catch {sqlite3_blob_reopen $::blob 1000}]} { error [sqlite3_errmsg db] } } -test { faultsim_test_result {0 {}} close $::blob } do_faultsim_test 2 -prep { sqlite3 db test.db set ::blob [db incrblob blob v 1] } -body { if {[catch {sqlite3_blob_reopen $::blob -1}]} { error [sqlite3_errmsg db] } } -test { faultsim_test_result {1 {no such rowid: -1}} close $::blob } do_faultsim_test 3 -prep { sqlite3 db test.db } -body { set ::blob [db incrblob blob v 1] gets $::blob } -test { faultsim_test_result {0 {hello world}} catch { close $::blob } } finish_test |