neo4j: Add an API for graphs.
authorJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Sat, 20 Dec 2014 23:09:17 +0000 (18:09 -0500)
committerJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Mon, 29 Dec 2014 20:51:23 +0000 (15:51 -0500)
Signed-off-by: Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>

lib/neo4j/graph/graph.nit [new file with mode: 0644]

diff --git a/lib/neo4j/graph/graph.nit b/lib/neo4j/graph/graph.nit
new file mode 100644 (file)
index 0000000..48ec4ba
--- /dev/null
@@ -0,0 +1,138 @@
+# 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.
+
+# Provides an interface for services on a Neo4j graphs.
+module neo4j::graph::graph
+
+import neo4j
+import progression
+
+# A Neo4j graph with a local identification scheme for its nodes.
+#
+# An identification scheme can be defined by subclassing `NeoNodeCollection`.
+#
+# `GraphStore` can be subclassed to add ways to save or load a graph. The
+# storing mechanisms may use `nodes.id_of` to identify the nodes in the graph
+# while encoding the relationships.
+class NeoGraph
+       # All the nodes in the graph.
+       var nodes: NeoNodeCollection
+
+       # All the relationships in the graph.
+       var edges: SimpleCollection[NeoEdge] = new Array[NeoEdge]
+
+       # Add a new node to the graph and return it.
+       #
+       # Set the local ID of the node before returning it.
+       #
+       # SEE: `NeoNodeCollection.add`
+       # SEE: `NeoNodeCollection.create_node`
+       # SEE: `NeoNodeCollection.register`
+       fun create_node: NeoNode do return nodes.create_node
+end
+
+# All the nodes in a `NeoGraph`.
+#
+# An identification scheme can be defined throught the `register` and `add`
+# methods. The `id_property` attribute defines where the local ID (that is the
+# ID managed by the collection) is stored in each node.
+abstract class NeoNodeCollection
+       super SimpleCollection[NeoNode]
+
+       # The type of the local IDs.
+       type ID_TYPE: Jsonable
+
+       # The property of the nodes that hold the local ID.
+       var id_property: String
+
+       # Retrieve the node that has the specified local id.
+       #
+       # Note: The default implementation uses `get_or_null`.
+       fun [](id: ID_TYPE): NeoNode do
+               var n = get_or_null(id)
+               assert n isa NeoNode
+               return n
+       end
+
+       # Retrieve the node that has the specified local id, or return `null`.
+       #
+       # Note: The default implementation uses `iterator`.
+       fun get_or_null(id: ID_TYPE): nullable NeoNode do
+               for n in self do
+                       if id_of(n) == id then return n
+               end
+               return null
+       end
+
+       # There is a node that has the specified local id?
+       #
+       # Note: The default implementation uses `get_or_null`.
+       fun has_id(id: ID_TYPE): Bool do return get_or_null(id) isa NeoNode
+
+       # Return the local ID of the node.
+       fun id_of(node: NeoNode): ID_TYPE do return node[id_property].as(ID_TYPE)
+
+       # Set the local ID of the specified node.
+       #
+       # Just update the property at `property_id`. Do not check anything.
+       protected fun id_of=(node: NeoNode, id: ID_TYPE) do
+               node[id_property] = id
+       end
+
+       # Add the specified node to the graph and set its local ID.
+       #
+       # SEE: `add`
+       # SEE: `create_node`
+       fun register(node: NeoNode) is abstract
+
+       # Add the specified node to the graph assuming that its local ID is already set.
+       #
+       # SEE: `create_node`
+       # SEE: `register`
+       redef fun add(node: NeoNode) is abstract
+
+       # Add a new node to the graph and return it.
+       #
+       # Set the local ID of the node before returning it.
+       #
+       # SEE: `add`
+       # SEE: `register`
+       fun create_node: NeoNode do
+               var node = new NeoNode
+               register(node)
+               return node
+       end
+end
+
+# A mean to save and load a Neo4j graph.
+abstract class GraphStore
+       super Trackable
+
+       # The graph to save or load.
+       var graph: NeoGraph
+
+       # Can we save the graph without conflict?
+       fun isolated_save: Bool is abstract
+
+       # Load the graph (or a part of it).
+       #
+       # Do not reset the graph.
+       fun load is abstract
+
+       # Save the graph.
+       fun save do save_part(graph.nodes, graph.edges)
+
+       # Save the specified part of the graph.
+       #
+       # Assume that for each relationship specified, both ends are already saved
+       # or are specified in the same call to this method.
+       fun save_part(nodes: Collection[NeoNode],
+                       edges: Collection[NeoEdge]) is abstract
+end