Skip to content

Instantly share code, notes, and snippets.

@abonhomme
Created December 5, 2012 06:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abonhomme/4212993 to your computer and use it in GitHub Desktop.
Save abonhomme/4212993 to your computer and use it in GitHub Desktop.
Experiment with Bulbs framework and transactions. Meant to mimic the examples in "lightbulb" mentioned at the bottom of this post https://groups.google.com/forum/#!msg/gremlin-users/HaznTd_8bG4/LzqhdXsdA00J
from bulbs.model import Node, NodeProxy, Relationship, build_data
from bulbs.property import String, Integer, DateTime
from bulbs.utils import extract, get_file_path, current_datetime
from bulbs.neo4jserver import Graph as Neo4jGraph
class Knows(Relationship):
label = "knows"
created = DateTime(default=current_datetime, nullable=False)
class User(Node):
element_type = "user"
userid = String(nullable=False)
name = String()
@classmethod
def get_proxy_class(cls):
return UserProxy
def _save(self, _data, kwds):
script = self._client.scripts.get('save_user_and_friends_as_batch')
params = self._get_params(_data, kwds)
result = self._client.gremlin(script, params).one()
self._initialize(result)
def _get_params(self, _data, kwds):
params = dict()
# Get the property data, regardless of how it was entered
data = build_data(_data, kwds)
params['friends'] = ["Joe","John","James","Jerry"]
# User
# clean off any extra kwds that aren't defined as a User Property
desired_keys = self.get_property_keys()
data = extract(desired_keys, data)
params['user_bundle'] = self.get_bundle(data)
return params
class UserProxy(NodeProxy):
def save(self, _data=None, **kwds):
node = self.element_class(self.client)
node._save(_data, kwds)
return node
# Undefine standard methods; use save() instead.
def create(self, _data=None, **kwds):
return NotImplementedError
def update(self, _id, _data=None, **kwds):
return NotImplementedError
class Graph(Neo4jGraph):
def __init__(self, config=None):
super(Graph, self).__init__(config)
# Node Proxies
self.users = self.build_proxy(User)
# Relationship Proxies
self.knows = self.build_proxy(Knows)
# Add our custom Gremlin-Groovy scripts
scripts_file = get_file_path(__file__, "gremlin_simple.groovy")
self.scripts.update(scripts_file)
if __name__=="__main__":
g = Graph()
fred = g.users.save(name="Fred",userid="3451")
# script = g.scripts.get('save_user_and_friends_as_batch')
# params = dict(friends=["Joe","John","James","Jerry"])
# items = g.gremlin.query(script, params)
def save_user_and_friends_as_batch(user_bundle, friends) {
def create_indexed_vertex = { final List bundle ->
(data, index_name, keys) = bundle
vertex = g.addVertex()
index = g.idx(index_name)
for (property in data) {
if (property.value == null) continue;
vertex.setProperty(property.key, property.value)
if (keys == null || keys.contains(property.key))
index.put(property.key, String.valueOf(property.value), vertex)
}
return vertex
}
def update_indexed_vertex = { final Vertex vertex, final List bundle ->
(data, index_name, keys) = bundle
index = g.idx(index_name);
// remove vertex from index
for (String key in vertex.getPropertyKeys()) {
if (keys == null || keys.contains(key)) {
value = vertex.getProperty(key);
index.remove(key, String.valueOf(value), vertex);
}
}
// update element properties
ElementHelper.removeProperties([vertex]);
ElementHelper.setProperties(vertex, data);
// add vertex to index
for (entry in data.entrySet()) {
if (entry.value == null) continue;
if (keys == null || keys.contains(entry.key))
index.put(entry.key,String.valueOf(entry.value),vertex);
}
return vertex;
}
def create_or_update_vertex = { final List bundle, final String index_key ->
(data, index_name, keys) = bundle
index_value = data[index_key]
vertices = g.idx(index_name).get(index_key, index_value).toList()
if (vertices.size() == 0) {
vertex = create_indexed_vertex(bundle)
} else {
assert vertices.size() == 1
vertex = update_indexed_vertex(vertices[0], bundle)
}
return vertex
}
def get_or_create_vertex = { final List bundle, final String index_key ->
(data, index_name, keys) = bundle
index_value = data[index_key]
vertices = g.idx(index_name).get(index_key, index_value).toList()
if (vertices.size() == 0) {
vertex = create_indexed_vertex(bundle)
} else {
assert vertices.size() == 1
vertex = vertices[0]
}
return vertex
}
def transaction = { final Closure closure ->
g.setMaxBufferSize(0);
g.startTransaction();
try {
results = closure();
g.stopTransaction(TransactionalGraph.Conclusion.SUCCESS);
return results;
} catch (e) {
g.stopTransaction(TransactionalGraph.Conclusion.FAILURE);
return e;
}
}
def save_user_and_friends_as_batch = {
user = create_or_update_vertex(user_bundle, "user");
fake_userid_prefix = "555000000"
i = 0
for (fname in friends) {
i += 1
friend_userid = fake_userid_prefix+i
friend_bundle = [[name:fname, fake_userid_prefix:friend_userid],"user"]
friend = get_or_create_vertex(friend_bundle, "name")
found = user.out("knows").filter{it == friend}.count()
if (!found) { g.addEdge(user, friend, "knows"); }
}
return user;
}
return transaction(save_user_and_friends_as_batch);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment