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 | |
| parent | f9f11a4e22ee580344f8cc092b07a44ce9c0945c (diff) | |
neo4j_qt.py: refactor query transformation logic to dedicated file
Diffstat (limited to 'src')
| -rw-r--r-- | src/server-tests/test_neo4j_cypher.py | 12 | ||||
| -rw-r--r-- | src/server/neo4j_cypher.py | 93 | ||||
| -rw-r--r-- | src/server/neo4j_qt.py | 93 | ||||
| -rw-r--r-- | src/server/rz_kernel.py | 2 |
4 files changed, 102 insertions, 98 deletions
diff --git a/src/server-tests/test_neo4j_cypher.py b/src/server-tests/test_neo4j_cypher.py index 3bab58d6..69433291 100644 --- a/src/server-tests/test_neo4j_cypher.py +++ b/src/server-tests/test_neo4j_cypher.py @@ -1,18 +1,18 @@ import unittest -from db_op import DBO_rz_clone, DBO_add_node_set, DBO_add_link_set, \ +from db_op import DBO_rzdoc__clone, DBO_add_node_set, DBO_add_link_set, \ DBO_block_chain__commit, DBO_diff_commit__attr, DBO_diff_commit__topo, \ - DBO_rm_node_set, DB_composed_op -import test_util + DBO_rm_node_set, DB_composed_op, DBO_block_chain__init, DBO_rzdoc__create,\ + DBO_rzdoc__delete, DBO_rzdoc__list, DBO_rzdoc__lookup_by_name from model.graph import Attr_Diff, Topo_Diff from test_util import generate_random_node_dict, generate_random_link_dict,\ generate_random_RZDoc import neo4j_test_util from neo4j_util import meta_attr_list_to_meta_attr_map from rz_server import Config, init_log -from neo4j_cypher import Cypher_Parser, DB_Query, QT_RZDOC_NS_Filter -import sys -from model.model import RZDoc +from neo4j_cypher import Cypher_Parser, DB_Query +from test_util__pydev import debug__pydev_pd_arg +from neo4j_qt import QT_RZDOC_NS_Filter class Test_DB_Op(unittest.TestCase): diff --git a/src/server/neo4j_cypher.py b/src/server/neo4j_cypher.py index 6a525f25..14f23241 100644 --- a/src/server/neo4j_cypher.py +++ b/src/server/neo4j_cypher.py @@ -3,12 +3,10 @@ Neo4j DB object """ from enum import Enum -from neo4j_cypher_parser import Cypher_Parser, e_clause__where, e_keyword, \ - e_value, p_node, p_path -import re +from neo4j_cypher_parser import Cypher_Parser, e_clause__where, e_keyword,\ + e_value import logging import neo4j_cypher_parser -from neo4j_util import rzdoc__ns_label, rzdoc__meta_ns_label import neo4j_schema log = logging.getLogger('rhizi') @@ -45,93 +43,6 @@ class Query_Struct_Type(Enum): return super(Query_Struct_Type, self).__eq__(other) -class Query_Transformation(object): - """ - A query transformation, which may be applied to either a DB_op or a DB_Query - """ - - def __call__(self, value): - - q_set = [] - - if isinstance(value, DB_Query): - q_set.append(value) - else: # assume iterable - assert hasattr(value, '__iter__') - - for dbq in value: - assert isinstance(dbq, DB_Query) - - q_set.append(dbq) - - for dbq in q_set: - log.debug('%r' % (dbq)) - self.apply_to_single_query(dbq) - log.debug('%r' % (dbq)) - - return value - - def apply_to_single_query(self, dbq): - pass - -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 apply_to_single_query(self, dbq): - - rgx__doc_label = re.compile(r'%s[\w\d_]+' % (neo4j_schema.META_LABEL__RZDOC_NS_PREFIX)) - assert None == rgx__doc_label.match(self.ns_label), 'Illegal doc ID label: %s' % (self.ns_label) # validate doc label - - 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 class DB_Query(object): 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 diff --git a/src/server/rz_kernel.py b/src/server/rz_kernel.py index ca9b56c4..278cb6fd 100644 --- a/src/server/rz_kernel.py +++ b/src/server/rz_kernel.py @@ -9,9 +9,9 @@ from db_op import DBO_diff_commit__attr, DBO_block_chain__commit, DBO_rzdoc__cre DBO_rzdoc__lookup_by_name, DBO_rz_clone, DBO_rzdoc__delete, DBO_rzdoc__list from db_op import DBO_diff_commit__topo from model.graph import Topo_Diff -from neo4j_cypher import QT_RZDOC_NS_Filter, QT_RZDOC_Meta_NS_Filter from model.model import RZDoc import neo4j_util +from neo4j_qt import QT_RZDOC_NS_Filter, QT_RZDOC_Meta_NS_Filter log = logging.getLogger('rhizi') |
