Skip to content

Instantly share code, notes, and snippets.

@jgreco
Created August 26, 2019 07:29
Show Gist options
  • Save jgreco/7fa7f832e70e8d2e3c09170915bbb207 to your computer and use it in GitHub Desktop.
Save jgreco/7fa7f832e70e8d2e3c09170915bbb207 to your computer and use it in GitHub Desktop.
;; Remove a given tag from a set of file ids.
;; If any of the file ids is not tagged with the given tag, they are silently skipped
;; without hassling the user. If a tag is empty after this operation, it is deleted.
;;
;; TODO: This procedure performs up to three database writes. If those writes
;; happened to be interleaved with other writes which are associated with
;; the same tag, screwy things might happen. Therefore these two/three
;; writes should be performed in a single transaction.
(define (untag-files tag . file-ids)
(let* ([tag-id (get-tag-id tag)]
[files-with-tags (map cons file-ids (apply get-tags-for-files file-ids))]
[files-with-our-tag (filter (lambda (f) (member? tag (cdr f))) files-with-tags)])
(for ([f files-with-our-tag])
(sql-write 'exec "DELETE FROM FileTags WHERE file_id=? AND tag_id=? AND probability=1" (car f) tag-id)
(sql-write 'exec "UPDATE Files SET num_tags = num_tags - 1 WHERE file_id=?" (car f)))
(invalidate-memo/partial get-tag-size tag)
(when (zero? (get-tag-size tag))
(sql-write 'exec "DELETE FROM Tags WHERE tag_id=?" tag-id))
;; TODO: fire plugins with tag and `files-with-our-tag` (which now do not have it.)
))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment