(feat): warn on duplicate IDs and refs rather than fail (#854)

Instead of having db update operations fail, a useful error is shown, and the db updates complete. Closes #816.
This commit is contained in:
Jethro Kuan
2020-06-21 17:00:20 +08:00
committed by GitHub
parent 408e38f8ba
commit 11e0aa4c55
2 changed files with 46 additions and 23 deletions

View File

@ -14,6 +14,8 @@
### Bugfixes
- [#854](https://github.com/org-roam/org-roam/pull/854) Warn instead of fail when duplicate refs and IDs exist.
## 1.2.0 (12-06-2020)
In this release, we improved the linking process by achieving feature parity between links to files and links to headlines. Before, we used the `file:foo::*bar` format to link to the headline `bar` in file `foo`, but this was prone to breakage upon renaming the file or modifying the headline. This is not the case anymore. Now, we use `org-id` to create IDs for those headlines, which are then stored in our database to compute the relationships and jump around. Note that this will work even if youre not using `org-id` in your global configuration for Org-mode.

View File

@ -240,11 +240,25 @@ This is equivalent to removing the node from the graph."
(list (vector file titles))))
(defun org-roam-db--insert-headlines (headlines)
"Insert HEADLINES into the Org-roam cache."
"Insert HEADLINES into the Org-roam cache.
Returns t if the insertion was successful, nil otherwise.
Insertions can fail when there is an ID conflict."
(condition-case nil
(progn
(org-roam-db-query
[:insert :into headlines
:values $v1]
headlines))
headlines)
t)
(error
(unless (listp headlines)
(setq headlines (list headlines)))
(lwarn '(org-roam) :error
(format "Duplicate IDs in %s, one of:\n\n%s\n\nskipping..."
(aref (car headlines) 1)
(string-join (mapcar (lambda (hl)
(aref hl 0)) headlines) "\n")))
nil)))
(defun org-roam-db--insert-tags (file tags)
"Insert TAGS for a FILE into the Org-roam cache."
@ -254,12 +268,27 @@ This is equivalent to removing the node from the graph."
(list (vector file tags))))
(defun org-roam-db--insert-ref (file ref)
"Insert REF for FILE into the Org-roam cache."
"Insert REF for FILE into the Org-roam cache.
Returns t if successful, and nil otherwise.
Insertions can fail if the key is already in the database."
(let ((key (cdr ref))
(type (car ref)))
(condition-case nil
(progn
(org-roam-db-query
[:insert :into refs :values $v1]
(list (vector key file type)))))
(list (vector key file type)))
t)
(error
(lwarn '(org-roam) :error
(format "Duplicate ref %s in:\n\nA: %s\nB: %s\n\nskipping..."
key
file
(caar (org-roam-db-query
[:select file :from refs
:where (= ref $v1)]
(vector key)))))
nil))))
;;;;; Fetching
(defun org-roam-db--get-current-files ()
@ -440,12 +469,9 @@ If FORCE, force a rebuild of the cache from scratch."
:values $v1]
(vector file contents-hash (list :atime atime :mtime mtime)))
(setq file-count (1+ file-count))
(when-let (headlines (org-roam--extract-headlines file))
(org-roam-db-query
[:insert :into headlines
:values $v1]
headlines)
(setq headline-count (1+ headline-count))))))))
(when-let ((headlines (org-roam--extract-headlines file)))
(when (org-roam-db--insert-headlines headlines)
(setq headline-count (1+ headline-count)))))))))
;; Second step: Rebuild the rest
(dolist (file org-roam-files)
(org-roam--with-temp-buffer file
@ -470,14 +496,9 @@ If FORCE, force a rebuild of the cache from scratch."
:values $v1]
(vector file titles))
(setq title-count (1+ title-count)))
(when-let* ((ref (org-roam--extract-ref))
(type (car ref))
(key (cdr ref)))
(org-roam-db-query
[:insert :into refs
:values $v1]
(vector key file type))
(setq ref-count (1+ ref-count))))
(when-let* ((ref (org-roam--extract-ref)))
(when (org-roam-db--insert-ref file ref)
(setq ref-count (1+ ref-count)))))
(remhash file current-files))))
(dolist (file (hash-table-keys current-files))
;; These files are no longer around, remove from cache...