aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordanielk1977 <danielk1977@noemail.net>2009-02-06 05:59:44 +0000
committerdanielk1977 <danielk1977@noemail.net>2009-02-06 05:59:44 +0000
commit03ab03579639d7de7cc7c3689f1bad4e6da5d05d (patch)
treed8e0124868d30fdb012e00d9ed44f13a58c6a2cd /src
parentf4883888cab3754dbce712194f703db09f5345ef (diff)
downloadsqlite-03ab03579639d7de7cc7c3689f1bad4e6da5d05d.tar.gz
sqlite-03ab03579639d7de7cc7c3689f1bad4e6da5d05d.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/backup.c26
-rw-r--r--src/sqlite.h.in5
2 files changed, 21 insertions, 10 deletions
diff --git a/src/backup.c b/src/backup.c
index 26299b9e0..31d14a0ae 100644
--- a/src/backup.c
+++ b/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"
@@ -188,6 +188,15 @@ sqlite3_backup *sqlite3_backup_init(
}
/*
+** 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
** destination database.
@@ -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,9 +421,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
assert( rc2==SQLITE_OK );
}
- if( rc!=SQLITE_LOCKED && rc!=SQLITE_BUSY ){
- p->rc = rc;
- }
+ 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;
}
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 69b4c037f..e7fdfe3f6 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -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