Skip to content

Commit b284519

Browse files
authored
Merge pull request #36 from iwongu/backup
Supports backup methods in database class.
2 parents 9a594a6 + 22ad8b6 commit b284519

6 files changed

Lines changed: 97 additions & 0 deletions

File tree

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,26 @@ sqlite3pp::query qry(
118118
"SELECT epi.* FROM episodes epi, test.contacts con WHERE epi.id = con.id");
119119
```
120120
121+
## backup
122+
123+
```cpp
124+
sqlite3pp::database db("test.db");
125+
sqlite3pp::database backupdb("backup.db");
126+
127+
db.backup(backupdb);
128+
```
129+
130+
```cpp
131+
db.backup(
132+
backupdb,
133+
[](int pagecount, int remaining, int rc) {
134+
cout << pagecount << "/" << remaining << endl;
135+
if (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED) {
136+
// sleep or do nothing.
137+
}
138+
});
139+
```
140+
121141
## callback
122142
123143
```cpp

headeronly_src/sqlite3pp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ namespace sqlite3pp
7878
using rollback_handler = std::function<void ()>;
7979
using update_handler = std::function<void (int, char const*, char const*, long long int)>;
8080
using authorize_handler = std::function<int (int, char const*, char const*, char const*, char const*)>;
81+
using backup_handler = std::function<void (int, int, int)>;
8182

8283
explicit database(char const* dbname = nullptr, int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, const char* vfs = nullptr);
8384

@@ -92,6 +93,9 @@ namespace sqlite3pp
9293
int attach(char const* dbname, char const* name);
9394
int detach(char const* name);
9495

96+
int backup(database& destdb, backup_handler h = {});
97+
int backup(char const* dbname, database& destdb, char const* destdbname, backup_handler h, int step_page = 5);
98+
9599
long long int last_insert_rowid() const;
96100

97101
int enable_foreign_keys(bool enable = true);

headeronly_src/sqlite3pp.ipp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,28 @@ namespace sqlite3pp
132132
return executef("DETACH '%q'", name);
133133
}
134134

135+
inline int database::backup(database& destdb, backup_handler h)
136+
{
137+
return backup("main", destdb, "main", h);
138+
}
139+
140+
inline int database::backup(char const* dbname, database& destdb, char const* destdbname, backup_handler h, int step_page)
141+
{
142+
sqlite3_backup* bkup = sqlite3_backup_init(destdb.db_, destdbname, db_, dbname);
143+
if (!bkup) {
144+
return error_code();
145+
}
146+
auto rc = SQLITE_OK;
147+
do {
148+
rc = sqlite3_backup_step(bkup, step_page);
149+
if (h) {
150+
h(sqlite3_backup_remaining(bkup), sqlite3_backup_pagecount(bkup), rc);
151+
}
152+
} while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED);
153+
sqlite3_backup_finish(bkup);
154+
return rc;
155+
}
156+
135157
inline void database::set_busy_handler(busy_handler h)
136158
{
137159
bh_ = h;

src/sqlite3pp.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,28 @@ namespace sqlite3pp
134134
return executef("DETACH '%q'", name);
135135
}
136136

137+
int database::backup(database& destdb, backup_handler h)
138+
{
139+
return backup("main", destdb, "main", h);
140+
}
141+
142+
int database::backup(char const* dbname, database& destdb, char const* destdbname, backup_handler h, int step_page)
143+
{
144+
sqlite3_backup* bkup = sqlite3_backup_init(destdb.db_, destdbname, db_, dbname);
145+
if (!bkup) {
146+
return error_code();
147+
}
148+
auto rc = SQLITE_OK;
149+
do {
150+
rc = sqlite3_backup_step(bkup, step_page);
151+
if (h) {
152+
h(sqlite3_backup_remaining(bkup), sqlite3_backup_pagecount(bkup), rc);
153+
}
154+
} while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED);
155+
sqlite3_backup_finish(bkup);
156+
return rc;
157+
}
158+
137159
void database::set_busy_handler(busy_handler h)
138160
{
139161
bh_ = h;

src/sqlite3pp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ namespace sqlite3pp
7979
using rollback_handler = std::function<void ()>;
8080
using update_handler = std::function<void (int, char const*, char const*, long long int)>;
8181
using authorize_handler = std::function<int (int, char const*, char const*, char const*, char const*)>;
82+
using backup_handler = std::function<void (int, int, int)>;
8283

8384
explicit database(char const* dbname = nullptr, int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, const char* vfs = nullptr);
8485

@@ -93,6 +94,9 @@ namespace sqlite3pp
9394
int attach(char const* dbname, char const* name);
9495
int detach(char const* name);
9596

97+
int backup(database& destdb, backup_handler h = {});
98+
int backup(char const* dbname, database& destdb, char const* destdbname, backup_handler h, int step_page = 5);
99+
96100
long long int last_insert_rowid() const;
97101

98102
int enable_foreign_keys(bool enable = true);

test/testbackup.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <iostream>
2+
#include "sqlite3pp.h"
3+
4+
using namespace std;
5+
6+
int main()
7+
{
8+
try {
9+
sqlite3pp::database db("test.db");
10+
sqlite3pp::database backupdb("backup.db");
11+
12+
db.backup(
13+
backupdb,
14+
[](int pagecount, int remaining, int rc) {
15+
cout << pagecount << "/" << remaining << endl;
16+
if (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED) {
17+
// sleep(250);
18+
}
19+
});
20+
}
21+
catch (exception& ex) {
22+
cout << ex.what() << endl;
23+
}
24+
25+
}

0 commit comments

Comments
 (0)