ホーム  |  製品 & サービス   |  サポート & ダウンロード  |  開発者向け情報  |  お問い合わせ
人生に地図はない
cl-sql を使う

ここだけみてなんとか pgsql にアクセスできました。 簡易O/R Mapper なことができるらしい。

私は asdf でインストールし(インストールの過程でやたらエラーが出る。これは mysql がないなどのエラー。mysql はインストールしていないから当たり前。無視して先に進んで postgresql で使う事が出来ました。)

* (require :asdf)
* (asdf:oos 'asdf:load-op :clsql)
* (clsql:connect '("host" "db" "user" "pass") :database-type :postgresql)
* (clsql:query "select * from table")

ここでは postgresql を使いました。postgresql-socket というのもあります。こちらはソケットインターフェースを使っています。cffi を使っていないので(おそらく) postgresql の C のライブラリがなくても動作するのでしょう(未確認)

日本語の扱い

clsql はEUC-JP の日本語をうまく扱ってくれません。UTF-8 なら大丈夫でした。私が使っている既存の DB は EUC-JP で格納しているのでうまくできませんでした。select した結果に EUC-JP が混じっているとエラーになります。

そこで、cffi を使い無理やり postgresql で変換してみました。PQsetClientEncoding は postgresql が持つ C の変換ルーチン。

(uffi:def-function ("PQsetClientEncoding" PQsetClientEncoding)
((conn pgsql-conn)
(encoding :cstring))
:module "postgresql"
:returning :int)

pgsql-conn が曲者です。
sql/database.lisp を読むと

(defvar *connected-databases* nil
"List of active database objects.")

ここにdatabase群が入っています。pool になっているようです。 *default-database* が使える database です。あるいは clsql:connect での返り値。こちらの方がスマートか。

postgresql の database の記述は

(defclass postgresql-database (generic-postgresql-database)
((conn-ptr :accessor database-conn-ptr :initarg :conn-ptr
:type pgsql-conn-def)
(lock
:accessor database-lock
:initform (make-process-lock "conn"))))

となっていて :accessor の conn-ptr を使うことにより、database の内部の固有情報にアクセスできます。

(PQsetClientEncoding  (database-conn-ptr *default-database*) "EUC-JP")

これでうまく select からの結果を扱えるはず、、、、と思ったら、どうやら clsql の変換は抜けているが、今度はシステムの変換に引っかかるらしい。

これは sbcl を立ち上げるときに LANG を ja_JP.UTF-8 を設定すればよさそう。
あるいは LC_TYPE か?

そんなことしなくても、UTF-8 に統一すれば動きます。はい。

参考:

なお日本語扱いについては


http://lispuser.net/commonlisp/japanese.html

によくまとまっている。


sbcl には sb-ext: で始まる encoding の指定があるようだが、、、、今のところ私はうまく使えていない。