CLCLCLのDBアクセスに、clojure.contrib.sqlを使うようにした

CLCLCLは、クリップボード履歴ツールです。

https://sourceforge.net/projects/clclcl/

最初のバージョンでは、データベース(Derby)への接続には、JDBCのクラスを直に参照してましたが、逆引きClojureを参考に、clojure.contrib.sqlを使うように変更しました。

DBを使いたい

インメモリで使えるDBとしてHyperSonicを使います。

DBを使いたい – 逆引きClojure

ソースの一部です。clojure.contrib.sqlの雰囲気がわかると思います。clojure.contrib.sqlには既にwith系マクロが用意されてるので、JDBC版の時に自分で書いたマクロは、不要になったので削除した。

(ns clclcl.database
(:gen-class)
(:use clojure.contrib.logging clojure.contrib.sql clclcl.utils)
(:import [org.apache.derby.jdbc EmbeddedDriver]
[java.sql SQLException]
[java.io File]))
(impl-get-log (str *ns*))
(def *database-path* (str (System/getenv "HOME") "/.clclcl/clclcl"))
(def *db* {:classname "org.apache.derby.jdbc.EmbeddedDriver"
:subprotocol "derby"
:subname *database-path*})
(defn db-delete-clipboard-data [s]
(with-connection *db*
(delete-rows :clipboard_data ["data=?" s])))
(defn db-insert-clipboard-data [s]
(with-connection *db*
(insert-values :clipboard_data [:data] [s])))
(defn db-select-clipboard-data [{list-max :list-max}]
(with-connection *db*
;bind parameter(?) got syntax error. so use String.format.
(with-query-results rs [(format "select * from clipboard_data order by id desc fetch first %d rows only" list-max)]
(doall rs))))

with-query-results問題Derbyのバインド変数問題

本当は、with-query-resultsを使うとき、パラメータ(?にバインドする値)を渡すようにしたかったんですが「Syntax error: Encountered “?”」というエラーが発生(DerbyのJDBC実装の中で発生している様子)。 数値以外入りえない箇所だったので、stringのformatでお茶を濁してあります。with-query-resultsで検索してもパラメータを渡してない簡単なサンプルはいくつか見つかるけど、パラメータも使っているようなサンプルが見付からず、with-query-results*のソースを見てもよくわからなかったので、逃げてしまいました。

もっと拡張をしていく時に、多分また同じ壁にぶつかるので、その時挑戦しよう。

追記2010/08/12

where句の?には、問題なくバインドすることができました。ということは、clojure.contrib.sqlの問題ではなく、DerbyのSQL解析でfetch句(というのかわからないがDerbyで検索結果取得数を制限する方法)に、バインド変数を指定することはできないという問題でした。これが仕様なのバグなのかは、Derbyのソースを見ないとなんともいえなさそう。(続くかな)

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください