diff options
author | danielk1977 <danielk1977@noemail.net> | 2009-02-06 05:59:44 +0000 |
---|---|---|
committer | danielk1977 <danielk1977@noemail.net> | 2009-02-06 05:59:44 +0000 |
commit | 03ab03579639d7de7cc7c3689f1bad4e6da5d05d (patch) | |
tree | d8e0124868d30fdb012e00d9ed44f13a58c6a2cd /src | |
parent | f4883888cab3754dbce712194f703db09f5345ef (diff) | |
download | sqlite-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.c | 26 | ||||
-rw-r--r-- | src/sqlite.h.in | 5 |
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 |