mirror of
https://github.com/zotero/zotero.git
synced 2026-10-03 02:21:49 +00:00
Merge c67827b568 into e863643a43
This commit is contained in:
commit
6bdfcd59bc
2 changed files with 61 additions and 3 deletions
|
|
@ -1213,6 +1213,15 @@ Zotero.DBConnection.prototype.closeDatabase = async function (permanent) {
|
|||
// potentially bad WAL data into the database file, which might be a valid file that a
|
||||
// stale WAL file is being incorrectly replayed into.
|
||||
if (!this._dbIsCorrupt) {
|
||||
// Refresh statistics for tables whose size changed a lot this session
|
||||
if (!this.readOnly) {
|
||||
try {
|
||||
await this._connection.execute("PRAGMA optimize");
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.logError(e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Zotero.debug("PRAGMA wal_checkpoint(TRUNCATE)");
|
||||
await this._connection.execute("PRAGMA wal_checkpoint(TRUNCATE)");
|
||||
|
|
@ -1664,9 +1673,11 @@ Zotero.DBConnection.prototype._openConnectionAsync = async function () {
|
|||
}
|
||||
}
|
||||
|
||||
// Set page cache size to 8MB
|
||||
// Set page cache size to 64MB. Pages are allocated only as they're read,
|
||||
// so small databases don't use it all, but loading a library larger than
|
||||
// the cache re-reads most pages from disk for every data type.
|
||||
let pageSize = await this.valueQueryAsync("PRAGMA page_size");
|
||||
let cacheSize = 8192000 / pageSize;
|
||||
let cacheSize = 65536000 / pageSize;
|
||||
await this.queryAsync("PRAGMA cache_size=" + cacheSize);
|
||||
|
||||
// Enable foreign key checks
|
||||
|
|
@ -1702,7 +1713,22 @@ Zotero.DBConnection.prototype._openConnectionAsync = async function () {
|
|||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Gather query planner statistics for any table that needs them. Without them,
|
||||
// SQLite reads every item through the items(libraryID, key) index instead of
|
||||
// scanning the table, which is several times slower for a large library. After
|
||||
// the first run, this is a no-op unless a table has grown or shrunk a lot.
|
||||
// Use _connection.execute() directly, since an error here shouldn't start
|
||||
// corruption handling -- the next real query will report a corrupt database.
|
||||
if (!this.readOnly) {
|
||||
try {
|
||||
await this._connection.execute("PRAGMA optimize=0x10002");
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.logError(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Register idle observer for DB backup
|
||||
if (!this._idleObserverScheduled) {
|
||||
this._idleObserverScheduled = true;
|
||||
|
|
|
|||
|
|
@ -830,6 +830,38 @@ describe("Zotero.DB", function () {
|
|||
assert.isFalse(db.readOnly);
|
||||
await db.closeDatabase();
|
||||
});
|
||||
|
||||
it("should set a 64MB page cache", async function () {
|
||||
var pageSize = await Zotero.DB.valueQueryAsync("PRAGMA page_size");
|
||||
assert.equal(await Zotero.DB.valueQueryAsync("PRAGMA cache_size"), 65536000 / pageSize);
|
||||
});
|
||||
|
||||
it("should gather query planner statistics", async function () {
|
||||
let dir = await getTempDirectory();
|
||||
let dbPath = PathUtils.join(dir, 'test.sqlite');
|
||||
let db = new Zotero.DBConnection(dbPath);
|
||||
await db.queryAsync("CREATE TABLE foo (a INT, b INT)");
|
||||
await db.queryAsync("CREATE INDEX foo_a ON foo(a)");
|
||||
await db.executeTransaction(async function () {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
await db.queryAsync("INSERT INTO foo VALUES (?, ?)", [i % 10, i]);
|
||||
}
|
||||
});
|
||||
await db.closeDatabase();
|
||||
// Open through internal initialization
|
||||
db._externalDB = false;
|
||||
|
||||
try {
|
||||
await db.queryAsync("SELECT COUNT(*) FROM foo");
|
||||
assert.isAbove(
|
||||
await db.valueQueryAsync("SELECT COUNT(*) FROM sqlite_stat1 WHERE tbl='foo'"),
|
||||
0
|
||||
);
|
||||
}
|
||||
finally {
|
||||
await db.closeDatabase();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue