0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【ひとりカレンダー】ClojureAdvent Calendar 2024

Day 24

Clojure: DuctでRSSリーダーを作る - HoneySQLその2

Last updated at Posted at 2024-12-23

advent_calendar_2024.png

Advent Calendar 2024 Day 24

昨日はHoneySQLを導入し、SQLクエリをClojureのデータ構造(マップやベクター)として構築できるようになりました

今日は親子関係の関係をもつDBにデータをinsertしたりデータを取得してみます

insert クエリを作る

まずはinsert-intoのSQLを作ってみたいと思います

HoneySQLがインポートされたREPLで作業していきます

作成するfeed, articleのテーブルは以下のようなものです

feed

Column Type Default
id int nextval
url text
title text
description text

article

Column Type Default
id int nextval
feed_id text
title text
url text
content text
author text
published_at text
created_at text current_timestamp

では実装します。

REPL
; feed
(sql/format {:insert-into
             :feed
             :columns [:url :title :description]
             :values [{:url "url" :title "title" :description "description"}]})
["INSERT INTO feed (url, title, description) VALUES (?, ?, ?)" "url" "title" "description"]

; article
(sql/format {:insert-into
             :article
             :columns [:feed_id :title :url :content :author :published]
             :values [{:feed_id "feed_id" :title "title" :url "url" :content "content" :author "author" :published_at "published"}]})
["INSERT INTO article (feed_id, title, url, content, author, published) VALUES (?, ?, ?, ?, ?, ?)"
 "feed_id"
 "title"
 "url"
 "content"
 "author"
 "published"]

このように実装できました。

これを関数にし、外からデータを受け取れるようにします。

REPL
(defn insert-feed [{:keys [url title description]}]
  (sql/format {:insert-into
               :feed
               :columns [:url :title :description]
               :values [{:url url :title title :description description}]
               :returning [:id]}))

(insert-feed {:url "http://example.com" :title "example" :description "example description"})
["INSERT INTO feed (url, title, description) VALUES (?, ?, ?) RETURNING id"
 "http://example.com"
 "example"
 "example description"]

(defn insert-article [{:keys [feed_id title url content author published]}]
  (sql/format {:insert-into
               :article
               :columns [:feed_id :title :url :content :author :published]
               :values [{:feed_id feed_id :title title :url url :content content :author author :published published}]}))

(insert-article {:feed_id 1 :title "example" :url "http://example.com" :content "example content" :author "example author" :published "2024-12-23 19:55:10.062472"})
["INSERT INTO article (feed_id, title, url, content, author, published) VALUES (?, ?, ?, ?, ?, ?)"
 1
 "example"
 "http://example.com"
 "example content"
 "example author"
 "2024-12-23 19:55:10.062472"]

いい感じですね

insert 実行

では実行してDBにちゃんと入るか確認します

(defn insert-article [{:keys [feed_id title url content author published]}]
  (sql/format {:insert-into
               :article
               :columns [:feed_id :title :url :content :author :published_at]
               :values [{:feed_id feed_id :title title :url url :content content :author author :published_at published}]}))

