diff --git a/server/database.js b/server/database.js index c9d9cc57..98494251 100644 --- a/server/database.js +++ b/server/database.js @@ -114,6 +114,7 @@ class Database { // Change to WAL await R.exec("PRAGMA journal_mode = WAL"); await R.exec("PRAGMA cache_size = -12000"); + await R.exec("PRAGMA auto_vacuum = FULL"); console.log("SQLite config:"); console.log(await R.getAll("PRAGMA journal_mode")); @@ -374,6 +375,17 @@ class Database { console.log("Nothing to restore"); } } + + static getSize() { + debug("Database.getSize()"); + let stats = fs.statSync(Database.path); + debug(stats); + return stats.size; + } + + static async shrink() { + await R.exec("VACUUM"); + } } module.exports = Database; diff --git a/server/server.js b/server/server.js index 49e867da..324ae677 100644 --- a/server/server.js +++ b/server/server.js @@ -119,6 +119,7 @@ module.exports.io = io; // Must be after io instantiation const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sendInfo } = require("./client"); const { statusPageSocketHandler } = require("./socket-handlers/status-page-socket-handler"); +const databaseSocketHandler = require("./socket-handlers/database-socket-handler"); app.use(express.json()); @@ -1295,6 +1296,7 @@ exports.entryPage = "dashboard"; // Status Page Socket Handler for admin only statusPageSocketHandler(socket); + databaseSocketHandler(socket); debug("added all socket handlers"); diff --git a/server/socket-handlers/database-socket-handler.js b/server/socket-handlers/database-socket-handler.js new file mode 100644 index 00000000..42fdb129 --- /dev/null +++ b/server/socket-handlers/database-socket-handler.js @@ -0,0 +1,37 @@ +const { checkLogin } = require("../util-server"); +const Database = require("../database"); + +module.exports = (socket) => { + + // Post or edit incident + socket.on("getDatabaseSize", async (callback) => { + try { + checkLogin(socket); + callback({ + ok: true, + size: Database.getSize(), + }); + } catch (error) { + callback({ + ok: false, + msg: error.message, + }); + } + }); + + socket.on("shrinkDatabase", async (callback) => { + try { + checkLogin(socket); + Database.shrink(); + callback({ + ok: true, + }); + } catch (error) { + callback({ + ok: false, + msg: error.message, + }); + } + }); + +}; diff --git a/src/pages/Settings.vue b/src/pages/Settings.vue index 9762da8d..e88f8605 100644 --- a/src/pages/Settings.vue +++ b/src/pages/Settings.vue @@ -231,13 +231,15 @@ {{ importAlert }} +

{{ $t("Advanced") }}

- + +
@@ -418,6 +420,7 @@ dayjs.extend(timezone); import { timezoneList, setPageLocale } from "../util-frontend"; import { useToast } from "vue-toastification"; +import { debug } from "../util.ts"; const toast = useToast(); @@ -427,6 +430,7 @@ export default { TwoFADialog, Confirm, }, + data() { return { timezoneList: timezoneList(), @@ -445,8 +449,16 @@ export default { importAlert: null, importHandle: "skip", processing: false, + databaseSize: 0, }; }, + + computed: { + databaseSizeDisplay() { + return Math.round(this.databaseSize / 1024 / 1024 * 10) / 10 + " MB"; + } + }, + watch: { "password.repeatNewPassword"() { this.invalidPassword = false; @@ -460,6 +472,7 @@ export default { mounted() { this.loadSettings(); + this.loadDatabaseSize(); }, methods: { @@ -592,7 +605,33 @@ export default { autoGetPrimaryBaseURL() { this.settings.primaryBaseURL = location.protocol + "//" + location.host; + }, + + shrinkDatabase() { + this.$root.getSocket().emit("shrinkDatabase", (res) => { + if (res.ok) { + this.loadDatabaseSize(); + toast.success("Done"); + } else { + debug(res); + } + }); + }, + + loadDatabaseSize() { + debug("load database size"); + this.$root.getSocket().emit("getDatabaseSize", (res) => { + + if (res.ok) { + this.databaseSize = res.size; + debug("database size: " + res.size); + } else { + debug(res); + } + + }); } + }, };