-
Notifications
You must be signed in to change notification settings - Fork 13
/
compability.clj
107 lines (86 loc) · 3.07 KB
/
compability.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
(ns neo4j-clj.compability
"Neo4j communicates with Java via custom data structures. Those are
can contain lists, maps, nulls, values or combinations. This namespace
has functions to help to convert between Neo4j's data structures and Clojure"
(:require [clojure.walk]
[clojure.string :as string])
(:import (org.neo4j.driver.v1 Values)
(org.neo4j.driver.internal
InternalRecord
InternalPair
InternalRelationship
InternalStatementResult
InternalNode)
(org.neo4j.driver.internal.value
NodeValue
NullValue
ListValue
MapValue
RelationshipValue
StringValue)
(org.neo4j.cypher.internal.javacompat
ExecutionResult)
(java.util Map List)
(clojure.lang ISeq)))
(defn clj->neo4j
"## Convert to Neo4j
Neo4j expects a map of key/value pairs. The map has to be constructed as
a `Values.parameters` instance which expects the values as an `Object` array"
[val]
(->> val
clojure.walk/stringify-keys
(mapcat identity)
(into-array Object)
Values/parameters))
(defmulti neo4j->clj
"## Convert from Neo4j
Neo4j returns results as `StatementResults`, which contain `InternalRecords`,
which contain `InternalPairs` etc. Therefore, this multimethod recursively
calls itself with the extracted content of the data structure until we have
values, lists or `nil`."
class)
(defn transform [m]
(let [f (fn [[k v]]
[(if (string? k) (keyword k) k) (neo4j->clj v)])]
;; only apply to maps
(clojure.walk/postwalk
(fn [x]
(if (or (map? x) (instance? Map x))
(with-meta (into {} (map f x))
(meta x))
x))
m)))
(defmethod neo4j->clj InternalStatementResult [record]
(map neo4j->clj (iterator-seq record)))
(defmethod neo4j->clj InternalRecord [record]
(apply merge (map neo4j->clj (.fields record))))
(defmethod neo4j->clj InternalPair [^InternalPair pair]
(let [k (-> pair .key keyword)
v (-> pair .value neo4j->clj)]
{k v}))
(defmethod neo4j->clj NodeValue [^NodeValue value]
(transform (into {} (.asMap value))))
(defmethod neo4j->clj RelationshipValue [^RelationshipValue value]
(transform (into {} (.asMap (.asRelationship value)))))
(defmethod neo4j->clj StringValue [^StringValue v]
(.asObject v))
(defmethod neo4j->clj ListValue [^ListValue l]
(map neo4j->clj (into [] (.asList l))))
(defmethod neo4j->clj ISeq [^ISeq s]
(map neo4j->clj s))
(defmethod neo4j->clj MapValue [^MapValue l]
(transform (into {} (.asMap l))))
(defmethod neo4j->clj InternalNode [^InternalNode n]
(with-meta (transform (into {} (.asMap n)))
{:labels (.labels n)
:id (.id n)}))
(defmethod neo4j->clj InternalRelationship [^InternalRelationship r]
(neo4j->clj (.asValue r)))
(defmethod neo4j->clj NullValue [n]
nil)
(defmethod neo4j->clj List [^List l]
(map neo4j->clj (into [] l)))
(defmethod neo4j->clj Map [^Map m]
(transform (into {} m)))
(defmethod neo4j->clj :default [x]
x)