From: Jean-Christophe Beaupré Date: Sat, 20 Dec 2014 23:09:17 +0000 (-0500) Subject: neo4j: Add an API for graphs. X-Git-Tag: v0.7.1~38^2~8 X-Git-Url: http://nitlanguage.org neo4j: Add an API for graphs. Signed-off-by: Jean-Christophe Beaupré --- diff --git a/lib/neo4j/graph/graph.nit b/lib/neo4j/graph/graph.nit new file mode 100644 index 0000000..48ec4ba --- /dev/null +++ b/lib/neo4j/graph/graph.nit @@ -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