Neo4jClient is needed to communicate through the REST API

var client = new Neo4jClient("http://neo4j:7474")
assert client.is_ok

Introduced properties

fun base_url: String

neo4j :: Neo4jClient :: base_url

Neo4j REST services baseurl
protected fun base_url=(base_url: String)

neo4j :: Neo4jClient :: base_url=

Neo4j REST services baseurl
fun clear_graph

neo4j :: Neo4jClient :: clear_graph

Empty the graph
fun cypher(query: CypherQuery): Serializable

neo4j :: Neo4jClient :: cypher

Perform a CypherQuery
fun delete(url: String): Serializable

neo4j :: Neo4jClient :: delete

DELETE url
fun delete_edge(edge: NeoEdge): Bool

neo4j :: Neo4jClient :: delete_edge

Remove the edge from base
fun delete_node(node: NeoNode): Bool

neo4j :: Neo4jClient :: delete_node

Remove the entity from base
fun errors: Array[String]

neo4j :: Neo4jClient :: errors

Last errors
protected fun errors=(errors: Array[String])

neo4j :: Neo4jClient :: errors=

Last errors
fun get(url: String): Serializable

neo4j :: Neo4jClient :: get

GET JSON data from url
fun is_ok: Bool

neo4j :: Neo4jClient :: is_ok

Is the connection with the Neo4j server ok?
fun load_edge(url: String): NeoEdge

neo4j :: Neo4jClient :: load_edge

Load a edge from base
fun load_node(url: String): NeoNode

neo4j :: Neo4jClient :: load_node

Load a node from base
fun nodes_with_label(lbl: String): Array[NeoNode]

neo4j :: Neo4jClient :: nodes_with_label

Retrieve all nodes with specified lbl
fun nodes_with_labels(labels: Array[String]): Array[NeoNode]

neo4j :: Neo4jClient :: nodes_with_labels

Retrieve nodes belonging to all the specified labels.
fun post(url: String, params: Serializable): Serializable

neo4j :: Neo4jClient :: post

POST params to url
fun put(url: String, params: Serializable): Serializable

neo4j :: Neo4jClient :: put

PUT params at url
fun save_edge(edge: NeoEdge): Bool

neo4j :: Neo4jClient :: save_edge

Save the edge in base
fun save_node(node: NeoNode): Bool

neo4j :: Neo4jClient :: save_node

Save the node in base

Redefined properties

redef type SELF: Neo4jClient

neo4j $ Neo4jClient :: SELF

Type of this instance, automatically specialized in every class

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
fun base_url: String

neo4j :: Neo4jClient :: base_url

Neo4j REST services baseurl
protected fun base_url=(base_url: String)

neo4j :: Neo4jClient :: base_url=

Neo4j REST services baseurl
protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
fun clear_graph

neo4j :: Neo4jClient :: clear_graph

Empty the graph
fun cypher(query: CypherQuery): Serializable

neo4j :: Neo4jClient :: cypher

Perform a CypherQuery
fun delete(url: String): Serializable

neo4j :: Neo4jClient :: delete

DELETE url
fun delete_edge(edge: NeoEdge): Bool

neo4j :: Neo4jClient :: delete_edge

Remove the edge from base
fun delete_node(node: NeoNode): Bool

neo4j :: Neo4jClient :: delete_node

Remove the entity from base
fun errors: Array[String]

neo4j :: Neo4jClient :: errors

Last errors
protected fun errors=(errors: Array[String])

neo4j :: Neo4jClient :: errors=

Last errors
fun get(url: String): Serializable

neo4j :: Neo4jClient :: get

GET JSON data from url
fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
fun hash: Int

core :: Object :: hash

The hash code of the object.
init init

core :: Object :: init

fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
fun is_ok: Bool

neo4j :: Neo4jClient :: is_ok

Is the connection with the Neo4j server ok?
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
fun load_edge(url: String): NeoEdge

neo4j :: Neo4jClient :: load_edge

Load a edge from base
fun load_node(url: String): NeoNode

neo4j :: Neo4jClient :: load_node

Load a node from base
fun nodes_with_label(lbl: String): Array[NeoNode]

neo4j :: Neo4jClient :: nodes_with_label

Retrieve all nodes with specified lbl
fun nodes_with_labels(labels: Array[String]): Array[NeoNode]

neo4j :: Neo4jClient :: nodes_with_labels

Retrieve nodes belonging to all the specified labels.
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
fun post(url: String, params: Serializable): Serializable

neo4j :: Neo4jClient :: post

