日曜プログラミング

休日趣味でやってるプログラミング関連記事をダラダラと

datomic を試してみる(番外) - SQL Database Storage 化失敗編

元々こっちを最初に試してたのだが、transactor から SQL DB への接続が上手くいってなないので途中で諦めた残骸。
結構な時間ハマって結局上手く行っていない。
誰かが助けてくれるかもと言う期待を込めてここに置いておく。

【失敗】SQL DB を Storage 化する(Provisioning a SQL database)

これをやる手順は以下のようになると最初に書いてある。

  1. SQL DB をセットアップするか、既存のを使う
  2. SQL Table を作成する(datomic_kvs)
  3. SQL ユーザを作成するか既存のを使う
  4. JDBC 接続文字列を取得する

1,3 に関しては自分は既存のを使う方を選択するので割愛。

SQL Table を作成する

最初の手順概要にあった 3 相当。~\bin\sql 以下に各 RDBMS
でセットアップに必要な sql スクリプトがあり、Oracle だと oracle-table.sql を実行。

ここでは 4 については特に触れられてなかったが別に特殊なものでもないんだろう。

評価キーインストール(Install your licence key)

プロパティファイルにキーを入れてね、とあるが、config/samples にあるものを触ればいいのかな。
とりあえず sql-transactor-template.properties を sql-transactor.properties にリネームコピ
ーして以下のエントリを編集。

license-key=(もらった評価キー)

もらった評価キーは 6 行になってるが、バックスラッシュで改行をエスケープしてるっぽいのでそのまま貼り付ける。

【失敗】transactor を起動する(SQL 時)

transactor って何さってのは詳しくは最初の紹介記事リンク先を読んでもらうとして、まだ入れる
前の時点での自分の認識は Storage に対する書込とインデクシングを担当する別プロセスと言うも
の。

で、手順だが、ああ、さっきのプロパティファイルってここで使うのか。
それとさっき飛ばしていた SQL DB とユーザの指定っぽい設定項目もプロパティファイルにあった。
JDBC のドライバクラスの指定もきっと要るので一緒に指定。

################################################################
# See http://docs.datomic.com/storage.html

sql-url=jdbc:oracle:thin:@//localhost:1521/TEST
sql-user=hoge
sql-password=fuga

# The Postgres driver is included with Datomic. For other SQL
# databases, you will need to install the driver on the
# transator classpath, by copying the file into lib/,
# and place the driver on your peer's classpath.
sql-driver-class=oracle.jdbc.driver.OracleDriver

と言うかこの指定って DB やユーザを新たに作成しても一緒なような。
あ、URL やユーザ・パス・JDBC ドライバクラスは自身が使うものに適時置き換えたって下さい。

また、プロパティファイルのコメント見ると書いてあるんだが、transactor 動かすには指定した
RDBMS のドライバを lib 以下に入れてねとあるのでそれに従い ojdbc をコピる。

ではいよいよ起動。
以下のように設定・保存したプロパティファイルを指定した上で起動する。

> bin\transactor config\sql-transactor.properties
'data-dir' property not set, defaulting to 'data' in current directory
'log-dir' property not set, defaulting to 'log' in current directory
************** This system is running in evaluation mode. For a production license, go to http://datomic.com. ****************
Starting datomic:sql://<DB-NAME>?jdbc:oracle:thin:@//localhost:1521/TEST?user=hoge&password=fuga, you may need to change the user and password parameters to work with your jdbc driver ...
System started datomic:sql://<DB-NAME>?jdbc:oracle:thin:@//localhost:1521/TEST?user=hoge&password=fuga, you may need to change the user and password parameters to work with your jdbc driver

ドキュメントによれば System started って出てれば OK とあるがこれ本当に DB と繋がってるんかね?
まあ次の手順で分かるか。

datomic_kvs を覗いてみる

ここでふと寄り道。テーブルにもう何か入ってるのかなと覗いてみた。

SELECT id, rev, DBMS_LOB.SUBSTR(map,2000,1), DBMS_LOB.SUBSTR(val,2000,1) AS VAL
  FROM datomic_kvs

何やら 1 行入ってた。何なんだろこれ。

transactor に接続する(Connecting to the transactor)

親切な事に起動した transactor にちゃんとつなげるかどうかだけであれば JavaClojure のソ
ースを書かなくても良く Java のシェルなるものが用意されててそれで確認できる。

bin\shell.cmd がそれなのでダブルクリックして早速試す。*1

んー動かん。JDBC ドライバロードできなかったから Class.forName した所まではいいんだがぬるぽが出る。

  • JDBC 他におまじないがある?
    • なさそうなんだよなあ。
  • sql-url で指定してる OracleJDBC 接続文字列の方にもユーザ・パスワード入れてみる?
    • テーブルに何かデータ書かれてたからあんま意味ない気がするけど
  • beanshell での Class.forName() 相当は getClass と言うコマンドがあるって試したがダメ
>bin\shell

Datomic Java Shell
Type Shell.help(); for help.
datomic % Class.forName("oracle.jdbc.driver.OracleDriver");
<class oracle.jdbc.driver.OracleDriver>
datomic % uri = "datomic:sql://test?jdbc:oracle:thin:user/pass@//localhost:1521/TEST";
<datomic:sql://test?jdbc:oracle:thin:user/pass@//localhost:1521/TEST>
datomic % Peer.createDatabase(uri);
// Error: // Uncaught Exception: bsh.TargetError: Method Invocation Peer.createDatabase : at Line: 3 : in file: <unknown file> : Peer .createDatabase ( uri )

Target exception: java.lang.NullPointerException

java.lang.NullPointerException
        at java.io.StringReader.<init>(StringReader.java:50)
        at clojure.lang.RT.readString(RT.java:1736)
        at clojure.core$read_string.invoke(core.clj:3427)
        at datomic.coordination$lookup_transactor_endpoint$fn__1979.invoke(coordination.clj:128)
        at datomic.coordination$lookup_transactor_endpoint.invoke(coordination.clj:125)
        at datomic.peer$send_admin_request$fn__9221.invoke(peer.clj:589)
        at datomic.peer$send_admin_request.invoke(peer.clj:583)
        at datomic.peer$create_database.invoke(peer.clj:603)
        at datomic.peer$create_database.invoke(peer.clj:595)
        at clojure.lang.Var.invoke(Var.java:415)
        at datomic.Peer.createDatabase(Peer.java:84)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at bsh.Reflect.invokeMethod(Reflect.java:146)
        at bsh.Reflect.invokeStaticMethod(Reflect.java:94)
        at bsh.Name.invokeMethod(Name.java:874)
        at bsh.BSHMethodInvocation.eval(BSHMethodInvocation.java:75)
        at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:102)
        at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:47)
        at bsh.Interpreter.run(Interpreter.java:479)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
        at clojure.lang.Reflector.invokeNoArgInstanceMember(Reflector.java:298)
        at user$eval29.invoke(shell.clj:50)
        at clojure.lang.Compiler.eval(Compiler.java:6619)
        at clojure.lang.Compiler.load(Compiler.java:7064)
        at clojure.lang.Compiler.loadFile(Compiler.java:7020)
        at clojure.main$load_script.invoke(main.clj:294)
        at clojure.main$script_opt.invoke(main.clj:356)
        at clojure.main$main.doInvoke(main.clj:440)
        at clojure.lang.RestFn.invoke(RestFn.java:408)
        at clojure.lang.Var.invoke(Var.java:415)
        at clojure.lang.AFn.applyToHelper(AFn.java:161)
        at clojure.lang.Var.applyTo(Var.java:532)
        at clojure.main.main(main.java:37)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at jline.ConsoleRunner.main(ConsoleRunner.java:73)
datomic %

*1:どうも datomic の bin 以下のユーティリティ群は展開フォルダ直下をカレントフォルダとして動作する事前提のようで、transactor.cmd など bin 以下に移動しても動かなかった