blob: 09e61b6c7affe7d3a7197b714686f8a78175b606 [file] [log] [blame]
danielk197704103022009-02-03 16:51:24 +00001/*
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**
danielk1977e70f4f62009-05-13 07:52:06 +000015** $Id: backup.c,v 1.14 2009/05/13 07:52:06 danielk1977 Exp $
danielk197704103022009-02-03 16:51:24 +000016*/
17#include "sqliteInt.h"
18#include "btreeInt.h"
19
20/* Macro to find the minimum of two numeric values.
21*/
22#ifndef MIN
23# define MIN(x,y) ((x)<(y)?(x):(y))
24#endif
25
26/*
27** Structure allocated for each backup operation.
28*/
29struct sqlite3_backup {
30 sqlite3* pDestDb; /* Destination database handle */
31 Btree *pDest; /* Destination b-tree file */
32 u32 iDestSchema; /* Original schema cookie in destination */
33 int bDestLocked; /* True once a write-transaction is open on pDest */
34
35 Pgno iNext; /* Page number of the next source page to copy */
36 sqlite3* pSrcDb; /* Source database handle */
37 Btree *pSrc; /* Source b-tree file */
38
39 int rc; /* Backup process error code */
40
41 /* These two variables are set by every call to backup_step(). They are
42 ** read by calls to backup_remaining() and backup_pagecount().
43 */
44 Pgno nRemaining; /* Number of pages left to copy */
45 Pgno nPagecount; /* Total number of pages to copy */
46
danielk1977e70f4f62009-05-13 07:52:06 +000047 int isAttached; /* True once backup has been registered with pager */
danielk197704103022009-02-03 16:51:24 +000048 sqlite3_backup *pNext; /* Next backup associated with source pager */
49};
50
51/*
52** THREAD SAFETY NOTES:
53**
54** Once it has been created using backup_init(), a single sqlite3_backup
55** structure may be accessed via two groups of thread-safe entry points:
56**
57** * Via the sqlite3_backup_XXX() API function backup_step() and
58** backup_finish(). Both these functions obtain the source database
59** handle mutex and the mutex associated with the source BtShared
60** structure, in that order.
61**
62** * Via the BackupUpdate() and BackupRestart() functions, which are
63** invoked by the pager layer to report various state changes in
64** the page cache associated with the source database. The mutex
65** associated with the source database BtShared structure will always
66** be held when either of these functions are invoked.
67**
68** The other sqlite3_backup_XXX() API functions, backup_remaining() and
69** backup_pagecount() are not thread-safe functions. If they are called
70** while some other thread is calling backup_step() or backup_finish(),
71** the values returned may be invalid. There is no way for a call to
72** BackupUpdate() or BackupRestart() to interfere with backup_remaining()
73** or backup_pagecount().
74**
75** Depending on the SQLite configuration, the database handles and/or
76** the Btree objects may have their own mutexes that require locking.
77** Non-sharable Btrees (in-memory databases for example), do not have
78** associated mutexes.
79*/
80
81/*
82** Return a pointer corresponding to database zDb (i.e. "main", "temp")
83** in connection handle pDb. If such a database cannot be found, return
84** a NULL pointer and write an error message to pErrorDb.
85**
86** If the "temp" database is requested, it may need to be opened by this
87** function. If an error occurs while doing so, return 0 and write an
88** error message to pErrorDb.
89*/
90static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
91 int i = sqlite3FindDbName(pDb, zDb);
92
93 if( i==1 ){
94 Parse sParse;
95 memset(&sParse, 0, sizeof(sParse));
96 sParse.db = pDb;
97 if( sqlite3OpenTempDatabase(&sParse) ){
98 sqlite3ErrorClear(&sParse);
99 sqlite3Error(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
100 return 0;
101 }
102 assert( sParse.zErrMsg==0 );
103 }
104
105 if( i<0 ){
106 sqlite3Error(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
107 return 0;
108 }
109
110 return pDb->aDb[i].pBt;
111}
112
113/*
114** Create an sqlite3_backup process to copy the contents of zSrcDb from
115** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
116** a pointer to the new sqlite3_backup object.
117**
118** If an error occurs, NULL is returned and an error code and error message
119** stored in database handle pDestDb.
120*/
121sqlite3_backup *sqlite3_backup_init(
122 sqlite3* pDestDb, /* Database to write to */
123 const char *zDestDb, /* Name of database within pDestDb */
124 sqlite3* pSrcDb, /* Database connection to read from */
125 const char *zSrcDb /* Name of database within pSrcDb */
126){
127 sqlite3_backup *p; /* Value to return */
128
129 /* Lock the source database handle. The destination database
drh662c58c2009-02-03 21:13:07 +0000130 ** handle is not locked in this routine, but it is locked in
131 ** sqlite3_backup_step(). The user is required to ensure that no
danielk197704103022009-02-03 16:51:24 +0000132 ** other thread accesses the destination handle for the duration
drh662c58c2009-02-03 21:13:07 +0000133 ** of the backup operation. Any attempt to use the destination
134 ** database connection while a backup is in progress may cause
135 ** a malfunction or a deadlock.
danielk197704103022009-02-03 16:51:24 +0000136 */
137 sqlite3_mutex_enter(pSrcDb->mutex);
drheef1eb02009-02-04 16:56:19 +0000138 sqlite3_mutex_enter(pDestDb->mutex);
danielk197704103022009-02-03 16:51:24 +0000139
140 if( pSrcDb==pDestDb ){
141 sqlite3Error(
drhb309bec2009-02-04 17:40:57 +0000142 pDestDb, SQLITE_ERROR, "source and destination must be distinct"
danielk197704103022009-02-03 16:51:24 +0000143 );
144 p = 0;
145 }else {
146 /* Allocate space for a new sqlite3_backup object */
147 p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
148 if( !p ){
149 sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
150 }
151 }
152
153 /* If the allocation succeeded, populate the new object. */
154 if( p ){
155 memset(p, 0, sizeof(sqlite3_backup));
156 p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
157 p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
158 p->pDestDb = pDestDb;
159 p->pSrcDb = pSrcDb;
160 p->iNext = 1;
danielk1977e70f4f62009-05-13 07:52:06 +0000161 p->isAttached = 0;
danielk197704103022009-02-03 16:51:24 +0000162
163 if( 0==p->pSrc || 0==p->pDest ){
164 /* One (or both) of the named databases did not exist. An error has
165 ** already been written into the pDestDb handle. All that is left
166 ** to do here is free the sqlite3_backup structure.
167 */
168 sqlite3_free(p);
169 p = 0;
170 }
171 }
danielk197704103022009-02-03 16:51:24 +0000172 if( p ){
danielk197704103022009-02-03 16:51:24 +0000173 p->pSrc->nBackup++;
174 }
175
drheef1eb02009-02-04 16:56:19 +0000176 sqlite3_mutex_leave(pDestDb->mutex);
danielk197704103022009-02-03 16:51:24 +0000177 sqlite3_mutex_leave(pSrcDb->mutex);
178 return p;
179}
180
181/*
danielk197703ab0352009-02-06 05:59:44 +0000182** Argument rc is an SQLite error code. Return true if this error is
183** considered fatal if encountered during a backup operation. All errors
184** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED.
185*/
186static int isFatalError(int rc){
187 return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED);
188}
189
190/*
danielk197704103022009-02-03 16:51:24 +0000191** Parameter zSrcData points to a buffer containing the data for
192** page iSrcPg from the source database. Copy this data into the
193** destination database.
194*/
195static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
196 Pager * const pDestPager = sqlite3BtreePager(p->pDest);
197 const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
198 int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
199 const int nCopy = MIN(nSrcPgsz, nDestPgsz);
200 const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
201
202 int rc = SQLITE_OK;
203 i64 iOff;
204
205 assert( p->bDestLocked );
danielk197703ab0352009-02-06 05:59:44 +0000206 assert( !isFatalError(p->rc) );
danielk197704103022009-02-03 16:51:24 +0000207 assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
208 assert( zSrcData );
209
210 /* Catch the case where the destination is an in-memory database and the
211 ** page sizes of the source and destination differ.
212 */
213 if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(sqlite3BtreePager(p->pDest)) ){
214 rc = SQLITE_READONLY;
215 }
216
217 /* This loop runs once for each destination page spanned by the source
218 ** page. For each iteration, variable iOff is set to the byte offset
219 ** of the destination page.
220 */
221 for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){
222 DbPage *pDestPg = 0;
223 Pgno iDest = (Pgno)(iOff/nDestPgsz)+1;
224 if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue;
225 if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg))
226 && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg))
227 ){
228 const u8 *zIn = &zSrcData[iOff%nSrcPgsz];
229 u8 *zDestData = sqlite3PagerGetData(pDestPg);
230 u8 *zOut = &zDestData[iOff%nDestPgsz];
231
232 /* Copy the data from the source page into the destination page.
233 ** Then clear the Btree layer MemPage.isInit flag. Both this module
234 ** and the pager code use this trick (clearing the first byte
235 ** of the page 'extra' space to invalidate the Btree layers
236 ** cached parse of the page). MemPage.isInit is marked
237 ** "MUST BE FIRST" for this purpose.
238 */
239 memcpy(zOut, zIn, nCopy);
240 ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
241 }
242 sqlite3PagerUnref(pDestPg);
243 }
244
245 return rc;
246}
247
248/*
danielk19773d0cbc32009-02-09 18:55:45 +0000249** If pFile is currently larger than iSize bytes, then truncate it to
250** exactly iSize bytes. If pFile is not larger than iSize bytes, then
251** this function is a no-op.
252**
253** Return SQLITE_OK if everything is successful, or an SQLite error
254** code if an error occurs.
255*/
256static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){
257 i64 iCurrent;
258 int rc = sqlite3OsFileSize(pFile, &iCurrent);
259 if( rc==SQLITE_OK && iCurrent>iSize ){
260 rc = sqlite3OsTruncate(pFile, iSize);
261 }
262 return rc;
263}
264
265/*
danielk1977e70f4f62009-05-13 07:52:06 +0000266** Register this backup object with the associated source pager for
267** callbacks when pages are changed or the cache invalidated.
268*/
269static void attachBackupObject(sqlite3_backup *p){
270 sqlite3_backup **pp;
271 assert( sqlite3BtreeHoldsMutex(p->pSrc) );
272 pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
273 p->pNext = *pp;
274 *pp = p;
275 p->isAttached = 1;
276}
277
278/*
danielk197704103022009-02-03 16:51:24 +0000279** Copy nPage pages from the source b-tree to the destination.
280*/
281int sqlite3_backup_step(sqlite3_backup *p, int nPage){
282 int rc;
283
284 sqlite3_mutex_enter(p->pSrcDb->mutex);
285 sqlite3BtreeEnter(p->pSrc);
drhd3a5c502009-02-03 22:51:06 +0000286 if( p->pDestDb ){
287 sqlite3_mutex_enter(p->pDestDb->mutex);
288 }
danielk197704103022009-02-03 16:51:24 +0000289
290 rc = p->rc;
danielk197703ab0352009-02-06 05:59:44 +0000291 if( !isFatalError(rc) ){
danielk197704103022009-02-03 16:51:24 +0000292 Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */
293 Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */
294 int ii; /* Iterator variable */
shane63207ab2009-02-04 01:49:30 +0000295 int nSrcPage = -1; /* Size of source db in pages */
danielk197704103022009-02-03 16:51:24 +0000296 int bCloseTrans = 0; /* True if src db requires unlocking */
297
298 /* If the source pager is currently in a write-transaction, return
danielk1977404ca072009-03-16 13:19:36 +0000299 ** SQLITE_BUSY immediately.
danielk197704103022009-02-03 16:51:24 +0000300 */
301 if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){
danielk1977404ca072009-03-16 13:19:36 +0000302 rc = SQLITE_BUSY;
danielk197703ab0352009-02-06 05:59:44 +0000303 }else{
304 rc = SQLITE_OK;
danielk197704103022009-02-03 16:51:24 +0000305 }
306
307 /* Lock the destination database, if it is not locked already. */
308 if( SQLITE_OK==rc && p->bDestLocked==0
309 && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2))
310 ){
311 p->bDestLocked = 1;
312 rc = sqlite3BtreeGetMeta(p->pDest, 1, &p->iDestSchema);
313 }
314
315 /* If there is no open read-transaction on the source database, open
316 ** one now. If a transaction is opened here, then it will be closed
317 ** before this function exits.
318 */
319 if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
320 rc = sqlite3BtreeBeginTrans(p->pSrc, 0);
321 bCloseTrans = 1;
322 }
323
324 /* Now that there is a read-lock on the source database, query the
325 ** source pager for the number of pages in the database.
326 */
327 if( rc==SQLITE_OK ){
328 rc = sqlite3PagerPagecount(pSrcPager, &nSrcPage);
329 }
danielk197703ab0352009-02-06 05:59:44 +0000330 for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
danielk197704103022009-02-03 16:51:24 +0000331 const Pgno iSrcPg = p->iNext; /* Source page number */
332 if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
333 DbPage *pSrcPg; /* Source page object */
334 rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
335 if( rc==SQLITE_OK ){
336 rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg));
337 sqlite3PagerUnref(pSrcPg);
338 }
339 }
340 p->iNext++;
341 }
342 if( rc==SQLITE_OK ){
343 p->nPagecount = nSrcPage;
344 p->nRemaining = nSrcPage+1-p->iNext;
shane63207ab2009-02-04 01:49:30 +0000345 if( p->iNext>(Pgno)nSrcPage ){
danielk197704103022009-02-03 16:51:24 +0000346 rc = SQLITE_DONE;
danielk1977e70f4f62009-05-13 07:52:06 +0000347 }else if( !p->isAttached ){
348 attachBackupObject(p);
danielk197704103022009-02-03 16:51:24 +0000349 }
350 }
351
352 if( rc==SQLITE_DONE ){
353 const int nSrcPagesize = sqlite3BtreeGetPageSize(p->pSrc);
354 const int nDestPagesize = sqlite3BtreeGetPageSize(p->pDest);
355 int nDestTruncate;
danielk197704103022009-02-03 16:51:24 +0000356
357 /* Update the schema version field in the destination database. This
358 ** is to make sure that the schema-version really does change in
359 ** the case where the source and destination databases have the
360 ** same schema version.
361 */
362 sqlite3BtreeUpdateMeta(p->pDest, 1, p->iDestSchema+1);
drhd3a5c502009-02-03 22:51:06 +0000363 if( p->pDestDb ){
364 sqlite3ResetInternalSchema(p->pDestDb, 0);
365 }
danielk197704103022009-02-03 16:51:24 +0000366
367 /* Set nDestTruncate to the final number of pages in the destination
368 ** database. The complication here is that the destination page
369 ** size may be different to the source page size.
370 **
371 ** If the source page size is smaller than the destination page size,
372 ** round up. In this case the call to sqlite3OsTruncate() below will
373 ** fix the size of the file. However it is important to call
374 ** sqlite3PagerTruncateImage() here so that any pages in the
375 ** destination file that lie beyond the nDestTruncate page mark are
376 ** journalled by PagerCommitPhaseOne() before they are destroyed
377 ** by the file truncation.
378 */
379 if( nSrcPagesize<nDestPagesize ){
380 int ratio = nDestPagesize/nSrcPagesize;
381 nDestTruncate = (nSrcPage+ratio-1)/ratio;
drh38aec8d2009-02-16 16:23:09 +0000382 if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
danielk1977f2a79f22009-02-12 17:01:49 +0000383 nDestTruncate--;
384 }
danielk197704103022009-02-03 16:51:24 +0000385 }else{
386 nDestTruncate = nSrcPage * (nSrcPagesize/nDestPagesize);
387 }
388 sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
389
390 if( nSrcPagesize<nDestPagesize ){
391 /* If the source page-size is smaller than the destination page-size,
392 ** two extra things may need to happen:
393 **
394 ** * The destination may need to be truncated, and
395 **
396 ** * Data stored on the pages immediately following the
397 ** pending-byte page in the source database may need to be
398 ** copied into the destination database.
399 */
danielk19773d0cbc32009-02-09 18:55:45 +0000400 const i64 iSize = (i64)nSrcPagesize * (i64)nSrcPage;
401 sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
402
danielk197704103022009-02-03 16:51:24 +0000403 assert( pFile );
danielk1977f2a79f22009-02-12 17:01:49 +0000404 assert( (i64)nDestTruncate*(i64)nDestPagesize >= iSize || (
shane65ad7d22009-02-16 17:55:47 +0000405 nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
danielk1977f2a79f22009-02-12 17:01:49 +0000406 && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+nDestPagesize
407 ));
danielk197704103022009-02-03 16:51:24 +0000408 if( SQLITE_OK==(rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1))
danielk19773d0cbc32009-02-09 18:55:45 +0000409 && SQLITE_OK==(rc = backupTruncateFile(pFile, iSize))
danielk197704103022009-02-03 16:51:24 +0000410 && SQLITE_OK==(rc = sqlite3PagerSync(pDestPager))
411 ){
412 i64 iOff;
413 i64 iEnd = MIN(PENDING_BYTE + nDestPagesize, iSize);
414 for(
415 iOff=PENDING_BYTE+nSrcPagesize;
416 rc==SQLITE_OK && iOff<iEnd;
417 iOff+=nSrcPagesize
418 ){
419 PgHdr *pSrcPg = 0;
shane63207ab2009-02-04 01:49:30 +0000420 const Pgno iSrcPg = (Pgno)((iOff/nSrcPagesize)+1);
danielk197704103022009-02-03 16:51:24 +0000421 rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
422 if( rc==SQLITE_OK ){
423 u8 *zData = sqlite3PagerGetData(pSrcPg);
424 rc = sqlite3OsWrite(pFile, zData, nSrcPagesize, iOff);
425 }
426 sqlite3PagerUnref(pSrcPg);
427 }
428 }
429 }else{
430 rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
431 }
432
433 /* Finish committing the transaction to the destination database. */
434 if( SQLITE_OK==rc
435 && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest))
436 ){
437 rc = SQLITE_DONE;
438 }
439 }
440
441 /* If bCloseTrans is true, then this function opened a read transaction
442 ** on the source database. Close the read transaction here. There is
443 ** no need to check the return values of the btree methods here, as
444 ** "committing" a read-only transaction cannot fail.
445 */
446 if( bCloseTrans ){
447 TESTONLY( int rc2 );
448 TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0);
449 TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc);
450 assert( rc2==SQLITE_OK );
451 }
452
danielk197703ab0352009-02-06 05:59:44 +0000453 p->rc = rc;
danielk197704103022009-02-03 16:51:24 +0000454 }
drhd3a5c502009-02-03 22:51:06 +0000455 if( p->pDestDb ){
456 sqlite3_mutex_leave(p->pDestDb->mutex);
457 }
danielk197704103022009-02-03 16:51:24 +0000458 sqlite3BtreeLeave(p->pSrc);
459 sqlite3_mutex_leave(p->pSrcDb->mutex);
460 return rc;
461}
462
463/*
464** Release all resources associated with an sqlite3_backup* handle.
465*/
466int sqlite3_backup_finish(sqlite3_backup *p){
467 sqlite3_backup **pp; /* Ptr to head of pagers backup list */
468 sqlite3_mutex *mutex; /* Mutex to protect source database */
469 int rc; /* Value to return */
470
471 /* Enter the mutexes */
472 sqlite3_mutex_enter(p->pSrcDb->mutex);
473 sqlite3BtreeEnter(p->pSrc);
474 mutex = p->pSrcDb->mutex;
drhd3a5c502009-02-03 22:51:06 +0000475 if( p->pDestDb ){
476 sqlite3_mutex_enter(p->pDestDb->mutex);
477 }
danielk197704103022009-02-03 16:51:24 +0000478
479 /* Detach this backup from the source pager. */
480 if( p->pDestDb ){
danielk1977e70f4f62009-05-13 07:52:06 +0000481 p->pSrc->nBackup--;
482 }
483 if( p->isAttached ){
danielk197704103022009-02-03 16:51:24 +0000484 pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
485 while( *pp!=p ){
486 pp = &(*pp)->pNext;
487 }
488 *pp = p->pNext;
danielk197704103022009-02-03 16:51:24 +0000489 }
490
491 /* If a transaction is still open on the Btree, roll it back. */
492 sqlite3BtreeRollback(p->pDest);
493
494 /* Set the error code of the destination database handle. */
495 rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
496 sqlite3Error(p->pDestDb, rc, 0);
497
498 /* Exit the mutexes and free the backup context structure. */
drhd3a5c502009-02-03 22:51:06 +0000499 if( p->pDestDb ){
500 sqlite3_mutex_leave(p->pDestDb->mutex);
501 }
danielk197704103022009-02-03 16:51:24 +0000502 sqlite3BtreeLeave(p->pSrc);
503 if( p->pDestDb ){
504 sqlite3_free(p);
505 }
506 sqlite3_mutex_leave(mutex);
507 return rc;
508}
509
510/*
511** Return the number of pages still to be backed up as of the most recent
512** call to sqlite3_backup_step().
513*/
514int sqlite3_backup_remaining(sqlite3_backup *p){
515 return p->nRemaining;
516}
517
518/*
519** Return the total number of pages in the source database as of the most
520** recent call to sqlite3_backup_step().
521*/
522int sqlite3_backup_pagecount(sqlite3_backup *p){
523 return p->nPagecount;
524}
525
526/*
527** This function is called after the contents of page iPage of the
528** source database have been modified. If page iPage has already been
529** copied into the destination database, then the data written to the
530** destination is now invalidated. The destination copy of iPage needs
531** to be updated with the new data before the backup operation is
532** complete.
533**
534** It is assumed that the mutex associated with the BtShared object
535** corresponding to the source database is held when this function is
536** called.
537*/
538void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
539 sqlite3_backup *p; /* Iterator variable */
540 for(p=pBackup; p; p=p->pNext){
541 assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
danielk197703ab0352009-02-06 05:59:44 +0000542 if( !isFatalError(p->rc) && iPage<p->iNext ){
danielk197704103022009-02-03 16:51:24 +0000543 /* The backup process p has already copied page iPage. But now it
544 ** has been modified by a transaction on the source pager. Copy
545 ** the new data into the backup.
546 */
547 int rc = backupOnePage(p, iPage, aData);
danielk197703ab0352009-02-06 05:59:44 +0000548 assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
danielk197704103022009-02-03 16:51:24 +0000549 if( rc!=SQLITE_OK ){
550 p->rc = rc;
551 }
552 }
553 }
554}
555
556/*
557** Restart the backup process. This is called when the pager layer
558** detects that the database has been modified by an external database
559** connection. In this case there is no way of knowing which of the
560** pages that have been copied into the destination database are still
561** valid and which are not, so the entire process needs to be restarted.
562**
563** It is assumed that the mutex associated with the BtShared object
564** corresponding to the source database is held when this function is
565** called.
566*/
567void sqlite3BackupRestart(sqlite3_backup *pBackup){
568 sqlite3_backup *p; /* Iterator variable */
569 for(p=pBackup; p; p=p->pNext){
570 assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
571 p->iNext = 1;
572 }
573}
574
575#ifndef SQLITE_OMIT_VACUUM
576/*
577** Copy the complete content of pBtFrom into pBtTo. A transaction
578** must be active for both files.
579**
580** The size of file pTo may be reduced by this operation. If anything
581** goes wrong, the transaction on pTo is rolled back. If successful, the
582** transaction is committed before returning.
583*/
584int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
585 int rc;
586 sqlite3_backup b;
587 sqlite3BtreeEnter(pTo);
588 sqlite3BtreeEnter(pFrom);
589
590 /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
591 ** to 0. This is used by the implementations of sqlite3_backup_step()
592 ** and sqlite3_backup_finish() to detect that they are being called
593 ** from this function, not directly by the user.
594 */
595 memset(&b, 0, sizeof(b));
596 b.pSrcDb = pFrom->db;
597 b.pSrc = pFrom;
598 b.pDest = pTo;
599 b.iNext = 1;
600
601 /* 0x7FFFFFFF is the hard limit for the number of pages in a database
602 ** file. By passing this as the number of pages to copy to
603 ** sqlite3_backup_step(), we can guarantee that the copy finishes
604 ** within a single call (unless an error occurs). The assert() statement
605 ** checks this assumption - (p->rc) should be set to either SQLITE_DONE
606 ** or an error code.
607 */
608 sqlite3_backup_step(&b, 0x7FFFFFFF);
609 assert( b.rc!=SQLITE_OK );
610 rc = sqlite3_backup_finish(&b);
611 if( rc==SQLITE_OK ){
612 pTo->pBt->pageSizeFixed = 0;
613 }
614
615 sqlite3BtreeLeave(pFrom);
616 sqlite3BtreeLeave(pTo);
617 return rc;
618}
619#endif /* SQLITE_OMIT_VACUUM */