--- /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.
+
+# 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