Annotation of embedaddon/sqlite3/src/backup.c, revision 1.1

1.1     ! misho       1: /*
        !             2: ** 2009 January 28
        !             3: **
        !             4: ** The author disclaims copyright to this source code.  In place of
        !             5: ** a legal notice, here is a blessing:
        !             6: **
        !             7: **    May you do good and not evil.
        !             8: **    May you find forgiveness for yourself and forgive others.
        !             9: **    May you share freely, never taking more than you give.
        !            10: **
        !            11: *************************************************************************
        !            12: ** This file contains the implementation of the sqlite3_backup_XXX() 
        !            13: ** API functions and the related features.
        !            14: */
        !            15: #include "sqliteInt.h"
        !            16: #include "btreeInt.h"
        !            17: 
        !            18: /* Macro to find the minimum of two numeric values.
        !            19: */
        !            20: #ifndef MIN
        !            21: # define MIN(x,y) ((x)<(y)?(x):(y))
        !            22: #endif
        !            23: 
        !            24: /*
        !            25: ** Structure allocated for each backup operation.
        !            26: */
        !            27: struct sqlite3_backup {
        !            28:   sqlite3* pDestDb;        /* Destination database handle */
        !            29:   Btree *pDest;            /* Destination b-tree file */
        !            30:   u32 iDestSchema;         /* Original schema cookie in destination */
        !            31:   int bDestLocked;         /* True once a write-transaction is open on pDest */
        !            32: 
        !            33:   Pgno iNext;              /* Page number of the next source page to copy */
        !            34:   sqlite3* pSrcDb;         /* Source database handle */
        !            35:   Btree *pSrc;             /* Source b-tree file */
        !            36: 
        !            37:   int rc;                  /* Backup process error code */
        !            38: 
        !            39:   /* These two variables are set by every call to backup_step(). They are
        !            40:   ** read by calls to backup_remaining() and backup_pagecount().
        !            41:   */
        !            42:   Pgno nRemaining;         /* Number of pages left to copy */
        !            43:   Pgno nPagecount;         /* Total number of pages to copy */
        !            44: 
        !            45:   int isAttached;          /* True once backup has been registered with pager */
        !            46:   sqlite3_backup *pNext;   /* Next backup associated with source pager */
        !            47: };
        !            48: 
        !            49: /*
        !            50: ** THREAD SAFETY NOTES:
        !            51: **
        !            52: **   Once it has been created using backup_init(), a single sqlite3_backup
        !            53: **   structure may be accessed via two groups of thread-safe entry points:
        !            54: **
        !            55: **     * Via the sqlite3_backup_XXX() API function backup_step() and 
        !            56: **       backup_finish(). Both these functions obtain the source database
        !            57: **       handle mutex and the mutex associated with the source BtShared 
        !            58: **       structure, in that order.
        !            59: **
        !            60: **     * Via the BackupUpdate() and BackupRestart() functions, which are
        !            61: **       invoked by the pager layer to report various state changes in
        !            62: **       the page cache associated with the source database. The mutex
        !            63: **       associated with the source database BtShared structure will always 
        !            64: **       be held when either of these functions are invoked.
        !            65: **
        !            66: **   The other sqlite3_backup_XXX() API functions, backup_remaining() and
        !            67: **   backup_pagecount() are not thread-safe functions. If they are called
        !            68: **   while some other thread is calling backup_step() or backup_finish(),
        !            69: **   the values returned may be invalid. There is no way for a call to
        !            70: **   BackupUpdate() or BackupRestart() to interfere with backup_remaining()
        !            71: **   or backup_pagecount().
        !            72: **
        !            73: **   Depending on the SQLite configuration, the database handles and/or
        !            74: **   the Btree objects may have their own mutexes that require locking.
        !            75: **   Non-sharable Btrees (in-memory databases for example), do not have
        !            76: **   associated mutexes.
        !            77: */
        !            78: 
        !            79: /*
        !            80: ** Return a pointer corresponding to database zDb (i.e. "main", "temp")
        !            81: ** in connection handle pDb. If such a database cannot be found, return
        !            82: ** a NULL pointer and write an error message to pErrorDb.
        !            83: **
        !            84: ** If the "temp" database is requested, it may need to be opened by this 
        !            85: ** function. If an error occurs while doing so, return 0 and write an 
        !            86: ** error message to pErrorDb.
        !            87: */
        !            88: static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
        !            89:   int i = sqlite3FindDbName(pDb, zDb);
        !            90: 
        !            91:   if( i==1 ){
        !            92:     Parse *pParse;
        !            93:     int rc = 0;
        !            94:     pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
        !            95:     if( pParse==0 ){
        !            96:       sqlite3Error(pErrorDb, SQLITE_NOMEM, "out of memory");
        !            97:       rc = SQLITE_NOMEM;
        !            98:     }else{
        !            99:       pParse->db = pDb;
        !           100:       if( sqlite3OpenTempDatabase(pParse) ){
        !           101:         sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
        !           102:         rc = SQLITE_ERROR;
        !           103:       }
        !           104:       sqlite3DbFree(pErrorDb, pParse->zErrMsg);
        !           105:       sqlite3StackFree(pErrorDb, pParse);
        !           106:     }
        !           107:     if( rc ){
        !           108:       return 0;
        !           109:     }
        !           110:   }
        !           111: 
        !           112:   if( i<0 ){
        !           113:     sqlite3Error(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
        !           114:     return 0;
        !           115:   }
        !           116: 
        !           117:   return pDb->aDb[i].pBt;
        !           118: }
        !           119: 
        !           120: /*
        !           121: ** Attempt to set the page size of the destination to match the page size
        !           122: ** of the source.
        !           123: */
        !           124: static int setDestPgsz(sqlite3_backup *p){
        !           125:   int rc;
        !           126:   rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0);
        !           127:   return rc;
        !           128: }
        !           129: 
        !           130: /*
        !           131: ** Create an sqlite3_backup process to copy the contents of zSrcDb from
        !           132: ** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
        !           133: ** a pointer to the new sqlite3_backup object.
        !           134: **
        !           135: ** If an error occurs, NULL is returned and an error code and error message
        !           136: ** stored in database handle pDestDb.
        !           137: */
        !           138: sqlite3_backup *sqlite3_backup_init(
        !           139:   sqlite3* pDestDb,                     /* Database to write to */
        !           140:   const char *zDestDb,                  /* Name of database within pDestDb */
        !           141:   sqlite3* pSrcDb,                      /* Database connection to read from */
        !           142:   const char *zSrcDb                    /* Name of database within pSrcDb */
        !           143: ){
        !           144:   sqlite3_backup *p;                    /* Value to return */
        !           145: 
        !           146:   /* Lock the source database handle. The destination database
        !           147:   ** handle is not locked in this routine, but it is locked in
        !           148:   ** sqlite3_backup_step(). The user is required to ensure that no
        !           149:   ** other thread accesses the destination handle for the duration
        !           150:   ** of the backup operation.  Any attempt to use the destination
        !           151:   ** database connection while a backup is in progress may cause
        !           152:   ** a malfunction or a deadlock.
        !           153:   */
        !           154:   sqlite3_mutex_enter(pSrcDb->mutex);
        !           155:   sqlite3_mutex_enter(pDestDb->mutex);
        !           156: 
        !           157:   if( pSrcDb==pDestDb ){
        !           158:     sqlite3Error(
        !           159:         pDestDb, SQLITE_ERROR, "source and destination must be distinct"
        !           160:     );
        !           161:     p = 0;
        !           162:   }else {
        !           163:     /* Allocate space for a new sqlite3_backup object...
        !           164:     ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
        !           165:     ** call to sqlite3_backup_init() and is destroyed by a call to
        !           166:     ** sqlite3_backup_finish(). */
        !           167:     p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
        !           168:     if( !p ){
        !           169:       sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
        !           170:     }
        !           171:   }
        !           172: 
        !           173:   /* If the allocation succeeded, populate the new object. */
        !           174:   if( p ){
        !           175:     memset(p, 0, sizeof(sqlite3_backup));
        !           176:     p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
        !           177:     p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
        !           178:     p->pDestDb = pDestDb;
        !           179:     p->pSrcDb = pSrcDb;
        !           180:     p->iNext = 1;
        !           181:     p->isAttached = 0;
        !           182: 
        !           183:     if( 0==p->pSrc || 0==p->pDest || setDestPgsz(p)==SQLITE_NOMEM ){
        !           184:       /* One (or both) of the named databases did not exist or an OOM
        !           185:       ** error was hit.  The error has already been written into the
        !           186:       ** pDestDb handle.  All that is left to do here is free the
        !           187:       ** sqlite3_backup structure.
        !           188:       */
        !           189:       sqlite3_free(p);
        !           190:       p = 0;
        !           191:     }
        !           192:   }
        !           193:   if( p ){
        !           194:     p->pSrc->nBackup++;
        !           195:   }
        !           196: 
        !           197:   sqlite3_mutex_leave(pDestDb->mutex);
        !           198:   sqlite3_mutex_leave(pSrcDb->mutex);
        !           199:   return p;
        !           200: }
        !           201: 
        !           202: /*
        !           203: ** Argument rc is an SQLite error code. Return true if this error is 
        !           204: ** considered fatal if encountered during a backup operation. All errors
        !           205: ** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED.
        !           206: */
        !           207: static int isFatalError(int rc){
        !           208:   return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && ALWAYS(rc!=SQLITE_LOCKED));
        !           209: }
        !           210: 
        !           211: /*
        !           212: ** Parameter zSrcData points to a buffer containing the data for 
        !           213: ** page iSrcPg from the source database. Copy this data into the 
        !           214: ** destination database.
        !           215: */
        !           216: static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
        !           217:   Pager * const pDestPager = sqlite3BtreePager(p->pDest);
        !           218:   const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
        !           219:   int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
        !           220:   const int nCopy = MIN(nSrcPgsz, nDestPgsz);
        !           221:   const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
        !           222: #ifdef SQLITE_HAS_CODEC
        !           223:   int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc);
        !           224:   int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
        !           225: #endif
        !           226: 
        !           227:   int rc = SQLITE_OK;
        !           228:   i64 iOff;
        !           229: 
        !           230:   assert( p->bDestLocked );
        !           231:   assert( !isFatalError(p->rc) );
        !           232:   assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
        !           233:   assert( zSrcData );
        !           234: 
        !           235:   /* Catch the case where the destination is an in-memory database and the
        !           236:   ** page sizes of the source and destination differ. 
        !           237:   */
        !           238:   if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
        !           239:     rc = SQLITE_READONLY;
        !           240:   }
        !           241: 
        !           242: #ifdef SQLITE_HAS_CODEC
        !           243:   /* Backup is not possible if the page size of the destination is changing
        !           244:   ** and a codec is in use.
        !           245:   */
        !           246:   if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
        !           247:     rc = SQLITE_READONLY;
        !           248:   }
        !           249: 
        !           250:   /* Backup is not possible if the number of bytes of reserve space differ
        !           251:   ** between source and destination.  If there is a difference, try to
        !           252:   ** fix the destination to agree with the source.  If that is not possible,
        !           253:   ** then the backup cannot proceed.
        !           254:   */
        !           255:   if( nSrcReserve!=nDestReserve ){
        !           256:     u32 newPgsz = nSrcPgsz;
        !           257:     rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
        !           258:     if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
        !           259:   }
        !           260: #endif
        !           261: 
        !           262:   /* This loop runs once for each destination page spanned by the source 
        !           263:   ** page. For each iteration, variable iOff is set to the byte offset
        !           264:   ** of the destination page.
        !           265:   */
        !           266:   for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){
        !           267:     DbPage *pDestPg = 0;
        !           268:     Pgno iDest = (Pgno)(iOff/nDestPgsz)+1;
        !           269:     if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue;
        !           270:     if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg))
        !           271:      && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg))
        !           272:     ){
        !           273:       const u8 *zIn = &zSrcData[iOff%nSrcPgsz];
        !           274:       u8 *zDestData = sqlite3PagerGetData(pDestPg);
        !           275:       u8 *zOut = &zDestData[iOff%nDestPgsz];
        !           276: 
        !           277:       /* Copy the data from the source page into the destination page.
        !           278:       ** Then clear the Btree layer MemPage.isInit flag. Both this module
        !           279:       ** and the pager code use this trick (clearing the first byte
        !           280:       ** of the page 'extra' space to invalidate the Btree layers
        !           281:       ** cached parse of the page). MemPage.isInit is marked 
        !           282:       ** "MUST BE FIRST" for this purpose.
        !           283:       */
        !           284:       memcpy(zOut, zIn, nCopy);
        !           285:       ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
        !           286:     }
        !           287:     sqlite3PagerUnref(pDestPg);
        !           288:   }
        !           289: 
        !           290:   return rc;
        !           291: }
        !           292: 
        !           293: /*
        !           294: ** If pFile is currently larger than iSize bytes, then truncate it to
        !           295: ** exactly iSize bytes. If pFile is not larger than iSize bytes, then
        !           296: ** this function is a no-op.
        !           297: **
        !           298: ** Return SQLITE_OK if everything is successful, or an SQLite error 
        !           299: ** code if an error occurs.
        !           300: */
        !           301: static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){
        !           302:   i64 iCurrent;
        !           303:   int rc = sqlite3OsFileSize(pFile, &iCurrent);
        !           304:   if( rc==SQLITE_OK && iCurrent>iSize ){
        !           305:     rc = sqlite3OsTruncate(pFile, iSize);
        !           306:   }
        !           307:   return rc;
        !           308: }
        !           309: 
        !           310: /*
        !           311: ** Register this backup object with the associated source pager for
        !           312: ** callbacks when pages are changed or the cache invalidated.
        !           313: */
        !           314: static void attachBackupObject(sqlite3_backup *p){
        !           315:   sqlite3_backup **pp;
        !           316:   assert( sqlite3BtreeHoldsMutex(p->pSrc) );
        !           317:   pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
        !           318:   p->pNext = *pp;
        !           319:   *pp = p;
        !           320:   p->isAttached = 1;
        !           321: }
        !           322: 
        !           323: /*
        !           324: ** Copy nPage pages from the source b-tree to the destination.
        !           325: */
        !           326: int sqlite3_backup_step(sqlite3_backup *p, int nPage){
        !           327:   int rc;
        !           328:   int destMode;       /* Destination journal mode */
        !           329:   int pgszSrc = 0;    /* Source page size */
        !           330:   int pgszDest = 0;   /* Destination page size */
        !           331: 
        !           332:   sqlite3_mutex_enter(p->pSrcDb->mutex);
        !           333:   sqlite3BtreeEnter(p->pSrc);
        !           334:   if( p->pDestDb ){
        !           335:     sqlite3_mutex_enter(p->pDestDb->mutex);
        !           336:   }
        !           337: 
        !           338:   rc = p->rc;
        !           339:   if( !isFatalError(rc) ){
        !           340:     Pager * const pSrcPager = sqlite3BtreePager(p->pSrc);     /* Source pager */
        !           341:     Pager * const pDestPager = sqlite3BtreePager(p->pDest);   /* Dest pager */
        !           342:     int ii;                            /* Iterator variable */
        !           343:     int nSrcPage = -1;                 /* Size of source db in pages */
        !           344:     int bCloseTrans = 0;               /* True if src db requires unlocking */
        !           345: 
        !           346:     /* If the source pager is currently in a write-transaction, return
        !           347:     ** SQLITE_BUSY immediately.
        !           348:     */
        !           349:     if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){
        !           350:       rc = SQLITE_BUSY;
        !           351:     }else{
        !           352:       rc = SQLITE_OK;
        !           353:     }
        !           354: 
        !           355:     /* Lock the destination database, if it is not locked already. */
        !           356:     if( SQLITE_OK==rc && p->bDestLocked==0
        !           357:      && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) 
        !           358:     ){
        !           359:       p->bDestLocked = 1;
        !           360:       sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
        !           361:     }
        !           362: 
        !           363:     /* If there is no open read-transaction on the source database, open
        !           364:     ** one now. If a transaction is opened here, then it will be closed
        !           365:     ** before this function exits.
        !           366:     */
        !           367:     if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
        !           368:       rc = sqlite3BtreeBeginTrans(p->pSrc, 0);
        !           369:       bCloseTrans = 1;
        !           370:     }
        !           371: 
        !           372:     /* Do not allow backup if the destination database is in WAL mode
        !           373:     ** and the page sizes are different between source and destination */
        !           374:     pgszSrc = sqlite3BtreeGetPageSize(p->pSrc);
        !           375:     pgszDest = sqlite3BtreeGetPageSize(p->pDest);
        !           376:     destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest));
        !           377:     if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){
        !           378:       rc = SQLITE_READONLY;
        !           379:     }
        !           380:   
        !           381:     /* Now that there is a read-lock on the source database, query the
        !           382:     ** source pager for the number of pages in the database.
        !           383:     */
        !           384:     nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc);
        !           385:     assert( nSrcPage>=0 );
        !           386:     for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
        !           387:       const Pgno iSrcPg = p->iNext;                 /* Source page number */
        !           388:       if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
        !           389:         DbPage *pSrcPg;                             /* Source page object */
        !           390:         rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
        !           391:         if( rc==SQLITE_OK ){
        !           392:           rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg));
        !           393:           sqlite3PagerUnref(pSrcPg);
        !           394:         }
        !           395:       }
        !           396:       p->iNext++;
        !           397:     }
        !           398:     if( rc==SQLITE_OK ){
        !           399:       p->nPagecount = nSrcPage;
        !           400:       p->nRemaining = nSrcPage+1-p->iNext;
        !           401:       if( p->iNext>(Pgno)nSrcPage ){
        !           402:         rc = SQLITE_DONE;
        !           403:       }else if( !p->isAttached ){
        !           404:         attachBackupObject(p);
        !           405:       }
        !           406:     }
        !           407:   
        !           408:     /* Update the schema version field in the destination database. This
        !           409:     ** is to make sure that the schema-version really does change in
        !           410:     ** the case where the source and destination databases have the
        !           411:     ** same schema version.
        !           412:     */
        !           413:     if( rc==SQLITE_DONE ){
        !           414:       rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
        !           415:       if( rc==SQLITE_OK ){
        !           416:         if( p->pDestDb ){
        !           417:           sqlite3ResetInternalSchema(p->pDestDb, -1);
        !           418:         }
        !           419:         if( destMode==PAGER_JOURNALMODE_WAL ){
        !           420:           rc = sqlite3BtreeSetVersion(p->pDest, 2);
        !           421:         }
        !           422:       }
        !           423:       if( rc==SQLITE_OK ){
        !           424:         int nDestTruncate;
        !           425:         /* Set nDestTruncate to the final number of pages in the destination
        !           426:         ** database. The complication here is that the destination page
        !           427:         ** size may be different to the source page size. 
        !           428:         **
        !           429:         ** If the source page size is smaller than the destination page size, 
        !           430:         ** round up. In this case the call to sqlite3OsTruncate() below will
        !           431:         ** fix the size of the file. However it is important to call
        !           432:         ** sqlite3PagerTruncateImage() here so that any pages in the 
        !           433:         ** destination file that lie beyond the nDestTruncate page mark are
        !           434:         ** journalled by PagerCommitPhaseOne() before they are destroyed
        !           435:         ** by the file truncation.
        !           436:         */
        !           437:         assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) );
        !           438:         assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) );
        !           439:         if( pgszSrc<pgszDest ){
        !           440:           int ratio = pgszDest/pgszSrc;
        !           441:           nDestTruncate = (nSrcPage+ratio-1)/ratio;
        !           442:           if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
        !           443:             nDestTruncate--;
        !           444:           }
        !           445:         }else{
        !           446:           nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
        !           447:         }
        !           448:         sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
        !           449: 
        !           450:         if( pgszSrc<pgszDest ){
        !           451:           /* If the source page-size is smaller than the destination page-size,
        !           452:           ** two extra things may need to happen:
        !           453:           **
        !           454:           **   * The destination may need to be truncated, and
        !           455:           **
        !           456:           **   * Data stored on the pages immediately following the 
        !           457:           **     pending-byte page in the source database may need to be
        !           458:           **     copied into the destination database.
        !           459:           */
        !           460:           const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
        !           461:           sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
        !           462:           i64 iOff;
        !           463:           i64 iEnd;
        !           464: 
        !           465:           assert( pFile );
        !           466:           assert( (i64)nDestTruncate*(i64)pgszDest >= iSize || (
        !           467:                 nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
        !           468:              && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
        !           469:           ));
        !           470: 
        !           471:           /* This call ensures that all data required to recreate the original
        !           472:           ** database has been stored in the journal for pDestPager and the
        !           473:           ** journal synced to disk. So at this point we may safely modify
        !           474:           ** the database file in any way, knowing that if a power failure
        !           475:           ** occurs, the original database will be reconstructed from the 
        !           476:           ** journal file.  */
        !           477:           rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
        !           478: 
        !           479:           /* Write the extra pages and truncate the database file as required */
        !           480:           iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
        !           481:           for(
        !           482:             iOff=PENDING_BYTE+pgszSrc; 
        !           483:             rc==SQLITE_OK && iOff<iEnd; 
        !           484:             iOff+=pgszSrc
        !           485:           ){
        !           486:             PgHdr *pSrcPg = 0;
        !           487:             const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
        !           488:             rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
        !           489:             if( rc==SQLITE_OK ){
        !           490:               u8 *zData = sqlite3PagerGetData(pSrcPg);
        !           491:               rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
        !           492:             }
        !           493:             sqlite3PagerUnref(pSrcPg);
        !           494:           }
        !           495:           if( rc==SQLITE_OK ){
        !           496:             rc = backupTruncateFile(pFile, iSize);
        !           497:           }
        !           498: 
        !           499:           /* Sync the database file to disk. */
        !           500:           if( rc==SQLITE_OK ){
        !           501:             rc = sqlite3PagerSync(pDestPager);
        !           502:           }
        !           503:         }else{
        !           504:           rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
        !           505:         }
        !           506:     
        !           507:         /* Finish committing the transaction to the destination database. */
        !           508:         if( SQLITE_OK==rc
        !           509:          && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0))
        !           510:         ){
        !           511:           rc = SQLITE_DONE;
        !           512:         }
        !           513:       }
        !           514:     }
        !           515:   
        !           516:     /* If bCloseTrans is true, then this function opened a read transaction
        !           517:     ** on the source database. Close the read transaction here. There is
        !           518:     ** no need to check the return values of the btree methods here, as
        !           519:     ** "committing" a read-only transaction cannot fail.
        !           520:     */
        !           521:     if( bCloseTrans ){
        !           522:       TESTONLY( int rc2 );
        !           523:       TESTONLY( rc2  = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0);
        !           524:       TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0);
        !           525:       assert( rc2==SQLITE_OK );
        !           526:     }
        !           527:   
        !           528:     if( rc==SQLITE_IOERR_NOMEM ){
        !           529:       rc = SQLITE_NOMEM;
        !           530:     }
        !           531:     p->rc = rc;
        !           532:   }
        !           533:   if( p->pDestDb ){
        !           534:     sqlite3_mutex_leave(p->pDestDb->mutex);
        !           535:   }
        !           536:   sqlite3BtreeLeave(p->pSrc);
        !           537:   sqlite3_mutex_leave(p->pSrcDb->mutex);
        !           538:   return rc;
        !           539: }
        !           540: 
        !           541: /*
        !           542: ** Release all resources associated with an sqlite3_backup* handle.
        !           543: */
        !           544: int sqlite3_backup_finish(sqlite3_backup *p){
        !           545:   sqlite3_backup **pp;                 /* Ptr to head of pagers backup list */
        !           546:   MUTEX_LOGIC( sqlite3_mutex *mutex; ) /* Mutex to protect source database */
        !           547:   int rc;                              /* Value to return */
        !           548: 
        !           549:   /* Enter the mutexes */
        !           550:   if( p==0 ) return SQLITE_OK;
        !           551:   sqlite3_mutex_enter(p->pSrcDb->mutex);
        !           552:   sqlite3BtreeEnter(p->pSrc);
        !           553:   MUTEX_LOGIC( mutex = p->pSrcDb->mutex; )
        !           554:   if( p->pDestDb ){
        !           555:     sqlite3_mutex_enter(p->pDestDb->mutex);
        !           556:   }
        !           557: 
        !           558:   /* Detach this backup from the source pager. */
        !           559:   if( p->pDestDb ){
        !           560:     p->pSrc->nBackup--;
        !           561:   }
        !           562:   if( p->isAttached ){
        !           563:     pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
        !           564:     while( *pp!=p ){
        !           565:       pp = &(*pp)->pNext;
        !           566:     }
        !           567:     *pp = p->pNext;
        !           568:   }
        !           569: 
        !           570:   /* If a transaction is still open on the Btree, roll it back. */
        !           571:   sqlite3BtreeRollback(p->pDest);
        !           572: 
        !           573:   /* Set the error code of the destination database handle. */
        !           574:   rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
        !           575:   sqlite3Error(p->pDestDb, rc, 0);
        !           576: 
        !           577:   /* Exit the mutexes and free the backup context structure. */
        !           578:   if( p->pDestDb ){
        !           579:     sqlite3_mutex_leave(p->pDestDb->mutex);
        !           580:   }
        !           581:   sqlite3BtreeLeave(p->pSrc);
        !           582:   if( p->pDestDb ){
        !           583:     /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
        !           584:     ** call to sqlite3_backup_init() and is destroyed by a call to
        !           585:     ** sqlite3_backup_finish(). */
        !           586:     sqlite3_free(p);
        !           587:   }
        !           588:   sqlite3_mutex_leave(mutex);
        !           589:   return rc;
        !           590: }
        !           591: 
        !           592: /*
        !           593: ** Return the number of pages still to be backed up as of the most recent
        !           594: ** call to sqlite3_backup_step().
        !           595: */
        !           596: int sqlite3_backup_remaining(sqlite3_backup *p){
        !           597:   return p->nRemaining;
        !           598: }
        !           599: 
        !           600: /*
        !           601: ** Return the total number of pages in the source database as of the most 
        !           602: ** recent call to sqlite3_backup_step().
        !           603: */
        !           604: int sqlite3_backup_pagecount(sqlite3_backup *p){
        !           605:   return p->nPagecount;
        !           606: }
        !           607: 
        !           608: /*
        !           609: ** This function is called after the contents of page iPage of the
        !           610: ** source database have been modified. If page iPage has already been 
        !           611: ** copied into the destination database, then the data written to the
        !           612: ** destination is now invalidated. The destination copy of iPage needs
        !           613: ** to be updated with the new data before the backup operation is
        !           614: ** complete.
        !           615: **
        !           616: ** It is assumed that the mutex associated with the BtShared object
        !           617: ** corresponding to the source database is held when this function is
        !           618: ** called.
        !           619: */
        !           620: void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
        !           621:   sqlite3_backup *p;                   /* Iterator variable */
        !           622:   for(p=pBackup; p; p=p->pNext){
        !           623:     assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
        !           624:     if( !isFatalError(p->rc) && iPage<p->iNext ){
        !           625:       /* The backup process p has already copied page iPage. But now it
        !           626:       ** has been modified by a transaction on the source pager. Copy
        !           627:       ** the new data into the backup.
        !           628:       */
        !           629:       int rc;
        !           630:       assert( p->pDestDb );
        !           631:       sqlite3_mutex_enter(p->pDestDb->mutex);
        !           632:       rc = backupOnePage(p, iPage, aData);
        !           633:       sqlite3_mutex_leave(p->pDestDb->mutex);
        !           634:       assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
        !           635:       if( rc!=SQLITE_OK ){
        !           636:         p->rc = rc;
        !           637:       }
        !           638:     }
        !           639:   }
        !           640: }
        !           641: 
        !           642: /*
        !           643: ** Restart the backup process. This is called when the pager layer
        !           644: ** detects that the database has been modified by an external database
        !           645: ** connection. In this case there is no way of knowing which of the
        !           646: ** pages that have been copied into the destination database are still 
        !           647: ** valid and which are not, so the entire process needs to be restarted.
        !           648: **
        !           649: ** It is assumed that the mutex associated with the BtShared object
        !           650: ** corresponding to the source database is held when this function is
        !           651: ** called.
        !           652: */
        !           653: void sqlite3BackupRestart(sqlite3_backup *pBackup){
        !           654:   sqlite3_backup *p;                   /* Iterator variable */
        !           655:   for(p=pBackup; p; p=p->pNext){
        !           656:     assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
        !           657:     p->iNext = 1;
        !           658:   }
        !           659: }
        !           660: 
        !           661: #ifndef SQLITE_OMIT_VACUUM
        !           662: /*
        !           663: ** Copy the complete content of pBtFrom into pBtTo.  A transaction
        !           664: ** must be active for both files.
        !           665: **
        !           666: ** The size of file pTo may be reduced by this operation. If anything 
        !           667: ** goes wrong, the transaction on pTo is rolled back. If successful, the 
        !           668: ** transaction is committed before returning.
        !           669: */
        !           670: int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
        !           671:   int rc;
        !           672:   sqlite3_file *pFd;              /* File descriptor for database pTo */
        !           673:   sqlite3_backup b;
        !           674:   sqlite3BtreeEnter(pTo);
        !           675:   sqlite3BtreeEnter(pFrom);
        !           676: 
        !           677:   assert( sqlite3BtreeIsInTrans(pTo) );
        !           678:   pFd = sqlite3PagerFile(sqlite3BtreePager(pTo));
        !           679:   if( pFd->pMethods ){
        !           680:     i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom);
        !           681:     rc = sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte);
        !           682:     if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
        !           683:     if( rc ) goto copy_finished;
        !           684:   }
        !           685: 
        !           686:   /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
        !           687:   ** to 0. This is used by the implementations of sqlite3_backup_step()
        !           688:   ** and sqlite3_backup_finish() to detect that they are being called
        !           689:   ** from this function, not directly by the user.
        !           690:   */
        !           691:   memset(&b, 0, sizeof(b));
        !           692:   b.pSrcDb = pFrom->db;
        !           693:   b.pSrc = pFrom;
        !           694:   b.pDest = pTo;
        !           695:   b.iNext = 1;
        !           696: 
        !           697:   /* 0x7FFFFFFF is the hard limit for the number of pages in a database
        !           698:   ** file. By passing this as the number of pages to copy to
        !           699:   ** sqlite3_backup_step(), we can guarantee that the copy finishes 
        !           700:   ** within a single call (unless an error occurs). The assert() statement
        !           701:   ** checks this assumption - (p->rc) should be set to either SQLITE_DONE 
        !           702:   ** or an error code.
        !           703:   */
        !           704:   sqlite3_backup_step(&b, 0x7FFFFFFF);
        !           705:   assert( b.rc!=SQLITE_OK );
        !           706:   rc = sqlite3_backup_finish(&b);
        !           707:   if( rc==SQLITE_OK ){
        !           708:     pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
        !           709:   }else{
        !           710:     sqlite3PagerClearCache(sqlite3BtreePager(b.pDest));
        !           711:   }
        !           712: 
        !           713:   assert( sqlite3BtreeIsInTrans(pTo)==0 );
        !           714: copy_finished:
        !           715:   sqlite3BtreeLeave(pFrom);
        !           716:   sqlite3BtreeLeave(pTo);
        !           717:   return rc;
        !           718: }
        !           719: #endif /* SQLITE_OMIT_VACUUM */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>