-
Notifications
You must be signed in to change notification settings - Fork 30.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sqlite: expose backup api #56253
base: main
Are you sure you want to change the base?
sqlite: expose backup api #56253
Conversation
6c61b4c
to
9b80c2d
Compare
632edd3
to
174ace5
Compare
174ace5
to
2aee11d
Compare
This comment mentions that The backup can be performed synchronously but I don't think it should be like that. I wonder if indeed this PR would be more suitable for async API. Any thoughts? Thanks in advance |
69a3bf3
to
bd43083
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #56253 +/- ##
==========================================
+ Coverage 89.18% 89.20% +0.02%
==========================================
Files 662 662
Lines 191759 192178 +419
Branches 36911 36992 +81
==========================================
+ Hits 171017 171439 +422
+ Misses 13613 13562 -51
- Partials 7129 7177 +48
|
371f368
to
a92e692
Compare
a92e692
to
fa23c05
Compare
9069aa8
to
fa23c05
Compare
Failing test seems unrelated |
8e2caea
to
c532c58
Compare
That is not a requirement. |
0909d3e
to
7b15cae
Compare
--> | ||
|
||
* `sourceDb` {DatabaseSync} The database to backup. The source database must be open. | ||
* `destination` {string} The path where the backup will be created. If the file already exists, the contents will be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is assumed to be a filesystem path, then handling it the same as our other fs APIs would be ideal. Paths can be expressed as either strings, Buffer
, or file://
scheme URLs. If you're not familiar, there are internal utilities for normalizing these into a usable path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. I will search for examples to see how to do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* `options` {Object} Optional configuration for the backup. The | ||
following properties are supported: | ||
* `source` {string} Name of the source database. **Default:** `'main'`. | ||
* `target` {string} Name of the target database. **Default:** `'main'`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For users who may not be that familiar with things here, the docs could likely benefit from more explanation about how source
and target
are used.
* Returns: {Promise} A promise that resolves when the backup is completed and rejects if an error occurs. | ||
|
||
This method makes a database backup. This method abstracts the [`sqlite3_backup_init()`][], [`sqlite3_backup_step()`][] | ||
and [`sqlite3_backup_finish()`][] functions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the backup operation is async and may take some time, some discussion in here about concurrent edits while the db is being backed up would be helpful for users to understand what to expect.
* `source` {string} Name of the source database. **Default:** `'main'`. | ||
* `target` {string} Name of the target database. **Default:** `'main'`. | ||
* `rate` {number} Number of pages to be transmitted in each batch of the backup. **Default:** `100`. | ||
* `progress` {Function} Callback function that will be called with the number of pages copied and the total number of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not something that needs to be added in this PR but... would it make sense for this operation to support cancelation via an AbortSignal
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
const database = makeSourceDb(); | ||
|
||
t.assert.throws(() => { | ||
backup(database); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per web platform API conventions, APIs that return a Promise should generally reject the promsie as opposed to throwing synchronously. I know we haven't always been super consistent with that for Node.js APIs tho. Non-blocking but I think I would prefer this to reject rather than throw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this an input validation issue though? Node APIs generally throw in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, that's why it's not blocking and just a preference.
Closes #55413
This PR exposes the SQLite Online Backup API, which allows database backup.
The API is inspired by better-sqlite3 https://github.com/WiseLibs/better-sqlite3/blob/master/docs/api.md#backupdestination-options---promise.
Multithreading caveats
As long as writes come from the same process and handle (
sqlite*
), the backup will continue progressing as expected. Other than that, it can cause the backup process to restart. From docs: