1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # This file is free software, which comes along with NIT. This software is
4 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
5 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
6 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
7 # is kept unaltered, and a notification of the changes is added.
8 # You are allowed to redistribute it and sell it, alone or is a part of
11 # Uses JSON as a storage medium for a Neo4j subgraph.
12 module neo4j
::json_store
15 private import template
17 # A Neo4j graph that uses as a storage medium.
19 # The graph is stored as a JSON object with the following properties:
21 # * `"nodes"`: An array with all nodes. Each node is an object with the
22 # following properties:
23 # * `"id"`: The ID (`Int`) that uniquely identifies the node in the current
25 # * `"labels"`: An array of all applied labels.
26 # * `"properties"`: An object mapping each defined property to its value.
27 # * `"links"`: An array with all relationships. Each relationship is an object
28 # with the following properties:
29 # * `"type"`: The type (`String`) of the relationship.
30 # * `"properties"`: An object mapping each defined property to its value.
31 # * `"from"`: The ID (`Int`) of the source node.
32 # * `"to"`: The ID (`Int`) of the destination node.
34 # TODO Refine the graph API instead when it will be available.
38 # All nodes in the graph.
39 var nodes
: SimpleCollection[NeoNode] = new Array[NeoNode]
41 # All relationships in the graph.
42 var links
: SimpleCollection[NeoEdge] = new Array[NeoEdge]
44 # Create an empty graph.
47 # Retrieve the graph from the specified JSON value.
49 # var graph = new JsonGraph
53 # a["Ultimate question of"] = new JsonArray.from(["life",
54 # "the Universe", "and Everything."])
60 # graph.links.add new NeoEdge(a, "BAZ", b)
62 # graph = new JsonGraph.from_json(graph.to_json)
63 # assert 1 == graph.links.length
64 # for link in graph.links do
65 # assert "BAZ" == link.rel_type
66 # assert a.labels == link.from.labels
67 # for k, v in a.properties do assert v == link.from.properties[k]
68 # assert b.labels == link.to.labels
69 # for k, v in b.properties do assert v == link.to.properties[k]
71 # assert 2 == graph.nodes.length
72 init from_json
(t
: Text) do
73 from_json_object
(t
.to_jsonable
.as(JsonObject))
76 # Retrieve the graph from the specified JSON object.
77 init from_json_object
(o
: JsonObject) do
78 var node_by_id
= new HashMap[Int, NeoNode]
79 var nodes
= o
["nodes"].as(JsonArray)
80 for json_node
in nodes
do
81 assert json_node
isa JsonObject
82 var node
= new NeoNode.from_json_object
(json_node
)
83 node_by_id
[json_node
["id"].as(Int)] = node
86 var links
= o
["links"].as(JsonArray)
87 for json_link
in links
do
88 assert json_link
isa JsonObject
89 var from
= node_by_id
[json_link
["from"].as(Int)]
90 var to
= node_by_id
[json_link
["to"].as(Int)]
91 var rel_type
= json_link
["type"].as(String)
92 var json_properties
= json_link
["properties"].as(JsonObject)
93 var link
= new NeoEdge(from
, rel_type
, to
)
94 link
.properties
.recover_with
(json_properties
)
101 t
.add
"\{\"nodes\
":["
104 if i
> 0 then t
.add
","
108 t
.add
"],\"links\
":["
111 if i
> 0 then t
.add
","
116 return t
.write_to_string
120 # Make `NeoNode` `Jsonable`.
124 # Retrieve the node from the specified JSON value.
126 # Note: Here, the `"id"` is optional and ignored.
130 # var node = new NeoNode.from_json("""
132 # "labels": ["foo", "Bar"],
138 # assert ["foo", "Bar"] == node.labels
139 # assert 42 == node["baz"]
140 init from_json
(t
: Text) do
141 from_json_object
(t
.to_jsonable
.as(JsonObject))
144 # Retrieve the node from the specified JSON value.
146 # Note: Here, the `"id"` is optional and ignored.
149 init from_json_object
(o
: JsonObject) do
151 var labels
= o
["labels"].as(JsonArray)
152 for lab
in labels
do self.labels
.add
(lab
.as(String))
153 var json_properties
= o
["properties"].as(JsonObject)
154 properties
.recover_with
(json_properties
)
157 # Get the JSON representation of `self`.
163 t
.add object_id
.to_json
164 t
.add
",\"labels\
":["
167 if i
> 0 then t
.add
","
171 t
.add
"],\"properties\
":"
172 t
.add properties
.to_json
174 return t
.write_to_string
177 redef fun to_s
do return to_json
180 # Make `NeoEdge` `Jsonable`.
187 t
.add rel_type
.to_json
188 t
.add
",\"properties\
":"
189 t
.add properties
.to_json
191 t
.add from
.object_id
.to_json
193 t
.add to
.object_id
.to_json
195 return t
.write_to_string
198 redef fun to_s
do return to_json