mirror of
https://github.com/louislam/uptime-kuma.git
synced 2026-08-07 09:14:58 +00:00
fix: [3.0.X] Migrate to better-sqlite (#7568)
This commit is contained in:
@@ -48,11 +48,6 @@ jobs:
|
||||
- run: npm --version
|
||||
|
||||
- run: npm clean-install --no-fund
|
||||
|
||||
- name: Rebuild native modules for ARM64
|
||||
if: matrix.os == 'ubuntu-22.04-arm'
|
||||
run: npm rebuild @louislam/sqlite3
|
||||
|
||||
- run: npm run build
|
||||
- run: npm run test-backend
|
||||
env:
|
||||
@@ -109,9 +104,6 @@ jobs:
|
||||
node-version: 26
|
||||
- run: npm clean-install --no-fund
|
||||
|
||||
- name: Rebuild native modules for ARM64
|
||||
run: npm rebuild @louislam/sqlite3
|
||||
|
||||
- name: Install Playwright ${{ env.PLAYWRIGHT_VERSION }}
|
||||
run: npx playwright@${{ env.PLAYWRIGHT_VERSION }} install --with-deps
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
PRAGMA writable_schema = TRUE;
|
||||
|
||||
UPDATE
|
||||
SQLITE_MASTER
|
||||
SET
|
||||
sql = replace(sql,
|
||||
'monitor_id INTEGER NOT NULL',
|
||||
'monitor_id INTEGER NOT NULL REFERENCES [monitor] ([id]) ON DELETE CASCADE ON UPDATE CASCADE'
|
||||
)
|
||||
WHERE
|
||||
name = 'monitor_tls_info'
|
||||
AND type = 'table';
|
||||
|
||||
PRAGMA writable_schema = RESET;
|
||||
|
||||
COMMIT;
|
||||
Generated
+221
-707
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -65,12 +65,12 @@
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "~1.8.22",
|
||||
"@louislam/ping": "~0.4.4-mod.1",
|
||||
"@louislam/sqlite3": "15.1.6",
|
||||
"@vvo/tzdb": "~6.198.0",
|
||||
"args-parser": "~1.3.0",
|
||||
"axios": "~0.32.0",
|
||||
"badge-maker": "~3.3.1",
|
||||
"bcryptjs": "~2.4.3",
|
||||
"better-sqlite3": "~12.11.1",
|
||||
"chardet": "~1.4.0",
|
||||
"check-password-strength": "~2.0.10",
|
||||
"cheerio": "~1.0.0",
|
||||
@@ -143,9 +143,9 @@
|
||||
"thirty-two": "~1.0.2",
|
||||
"tldts": "~7.0.23",
|
||||
"tough-cookie": "~4.1.4",
|
||||
"tsx": "~4.20.6",
|
||||
"validator": "~13.15.26",
|
||||
"web-push": "~3.6.7",
|
||||
"tsx": "~4.20.6",
|
||||
"ws": "~8.19.0",
|
||||
"zod": "~4.1.12"
|
||||
},
|
||||
@@ -230,7 +230,7 @@
|
||||
}
|
||||
},
|
||||
"allowScripts": {
|
||||
"@louislam/sqlite3@15.1.6": true,
|
||||
"better-sqlite3@12.11.1": true,
|
||||
"@fortawesome/fontawesome-common-types@0.2.36": true,
|
||||
"@fortawesome/fontawesome-svg-core@1.2.36": true,
|
||||
"@fortawesome/free-regular-svg-icons@5.15.4": true,
|
||||
|
||||
+18
-21
@@ -295,9 +295,6 @@ class Database {
|
||||
fs.copyFileSync(Database.templatePath, Database.sqlitePath);
|
||||
}
|
||||
|
||||
const Dialect = require("knex/lib/dialects/sqlite3/index.js");
|
||||
Dialect.prototype._driver = () => require("@louislam/sqlite3");
|
||||
|
||||
// SQLite is actually multiple connections for WAL mode, so we can set it to a higher number.
|
||||
// See: https://github.com/knex/knex/issues/3176#issuecomment-3389054899
|
||||
let poolConfig = {
|
||||
@@ -316,7 +313,7 @@ class Database {
|
||||
}
|
||||
|
||||
config = {
|
||||
client: Dialect,
|
||||
client: "better-sqlite3",
|
||||
connection: {
|
||||
filename: Database.sqlitePath,
|
||||
acquireConnectionTimeout: acquireConnectionTimeout,
|
||||
@@ -326,9 +323,12 @@ class Database {
|
||||
...poolConfig,
|
||||
acquireTimeoutMillis: acquireConnectionTimeout,
|
||||
afterCreate: (rawConn, done) => {
|
||||
this.initSQLite(rawConn, testMode)
|
||||
.then(() => done(undefined, rawConn))
|
||||
.catch((err) => done(err, rawConn));
|
||||
try {
|
||||
this.initSQLite(rawConn, testMode);
|
||||
done(undefined, rawConn);
|
||||
} catch (err) {
|
||||
done(err, rawConn);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -447,35 +447,32 @@ class Database {
|
||||
|
||||
/**
|
||||
* Initialize SQLite for each connection
|
||||
* @param {any} rawConn The raw node-sqlite3 Database object
|
||||
* @param {import("better-sqlite3").Database} rawConn The raw better-sqlite3 Database object
|
||||
* @param {boolean} testMode Should the connection be started in test mode?
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async initSQLite(rawConn, testMode) {
|
||||
// Since rawConn.run is callback based, in order to avoid callback hell, wrap it in a promise
|
||||
const asyncRun = (sql) => {
|
||||
return new Promise((resolve, reject) => rawConn.run(sql, (err) => (err ? reject(err) : resolve())));
|
||||
};
|
||||
static initSQLite(rawConn, testMode) {
|
||||
// Required for legacy SQL patch files that use unsafe PRAGMAs (e.g. PRAGMA writable_schema)
|
||||
rawConn.unsafeMode(true);
|
||||
|
||||
if (testMode) {
|
||||
// Change to MEMORY
|
||||
await asyncRun("PRAGMA journal_mode = MEMORY");
|
||||
rawConn.exec("PRAGMA journal_mode = MEMORY");
|
||||
} else {
|
||||
// Change to WAL
|
||||
await asyncRun("PRAGMA journal_mode = WAL");
|
||||
rawConn.exec("PRAGMA journal_mode = WAL");
|
||||
}
|
||||
|
||||
await asyncRun("PRAGMA foreign_keys = ON");
|
||||
await asyncRun("PRAGMA cache_size = -12000");
|
||||
await asyncRun("PRAGMA auto_vacuum = INCREMENTAL");
|
||||
rawConn.exec("PRAGMA foreign_keys = ON");
|
||||
rawConn.exec("PRAGMA cache_size = -12000");
|
||||
rawConn.exec("PRAGMA auto_vacuum = INCREMENTAL");
|
||||
|
||||
// Avoid error "SQLITE_BUSY: database is locked" by allowing SQLITE to wait up to 5 seconds to do a write
|
||||
await asyncRun("PRAGMA busy_timeout = 5000");
|
||||
rawConn.exec("PRAGMA busy_timeout = 5000");
|
||||
|
||||
// This ensures that an operating system crash or power failure will not corrupt the database.
|
||||
// FULL synchronous is very safe, but it is also slower.
|
||||
// Read more: https://sqlite.org/pragma.html#pragma_synchronous
|
||||
await asyncRun("PRAGMA synchronous = NORMAL");
|
||||
rawConn.exec("PRAGMA synchronous = NORMAL");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,12 +20,9 @@ describe("Database Migration", () => {
|
||||
}
|
||||
|
||||
// Use the same SQLite driver as the project
|
||||
const Dialect = require("knex/lib/dialects/sqlite3/index.js");
|
||||
Dialect.prototype._driver = () => require("@louislam/sqlite3");
|
||||
|
||||
const knex = require("knex");
|
||||
const db = knex({
|
||||
client: Dialect,
|
||||
client: "better-sqlite3",
|
||||
connection: {
|
||||
filename: testDbPath,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user