Ejemplo n.º 1
0
 def get_filtered_nodes(self, lookups, label=None, include_properties=None,
                        limit=None, offset=None):
     # Using Cypher
     cypher = self.cypher
     if label:
         script = """start n=node:`%s`('label:%s') """ \
                  % (self.nidx.name, label)
     else:
         script = """start n=node:`%s`('label:*') """ \
                  % self.nidx.name
     where = None
     params = []
     if lookups:
         wheres = q_lookup_builder()
         for lookup in lookups:
             if isinstance(lookup, q_lookup_builder):
                 wheres &= lookup
             elif isinstance(lookup, dict):
                 wheres &= q_lookup_builder(**lookup)
         where, params = wheres.get_query_objects(var="n")
     if where:
         script = u"%s where %s return " % (script, where)
     else:
         script = u"%s return " % script
     if include_properties:
         script = u"%s id(n), n" % script
     else:
         script = u"%s id(n)" % script
     page = 1000
     skip = offset or 0
     limit = limit or page
     try:
         paged_script = "%s skip %s limit %s" % (script, skip, limit)
         result = cypher(query=paged_script, params=params)
     except:
         result = None
     while result and "data" in result:
         if include_properties:
             for element in result["data"]:
                 properties = element[1]["data"]
                 elto_id = properties.pop("_id")
                 elto_label = properties.pop("_label")
                 properties.pop("_graph", None)
                 yield (elto_id, properties, elto_label)
         else:
             for element in result["data"]:
                 if len(element) > 1:
                     yield (element[0], None, element[1])
                 else:
                     yield (element[0], None, None)
         skip += limit
         if len(result["data"]) == limit:
             try:
                 paged_script = "%s skip %s limit %s" % (script, skip,
                                                         limit)
                 result = cypher(query=paged_script, params=params)
             except:
                 result = None
         else:
             break
Ejemplo n.º 2
0
 def get_filtered_nodes(self, lookups, label=None, include_properties=None,
                        limit=None, offset=None, order_by=None):
     # Using Cypher
     cypher = self.cypher
     if isinstance(label, (list, tuple)) and not label:
         return
     script = self._prepare_script(for_node=True, label=label)
     where = None
     params = []
     if lookups:
         wheres = q_lookup_builder()
         for lookup in lookups:
             if isinstance(lookup, q_lookup_builder):
                 wheres &= lookup
             elif isinstance(lookup, dict):
                 wheres &= q_lookup_builder(**lookup)
         where, params = wheres.get_query_objects(var="n")
     if where:
         script = u"%s where %s return " % (script, where)
     else:
         script = u"%s return " % script
     if include_properties:
         script = u"%s id(n), n" % script
     else:
         script = u"%s id(n)" % script
     if order_by:
         script = u"%s order by n.`%s` %s " % (script, order_by[0][0].replace('`', '\`'), order_by[0][1])
     page = 1000
     skip = offset or 0
     limit = limit or page
     try:
         paged_script = "%s skip %s limit %s" % (script, skip, limit)
         result = cypher(query=paged_script, params=params)
     except:
         result = None
     while result and "data" in result:
         if include_properties:
             for element in result["data"]:
                 properties = element[1]["data"]
                 elto_id = properties.pop("_id")
                 elto_label = properties.pop("_label")
                 properties.pop("_graph", None)
                 yield (elto_id, properties, elto_label)
         else:
             for element in result["data"]:
                 if len(element) > 1:
                     yield (element[0], None, element[1])
                 else:
                     yield (element[0], None, None)
         skip += limit
         if len(result["data"]) == limit:
             try:
                 paged_script = "%s skip %s limit %s" % (script, skip,
                                                         limit)
                 result = cypher(query=paged_script, params=params)
             except:
                 result = None
         else:
             break
Ejemplo n.º 3
0
 def _query_generator_conditions(self, conditions_dict):
     # This list is used to control when use the index for the relationship,
     # in the origins or in the patterns
     conditions_alias = set()
     elems = q_lookup_builder()
     for condition_dict in conditions_dict:
         lookup, property_tuple, match, connector, datatype = condition_dict
         conditions_alias.add(property_tuple[1])
         # This is the option to have properties of another boxes
         # We need to check 'property_box' too for the old queries
         if datatype in ['f_expression', 'property_box']:
             # We catch exception of type IndexError, in case that we
             # doesn't receive an appropiate array.
             try:
                 match = self._query_generator_f_expression(match, datatype)
             except IndexError:
                 match = {
                     "var": "",
                     "property": "",
                 }
         if lookup == "between":
             gte = q_lookup_builder(property=property_tuple[2],
                                    lookup="gte",
                                    match=match[0],
                                    nullable=True,
                                    var=property_tuple[1],
                                    datatype=datatype[0])
             lte = q_lookup_builder(property=property_tuple[2],
                                    lookup="lte",
                                    match=match[1],
                                    nullable=True,
                                    var=property_tuple[1],
                                    datatype=datatype[1])
             q_element = (gte & lte)
         elif lookup == 'idoesnotcontain':
             q_element = ~q_lookup_builder(property=property_tuple[2],
                                           lookup="icontains",
                                           match=match,
                                           nullable=True,
                                           var=property_tuple[1],
                                           datatype=datatype)
         else:
             q_element = q_lookup_builder(property=property_tuple[2],
                                          lookup=lookup,
                                          match=match,
                                          nullable=True,
                                          var=property_tuple[1],
                                          datatype=datatype)
         if connector.upper() == "OR":
             elems |= q_element
         else:
             elems &= q_element
     conditions, query_params = elems.get_query_objects()
     return (conditions.strip(), query_params, conditions_alias)
Ejemplo n.º 4
0
    def _query_generator_conditions(self, conditions_dict):
        query_params = dict()
        # This list is used to control when use the index for the relationship,
        # in the origins or in the patterns
        conditions_alias = set()
        # conditions_set = set()
        # We are going to use a list because when the set add elements,
        # it include them in order and breaks our pattern with AND, OR
        conditions_set = list()
        conditions_indexes = enumerate(conditions_dict)
        conditions_length = len(conditions_dict) - 1
        for lookup, property_tuple, match, connector, datatype \
                in conditions_dict:
            # This is the option to have properties of another boxes
            if datatype == "property_box":
                match_dict = dict()
                # We catch exception of type IndexError, in case that we
                # doesn't receive an appropiate array.
                try:
                    # The match can be defined in three different ways:
                    # slug.property_id
                    # aggregate (slug.property_id)
                    # aggregate (DISTINCT slug.property_id)
                    # And also, we could have two match values for
                    # 'in between' lookups...
                    match_results = list()
                    match_elements = list()
                    datatypes = list()
                    if type(match) is not list:
                        match_elements.append(match)
                        datatypes.append(datatype)
                    else:
                        match_elements = match
                        datatypes = datatype
                    index = 0
                    while index < len(match_elements):
                        match_element = match_elements[index]
                        if datatypes[index] == 'property_box':
                            # Let's check what definition we have...
                            match_splitted = re.split('\)|\(|\\.| ',
                                                      match_element)
                            match_first_element = match_splitted[0]
                            # We check if aggregate belongs to the aggregate
                            # set
                            if match_first_element not in AGGREGATES:
                                slug = match_first_element
                                prop = match_splitted[1]
                                match_var, match_property = (
                                    self._get_slug_and_prop(slug, prop))
                                # Finally, we assign the correct values to the
                                # dict
                                match_dict['var'] = match_var
                                match_dict['property'] = match_property
                                match = match_dict
                            else:
                                # We have aggregate
                                aggregate = match_first_element
                                match_second_element = match_splitted[1]
                                # We check if we already have the distinct
                                # clause
                                if match_second_element != 'DISTINCT':
                                    # We get the slug and the property
                                    slug = match_second_element
                                    prop = match_splitted[2]
                                    match_var, match_property = (
                                        self._get_slug_and_prop(slug, prop))
                                    # Once we have the slug and the prop, we
                                    # build the
                                    # aggregate again
                                    agg_field = u"{0}({1}.{2})".format(
                                        aggregate, match_var, match_property)
                                    match_dict['aggregate'] = agg_field
                                    match = match_dict
                                else:
                                    # We have distinct, slug and the property
                                    distinct = match_second_element
                                    # We get the slug and the property
                                    slug = match_splitted[2]
                                    prop = match_splitted[3]
                                    match_var, match_property = (
                                        self._get_slug_and_prop(slug, prop))
                                    # Once we have the slug and the prop, we
                                    # build the aggregate again
                                    agg_field = (u"{0}({1} {2}.{3})".format(
                                        aggregate, distinct, match_var,
                                        match_property))
                                    match_dict['aggregate'] = agg_field
                                    match = match_dict
                        else:
                            match = match_element
                        index = index + 1
                        match_results.append(match)
                    if len(match_results) == 1:
                        match = match_results[0]
                    else:
                        match = match_results
                except IndexError:
                    match_dict['var'] = ""
                    match_dict['property'] = ""
                    match = match_dict

            if lookup == "between":
                gte = q_lookup_builder(property=property_tuple[2],
                                       lookup="gte",
                                       match=match[0],
                                       var=property_tuple[1],
                                       datatype=datatype[0])
                lte = q_lookup_builder(property=property_tuple[2],
                                       lookup="lte",
                                       match=match[1],
                                       var=property_tuple[1],
                                       datatype=datatype[1])
                gte_query_objects = gte.get_query_objects(params=query_params)
                lte_query_objects = lte.get_query_objects(params=query_params)
                gte_condition = gte_query_objects[0]
                gte_params = gte_query_objects[1]
                lte_condition = lte_query_objects[0]
                lte_params = lte_query_objects[1]
                # conditions_set.add(unicode(gte_condition))
                if gte_condition not in conditions_set:
                    conditions_set.append(unicode(gte_condition))
                query_params.update(gte_params)
                # conditions_set.add(unicode(lte_condition))
                if lte_condition not in conditions_set:
                    conditions_set.append(unicode(lte_condition))
                query_params.update(lte_params)
                # We append the two property in the list
                conditions_alias.add(property_tuple[1])
            elif lookup == 'idoesnotcontain':
                q_element = ~q_lookup_builder(property=property_tuple[2],
                                              lookup="icontains",
                                              match=match,
                                              var=property_tuple[1],
                                              datatype=datatype)
                query_objects = q_element.get_query_objects(
                    params=query_params)
                condition = query_objects[0]
                params = query_objects[1]
                # conditions_set.add(unicode(condition))
                if condition not in conditions_set:
                    conditions_set.append(unicode(condition))
                query_params.update(params)
                # We append the two property in the list
                conditions_alias.add(property_tuple[1])
            else:
                q_element = q_lookup_builder(property=property_tuple[2],
                                             lookup=lookup,
                                             match=match,
                                             var=property_tuple[1],
                                             datatype=datatype)
                query_objects = q_element.get_query_objects(
                    params=query_params)
                condition = query_objects[0]
                params = query_objects[1]
                # conditions_set.add(unicode(condition))
                if condition not in conditions_set:
                    conditions_set.append(unicode(condition))
                # Uncomment this line to see the difference between use
                # query params or use the q_element
                # conditions_set.add(unicode(q_element))
                query_params.update(params)
                # We append the two property in the list
                conditions_alias.add(property_tuple[1])
            if connector != 'not':
                # We have to get the next element to keep the concordance
                elem = conditions_indexes.next()
                connector = u' {} '.format(connector.upper())
                # conditions_set.add(connector)
                conditions_set.append(connector)
            elif connector == 'not':
                elem = conditions_indexes.next()
                if elem[0] < conditions_length:
                    connector = u' AND '
                    # conditions_set.add(connector)
                    conditions_set.append(connector)
        # We check if we have only one condition and one operator
        if len(conditions_set) > 0:
            conditions_last_index = len(conditions_set) - 1
            conditions_last_element = conditions_set[conditions_last_index]
            if (conditions_last_element == ' AND '
                    or conditions_last_element == ' OR '):
                conditions_set.pop()
        conditions = u" ".join(conditions_set)
        return (conditions, query_params, conditions_alias)
