diff options
author | Masaya Tojo <masaya@tojo.tokyo> | 2024-03-24 21:13:56 +0900 |
---|---|---|
committer | Masaya Tojo <masaya@tojo.tokyo> | 2024-03-24 21:14:52 +0900 |
commit | ef3bde22daa1f6f25300f6c5eba0684fb8e8111b (patch) | |
tree | 8907016c4f262c183aef3fe28a07027890573ba3 | |
parent | aa998886fc0762c221ea41af68a0490c45bb7cba (diff) |
Add a script for registering articles.
-rw-r--r-- | scripts/register-articles.rkt | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/scripts/register-articles.rkt b/scripts/register-articles.rkt new file mode 100644 index 0000000..41a9ce5 --- /dev/null +++ b/scripts/register-articles.rkt @@ -0,0 +1,88 @@ +#lang typed/racket + +(require typed/db) +(require "../entities/article.rkt") +(require "../db/connection.rkt") +(require "../db/articles.rkt") +(require "../db/tags.rkt") +(require "../readers/article.rkt") + +(: make-db-conn (-> String String Connection)) +(define (make-db-conn database user) + (connect #:database database #:user user #:socket 'guess)) + +(: register-articles (-> Connection Path-String Void)) +(define (register-articles db-conn path) + (define article-hashes (fetch-article-hashes db-conn)) + (call-with-input-file path + (lambda ([in : Input-Port]) + (for/fold + ([tag-ids : (Immutable-HashTable String Integer) + (fetch-tag-ids db-conn)]) + ([article (in-port read-article in)]) + (cond + [(hash-ref article-hashes (article-id article) #f) + => (lambda ([h : String]) + (cond + [(string=? h (article-hash article)) tag-ids] + [else + (update-article db-conn article) + (begin0 (register-tags db-conn article tag-ids) + (displayln (format "updated: ~a, ~a" + (article-id article) + (article-title article))))]))] + [else + (insert-article db-conn article) + (begin0 (register-tags db-conn article tag-ids) + (displayln (format "registered: ~a, ~a" + (article-id article) + (article-title article))))])))) + (void)) + +(: register-tags (-> Connection + Article-With-Tags + (Immutable-HashTable String Integer) + (Immutable-HashTable String Integer))) +(define (register-tags db-conn article tag-ids) + (define (register-new-tags) + (for/fold ([s : (Setof Integer) + (set)] + [tag-ids : (Immutable-HashTable String Integer) + tag-ids] + [taggings : (Setof Integer) + (fetch-article-taggings db-conn (article-id article))]) + ([tag (article-tags article)]) + (cond [(hash-ref tag-ids tag #f) + => (lambda ([tag-id : Integer]) + (values (set-add s tag-id) + tag-ids + taggings))] + [else + (let ([tag-id : Integer (insert-tag db-conn tag)]) + (insert-article-tagging db-conn (article-id article) tag-id) + (values (set-add s tag-id) + (hash-set tag-ids tag tag-id) + (set-add taggings tag-id)))]))) + (let-values ([(current-tag-ids tag-ids taggings) + (register-new-tags)]) + (for ([tag-id (in-set (set-subtract taggings current-tag-ids))]) + (delete-article-tagging db-conn (article-id article) tag-id)) + tag-ids)) + +(module+ main + (require racket/cmdline) + (define database (box "diary")) + (define username (box "postgres")) + (command-line #:program "register-articles" + #:once-each + [("-d" "--database") name + "Database name" + (set-box! database (assert name string?))] + [("-u" "--user") name + "Username" + (set-box! username (assert (assert name string?)))] + #:args (filename) + (let ([db-conn (make-db-conn (unbox database) (unbox username))]) + (call-with-transaction db-conn + (thunk + (register-articles db-conn (assert filename string?))))))) |