Modifications so that the sessions extension works with blob handles.
FossilOrigin-Name: 82ac16c4f873d3bd7c22f36ba7b974b4903a2d50
This commit is contained in:
parent
88ab69f614
commit
e437ca5ec0
90
ext/session/session6.test
Normal file
90
ext/session/session6.test
Normal file
@ -0,0 +1,90 @@
|
||||
# 2011 July 11
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite sessions extension.
|
||||
# Specifically, it tests that sessions work when the database is modified
|
||||
# using incremental blob handles.
|
||||
#
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source [file join [file dirname [info script]] session_common.tcl]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
|
||||
set testprefix session6
|
||||
|
||||
proc do_then_apply_tcl {tcl {dbname main}} {
|
||||
proc xConflict args { return "OMIT" }
|
||||
set rc [catch {
|
||||
sqlite3session S db $dbname
|
||||
db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" {
|
||||
S attach $name
|
||||
}
|
||||
eval $tcl
|
||||
sqlite3changeset_apply db2 [S changeset] xConflict
|
||||
} msg]
|
||||
|
||||
catch { S delete }
|
||||
if {$rc} {error $msg}
|
||||
}
|
||||
|
||||
test_sqlite3_log x
|
||||
proc x {args} {puts $args}
|
||||
|
||||
forcedelete test.db2
|
||||
sqlite3 db2 test.db2
|
||||
|
||||
do_common_sql {
|
||||
CREATE TABLE t1(a PRIMARY KEY, b);
|
||||
CREATE TABLE t2(c PRIMARY KEY, d);
|
||||
}
|
||||
|
||||
# Test a blob update.
|
||||
#
|
||||
do_test 1.1 {
|
||||
do_then_apply_tcl {
|
||||
db eval { INSERT INTO t1 VALUES(1, 'helloworld') }
|
||||
db eval { INSERT INTO t2 VALUES(2, 'onetwothree') }
|
||||
}
|
||||
compare_db db db2
|
||||
} {}
|
||||
do_test 1.2 {
|
||||
do_then_apply_tcl {
|
||||
set fd [db incrblob t1 b 1]
|
||||
puts -nonewline $fd 1234567890
|
||||
close $fd
|
||||
}
|
||||
compare_db db db2
|
||||
} {}
|
||||
|
||||
# Test an attached database.
|
||||
#
|
||||
do_test 2.1 {
|
||||
forcedelete test.db3
|
||||
file copy test.db2 test.db3
|
||||
execsql { ATTACH 'test.db3' AS aux; }
|
||||
|
||||
do_then_apply_tcl {
|
||||
set fd [db incrblob aux t2 d 1]
|
||||
puts -nonewline $fd fourfivesix
|
||||
close $fd
|
||||
} aux
|
||||
|
||||
sqlite3 db3 test.db3
|
||||
compare_db db2 db3
|
||||
} {}
|
||||
|
||||
|
||||
db3 close
|
||||
db2 close
|
||||
|
||||
finish_test
|
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
||||
C Pull\sthe\slatest\sversion\s3.7.7\srelease-candidate\schanges\sinto\sthe\nsessions\sbranch.
|
||||
D 2011-06-23T17:40:15.467
|
||||
C Modifications\sso\sthat\sthe\ssessions\sextension\sworks\swith\sblob\shandles.
|
||||
D 2011-07-11T19:45:38.954
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -107,6 +107,7 @@ F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b
|
||||
F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01
|
||||
F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84
|
||||
F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478
|
||||
F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26
|
||||
F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5
|
||||
F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180
|
||||
F ext/session/sqlite3session.c 26de50c3e34d89ae62e97024ad07e772e1c52db2
|
||||
@ -251,9 +252,9 @@ F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e
|
||||
F src/vdbe.c df52db6162fd94767b76bb4e9a7cb9207e83086f
|
||||
F src/vdbe.h 322af148cceef120bb1ec9cff7f122e76abf94da
|
||||
F src/vdbeInt.h 3de6588b36c833969aebab202e1766d586c37ec2
|
||||
F src/vdbeapi.c 1d947da083c24e8bf61823f02f619a1f4a682100
|
||||
F src/vdbeaux.c db3d4eedccea5add714dfb8b10f70d0f8d692db5
|
||||
F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3
|
||||
F src/vdbeapi.c 432a8a194accb9fe9fae45338f210174c6c961b4
|
||||
F src/vdbeaux.c bb86d48ce99c288d17e8d79711713399c21f0a8d
|
||||
F src/vdbeblob.c a547f286b651641bdb43a567af66d0e776a39ea2
|
||||
F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b
|
||||
F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114
|
||||
F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582
|
||||
@ -960,7 +961,7 @@ F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00
|
||||
F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d
|
||||
P 5d95b42946b5cf0346164aebe0a8c4f37527bc31 b61a76a53af04f731fe7617f7b6b4fb2aef6587b
|
||||
R 5b9118bd8782ff0e4b99f3cb89f8be24
|
||||
U drh
|
||||
Z 3edc7355d0a27e1ff60419d5d75c34a3
|
||||
P 840bf9c2d92192ee3cc2aa7c0e9bdb805a066fd4
|
||||
R c823c2479e73fc426d6fab6fb150638b
|
||||
U dan
|
||||
Z 6339a08530525dea9c6675e0fc9a27f5
|
||||
|
@ -1 +1 @@
|
||||
840bf9c2d92192ee3cc2aa7c0e9bdb805a066fd4
|
||||
82ac16c4f873d3bd7c22f36ba7b974b4903a2d50
|
@ -1389,7 +1389,7 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
|
||||
*/
|
||||
int sqlite3_preupdate_count(sqlite3 *db){
|
||||
PreUpdate *p = db->pPreUpdate;
|
||||
return (p ? p->pCsr->nField : 0);
|
||||
return (p ? p->keyinfo.nField : 0);
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
|
||||
|
||||
|
@ -3274,13 +3274,17 @@ void sqlite3VdbePreUpdateHook(
|
||||
iKey2 = iKey1;
|
||||
}
|
||||
|
||||
assert( pCsr->nField==pTab->nCol
|
||||
|| (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
|
||||
);
|
||||
|
||||
preupdate.v = v;
|
||||
preupdate.pCsr = pCsr;
|
||||
preupdate.op = op;
|
||||
preupdate.iNewReg = iReg;
|
||||
preupdate.keyinfo.db = db;
|
||||
preupdate.keyinfo.enc = ENC(db);
|
||||
preupdate.keyinfo.nField = pCsr->nField;
|
||||
preupdate.keyinfo.nField = pTab->nCol;
|
||||
preupdate.iKey1 = iKey1;
|
||||
preupdate.iKey2 = iKey2;
|
||||
preupdate.iPKey = pTab->iPKey;
|
||||
|
@ -30,6 +30,8 @@ struct Incrblob {
|
||||
BtCursor *pCsr; /* Cursor pointing at blob row */
|
||||
sqlite3_stmt *pStmt; /* Statement holding cursor open */
|
||||
sqlite3 *db; /* The associated database */
|
||||
char *zDb; /* Database name */
|
||||
Table *pTab; /* Table object */
|
||||
};
|
||||
|
||||
|
||||
@ -194,6 +196,8 @@ int sqlite3_blob_open(
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
goto blob_open_out;
|
||||
}
|
||||
pBlob->pTab = pTab;
|
||||
pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zName;
|
||||
|
||||
/* Now search pTab for the exact column. */
|
||||
for(iCol=0; iCol<pTab->nCol; iCol++) {
|
||||
@ -386,6 +390,30 @@ static int blobReadWrite(
|
||||
*/
|
||||
assert( db == v->db );
|
||||
sqlite3BtreeEnterCursor(p->pCsr);
|
||||
|
||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
if( xCall==sqlite3BtreePutData ){
|
||||
/* If a pre-update hook is registered and this is a write cursor,
|
||||
** invoke it here.
|
||||
**
|
||||
** TODO: The preupdate-hook is passed SQLITE_DELETE, even though this
|
||||
** operation should really be an SQLITE_UPDATE. This is probably
|
||||
** incorrect, but is convenient because at this point the new.* values
|
||||
** are not easily obtainable. And for the sessions module, an
|
||||
** SQLITE_UPDATE where the PK columns do not change is handled in the
|
||||
** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually
|
||||
** slightly more efficient). Since you cannot write to a PK column
|
||||
** using the incremental-blob API, this works. For the sessions module
|
||||
** anyhow.
|
||||
*/
|
||||
sqlite3_int64 iKey;
|
||||
sqlite3BtreeKeySize(p->pCsr, &iKey);
|
||||
sqlite3VdbePreUpdateHook(
|
||||
v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
|
||||
sqlite3BtreeLeaveCursor(p->pCsr);
|
||||
if( rc==SQLITE_ABORT ){
|
||||
|
Loading…
Reference in New Issue
Block a user