Ejemplo n.º 5
0
 def get_filtered_relationships(self,
                                lookups,
                                label=None,
                                include_properties=None,
                                limit=None,
                                offset=None,
                                order_by=None):
     # Using Cypher
     cypher = self.cypher
     if isinstance(label, (list, tuple)) and not label:
         return
     script = self._prepare_script(for_node=False, label=label)
     script = """%s match a-[r]->b """ % script
     where = None
     params = []
     if lookups:
         wheres = q_lookup_builder()
         for lookup in lookups:
             if isinstance(lookup, q_lookup_builder):
                 wheres &= lookup
             elif isinstance(lookup, dict):
                 wheres &= q_lookup_builder(**lookup)
         where, params = wheres.get_query_objects(var="r")
     if include_properties:
         type_or_r = "r"
     else:
         type_or_r = "type(r)"
     if where:
         script = u"%s where %s return distinct id(r), %s, a, b" \
                  % (script, where, type_or_r)
     else:
         script = u"%s return distinct id(r), %s, a, b" \
                  % (script, type_or_r)
     if order_by:
         script = u"%s order by n.`%s` %s " % (
             script, order_by[0][0].replace('`', '\`'), order_by[0][1])
     page = 1000
     skip = offset or 0
     limit = limit or page
     try:
         paged_script = "%s skip %s limit %s" % (script, skip, limit)
         result = cypher(query=paged_script, params=params)
     except:
         result = None
     while result and "data" in result and len(result["data"]) > 0:
         if include_properties:
             for element in result["data"]:
                 properties = element[1]["data"]
                 properties.pop("_id")
                 properties.pop("_graph", None)
                 elto_label = properties.pop("_label")
                 source_props = element[2]["data"]
                 source_id = source_props.pop("_id")
                 source_label = source_props.pop("_label")
                 source_props.pop("_graph", None)
                 source = {
                     "id": source_id,
                     "properties": source_props,
                     "label": source_label
                 }
                 target_props = element[3]["data"]
                 target_id = target_props.pop("_id")
                 target_label = target_props.pop("_label")
                 target_props.pop("_graph", None)
                 target = {
                     "id": target_id,
                     "properties": target_props,
                     "label": target_label
                 }
                 yield (element[0], properties, elto_label, source, target)
         else:
             for element in result["data"]:
                 yield (element[0], None, element[1])
         skip += page
         if len(result["data"]) == limit:
             try:
                 paged_script = "%s skip %s limit %s" % (script, skip,
                                                         limit)
                 result = cypher(query=paged_script, params=params)
             except:
                 result = None
         else:
             break
Ejemplo n.º 6
0
 def get_filtered_relationships(self, lookups, label=None,
                                include_properties=None,
                                limit=None, offset=None, order_by=None):
     # Using Cypher
     cypher = self.cypher
     if isinstance(label, (list, tuple)) and not label:
         return
     script = self._prepare_script(for_node=False, label=label)
     script = """%s match a-[r]->b """ % script
     where = None
     params = []
     if lookups:
         wheres = q_lookup_builder()
         for lookup in lookups:
             if isinstance(lookup, q_lookup_builder):
                 wheres &= lookup
             elif isinstance(lookup, dict):
                 wheres &= q_lookup_builder(**lookup)
         where, params = wheres.get_query_objects(var="r")
     if include_properties:
         type_or_r = "r"
     else:
         type_or_r = "type(r)"
     if where:
         script = u"%s where %s return distinct id(r), %s, a, b" \
                  % (script, where, type_or_r)
     else:
         script = u"%s return distinct id(r), %s, a, b" \
                  % (script, type_or_r)
     if order_by:
         script = u"%s order by n.`%s` %s " % (script, order_by[0][0].replace('`', '\`'), order_by[0][1])
     page = 1000
     skip = offset or 0
     limit = limit or page
     try:
         paged_script = "%s skip %s limit %s" % (script, skip, limit)
         result = cypher(query=paged_script, params=params)
     except:
         result = None
     while result and "data" in result and len(result["data"]) > 0:
         if include_properties:
             for element in result["data"]:
                 properties = element[1]["data"]
                 properties.pop("_id")
                 properties.pop("_graph", None)
                 elto_label = properties.pop("_label")
                 source_props = element[2]["data"]
                 source_id = source_props.pop("_id")
                 source_label = source_props.pop("_label")
                 source_props.pop("_graph", None)
                 source = {
                     "id": source_id,
                     "properties": source_props,
                     "label": source_label
                 }
                 target_props = element[3]["data"]
                 target_id = target_props.pop("_id")
                 target_label = target_props.pop("_label")
                 target_props.pop("_graph", None)
                 target = {
                     "id": target_id,
                     "properties": target_props,
                     "label": target_label
                 }
                 yield (element[0], properties, elto_label, source, target)
         else:
             for element in result["data"]:
                 yield (element[0], None, element[1])
         skip += page
         if len(result["data"]) == limit:
             try:
                 paged_script = "%s skip %s limit %s" % (script, skip,
                                                         limit)
                 result = cypher(query=paged_script, params=params)
             except:
                 result = None
         else:
             break
