昨日は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 | QiitaでClojureタグが付けられた新着記事
feed=# select * from article;
id | feed_id | title | url | content | author | published_at
----+---------+-----------------------------------------------------------+-------------------------------------------------------+----------------------------------------------------+--------+---------------------------
1 | 1 | Clojure: DuctでRSSリーダーを作る - 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: DuctでRSSリーダーを作る - 環境変数 | 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を表現できていいですね