diff options
| author | LV-426 <lv-426@taproot.org.il> | 2015-03-31 23:10:05 +0300 |
|---|---|---|
| committer | LV-426 <lv-426@taproot.org.il> | 2015-04-01 22:25:56 +0300 |
| commit | 6750ee7f5f67822355c7fa24776c61c60e0b5672 (patch) | |
| tree | 36b09a3c775f837b8bba7445a5f146fe205ebd64 /src/server/neo4j_qt.py | |
| parent | f9f11a4e22ee580344f8cc092b07a44ce9c0945c (diff) | |
neo4j_qt.py: refactor query transformation logic to dedicated file
Diffstat (limited to 'src/server/neo4j_qt.py')
| -rw-r--r-- | src/server/neo4j_qt.py | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/server/neo4j_qt.py b/src/server/neo4j_qt.py new file mode 100644 index 00000000..5bdb9604 --- /dev/null +++ b/src/server/neo4j_qt.py @@ -0,0 +1,93 @@ +from neo4j_cypher import Query_Struct_Type, DB_Query +from neo4j_util import rzdoc__ns_label, rzdoc__meta_ns_label +from neo4j_cypher_parser import p_path, p_node +from db_op import DBO_rzdoc__clone, DB_op +import re +import neo4j_schema + +class Query_Transformation(object): + """ + DB_op / DB_Query transformation + """ + + def __call__(self, value): + """ + Apply transformation to either a DB_op or a DB_Query + """ + if isinstance(value, DB_Query): + return self.apply_to_db_op(value) + if isinstance(value, DB_op): + return self.apply_to_db_op(value) + + def apply_to_db_op(self, op): + for dbq in op: # apply to sub queries + self.apply_to_single_query(dbq) + return op + + def apply_to_single_query(self, dbq): pass # subclass hook + +class QT_RZDOC_NS_Filter__common(Query_Transformation): + """ + Add RZDoc name-space filter: + - inject NS labels into node patterns + - [!] ignore nodes which are part of path patterns to avoid overriding bound references + """ + + def __init__(self, ns_label): + self.ns_label = ns_label + + def deco__process_q_ret__n_label_set(self, label_set): + ret = [lbl for lbl in label_set if lbl != self.ns_label] + return ret + + def apply_to_db_op(self, op): + ret = Query_Transformation.apply_to_db_op(self, op) + + # override DBO_rzdoc__clone.process_q_ret__n_label_set hook + if op.__class__ == DBO_rzdoc__clone: + op.process_q_ret__n_label_set = self.deco__process_q_ret__n_label_set + + return ret + + def apply_to_single_query(self, dbq): + q_type = dbq.query_struct_type + clause_set = [] + + if Query_Struct_Type.w == q_type: + clause_set += dbq.pt_root.clause_set_by_kw('create') + if Query_Struct_Type.r == q_type: + clause_set += dbq.pt_root.clause_set_by_kw('match') + if Query_Struct_Type.rw == q_type: + clause_set += dbq.pt_root.clause_set_by_kw('create') + clause_set += dbq.pt_root.clause_set_by_kw('match') + + for c in clause_set: + n_exp_set = c.sub_exp_set_by_type(p_node, recurse=True) + for n_exp in n_exp_set: + + if n_exp.parent.__class__ == p_path: + continue; + + lbl_set = n_exp.label_set + if not lbl_set: # add label set if necessary + lbl_set = n_exp.spawn_label_set() + lbl_set.add_label(self.ns_label) + + # log.debug('db_q trans: in clause: %s, out clause: %s' % (cur_clause, new_clause)) + +class QT_RZDOC_NS_Filter(QT_RZDOC_NS_Filter__common): + + def __init__(self, rzdoc): + ns_label = rzdoc__ns_label(rzdoc) + super(QT_RZDOC_NS_Filter, self).__init__(ns_label) + +class QT_RZDOC_Meta_NS_Filter(QT_RZDOC_NS_Filter__common): + + def __init__(self, rzdoc): + ns_label = rzdoc__meta_ns_label(rzdoc) + super(QT_RZDOC_Meta_NS_Filter, self).__init__(ns_label) + +class QT_Node_Filter__meta_label_set(Query_Transformation): + # TODO: impl + # 'where 0 = length(filter(_lbl in labels(n) where _lbl =~ \'^__.*$\'))', # filter nodes with meta labels + pass |
