2019/04/01

Common LispでSQLite3

cl-dbi

ちょっとずつ進めているCommon Lispの勉強ですが、時々欲していたデータベース、特にPythonで気軽に使えていたSQLite3をCommon Lispでも使いたいという思いがあり、色々調べていたところ、著名なLisperの深町さんが作成なさったcl-dbiというライブラリを発見しました。早速使わせていただこうということで、ソースコードを眺める。
Lisp初心者な私ですが、test.lispで何となく使い方を掴む。

* (ql:quickload :cl-dbi)
To load "cl-dbi":
  Load 1 ASDF system:
    cl-dbi
; Loading "cl-dbi"

(:CL-DBI)
* (defvar *db* (dbi:connect :sqlite3 :database-name "/home/masahiko/cl_dev/books.db")
)
*DB*
* (dbi:do-sql *db* "CREATE TABLE books (title VARCHAR(50), author VARCHAR(100))")
* (dbi:do-sql *db* "INSERT INTO books (title, author) VALUES ('Harry Potter', 'J.K.Rolling')")
* (dbi:disconnect *db*)
#<SQLITE:SQLITE-HANDLE {1003872E83}>
* (quit)

早速sqlite3で内容を確認してみる。なぜ「Harry Potter」かは気にしないでください。なぜか最初に思い浮かぶ本がこれなだけで、持っているわけではありません。本屋時代、良くも悪くもこの本に売上を大きく左右されたから、印象に残っているだけです。そう、第3・4巻あたりまでは良かったんです。確かある巻から2冊セットになり、それでもバカ売れする「Harry Potter」を書店員はきっと、救世主と崇めたことでしょう。その次のセットから買い切り商品となりました。そして、書店員は前作までの売れ行きから予想して、欲しい冊数を申し込みました。私がいた中規模いや小規模の書店ですら、100冊近くを申し込みました。大規模書店ならもっとでしょう。「救世主なのだから大丈夫!」きっと全書店員がそう思ったことでしょう。いざ開けてみると「えっ!?半分残った……」という状態に。1セット4~5000円くらいだったと思います。掛けることの50冊、25万!
薄利多売な書店で25万をリカバーすることの大変さたるやもう、という状態。
救世主はいなかった。ニーチェが頭に浮かぶ。「神は死んだ」
それはそれとして、cl-dbiを使った結果を確認。

$ sqlite3 books.db
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
sqlite> .mode column
sqlite> .headers on
sqlite> SELECT * FROM books;
title         author     
------------  -----------
Harry Potter  J.K.Rolling
sqlite> .quit

問題なくデータを格納できました。深町さんに感謝。
またwith-connectionという、Pythonのwith文のように自動で接続を切る関数もありました。使いやすい印象を受けたので、もう少し詳しく勉強しようと思います。

追記

本を管理するパッケージを作ってみました。まだ途中ですが、GitHubに置いておきます。my-book-shelf
機能としては、ごく単純で本のタイトル・著者・出版社・ISBNをデータとして保存します。それらから検索できるようにする予定です。自分で使う際は、著者検索が便利かなと思い、とりあえずそれだけ実装してあります。

追記2

タイトル・著者名・出版社・ISBNで検索できるようにしました。