動くんじゃろうか。
2年くらい経過しとるけぇね。 でもその間に Neo4j は REST-API でトランザクション処理が出来るようになっとるみたい。
19.1. Transactional Cypher HTTP endpoint - - The Neo4j Manual v2.1.5
まだやったことないけど、cl-neo4j 少し変更しとるけぇ、pull request してみよう。
GitHub実践入門 ~Pull Requestによる開発の変革 (WEB+DB PRESS plus)
- 作者: 大塚弘記
- 出版社/メーカー: 技術評論社
- 発売日: 2014/03/20
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (11件) を見る
とりあえず動作確認を初める。
(1) Github からクローン
(2) README.org を作成
元のは残しときたいんで、ってのと org-mode で書けるけぇ、そちらんが楽なんよ。
cl-neo4j/README.org at master · yanqirenshi/cl-neo4j · GitHub
追加した内容は以下五点。
- Basic API に REST API wrapper を追加。
- REST API wrapper に API の一覧を追加。
- Usage を追加
- Installation を追加
- Dependencies を追加
(3) パッケージのニックネームを設定。 (file:package.lisp)
毎回 "cl-" 付けるんメンドイけぇね。
(:nicknames :neo4j)
(4) まず get-node の動作テスト。 (Node は 先に追加済み)
いきなりコケた。 なんでじゃろう。
CL-USER> (in-package :neo4j)
#
NEO4J> (get-node 0)
odd number of &KEY arguments
[Condition of type SB-INT:SIMPLE-PROGRAM-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] Abort thread (#)
Backtrace:
0: (GET-NODE 0) [more,optional]
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (GET-NODE 0) #)
2: (EVAL (GET-NODE 0))
--more--
(5) コケた理由調査。
まず、defmacro def-neo4j-fun を確認。内部では defun にて関数を生成&返すそうな。
あれ? 関数じゃない。。。?
NEO4J> (functionp 'get-node)
NIL
関数の定義を実行してみる。
関数じゃねえ。。。
あ、パラメータが キーワードパラメータになっとる。
NEO4J>
(macroexpand-1
'(def-neo4j-fun get-node (node-id)
:get
(:uri-spec (if node-id
(format nil "node/~A" node-id)
""))
(:status-handlers
(200 (decode-neo4j-json-output body))
(404 (error 'node-not-found-error :uri uri)))))
(PROGN
(DEFUN GET-NODE (&KEY NODE-ID)
(LET ((URI
(IF NODE-ID
(FORMAT NIL "node/~A" NODE-ID)
""))
(URI-QUERY NIL)
(JSON (ENCODE-NEO4J-JSON-PAYLOAD NIL :STRING)))
(MAKE-NEO4J-REQUEST :GET URI URI-QUERY JSON
(LIST
(LIST 200
(LAMBDA (BODY URI JSON)
(DECODE-NEO4J-JSON-OUTPUT BODY)))
(LIST 404
(LAMBDA (BODY URI JSON)
(ERROR 'NODE-NOT-FOUND-ERROR :URI URI))))))))
T
再度キーワードパラメータにして実行。
成功しました。
NEO4J> (get-node :node-id 0)
((:EXTENSIONS)
(:OUTGOING--RELATIONSHIPS
. "http://localhost:7474/db/data/node/0/relationships/out")
(:LABELS . "http://localhost:7474/db/data/node/0/labels")
(:ALL--TYPED--RELATIONSHIPS
. "http://localhost:7474/db/data/node/0/relationships/all/{-list|&|types}")
(:TRAVERSE . "http://localhost:7474/db/data/node/0/traverse/{returnType}")
(:SELF . "http://localhost:7474/db/data/node/0")
(:PROPERTY . "http://localhost:7474/db/data/node/0/properties/{key}")
(:OUTGOING--TYPED--RELATIONSHIPS
. "http://localhost:7474/db/data/node/0/relationships/out/{-list|&|types}")
(:PROPERTIES . "http://localhost:7474/db/data/node/0/properties")
(:INCOMING--RELATIONSHIPS
. "http://localhost:7474/db/data/node/0/relationships/in")
(:CREATE--RELATIONSHIP . "http://localhost:7474/db/data/node/0/relationships")
(:PAGED--TRAVERSE
. "http://localhost:7474/db/data/node/0/paged/traverse/{returnType}{?pageSize,leaseTime}")
(:ALL--RELATIONSHIPS
. "http://localhost:7474/db/data/node/0/relationships/all")
(:INCOMING--TYPED--RELATIONSHIPS
. "http://localhost:7474/db/data/node/0/relationships/in/{-list|&|types}")
(:METADATA (:ID . 0) (:LABELS)) (:DATA (:NAME . "World")))
結論としては基本的なやつは動きそうじゃね。