mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Changes to the backup API: (1) if a negative number is passed as the second argument to backup_step(), this is interpreted as "copy all remaining pages" and (2) if backup_finish() is called after backup_step() fails with a BUSY or LOCKED error, then this error is also returned by backup_finish() (same handling as for other errors encountered by backup_step()). (CVS 6266)
FossilOrigin-Name: 9b8c8b18cf6b7d44d5fd64760537bc030097756b
This commit is contained in:
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sa\stest\scase\sthat\swas\sstill\susing\sthe\sold\spending_byte\smechanism.\s(CVS\s6265)
|
||||
D 2009-02-05T17:00:54
|
||||
C Changes\sto\sthe\sbackup\sAPI:\s(1)\sif\sa\snegative\snumber\sis\spassed\sas\sthe\ssecond\sargument\sto\sbackup_step(),\sthis\sis\sinterpreted\sas\s"copy\sall\sremaining\spages"\sand\s(2)\sif\sbackup_finish()\sis\scalled\safter\sbackup_step()\sfails\swith\sa\sBUSY\sor\sLOCKED\serror,\sthen\sthis\serror\sis\salso\sreturned\sby\sbackup_finish()\s(same\shandling\sas\sfor\sother\serrors\sencountered\sby\sbackup_step()).\s(CVS\s6266)
|
||||
D 2009-02-06T05:59:44
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in c7a5a30fb6852bd7839b1024e1661da8549878ee
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -101,7 +101,7 @@ F src/alter.c 0ec29744c36c6e976596ce38c16289ebc5dc94db
|
||||
F src/analyze.c c86fd6a1425b22b3a46ce72ad403e4280026364f
|
||||
F src/attach.c 81d37d1948f409146a7b22b96998fd90649d1fd3
|
||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||
F src/backup.c 12cd9a55b9188c21ae2dd466436e1f2b78b71fa2
|
||||
F src/backup.c 9563f47385f491579135fd7924d70c76c2eba740
|
||||
F src/bitvec.c 44f7059ac1f874d364b34af31b9617e52223ba75
|
||||
F src/btmutex.c 63c5cc4ad5715690767ffcb741e185d7bc35ec1a
|
||||
F src/btree.c 71f30e74389aa7ae51421592dfaf69511152677c
|
||||
@ -157,7 +157,7 @@ F src/resolve.c 18dc9f0df1d60048e012ce6632251063e0dd356a
|
||||
F src/rowset.c ba9375f37053d422dd76965a9c370a13b6e1aac4
|
||||
F src/select.c ae72b604e47092521c4d9ae54e1b1cbeb872a747
|
||||
F src/shell.c f109ebbb50132926ebbc173a6c2d8838d5d78527
|
||||
F src/sqlite.h.in bc6654bb2c8e07281c66e860a018b1f4cb6e5dfa
|
||||
F src/sqlite.h.in f44c38b1e16d60de73ad3f49bffab05c00e8370c
|
||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||
F src/sqliteInt.h 55cc7e45a7fcc166be62b984168dd69159d877eb
|
||||
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
||||
@ -233,7 +233,7 @@ F test/autoinc.test ab549b48b389cabd92967b86c379ec8b31fa6c16
|
||||
F test/autovacuum.test 61260e25744189ff766f61ca3df23c1eeec0060e
|
||||
F test/autovacuum_ioerr2.test 598b0663074d3673a9c1bc9a16e80971313bafe6
|
||||
F test/avtrans.test 1e901d8102706b63534dbd2bdd4d8f16c4082650
|
||||
F test/backup.test f3592c6759de90fa7a7dcd4bce380aed97115c88
|
||||
F test/backup.test 12d7ad0545f47175e27445267d0810a277679ef2
|
||||
F test/backup2.test 392318e059b83e87e5e4175f08be181a6ddce468
|
||||
F test/backup_ioerr.test a9b8084e488154341719833783ac9db321e14284
|
||||
F test/backup_malloc.test 1e063c6d75143d0d6e0ae77971dd690070369387
|
||||
@ -701,7 +701,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
P 193c871f3d16ce982040334c543610d330117bd5
|
||||
R d5652a2a1df1206bcb9247c6e46b26d9
|
||||
U drh
|
||||
Z 566a5233b34049b2c94643d8e525a629
|
||||
P 08ec4f2c394ec834c20bfce0d98bbe6b4ce2be65
|
||||
R d04d3b804c3f1e9769c67b029dd2532c
|
||||
U danielk1977
|
||||
Z 0d132187e7d66d9f6523f0e0833bc7a9
|
||||
|
@ -1 +1 @@
|
||||
08ec4f2c394ec834c20bfce0d98bbe6b4ce2be65
|
||||
9b8c8b18cf6b7d44d5fd64760537bc030097756b
|
24
src/backup.c
24
src/backup.c
@ -12,7 +12,7 @@
|
||||
** This file contains the implementation of the sqlite3_backup_XXX()
|
||||
** API functions and the related features.
|
||||
**
|
||||
** $Id: backup.c,v 1.7 2009/02/04 17:40:58 drh Exp $
|
||||
** $Id: backup.c,v 1.8 2009/02/06 05:59:44 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "btreeInt.h"
|
||||
@ -187,6 +187,15 @@ sqlite3_backup *sqlite3_backup_init(
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Argument rc is an SQLite error code. Return true if this error is
|
||||
** considered fatal if encountered during a backup operation. All errors
|
||||
** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED.
|
||||
*/
|
||||
static int isFatalError(int rc){
|
||||
return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED);
|
||||
}
|
||||
|
||||
/*
|
||||
** Parameter zSrcData points to a buffer containing the data for
|
||||
** page iSrcPg from the source database. Copy this data into the
|
||||
@ -203,7 +212,7 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
|
||||
i64 iOff;
|
||||
|
||||
assert( p->bDestLocked );
|
||||
assert( p->rc==SQLITE_OK );
|
||||
assert( !isFatalError(p->rc) );
|
||||
assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
|
||||
assert( zSrcData );
|
||||
|
||||
@ -258,7 +267,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
}
|
||||
|
||||
rc = p->rc;
|
||||
if( rc==SQLITE_OK ){
|
||||
if( !isFatalError(rc) ){
|
||||
Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */
|
||||
Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */
|
||||
int ii; /* Iterator variable */
|
||||
@ -270,6 +279,8 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
*/
|
||||
if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){
|
||||
rc = SQLITE_LOCKED;
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Lock the destination database, if it is not locked already. */
|
||||
@ -295,7 +306,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerPagecount(pSrcPager, &nSrcPage);
|
||||
}
|
||||
for(ii=0; ii<nPage && p->iNext<=(Pgno)nSrcPage && rc==SQLITE_OK; ii++){
|
||||
for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
|
||||
const Pgno iSrcPg = p->iNext; /* Source page number */
|
||||
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
|
||||
DbPage *pSrcPg; /* Source page object */
|
||||
@ -410,10 +421,8 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
assert( rc2==SQLITE_OK );
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_LOCKED && rc!=SQLITE_BUSY ){
|
||||
p->rc = rc;
|
||||
}
|
||||
}
|
||||
if( p->pDestDb ){
|
||||
sqlite3_mutex_leave(p->pDestDb->mutex);
|
||||
}
|
||||
@ -499,12 +508,13 @@ void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
|
||||
sqlite3_backup *p; /* Iterator variable */
|
||||
for(p=pBackup; p; p=p->pNext){
|
||||
assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
|
||||
if( p->rc==SQLITE_OK && iPage<p->iNext ){
|
||||
if( !isFatalError(p->rc) && iPage<p->iNext ){
|
||||
/* The backup process p has already copied page iPage. But now it
|
||||
** has been modified by a transaction on the source pager. Copy
|
||||
** the new data into the backup.
|
||||
*/
|
||||
int rc = backupOnePage(p, iPage, aData);
|
||||
assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
|
||||
if( rc!=SQLITE_OK ){
|
||||
p->rc = rc;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
** the version number) and changes its name to "sqlite3.h" as
|
||||
** part of the build process.
|
||||
**
|
||||
** @(#) $Id: sqlite.h.in,v 1.427 2009/02/05 16:31:46 drh Exp $
|
||||
** @(#) $Id: sqlite.h.in,v 1.428 2009/02/06 05:59:44 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITE3_H_
|
||||
#define _SQLITE3_H_
|
||||
@ -6787,7 +6787,8 @@ typedef struct sqlite3_backup sqlite3_backup;
|
||||
**
|
||||
** Function [sqlite3_backup_step()] is used to copy up to nPage pages between
|
||||
** the source and destination databases, where nPage is the value of the
|
||||
** second parameter passed to sqlite3_backup_step(). If nPage pages are
|
||||
** second parameter passed to sqlite3_backup_step(). If nPage is a negative
|
||||
** value, all remaining source pages are copied. If the required pages are
|
||||
** succesfully copied, but there are still more pages to copy before the
|
||||
** backup is complete, it returns [SQLITE_OK]. If no error occured and there
|
||||
** are no more pages to copy, then [SQLITE_DONE] is returned. If an error
|
||||
|
@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the sqlite3_backup_XXX API.
|
||||
#
|
||||
# $Id: backup.test,v 1.3 2009/02/04 22:46:47 drh Exp $
|
||||
# $Id: backup.test,v 1.4 2009/02/06 05:59:45 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -36,6 +36,9 @@ source $testdir/tester.tcl
|
||||
#
|
||||
# backup-8.*: Test multiple simultaneous backup operations.
|
||||
#
|
||||
# backup-9.*: Test that passing a negative argument to backup_step() is
|
||||
# interpreted as "copy the whole file".
|
||||
#
|
||||
|
||||
proc data_checksum {db file} { $db one "SELECT md5sum(a, b) FROM ${file}.t1" }
|
||||
proc test_contents {name db1 file1 db2 file2} {
|
||||
@ -763,5 +766,42 @@ do_test backup-8.10 {
|
||||
catch { db2 close }
|
||||
catch { db3 close }
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# The following tests, backup-9.*, test that:
|
||||
#
|
||||
# * Passing 0 as an argument to sqlite3_backup_step() means no pages
|
||||
# are backed up (backup-9.1.*), and
|
||||
# * Passing a negative value as an argument to sqlite3_backup_step() means
|
||||
# all pages are backed up (backup-9.2.*).
|
||||
#
|
||||
# These tests reuse the database "test.db" left over from backup-7.*.
|
||||
#
|
||||
do_test backup-9.1.1 {
|
||||
sqlite3 db2 test2.db
|
||||
sqlite3_backup B db2 main db main
|
||||
B step 1
|
||||
} {SQLITE_OK}
|
||||
do_test backup-9.1.2 {
|
||||
set nRemaining [B remaining]
|
||||
expr {$nRemaining>100}
|
||||
} {1}
|
||||
do_test backup-9.1.3 {
|
||||
B step 0
|
||||
} {SQLITE_OK}
|
||||
do_test backup-9.1.4 {
|
||||
B remaining
|
||||
} $nRemaining
|
||||
|
||||
do_test backup-9.2.1 {
|
||||
B step -1
|
||||
} {SQLITE_DONE}
|
||||
do_test backup-9.2.2 {
|
||||
B remaining
|
||||
} {0}
|
||||
do_test backup-9.2.3 {
|
||||
B finish
|
||||
} {SQLITE_OK}
|
||||
catch {db2 close}
|
||||
|
||||
finish_test
|
||||
|
||||
|
Reference in New Issue
Block a user