Property definitions

neo4j $ NeoEntity :: defaultinit
# The fundamental units that form a graph are nodes and relationships.
#
# Entities can have two states:
#
# * linked: the NeoEntity references an existing node or edge in Neo4j
# * unlinked: the NeoEntity is not yet created in Neo4j
#
# If the entity is initialized unlinked from neo4j:
#
#     # Create a disconnected node
#     var andres = new NeoNode
#     andres["name"] = "Andres"
#     # At this point, the node is not linked
#     assert not andres.is_linked
#
# Then we can link the entity to the base:
#
#     # Init client
#     var client = new Neo4jClient("http://neo4j:7474")
#     client.save_node(andres)
#     # The node is now linked
#     assert andres.is_linked
#
# Entities can also be loaded from Neo4j:
#
#     # Get a node from Neo4j
#     var url = andres.url.to_s
#     var node = client.load_node(url)
#     assert node.is_linked
#
# When working in connected mode, all reading operations are executed lazily on the base:
#
#     # Get the node `name` property
#     assert node["name"] == "Andres"	# loaded lazily from base
abstract class NeoEntity
	# Neo4j client connector
	private var neo: Neo4jClient is noinit

	# Entity unique URL in Neo4j REST API
	var url: nullable String = null

	# Temp id used in batch mode to update the entity
	private var batch_id: nullable Int = null

	# Load the entity from base
	private init from_neo(neo: Neo4jClient, url: String) is nosuper do
		self.neo = neo
		self.url = url
	end

	# Init entity from JSON representation
	private init from_json(neo: Neo4jClient, obj: JsonObject) is nosuper do
		self.neo = neo
		self.url = obj["self"].to_s
		self.internal_properties = obj["data"].as(JsonObject)
	end

	# Create a empty (and not-connected) entity
	init do
		self.internal_properties = new JsonObject
	end

	# Is the entity linked to a Neo4j database?
	fun is_linked: Bool do return url != null

	# In Neo4j, both nodes and relationships can contain properties.
	# Properties are key-value pairs where the key is a string.
	# Property values are JSON formatted.
	#
	# Properties are loaded lazily
	fun properties: JsonObject do return internal_properties or else load_properties

	private var internal_properties: nullable JsonObject = null

	private fun load_properties: JsonObject do
		var obj = neo.get(url.to_s / "properties").as(JsonObject)
		internal_properties = obj
		return obj
	end

	# Get the entity `id` if connected to base
	fun id: nullable Int do
		if url == null then return null
		return url.split("/").last.to_i
	end

	# Get the entity property at `key`
	fun [](key: String): nullable Serializable do
		if not properties.has_key(key) then return null
		return properties[key]
	end

	# Set the entity property `value` at `key`
	fun []=(key: String, value: nullable Serializable) do properties[key] = value

	# Is the property `key` set?
	fun has_key(key: String): Bool do return properties.has_key(key)
end
lib/neo4j/neo4j.nit:455,1--552,3