POST params to url
fun put(url: String, params: Serializable): Serializable

neo4j :: Neo4jClient :: put

PUT params at url
fun save_edge(edge: NeoEdge): Bool

neo4j :: Neo4jClient :: save_edge

Save the edge in base
fun save_node(node: NeoNode): Bool

neo4j :: Neo4jClient :: save_node

Save the node in base
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
package_diagram neo4j::Neo4jClient Neo4jClient core::Object Object neo4j::Neo4jClient->core::Object

Parents

interface Object

core :: Object

The root of the class hierarchy.

Class definitions

neo4j $ Neo4jClient
# `Neo4jClient` is needed to communicate through the REST API
#
#     var client = new Neo4jClient("http://neo4j:7474")
#     assert client.is_ok
class Neo4jClient

	# Neo4j REST services baseurl
	var base_url: String
	# REST service to get node data
	private var node_url: String
	# REST service to batch
	private var batch_url: String
	# REST service to send cypher requests
	private var cypher_url: String

	init(base_url: String) do
		self.base_url = base_url
		var root = service_root
		assert root isa JsonObject else
			sys.stderr.write "Neo4jClientError: cannot connect to server at <{base_url}>.\n"
		end
		self.node_url = root["node"].to_s
		self.batch_url = root["batch"].to_s
		self.cypher_url = root["cypher"].to_s
	end

	fun service_root: Serializable do return get(base_url / "db/data")

	# Is the connection with the Neo4j server ok?
	fun is_ok: Bool do return service_root isa JsonObject

	# Empty the graph
	fun clear_graph do
		cypher(new CypherQuery.from_string("MATCH (n) OPTIONAL MATCH n-[r]-() DELETE r, n"))
	end

	# Last errors
	var errors = new Array[String]

	# Nodes view stored locally
	private var local_nodes = new HashMap[String, nullable NeoNode]

	# Save the node in base
	#
	#     var client = new Neo4jClient("http://neo4j:7474")
	#
	#     # Create a node
	#     var andres = new NeoNode
	#     andres["name"] = "Andres"
	#     client.save_node(andres)
	#     assert andres.is_linked
	#
	# Once linked, nodes cannot be created twice:
	#
	#     var oldurl = andres.url
	#     client.save_node(andres) # do nothing
	#     assert andres.url == oldurl
	fun save_node(node: NeoNode): Bool do
		if node.is_linked then return true
		node.neo = self
		var batch = new NeoBatch(self)
		batch.save_node(node)
		# batch.create_edges(node.out_edges)
		var errors = batch.execute
		if not errors.is_empty then
			errors.add_all errors
			return false
		end
		local_nodes[node.url.to_s] = node
		return true
	end

	# Load a node from base
	# Data, labels and edges will be loaded lazily.
	fun load_node(url: String): NeoNode do
		if local_nodes.has_key(url) then
			var node = local_nodes[url]
			if node != null then return node
		end
		var node = new NeoNode.from_neo(self, url)
		local_nodes[url] = node
		return node
	end

	# Remove the entity from base
	fun delete_node(node: NeoNode): Bool do
		if not node.is_linked then return false
		var url = node.url.to_s
		delete(url)
		local_nodes[url] = null
		node.url = null
		return true
	end

	# Edges view stored locally
	private var local_edges = new HashMap[String, nullable NeoEdge]

	# Save the edge in base
	# From and to nodes will be created.
	#
	#     var client = new Neo4jClient("http://neo4j:7474")
	#
	#     var andres = new NeoNode
	#     var kate = new NeoNode
	#     var edge = new NeoEdge(andres, "LOVES", kate)
	#     client.save_edge(edge)
	#     assert andres.is_linked
	#     assert kate.is_linked
	#     assert edge.is_linked
	fun save_edge(edge: NeoEdge): Bool do
		if edge.is_linked then return true
		edge.neo = self
		edge.from.out_edges.add edge
		edge.to.in_edges.add edge
		var batch = new NeoBatch(self)
		batch.save_edge(edge)
		var errors = batch.execute
		if not errors.is_empty then
			errors.add_all errors
			return false
		end
		local_edges[edge.url.to_s] = edge
		return true
	end

	# Load a edge from base
	# Data will be loaded lazily.
	fun load_edge(url: String): NeoEdge do
		if local_edges.has_key(url) then
			var node = local_edges[url]
			if node != null then return node
		end
		var edge = new NeoEdge.from_neo(self, url)
		local_edges[url] = edge
		return edge
	end

	# Remove the edge from base
	fun delete_edge(edge: NeoEdge): Bool do
		if not edge.is_linked then return false
		var url = edge.url.to_s
		delete(url)
		local_edges[url] = null
		edge.url = null
		return true
	end

	# Retrieve all nodes with specified `lbl`
	#
	#     var client = new Neo4jClient("http://neo4j:7474")
	#
	#     var andres = new NeoNode
	#     andres.labels.add_all(["Human", "Male"])
	#     client.save_node(andres)
	#     var kate = new NeoNode
	#     kate.labels.add_all(["Human", "Female"])
	#     client.save_node(kate)
	#
	#     var nodes = client.nodes_with_label("Human")
	#     assert nodes.has(andres)
	#     assert nodes.has(kate)
	fun nodes_with_label(lbl: String): Array[NeoNode] do
		var res = get(base_url / "db/data/label/{lbl.to_percent_encoding}/nodes")
		var nodes = new Array[NeoNode]
		for json in res.as(JsonArray) do
			var obj = json.as(JsonObject)
			var node = load_node(obj["self"].to_s)
			node.internal_properties = obj["data"].as(JsonObject)
			nodes.add node
		end
		return nodes
	end

	# Retrieve nodes belonging to all the specified `labels`.
	#
	#     var client = new Neo4jClient("http://neo4j:7474")
	#
	#     var andres = new NeoNode
	#     andres.labels.add_all(["Human", "Male"])
	#     client.save_node(andres)
	#     var kate = new NeoNode
	#     kate.labels.add_all(["Human", "Female"])
	#     client.save_node(kate)
	#
	#     var nodes = client.nodes_with_labels(["Human", "Male"])
	#     assert nodes.has(andres)
	#     assert not nodes.has(kate)
	fun nodes_with_labels(labels: Array[String]): Array[NeoNode] do
		assert not labels.is_empty

		# Build the query.
		var buffer = new Buffer
		buffer.append "match (n) where \{label_0\} in labels(n)"
		for i in [1..labels.length[ do
			buffer.append " and \{label_{i}\} in labels(n)"
		end
		buffer.append " return n"
		var query = new CypherQuery.from_string(buffer.write_to_string)
		for i in [0..labels.length[ do
			query.params["label_{i}"] = labels[i]
		end

		# Retrieve the answer.
		var res = cypher(query)
		var nodes = new Array[NeoNode]
		for json in res.as(JsonObject)["data"].as(JsonArray) do
			var obj = json.as(JsonArray).first.as(JsonObject)
			var node = load_node(obj["self"].to_s)
			node.internal_properties = obj["data"].as(JsonObject)
			nodes.add node
		end
		return nodes
	end

	# Perform a `CypherQuery`
	# see: CypherQuery
	fun cypher(query: CypherQuery): Serializable do
		return post("{cypher_url}", query.to_rest)
	end

	# GET JSON data from `url`
	fun get(url: String): Serializable do
		var request = new JsonGET(url)
		var response = request.execute
		return parse_response(response)
	end

	# POST `params` to `url`
	fun post(url: String, params: Serializable): Serializable do
		var request = new JsonPOST(url)
		request.json_data = params
		var response = request.execute
		return parse_response(response)
	end

	# PUT `params` at `url`
	fun put(url: String, params: Serializable): Serializable do
		var request = new JsonPUT(url)
		request.json_data = params
		var response = request.execute
		return parse_response(response)
	end

	# DELETE `url`
	fun delete(url: String): Serializable do
		var request = new JsonDELETE(url)
		var response = request.execute
		return parse_response(response)
	end

	# Parse the cURL `response` as a JSON string
	private fun parse_response(response: CurlResponse): Serializable do
		if response isa CurlResponseSuccess then
			var str = response.body_str
			if str.is_empty then return new JsonObject
			var res = str.parse_json
			if res isa JsonParseError then
				var e = new NeoError(res.to_s, "JsonParseError")
				e.cause = res
				return e
			end
			if res == null then
				# empty response wrap it in empty object
				return new JsonObject
			else if res isa JsonObject and res.has_key("exception") then
				var error = "Neo4jError::{res["exception"] or else "null"}"
				var msg = ""
				if res.has_key("message") then
					msg = res["message"].to_s
				end
				return new NeoError(msg, error)
			else
				return res
			end
		else if response isa CurlResponseFailed then
			return new NeoError("{response.error_msg} ({response.error_code})", "CurlError")
		else
			return new NeoError("Unexpected response \"{response}\".", "CurlError")
		end
	end
end
lib/neo4j/neo4j.nit:63,1--343,3