0
# Database Backup
1
2
Database backup and restoration functionality with step-by-step control and progress monitoring. The Backup class extends EventEmitter and provides comprehensive backup operations for SQLite databases.
3
4
## Capabilities
5
6
### Create Backup
7
8
Creates a backup instance for database backup operations.
9
10
```javascript { .api }
11
/**
12
* Creates a database backup (simple form) - backs up main database to file
13
* @param filename - Destination filename for backup
14
* @param callback - Optional callback called when backup is initialized
15
* @returns Backup instance
16
*/
17
backup(filename: string, callback?: (err: Error | null) => void): Backup;
18
19
/**
20
* Creates a database backup (advanced form) - full control over source/destination
21
* @param filename - Source or destination filename
22
* @param destName - Destination database name (usually 'main')
23
* @param sourceName - Source database name (usually 'main')
24
* @param filenameIsDest - Whether filename parameter is destination (true) or source (false)
25
* @param callback - Optional callback called when backup is initialized
26
* @returns Backup instance
27
*/
28
backup(
29
filename: string,
30
destName: string,
31
sourceName: string,
32
filenameIsDest: boolean,
33
callback?: (err: Error | null) => void
34
): Backup;
35
```
36
37
**Usage Examples:**
38
39
```javascript
40
const sqlite3 = require('sqlite3').verbose();
41
const db = new sqlite3.Database('source.db');
42
43
// Simple backup - backup current database to file
44
const backup = db.backup('backup.db', (err) => {
45
if (err) {
46
console.error('Backup initialization failed:', err.message);
47
} else {
48
console.log('Backup initialized successfully');
49
}
50
});
51
52
// Advanced backup - restore from file to current database
53
const restoreBackup = db.backup('backup.db', 'main', 'main', false, (err) => {
54
if (err) {
55
console.error('Restore initialization failed:', err.message);
56
}
57
});
58
59
// Backup to a different database name
60
const attachedBackup = db.backup('backup.db', 'backup_db', 'main', true);
61
```
62
63
### Step Backup Forward
64
65
Advances the backup process by copying a specified number of pages.
66
67
```javascript { .api }
68
/**
69
* Steps the backup process forward by copying pages
70
* @param pages - Number of pages to copy in this step (-1 for all remaining)
71
* @param callback - Optional callback called when step completes
72
* @returns Backup instance for chaining
73
*/
74
step(pages: number, callback?: (err: Error | null) => void): this;
75
```
76
77
**Usage Examples:**
78
79
```javascript
80
const backup = db.backup('backup.db');
81
82
// Copy 5 pages at a time
83
backup.step(5, (err) => {
84
if (err) {
85
console.error('Backup step failed:', err.message);
86
} else {
87
console.log(`Backup progress: ${backup.remaining} pages remaining`);
88
89
if (!backup.completed && !backup.failed) {
90
// Continue with next step
91
backup.step(5);
92
}
93
}
94
});
95
96
// Copy all remaining pages at once
97
backup.step(-1, (err) => {
98
if (err) {
99
console.error('Backup failed:', err.message);
100
} else {
101
console.log('Backup completed successfully');
102
}
103
});
104
105
// Step-by-step with progress monitoring
106
function performBackupWithProgress() {
107
const backup = db.backup('backup.db');
108
const totalPages = backup.pageCount;
109
110
function stepBackup() {
111
backup.step(1, (err) => {
112
if (err) {
113
console.error('Backup error:', err.message);
114
return;
115
}
116
117
const progress = ((totalPages - backup.remaining) / totalPages) * 100;
118
console.log(`Backup progress: ${progress.toFixed(1)}%`);
119
120
if (backup.completed) {
121
console.log('Backup completed successfully');
122
backup.finish();
123
} else if (backup.failed) {
124
console.log('Backup failed');
125
backup.finish();
126
} else {
127
// Continue with next step
128
setTimeout(stepBackup, 10); // Small delay between steps
129
}
130
});
131
}
132
133
stepBackup();
134
}
135
```
136
137
### Finish Backup
138
139
Finishes the backup operation and releases resources.
140
141
```javascript { .api }
142
/**
143
* Finishes the backup operation and releases resources
144
* @param callback - Optional callback called when backup is finished
145
* @returns Backup instance for chaining
146
*/
147
finish(callback?: (err: Error | null) => void): this;
148
```
149
150
**Usage Examples:**
151
152
```javascript
153
const backup = db.backup('backup.db');
154
155
// Perform complete backup
156
backup.step(-1, (err) => {
157
if (err) {
158
console.error('Backup failed:', err.message);
159
} else {
160
console.log('Backup data copied successfully');
161
}
162
163
// Always finish to clean up resources
164
backup.finish((err) => {
165
if (err) {
166
console.error('Backup finish failed:', err.message);
167
} else {
168
console.log('Backup operation completed and resources cleaned up');
169
}
170
});
171
});
172
```
173
174
### Backup Properties
175
176
Read-only properties that provide backup status and progress information.
177
178
```javascript { .api }
179
/**
180
* Number of pages remaining to be backed up
181
*/
182
readonly remaining: number;
183
184
/**
185
* Total number of pages in the source database
186
*/
187
readonly pageCount: number;
188
189
/**
190
* Whether the backup has completed successfully
191
*/
192
readonly completed: boolean;
193
194
/**
195
* Whether the backup has failed
196
*/
197
readonly failed: boolean;
198
199
/**
200
* Whether the backup is currently idle (no operation in progress or queued)
201
*/
202
readonly idle: boolean;
203
204
/**
205
* Array of SQLite error codes that should trigger retry attempts
206
* Default: [BUSY, LOCKED]
207
*/
208
retryErrors: number[];
209
```
210
211
**Usage Examples:**
212
213
```javascript
214
const backup = db.backup('backup.db');
215
216
// Monitor backup progress
217
function checkProgress() {
218
console.log(`Pages: ${backup.remaining}/${backup.pageCount} remaining`);
219
console.log(`Progress: ${((backup.pageCount - backup.remaining) / backup.pageCount * 100).toFixed(1)}%`);
220
console.log(`Completed: ${backup.completed}`);
221
console.log(`Failed: ${backup.failed}`);
222
}
223
224
// Configure retry behavior
225
backup.retryErrors = [sqlite3.BUSY, sqlite3.LOCKED, sqlite3.INTERRUPT];
226
227
// Step through backup with monitoring
228
backup.step(10, (err) => {
229
checkProgress();
230
231
if (!backup.completed && !backup.failed) {
232
// Continue backup
233
backup.step(10);
234
} else {
235
backup.finish();
236
}
237
});
238
```
239
240
## Complete Backup Examples
241
242
### Simple Complete Backup
243
244
```javascript
245
const sqlite3 = require('sqlite3').verbose();
246
const db = new sqlite3.Database('source.db');
247
248
function createBackup(sourceDb, backupFile, callback) {
249
const backup = sourceDb.backup(backupFile, (err) => {
250
if (err) {
251
return callback(err);
252
}
253
254
// Perform complete backup
255
backup.step(-1, (err) => {
256
if (err) {
257
backup.finish();
258
return callback(err);
259
}
260
261
if (backup.completed) {
262
backup.finish((err) => {
263
if (err) {
264
return callback(err);
265
}
266
callback(null, 'Backup completed successfully');
267
});
268
} else {
269
backup.finish();
270
callback(new Error('Backup did not complete'));
271
}
272
});
273
});
274
}
275
276
// Usage
277
createBackup(db, 'my-backup.db', (err, message) => {
278
if (err) {
279
console.error('Backup failed:', err.message);
280
} else {
281
console.log(message);
282
}
283
db.close();
284
});
285
```
286
287
### Progressive Backup with Progress Reporting
288
289
```javascript
290
function createProgressiveBackup(sourceDb, backupFile, progressCallback, completeCallback) {
291
const backup = sourceDb.backup(backupFile, (err) => {
292
if (err) {
293
return completeCallback(err);
294
}
295
296
const totalPages = backup.pageCount;
297
console.log(`Starting backup of ${totalPages} pages`);
298
299
function stepWithProgress() {
300
// Copy 100 pages at a time
301
backup.step(100, (err) => {
302
if (err) {
303
backup.finish();
304
return completeCallback(err);
305
}
306
307
const remaining = backup.remaining;
308
const copied = totalPages - remaining;
309
const progress = (copied / totalPages) * 100;
310
311
// Report progress
312
if (progressCallback) {
313
progressCallback(progress, copied, totalPages);
314
}
315
316
if (backup.completed) {
317
backup.finish((err) => {
318
if (err) {
319
return completeCallback(err);
320
}
321
completeCallback(null, 'Backup completed successfully');
322
});
323
} else if (backup.failed) {
324
backup.finish();
325
completeCallback(new Error('Backup failed'));
326
} else {
327
// Continue with next batch
328
setTimeout(stepWithProgress, 50); // Small delay
329
}
330
});
331
}
332
333
stepWithProgress();
334
});
335
}
336
337
// Usage
338
createProgressiveBackup(
339
db,
340
'progressive-backup.db',
341
(progress, copied, total) => {
342
console.log(`Backup progress: ${progress.toFixed(1)}% (${copied}/${total} pages)`);
343
},
344
(err, message) => {
345
if (err) {
346
console.error('Progressive backup failed:', err.message);
347
} else {
348
console.log(message);
349
}
350
db.close();
351
}
352
);
353
```
354
355
### Restore from Backup
356
357
```javascript
358
function restoreFromBackup(targetDb, backupFile, callback) {
359
// Note: filenameIsDest = false means we're reading FROM the backupFile
360
const restore = targetDb.backup(backupFile, 'main', 'main', false, (err) => {
361
if (err) {
362
return callback(err);
363
}
364
365
console.log('Starting restore operation');
366
367
// Restore all pages at once
368
restore.step(-1, (err) => {
369
if (err) {
370
restore.finish();
371
return callback(err);
372
}
373
374
if (restore.completed) {
375
restore.finish((err) => {
376
if (err) {
377
return callback(err);
378
}
379
callback(null, 'Restore completed successfully');
380
});
381
} else {
382
restore.finish();
383
callback(new Error('Restore did not complete'));
384
}
385
});
386
});
387
}
388
389
// Usage
390
const targetDb = new sqlite3.Database(':memory:'); // Or any target database
391
restoreFromBackup(targetDb, 'my-backup.db', (err, message) => {
392
if (err) {
393
console.error('Restore failed:', err.message);
394
} else {
395
console.log(message);
396
397
// Verify restore by querying the restored database
398
targetDb.get("SELECT COUNT(*) as count FROM sqlite_master WHERE type='table'", (err, row) => {
399
if (err) {
400
console.error('Verification failed:', err.message);
401
} else {
402
console.log(`Restored database contains ${row.count} tables`);
403
}
404
targetDb.close();
405
});
406
}
407
});
408
```
409
410
### Concurrent Backup (Non-Blocking)
411
412
```javascript
413
function createConcurrentBackup(sourceDb, backupFile, callback) {
414
const backup = sourceDb.backup(backupFile);
415
416
// Configure for busy databases
417
backup.retryErrors = [sqlite3.BUSY, sqlite3.LOCKED];
418
419
function performStep() {
420
// Copy small chunks to avoid blocking
421
backup.step(10, (err) => {
422
if (err) {
423
// Check if this is a retryable error
424
if (backup.retryErrors.includes(err.errno)) {
425
console.log('Database busy, retrying...');
426
setTimeout(performStep, 100); // Retry after delay
427
return;
428
}
429
430
backup.finish();
431
return callback(err);
432
}
433
434
if (backup.completed) {
435
backup.finish((err) => {
436
callback(err, 'Concurrent backup completed');
437
});
438
} else if (backup.failed) {
439
backup.finish();
440
callback(new Error('Concurrent backup failed'));
441
} else {
442
// Continue with next step, allowing other operations
443
setImmediate(performStep);
444
}
445
});
446
}
447
448
performStep();
449
}
450
```