(defn register-articles [db {:keys [feed_id items]}]
  (doall (map #(jdbc/execute! db (insert-article (assoc % :feed_id feed_id))) items)))

(defn insert-feed [{:keys [url title description]}]
  (sql/format {:insert-into
               :feed
               :columns [:url :title :description]
               :values [{:url url :title title :description description}]
               :returning [:id]}))

(defn register-feed [db feed-data]
  (let [feed-ids (jdbc/execute! db (insert-feed feed-data) {:builder-fn rs/as-unqualified-lower-maps})
        id (-> feed-ids first :id)]
    (register-articles db (assoc feed-data :feed_id id))))
(register-feed db data)

DBを確認します

feed=# select * from feed;
 id |                 url                 |                  title                  |              description               
----+-------------------------------------+-----------------------------------------+----------------------------------------
  1 | https://qiita.com/tags/clojure/feed | Clojureタグが付けられた新着記事 - Qiita | QiitaClojureタグが付けられた新着記事

feed=# select * from article;
 id | feed_id |                           title                           |                          url                          |                      content                       | author |       published_at        
----+---------+-----------------------------------------------------------+-------------------------------------------------------+----------------------------------------------------+--------+---------------------------
  1 |       1 | Clojure: DuctRSSリーダーを作る - HoneySQL               | https://qiita.com/maaaashi/items/5d9f5d8ced8c5f0ecad5 |                                                   +|        | 2024-12-23T07:04:04+09:00
    |         |                                                           |                                                       | Advent Calendar 2024 Day 23                       +|        | 
    |         |                                                           |                                                       | 昨日は環境変数を扱いました。                      +|        | 
    |         |                                                           |                                                       | 今日はよりDBからのデータ取得周りを改善してみます  +|        | 
    |         |                                                           |                                                       | HoneySQLというSQLクエリをClojureのデータ…          |        | 
  2 |       1 | Clojure: DuctRSSリーダーを作る - 環境変数               | https://qiita.com/maaaashi/items/525d676aba72872aac19 |                                                   +|        | 2024-12-22T07:03:53+09:00
    |         |                                                           |                                                       | Advent Calendar 2024 Day 22                       +|        | 
    |         |                                                           |                                                       | 昨日は以下のようにDB接続を設定しました。          +|        | 
    |         |                                                           |                                                       |   :duct.database.sql/hikaricp                     +|        | 
    |         |                                                           |                                                       |   {:adapter "postgresq…                            |        | 
  3 |       1 | Clojure: DuctでRSSリーダーを作る - DB接続(HikariCP, Jdbc) | https://qiita.com/maaaashi/items/32fee6a9b924d31e4c9a |                                                   +|        | 2024-12-21T23:45:41+09:00
    |         |                                                           |                                                       | Advent Calendar 2024 Day 21                       +|        | 
    |         |                                                           |                                                       | 昨日はDuctでルーティングを実装しました            +|        | 
    |         |                                                           |                                                       | 今日はDB接続したいと思います。                    +|        | 
    |         |                                                           |                                                       |                                                   +|        | 
    |         |                                                           |                                                       | 今回の記事ではpostgresqlに接続しますが、          +|        | 
    |         |                                                           |                                                       | DBの立ち…                                          |        | 
  4 |       1 | Clojure: DuctでRSSリーダーを作る - ルーティング           | https://qiita.com/maaaashi/items/a5dac663b974082dba9c |                                                   +|        | 2024-12-20T07:04:07+09:00
    |         |                                                           |                                                       | Advent Calendar 2024 Day 20                       +|        | 
    |         |                                                           |                                                       | 昨日はDuctでプロジェクトのセットアップをしました。+|        | 
    |         |                                                           |                                                       | 今日はataraxyのルーティングを実装してみます       +|        | 
    |         |                                                           |                                                       | Ataraxy                                           +|        | 
    |         |                                                           |                                                       | Ataraxyは…                                         |        | 

いい感じでデータを投入することができました

次に投入したデータを取得してみます

select クエリを作る

feedテーブルからデータを取得するクエリ
select * from feed;
と、articleテーブルから、feed_idで絞ってデータを取得するクエリ
select * from article where feed_id = ?を作ってみます

(def select-feeds (sql/format {:select [:*]
                               :from [:feed]}))

(defn select-articles [{:keys [id]}]
  (sql/format {:select [:*]
               :from [:article]
               :where [:= :feed_id id]}))

こんな感じで作ってみました

select 実行

(def select-feeds (sql/format {:select [:*]
                               :from [:feed]}))

(defn select-articles [{:keys [id]}]
  (sql/format {:select [:*]
               :from [:article]
               :where [:= :feed_id id]}))

(defn get-feeds [db]
  (let [feeds (jdbc/execute! db select-feeds {:builder-fn rs/as-unqualified-lower-maps})
        feeds-articles (map #(->> (jdbc/execute! db (select-articles %) {:builder-fn rs/as-unqualified-lower-maps})
                                 (assoc % :articles)) feeds)]
    {:feeds feeds-articles}))

こんな感じで実装してみました。

昨日に引き続きHoneySQLを触ってみましたが、生のSQLを書かずにデータ構造でSQLを表現できていいですね

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?