summaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorAlon Levy <alon@pobox.com>2014-12-22 20:20:52 +0200
committerAlon Levy <alon@pobox.com>2014-12-22 20:20:55 +0200
commit89be53c7ebc6d05b3c7bd0ad2ef435b0630a5ca4 (patch)
tree001150322df7cbc858aca7997475de361a960f20 /src/server
parent631e00d723b0b54c61b94f6c06ae4a73e1770c25 (diff)
server: link attribute updates
Tested for name changes only, with the next commit's client side change. Notes: uses more than a single query to change each link's name. Since we use label's, and neo4j is finniky about them, we must: 1. create a new link with copied properties (for future proofing, we use none at the moment) 2. delete the old link. Cannot do those in the same statement, the following results in a Neo4j error: match a-[l]->b create a-[l2:Poo]->b set l2=l delete l "errors": [ { "code": "Neo.DatabaseError.Statement.ExecutionFailure", "message": "Relationship 13 has been deleted", "stackTrace": <snip> } ]
Diffstat (limited to 'src/server')
-rw-r--r--src/server/db_controller.py53
1 files changed, 52 insertions, 1 deletions
diff --git a/src/server/db_controller.py b/src/server/db_controller.py
index af776a5f..d8838936 100644
--- a/src/server/db_controller.py
+++ b/src/server/db_controller.py
@@ -185,7 +185,58 @@ class DBO_attr_diff_commit(DB_op):
self.add_statement(q, q_param_set)
for id_attr, n_attr_diff in attr_diff.type__link.items():
- pass # TODO: handl link attr_diffs
+ r_attr_set = n_attr_diff['__attr_remove']
+ w_attr_set = n_attr_diff['__attr_write']
+
+ assert len(r_attr_set) > 0 or len(w_attr_set) > 0
+ assert 'name' not in r_attr_set
+
+ # Labels on relationships are different, we use a label for the name property
+ if 'name' in w_attr_set:
+ self.add_link_rename_statements(id_attr, w_attr_set['name'])
+ del w_attr_set['name']
+ if len(w_attr_set) == 0 and len(r_attr_set) == 0:
+ print('that is all she wrote')
+ return
+
+ q_arr = ["match (a)-[l {id: {id}}]-(b)",
+ "return l.id, l"]
+ q_param_set = {'id': id_attr}
+
+ if len(r_attr_set) > 0:
+ stmt_attr_rm = "remove " + ', '.join(['l.' + attr for attr in r_attr_set])
+ q_arr.insert(1, stmt_attr_rm)
+
+ if len(w_attr_set) > 0:
+ stmt_attr_set = "set l += {attr_set}"
+ q_arr.insert(1, stmt_attr_set)
+ q_param_set['attr_set'] = w_attr_set
+
+ q = " ".join(q_arr)
+ self.add_statement(q, q_param_set)
+
+ def add_link_rename_statements(self, id_attr, new_label):
+ # TODO - where do we sanitize the label name? any better way of doing this?
+ # XXX - the return here is a bit verbose? maybe better built on python side?
+ # NONGOALS: doing this on the client.
+
+ # Should assert the following returns 1
+ # match a-[l:new_label]->b return count(l)
+ # Not doing so to avoid roundtrip - the following doesn't require knowing
+ # the replaced label.
+
+ q_param_set = {'id': id_attr}
+ q_create_new = (' '.join([
+ "match a-[l_old {id: {id}}]->b",
+ "create a-[l_new:%s]->b set l_new=l_old",
+ "return l_new.id, {id: l_new.id, name: type(l_new)}",
+ ])% new_label)
+ q_delete_old = (' '.join([
+ "match a-[l_old {id: {id}}]->b",
+ "where type(l_old)<>'%s' delete l_old",
+ ]) % new_label)
+ self.add_statement(q_create_new, q_param_set)
+ self.add_statement(q_delete_old, q_param_set)
def process_result_set(self):
ret = {}