Skip to content
This repository was archived by the owner on Jun 19, 2022. It is now read-only.

Commit 83416a2

Browse files
Jun Tangwuyuehyang
authored andcommittedApr 2, 2019
Backup database
1 parent 7977024 commit 83416a2

File tree

6 files changed

+114
-0
lines changed

6 files changed

+114
-0
lines changed
 

‎swift/WCDB.swift.xcodeproj/project.pbxproj‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@
113113
DF1911AE209467AE00BD415D /* UpdateSQL.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1911AD209467AE00BD415D /* UpdateSQL.swift */; };
114114
DF1911B020946B7600BD415D /* StatementSelectSQL.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1911AF20946B7600BD415D /* StatementSelectSQL.swift */; };
115115
DF1911B220946B8E00BD415D /* StatementUpdateSQL.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1911B120946B8E00BD415D /* StatementUpdateSQL.swift */; };
116+
DF1F278121A54CE5009A74C6 /* sqlite_backup.h in Headers */ = {isa = PBXBuildFile; fileRef = DF1F277F21A54CE5009A74C6 /* sqlite_backup.h */; };
117+
DF1F278221A54CE5009A74C6 /* sqlite_backup.c in Sources */ = {isa = PBXBuildFile; fileRef = DF1F278021A54CE5009A74C6 /* sqlite_backup.c */; };
116118
/* End PBXBuildFile section */
117119

118120
/* Begin PBXContainerItemProxy section */
@@ -256,6 +258,8 @@
256258
DF1911AD209467AE00BD415D /* UpdateSQL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateSQL.swift; sourceTree = "<group>"; };
257259
DF1911AF20946B7600BD415D /* StatementSelectSQL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatementSelectSQL.swift; sourceTree = "<group>"; };
258260
DF1911B120946B8E00BD415D /* StatementUpdateSQL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatementUpdateSQL.swift; sourceTree = "<group>"; };
261+
DF1F277F21A54CE5009A74C6 /* sqlite_backup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sqlite_backup.h; sourceTree = "<group>"; };
262+
DF1F278021A54CE5009A74C6 /* sqlite_backup.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sqlite_backup.c; sourceTree = "<group>"; };
259263
/* End PBXFileReference section */
260264

261265
/* Begin PBXFrameworksBuildPhase section */
@@ -480,6 +484,8 @@
480484
230209BF1FBEE3CC000D69B6 /* Convenience.swift */,
481485
231BC02E1FC2CC6E00011C69 /* TimedQueue.swift */,
482486
231BC0301FC2CDCA00011C69 /* SteadyClock.swift */,
487+
DF1F277F21A54CE5009A74C6 /* sqlite_backup.h */,
488+
DF1F278021A54CE5009A74C6 /* sqlite_backup.c */,
483489
);
484490
path = util;
485491
sourceTree = "<group>";
@@ -509,6 +515,7 @@
509515
files = (
510516
238D0BCD1FAB1F7E00BC2659 /* SQLite-Bridging.h in Headers */,
511517
23794DB41FAB23AD001E79DE /* WCDB-Bridging.h in Headers */,
518+
DF1F278121A54CE5009A74C6 /* sqlite_backup.h in Headers */,
512519
);
513520
runOnlyForDeploymentPostprocessing = 0;
514521
};
@@ -704,6 +711,7 @@
704711
23E9E0051FC3C76F005DE71C /* SQLite-Bridging.swift in Sources */,
705712
DF1911AB209466FB00BD415D /* SelectSQL.swift in Sources */,
706713
238D0B781FAB1F7E00BC2659 /* ColumnDef.swift in Sources */,
714+
DF1F278221A54CE5009A74C6 /* sqlite_backup.c in Sources */,
707715
230686DC1FAC0E5B0005EE8B /* Convertible.swift in Sources */,
708716
238D0B991FAB1F7E00BC2659 /* StatementSelect.swift in Sources */,
709717
238D0B8B1FAB1F7E00BC2659 /* StatementCreateIndex.swift in Sources */,

‎swift/source/abstract/Handle.swift‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,16 @@ extension Handle {
169169
return path+Handle.backupSubfix
170170
}
171171

172+
public func backup(withFile path: String, progress: @escaping @convention (c) (Int32, Int32) -> Void) throws {
173+
var rc = SQLITE_OK
174+
rc = backupDb(handle, path, progress)
175+
guard rc == SQLITE_OK else {
176+
throw Error.reportRepair(path: path,
177+
operation: .loadMaster,
178+
code: Int(rc))
179+
}
180+
}
181+
172182
public func backup(withKey optionalKey: Data? = nil) throws {
173183
var rc = SQLITE_OK
174184
if let key = optionalKey {

‎swift/source/core/base/Database.swift‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,12 @@ extension Database {
696696
try handle.raw.handle.backup(withKey: key)
697697
}
698698

699+
/// Backup data
700+
public func backup(withFile path: String, progress: @escaping @convention (c) (Int32, Int32) -> Void) throws {
701+
let handle = try flowOut()
702+
try handle.raw.handle.backup(withFile: path, progress: progress)
703+
}
704+
699705
/// Recover data from a corruped db. You'd better to recover a closed database.
700706
///
701707
/// - Parameters:

‎swift/source/util/SQLite-Bridging.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#import <sqlcipher/sqlite3.h>
2525
#import <sqlcipher/fts3_tokenizer.h>
26+
#import "sqlite_backup.h"
2627

2728
struct Tokenizer {
2829
sqlite3_tokenizer base;

‎swift/source/util/sqlite_backup.c‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//
2+
// sqlite_backup.c
3+
// WCDB.swift
4+
//
5+
// Created by tangjun on 2018/11/21.
6+
// Copyright © 2018年 sanhuazhang. All rights reserved.
7+
//
8+
9+
#include "sqlite_backup.h"
10+
11+
int backupDb(
12+
sqlite3 *pDb, /* Database to back up */
13+
const char *zFilename, /* Name of file to back up to */
14+
void(*xProgress)(int, int) /* Progress function to invoke */
15+
){
16+
int rc; /* Function return code */
17+
sqlite3 *pFile; /* Database connection opened on zFilename */
18+
sqlite3_backup *pBackup; /* Backup handle used to copy data */
19+
20+
/* Open the database file identified by zFilename. */
21+
rc = sqlite3_open(zFilename, &pFile);
22+
if( rc==SQLITE_OK ){
23+
24+
/* Open the sqlite3_backup object used to accomplish the transfer */
25+
pBackup = sqlite3_backup_init(pFile, "main", pDb, "main");
26+
if( pBackup ){
27+
28+
/* Each iteration of this loop copies 5 database pages from database
29+
** pDb to the backup database. If the return value of backup_step()
30+
** indicates that there are still further pages to copy, sleep for
31+
** 250 ms before repeating. */
32+
do {
33+
rc = sqlite3_backup_step(pBackup, 50);
34+
xProgress(
35+
sqlite3_backup_remaining(pBackup),
36+
sqlite3_backup_pagecount(pBackup)
37+
);
38+
if( rc==SQLITE_OK || rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
39+
sqlite3_sleep(100);
40+
}
41+
} while( rc==SQLITE_OK || rc==SQLITE_BUSY || rc==SQLITE_LOCKED );
42+
43+
/* Release resources allocated by backup_init(). */
44+
(void)sqlite3_backup_finish(pBackup);
45+
}
46+
rc = sqlite3_errcode(pFile);
47+
}
48+
49+
/* Close the database connection opened on database file zFilename
50+
** and return the result of this function. */
51+
(void)sqlite3_close(pFile);
52+
return rc;
53+
}

‎swift/source/util/sqlite_backup.h‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef sqlite_backup_h
2+
#define sqlite_backup_h
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
#include <stdlib.h>
9+
#import <sqlcipher/sqlite3.h>
10+
11+
/*
12+
** Perform an online backup of database pDb to the database file named
13+
** by zFilename. This function copies 5 database pages from pDb to
14+
** zFilename, then unlocks pDb and sleeps for 250 ms, then repeats the
15+
** process until the entire database is backed up.
16+
**
17+
** The third argument passed to this function must be a pointer to a progress
18+
** function. After each set of 5 pages is backed up, the progress function
19+
** is invoked with two integer parameters: the number of pages left to
20+
** copy, and the total number of pages in the source file. This information
21+
** may be used, for example, to update a GUI progress bar.
22+
**
23+
** While this function is running, another thread may use the database pDb, or
24+
** another process may access the underlying database file via a separate
25+
** connection.
26+
**
27+
** If the backup process is successfully completed, SQLITE_OK is returned.
28+
** Otherwise, if an error occurs, an SQLite error code is returned.
29+
*/
30+
int backupDb(
31+
sqlite3 *pDb, /* Database to back up */
32+
const char *zFilename, /* Name of file to back up to */
33+
void(*xProgress)(int, int) /* Progress function to invoke */
34+
);
35+
36+
#endif /* sqlite_backup_h */

0 commit comments

Comments
 (0)
This repository has been archived.