mirror of https://github.com/logseq/logseq
enhance: backup files when there're differences between db and disk
Previously, files are backuped to logseq/bak when logseq detects there're differences between the db and disk. But it has two problems: 1. Only a few of users know `logseq/bak`, other users think that their data has been lost. 2. Files in the logseq/bak folder are never truncated. This PR backups old file in DB with timestamp suffixes instead of logesq/bak, and only keep the latest 10 versions of any changed file.pull/4486/head
parent
2e46a6bcb7
commit
8e6fb5613d
|
@ -32,6 +32,7 @@
|
|||
"semver": "7.3.5",
|
||||
"update-electron-app": "2.0.1",
|
||||
"extract-zip": "2.0.1",
|
||||
"diff-match-patch": "1.0.5",
|
||||
"https-proxy-agent": "5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
["fs-extra" :as fs-extra]
|
||||
["path" :as path]
|
||||
["os" :as os]
|
||||
["diff-match-patch" :as google-diff]
|
||||
[electron.fs-watcher :as watcher]
|
||||
[electron.configs :as cfgs]
|
||||
[promesa.core :as p]
|
||||
|
@ -16,7 +17,8 @@
|
|||
[electron.search :as search]
|
||||
[electron.git :as git]
|
||||
[electron.plugin :as plugin]
|
||||
[electron.window :as win]))
|
||||
[electron.window :as win]
|
||||
[goog.object :as gobj]))
|
||||
|
||||
(defmulti handle (fn [_window args] (keyword (first args))))
|
||||
|
||||
|
@ -56,21 +58,36 @@
|
|||
new-path (str recycle-dir "/" file-name)]
|
||||
(fs/renameSync path new-path))))
|
||||
|
||||
(defonce Diff (google-diff.))
|
||||
(defn string-some-deleted?
|
||||
[old new]
|
||||
(let [result (.diff_main Diff old new)]
|
||||
(some (fn [a] (= -1 (first a))) result)))
|
||||
|
||||
(defn- truncate-old-versioned-files!
|
||||
[file-path]
|
||||
(let [dir (path/dirname file-path)
|
||||
files (fs/readdirSync dir (clj->js {:withFileTypes true}))
|
||||
files (map #(.-name %) files)
|
||||
prefix (str (path/basename file-path) ".")
|
||||
versioned-files (filter #(string/starts-with? % prefix) files)
|
||||
old-versioned-files (drop 10 (reverse (sort versioned-files)))]
|
||||
(doseq [file old-versioned-files]
|
||||
(fs-extra/removeSync (path/join dir file)))))
|
||||
|
||||
(defn backup-file
|
||||
[repo path content]
|
||||
(let [file-name (-> (string/replace path (str repo "/") "")
|
||||
(string/replace "/" "_")
|
||||
(string/replace "\\" "_"))
|
||||
bak-dir (str repo "/logseq/bak")
|
||||
_ (fs-extra/ensureDirSync bak-dir)
|
||||
new-path (str bak-dir "/" file-name "."
|
||||
(string/replace (.toISOString (js/Date.)) ":" "_"))]
|
||||
(let [new-path (str path "." (string/replace (.toISOString (js/Date.)) ":" "_"))]
|
||||
(fs/writeFileSync new-path content)
|
||||
(fs/statSync new-path)
|
||||
(truncate-old-versioned-files! path)
|
||||
new-path))
|
||||
|
||||
(defmethod handle :backupDbFile [_window [_ repo path db-content]]
|
||||
(backup-file repo path db-content))
|
||||
(defmethod handle :backupDbFile [_window [_ repo path db-content new-content]]
|
||||
(when (and (string? db-content)
|
||||
(string? new-content)
|
||||
(string-some-deleted? db-content new-content))
|
||||
(backup-file repo path db-content)))
|
||||
|
||||
(defmethod handle :readFile [_window [_ path]]
|
||||
(utils/read-file path))
|
||||
|
@ -80,7 +97,7 @@
|
|||
(assert (string? path))
|
||||
(try
|
||||
(fs/accessSync path (aget fs "W_OK"))
|
||||
(catch js/Error _e
|
||||
(catch :default _e
|
||||
false)))
|
||||
|
||||
(defmethod handle :writeFile [_window [_ repo path content]]
|
||||
|
@ -93,10 +110,10 @@
|
|||
(fs/chmodSync path "644"))
|
||||
(fs/writeFileSync path content)
|
||||
(fs/statSync path)
|
||||
(catch js/Error e
|
||||
(catch :default e
|
||||
(let [backup-path (try
|
||||
(backup-file repo path content)
|
||||
(catch js/Error e
|
||||
(catch :default e
|
||||
(println "Backup file failed")
|
||||
(js/console.dir e)))]
|
||||
(utils/send-to-renderer "notification" {:type "error"
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
(defn- handle-add-and-change!
|
||||
[repo path content db-content mtime backup?]
|
||||
(p/let [
|
||||
;; save the previous content in a bak file to avoid data overwritten.
|
||||
_ (when backup? (ipc/ipc "backupDbFile" (config/get-local-dir repo) path db-content))
|
||||
;; save the previous content in a versioned bak file to avoid data overwritten.
|
||||
_ (when backup? (ipc/ipc "backupDbFile" (config/get-local-dir repo) path db-content content))
|
||||
_ (file-handler/alter-file repo path content {:re-render-root? true
|
||||
:from-disk? true})]
|
||||
(set-missing-block-ids! content)
|
||||
|
|
|
@ -1529,6 +1529,11 @@ detect-node@^2.0.4:
|
|||
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
|
||||
integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
|
||||
|
||||
diff-match-patch@1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37"
|
||||
integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==
|
||||
|
||||
dir-compare@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/dir-compare/-/dir-compare-2.4.0.tgz#785c41dc5f645b34343a4eafc50b79bac7f11631"
|
||||
|
|
Loading…
Reference in New Issue