Ejemplo n.º 7
0
 def _query_generator_conditions(self, conditions_dict):
     query_params = dict()
     # This list is used to control when use the index for the relationship,
     # in the origins or in the patterns
     conditions_alias = set()
     conditions_set = set()
     conditions_indexes = enumerate(conditions_dict)
     conditions_length = len(conditions_dict) - 1
     for lookup, property_tuple, match, connector, datatype \
             in conditions_dict:
         if lookup == "between":
             gte = q_lookup_builder(property=property_tuple[2],
                                    lookup="gte",
                                    match=match[0],
                                    var=property_tuple[1],
                                    datatype=datatype)
             lte = q_lookup_builder(property=property_tuple[2],
                                    lookup="lte",
                                    match=match[1],
                                    var=property_tuple[1],
                                    datatype=datatype)
             gte_query_objects = gte.get_query_objects(params=query_params)
             lte_query_objects = lte.get_query_objects(params=query_params)
             gte_condition = gte_query_objects[0]
             gte_params = gte_query_objects[1]
             lte_condition = lte_query_objects[0]
             lte_params = lte_query_objects[1]
             conditions_set.add(unicode(gte_condition))
             query_params.update(gte_params)
             conditions_set.add(unicode(lte_condition))
             query_params.update(lte_params)
             # We append the two property in the list
             conditions_alias.add(property_tuple[1])
         elif lookup == 'idoesnotcontain':
             q_element = ~q_lookup_builder(property=property_tuple[2],
                                           lookup="icontains",
                                           match=match,
                                           var=property_tuple[1],
                                           datatype=datatype)
             query_objects = q_element.get_query_objects(
                 params=query_params)
             condition = query_objects[0]
             params = query_objects[1]
             conditions_set.add(unicode(condition))
             query_params.update(params)
             # We append the two property in the list
             conditions_alias.add(property_tuple[1])
         else:
             q_element = q_lookup_builder(property=property_tuple[2],
                                          lookup=lookup,
                                          match=match,
                                          var=property_tuple[1],
                                          datatype=datatype)
             query_objects = q_element.get_query_objects(
                 params=query_params)
             condition = query_objects[0]
             params = query_objects[1]
             conditions_set.add(unicode(condition))
             query_params.update(params)
             # We append the two property in the list
             conditions_alias.add(property_tuple[1])
         if connector != 'not':
             # We have to get the next element to keep the concordance
             elem = conditions_indexes.next()
             connector = u' {} '.format(connector.upper())
             conditions_set.add(connector)
         elif connector == 'not':
             elem = conditions_indexes.next()
             if elem[0] < conditions_length:
                 connector = u' AND '
                 conditions_set.add(connector)
     conditions = u" ".join(conditions_set)
     return (conditions, query_params, conditions_alias)
