読者です 読者をやめる 読者になる 読者になる

あのねノート

せんせいあのね、パソコンで字が書けるようになったよ

RacketでpostgreSQLをさわってみる

実験でjavapostgreSQLを使ってデータベースを用いたwebアプリケーションを作っているのですが、そういえばRacketでもそういうのできるって書いてた気がするなと思って少しだけやってみました。
Racketにはデータベースを扱うためのモジュールがあるので読みこんでもらいます。

(require db)

詳しくはドキュメントを見ましょう。わたしは最初の方しか読んでいませんし最初の方のことしかしていません。
DB: Database Connectivity
PostgreSQL,MySQL,SQLite,ODBCというのに対応しているみたいです。ここではPostgreSQLを使いますが接続のやり方が違うだけでSQLの実行は同じようにできそうです(要出典)。

ユーザー名、データベースの名前、パスワードを入れてデータベースに接続します。

(define 接続の名前
  (postgresql-connect #:user "ユーザー名"
                      #:database "データベース名"
                      #:password "パスワード"))

自分の設定に合わせて入れましょう。
あとは(query-exec 接続名 "実行したいSQL文")でとりあえず実行できます。結果はベクタのリストで返ってきます。
わたしは先に作ってあるデータベースを使ったのでselect文で試していますが、createもできます。

> (query pgc "select * from books limit 10")
(rows-result
 '(((name . "id") (typeid . 23) (type-size . 4) (type-mod . -1))
   ((name . "name") (typeid . 25) (type-size . -1) (type-mod . -1))
   ((name . "author") (typeid . 25) (type-size . -1) (type-mod . -1))
   ((name . "price") (typeid . 23) (type-size . 4) (type-mod . -1)))
 '(#(1 "813ae1" "d1e9bc" 2818)
   #(2 "4e3f48" "886a6d" 455)
   #(3 "fbaa38" "e0bbf2" 58)
   #(4 "571abf" "4a31bf" 1670)
   #(5 "9abd27" "6f5da6" 1375)
   #(6 "a0a9b0" "0693a0" 2242)
   #(7 "999d44" "f91e51" 1596)
   #(8 "b32aea" "3306cf" 1298)
   #(9 "d5d5ac" "437abc" 2867)
   #(10 "4a0f77" "9d166c" 1748)))

explain analyzeもできます。

> (query pgc "explain analyze select * from books order by price limit 10")
(rows-result
 '(((name . "QUERY PLAN") (typeid . 25) (type-size . -1) (type-mod . -1)))
 '(#("Limit  (cost=37979.64..37979.67 rows=10 width=22) (actual time=207.371..207.372 rows=10 loops=1)")
   #("  ->  Sort  (cost=37979.64..40479.64 rows=1000000 width=22) (actual time=207.370..207.370 rows=10 loops=1)")
   #("        Sort Key: price")
   #("        Sort Method: top-N heapsort  Memory: 25kB")
   #("        ->  Seq Scan on books  (cost=0.00..16370.00 rows=1000000 width=22) (actual time=0.016..95.671 rows=1000000 loops=1)")
   #("Planning time: 0.113 ms")
   #("Execution time: 207.396 ms")))

なんだか見にくいのでprintfを使います。

(for (((n d) (in-query pgc "select id, price from books limit 10")))
  (printf "~a: ~a\n" n d))

select文でとってきた2つの結果をそれぞれn,dとしてprintfで出力できるみたいです。

> (for (((n d) (in-query pgc "select id, price from books limit 10")))
  (printf "~a: ~a\n" n d))
1: 2818
2: 455
3: 58
4: 1670
5: 1375
6: 2242
7: 1596
8: 1298
9: 2867
10: 1748

取り急ぎここまでやりました。落ち着いたらちゃんとやりたいです。