+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT. This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. You can modify it is you want, provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You are allowed to redistribute it and sell it, alone or is a part of
-# another product.
-
-# Uses JSON as a storage medium for a Neo4j subgraph.
-module neo4j::json_store
-
-import neo4j
-private import template
-
-# A Neo4j graph that uses as a storage medium.
-#
-# The graph is stored as a JSON object with the following properties:
-#
-# * `"nodes"`: An array with all nodes. Each node is an object with the
-# following properties:
-# * `"id"`: The ID (`Int`) that uniquely identifies the node in the current
-# graph.
-# * `"labels"`: An array of all applied labels.
-# * `"properties"`: An object mapping each defined property to its value.
-# * `"links"`: An array with all relationships. Each relationship is an object
-# with the following properties:
-# * `"type"`: The type (`String`) of the relationship.
-# * `"properties"`: An object mapping each defined property to its value.
-# * `"from"`: The ID (`Int`) of the source node.
-# * `"to"`: The ID (`Int`) of the destination node.
-#
-# TODO Refine the graph API instead when it will be available.
-class JsonGraph
- super Jsonable
-
- # All nodes in the graph.
- var nodes: SimpleCollection[NeoNode] = new Array[NeoNode]
-
- # All relationships in the graph.
- var links: SimpleCollection[NeoEdge] = new Array[NeoEdge]
-
- # Create an empty graph.
- init do end
-
- # Retrieve the graph from the specified JSON value.
- #
- # var graph = new JsonGraph
- # var a = new NeoNode
- # a.labels.add "Foo"
- # a["answer"] = 42
- # a["Ultimate question of"] = new JsonArray.from(["life",
- # "the Universe", "and Everything."])
- # graph.nodes.add a
- # var b = new NeoNode
- # b.labels.add "Foo"
- # b.labels.add "Bar"
- # graph.nodes.add b
- # graph.links.add new NeoEdge(a, "BAZ", b)
- # #
- # graph = new JsonGraph.from_json(graph.to_json)
- # assert 1 == graph.links.length
- # for link in graph.links do
- # assert "BAZ" == link.rel_type
- # assert a.labels == link.from.labels
- # for k, v in a.properties do assert v == link.from.properties[k]
- # assert b.labels == link.to.labels
- # for k, v in b.properties do assert v == link.to.properties[k]
- # end
- # assert 2 == graph.nodes.length
- init from_json(t: Text) do
- from_json_object(t.parse_json.as(JsonObject))
- end
-
- # Retrieve the graph from the specified JSON object.
- init from_json_object(o: JsonObject) do
- var node_by_id = new HashMap[Int, NeoNode]
- var nodes = o["nodes"].as(JsonArray)
- for json_node in nodes do
- assert json_node isa JsonObject
- var node = new NeoNode.from_json_object(json_node)
- node_by_id[json_node["id"].as(Int)] = node
- self.nodes.add node
- end
- var links = o["links"].as(JsonArray)
- for json_link in links do
- assert json_link isa JsonObject
- var from = node_by_id[json_link["from"].as(Int)]
- var to = node_by_id[json_link["to"].as(Int)]
- var rel_type = json_link["type"].as(String)
- var json_properties = json_link["properties"].as(JsonObject)
- var link = new NeoEdge(from, rel_type, to)
- link.properties.recover_with(json_properties)
- self.links.add link
- end
- end
-
- redef fun to_json do
- var t = new Template
- t.add "\{\"nodes\":["
- var i = 0
- for n in nodes do
- if i > 0 then t.add ","
- t.add n.to_json
- i += 1
- end
- t.add "],\"links\":["
- i = 0
- for link in links do
- if i > 0 then t.add ","
- t.add link.to_json
- i += 1
- end
- t.add "]\}"
- return t.write_to_string
- end
-end
-
-# Make `NeoNode` `Jsonable`.
-redef class NeoNode
- super Jsonable
-
- # Retrieve the node from the specified JSON value.
- #
- # Note: Here, the `"id"` is optional and ignored.
- #
- # SEE: `JsonGraph`
- #
- # var node = new NeoNode.from_json("""
- # {
- # "labels": ["foo", "Bar"],
- # "properties": {
- # "baz": 42
- # }
- # }
- # """)
- # assert ["foo", "Bar"] == node.labels
- # assert 42 == node["baz"]
- init from_json(t: Text) do
- from_json_object(t.parse_json.as(JsonObject))
- end
-
- # Retrieve the node from the specified JSON value.
- #
- # Note: Here, the `"id"` is optional and ignored.
- #
- # SEE: `JsonGraph`
- init from_json_object(o: JsonObject) do
- init
- var labels = o["labels"].as(JsonArray)
- for lab in labels do self.labels.add(lab.as(String))
- var json_properties = o["properties"].as(JsonObject)
- properties.recover_with(json_properties)
- end
-
- # Get the JSON representation of `self`.
- #
- # SEE: `JsonGraph`
- redef fun to_json do
- var t = new Template
- t.add "\{\"id\":"
- t.add object_id.to_json
- t.add ",\"labels\":["
- var i = 0
- for lab in labels do
- if i > 0 then t.add ","
- t.add lab.to_json
- i += 1
- end
- t.add "],\"properties\":"
- t.add properties.to_json
- t.add "}"
- return t.write_to_string
- end
-
- redef fun to_s do return to_json
-end
-
-# Make `NeoEdge` `Jsonable`.
-redef class NeoEdge
- super Jsonable
-
- redef fun to_json do
- var t = new Template
- t.add "\{\"type\":"
- t.add rel_type.to_json
- t.add ",\"properties\":"
- t.add properties.to_json
- t.add ",\"from\":"
- t.add from.object_id.to_json
- t.add ",\"to\":"
- t.add to.object_id.to_json
- t.add "}"
- return t.write_to_string
- end
-
- redef fun to_s do return to_json
-end