Ejemplo n.º 8
0
    def _query_generator_conditions(self, conditions_dict):
        query_params = dict()
        # This list is used to control when use the index for the relationship,
        # in the origins or in the patterns
        conditions_alias = set()
        # conditions_set = set()
        # We are going to use a list because when the set add elements,
        # it include them in order and breaks our pattern with AND, OR
        conditions_set = list()
        conditions_indexes = enumerate(conditions_dict)
        conditions_length = len(conditions_dict) - 1
        for lookup, property_tuple, match, connector, datatype \
                in conditions_dict:
            # This is the option to have properties of another boxes
            if datatype == "property_box":
                match_dict = dict()
                # We catch exception of type IndexError, in case that we
                # doesn't receive an appropiate array.
                try:
                    # The match can be defined in three different ways:
                    # slug.property_id
                    # aggregate (slug.property_id)
                    # aggregate (DISTINCT slug.property_id)
                    # And also, we could have two match values for
                    # 'in between' lookups...
                    match_results = list()
                    match_elements = list()
                    datatypes = list()
                    if type(match) is not list:
                        match_elements.append(match)
                        datatypes.append(datatype)
                    else:
                        match_elements = match
                        datatypes = datatype
                    index = 0
                    while index < len(match_elements):
                        match_element = match_elements[index]
                        if datatypes[index] == 'property_box':
                            # Let's check what definition we have...
                            match_splitted = re.split('\)|\(|\\.| ',
                                                      match_element)
                            match_first_element = match_splitted[0]
                            # We check if aggregate belongs to the aggregate
                            # set
                            if match_first_element not in AGGREGATES:
                                slug = match_first_element
                                prop = match_splitted[1]
                                match_var, match_property = (
                                    self._get_slug_and_prop(slug, prop))
                                # Finally, we assign the correct values to the
                                # dict
                                match_dict['var'] = match_var
                                match_dict['property'] = match_property
                                match = match_dict
                            else:
                                # We have aggregate
                                aggregate = match_first_element
                                match_second_element = match_splitted[1]
                                # We check if we already have the distinct
                                # clause
                                if match_second_element != 'DISTINCT':
                                    # We get the slug and the property
                                    slug = match_second_element
                                    prop = match_splitted[2]
                                    match_var, match_property = (
                                        self._get_slug_and_prop(slug, prop))
                                    # Once we have the slug and the prop, we
                                    # build the
                                    # aggregate again
                                    agg_field = u"{0}({1}.{2})".format(
                                        aggregate, match_var, match_property)
                                    match_dict['aggregate'] = agg_field
                                    match = match_dict
                                else:
                                    # We have distinct, slug and the property
                                    distinct = match_second_element
                                    # We get the slug and the property
                                    slug = match_splitted[2]
                                    prop = match_splitted[3]
                                    match_var, match_property = (
                                        self._get_slug_and_prop(slug, prop))
                                    # Once we have the slug and the prop, we
                                    # build the aggregate again
                                    agg_field = (
                                        u"{0}({1} {2}.{3})".format(
                                            aggregate, distinct, match_var,
                                            match_property))
                                    match_dict['aggregate'] = agg_field
                                    match = match_dict
                        else:
                            match = match_element
                        index = index + 1
                        match_results.append(match)
                    if len(match_results) == 1:
                        match = match_results[0]
                    else:
                        match = match_results
                except IndexError:
                    match_dict['var'] = ""
                    match_dict['property'] = ""
                    match = match_dict

            if lookup == "between":
                gte = q_lookup_builder(property=property_tuple[2],
                                       lookup="gte",
                                       match=match[0],
                                       var=property_tuple[1],
                                       datatype=datatype[0])
                lte = q_lookup_builder(property=property_tuple[2],
                                       lookup="lte",
                                       match=match[1],
                                       var=property_tuple[1],
                                       datatype=datatype[1])
                gte_query_objects = gte.get_query_objects(params=query_params)
                lte_query_objects = lte.get_query_objects(params=query_params)
                gte_condition = gte_query_objects[0]
                gte_params = gte_query_objects[1]
                lte_condition = lte_query_objects[0]
                lte_params = lte_query_objects[1]
                # conditions_set.add(unicode(gte_condition))
                if gte_condition not in conditions_set:
                    conditions_set.append(unicode(gte_condition))
                query_params.update(gte_params)
                # conditions_set.add(unicode(lte_condition))
                if lte_condition not in conditions_set:
                    conditions_set.append(unicode(lte_condition))
                query_params.update(lte_params)
                # We append the two property in the list
                conditions_alias.add(property_tuple[1])
            elif lookup == 'idoesnotcontain':
                q_element = ~q_lookup_builder(property=property_tuple[2],
                                              lookup="icontains",
                                              match=match,
                                              var=property_tuple[1],
                                              datatype=datatype)
                query_objects = q_element.get_query_objects(
                    params=query_params)
                condition = query_objects[0]
                params = query_objects[1]
                # conditions_set.add(unicode(condition))
                if condition not in conditions_set:
                    conditions_set.append(unicode(condition))
                query_params.update(params)
                # We append the two property in the list
                conditions_alias.add(property_tuple[1])
            else:
                q_element = q_lookup_builder(property=property_tuple[2],
                                             lookup=lookup,
                                             match=match,
                                             var=property_tuple[1],
                                             datatype=datatype)
                query_objects = q_element.get_query_objects(
                    params=query_params)
                condition = query_objects[0]
                params = query_objects[1]
                # conditions_set.add(unicode(condition))
                if condition not in conditions_set:
                    conditions_set.append(unicode(condition))
                # Uncomment this line to see the difference between use
                # query params or use the q_element
                # conditions_set.add(unicode(q_element))
                query_params.update(params)
                # We append the two property in the list
                conditions_alias.add(property_tuple[1])
            if connector != 'not':
                # We have to get the next element to keep the concordance
                elem = conditions_indexes.next()
                connector = u' {} '.format(connector.upper())
                # conditions_set.add(connector)
                conditions_set.append(connector)
            elif connector == 'not':
                elem = conditions_indexes.next()
                if elem[0] < conditions_length:
                    connector = u' AND '
                    # conditions_set.add(connector)
                    conditions_set.append(connector)
        # We check if we have only one condition and one operator
        if len(conditions_set) > 0:
            conditions_last_index = len(conditions_set) - 1
            conditions_last_element = conditions_set[conditions_last_index]
            if (conditions_last_element == ' AND ' or
                    conditions_last_element == ' OR '):
                conditions_set.pop()
        conditions = u" ".join(conditions_set)
        return (conditions, query_params, conditions_alias)
Ejemplo n.º 9
0
 def get_filtered_relationships(self, lookups, label=None,
                                include_properties=None,
                                source_id=None, target_id=None,
                                directed=True,
                                limit=None, offset=None, order_by=None):
     # Using Cypher
     cypher = self.cypher
     if isinstance(label, (list, tuple)) and not label:
         return
     script = self._prepare_script(for_node=False, label=label)
     if source_id and target_id:
         script = """%s, a=node(%s), b=node(%s)""" % (
             script, source_id, target_id)
     elif source_id and not target_id:
         script = """%s, a=node(%s)""" % (script, source_id)
     elif not source_id and target_id:
         script = """%s, b=node(%s)""" % (script, target_id)
     if directed:
         script = """%s match (a)-[r]->(b) """ % script
     else:
         script = """%s match (a)-[r]-(b) """ % script
     where = None
     params = {}
     if lookups:
         wheres = q_lookup_builder()
         for lookup in lookups:
             if isinstance(lookup, q_lookup_builder):
                 wheres &= lookup
             elif isinstance(lookup, dict):
                 wheres &= q_lookup_builder(**lookup)
         where, params = wheres.get_query_objects(var="r")
     if include_properties:
         type_or_r = "r"
     else:
         type_or_r = "type(r)"
     if where:
         script = u"%s where %s return distinct id(r), %s, a, b" \
                  % (script, where, type_or_r)
     else:
         script = u"%s return distinct id(r), %s, a, b" \
                  % (script, type_or_r)
     if order_by:
         script = u"%s order by n.`%s` %s " % (
             script, order_by[0][0].replace(u'`', u'\\`'), order_by[0][1]
         )
     page = 1000
     skip = offset or 0
     limit = limit or page
     try:
         paged_script = "%s skip %s limit %s" % (script, skip, limit)
         result = cypher(q=paged_script, params=params)
     except:
         result = None
     while result and "data" in result and len(result["data"]) > 0:
         if include_properties:
             for element in result["data"]:
                 yield self._get_filtered_relationships_properties(element)
         else:
             for element in result["data"]:
                 yield (element[0], None, element[1])
         skip += page
         if len(result["data"]) == limit:
             try:
                 paged_script = "%s skip %s limit %s" % (script, skip,
                                                         limit)
                 result = cypher(q=paged_script, params=params)
             except:
                 result = None
         else:
             break