예제 #1
0
    def build_sql_query(self, query_desc):
        """Modify a raw SQL query with some others rules."""

        query = query_desc['sql']
        params = []

        for name, value in query_desc.iteritems():
            #skip system fields
            if name.startswith('_'):
                #FIXME: put this in a central place!
                if name not in ('_limit', '_limit_start',
                                '_resolve_phonenumber',
                                '_retrieve_full_contact'):
                    raise InvalidField("Query rule '%s' does not exist." %
                                       (name, ))
                else:
                    continue
            elif name.startswith('@'):
                if name[1:] not in DomainManager.get_domains():
                    raise InvalidField("Domain '%s' does not exist." %
                                       (name[1:], ))
                else:
                    continue

        limit_start = 0
        if '_limit_start' in query_desc:
            try:
                limit_start = int(query_desc['_limit_start'])
            except:
                raise InvalidField("_limit_start should be an integer value")

        limit_end = -1
        if '_limit' in query_desc:
            try:
                limit_end = int(query_desc['_limit'])
            except:
                raise InvalidField("_limit should be an integer value")

        if (limit_start != 0 or limit_end != -1):
            query = "SELECT * FROM (" + query + ") LIMIT ?,?"
            params.extend([limit_start, limit_end])

        return {'Query': query, 'Parameters': params}
예제 #2
0
    def build_search_query(self, query_desc):
        """Recieves a dictionary and makes an sql query that returns all the
        id's of those who meet the dictionaries restrictions"""
        params = []
        not_first = False

        if '_at_least_one' in query_desc:
            table_join_operator = " UNION "
        else:
            table_join_operator = " INTERSECT "
        query = ""
        for name, value in query_desc.iteritems():
            #skip system fields
            if name.startswith('_'):
                #FIXME: put this in a central place!
                if name not in ('_at_least_one', '_sortdesc', '_sortby',
                                '_limit', '_limit_start',
                                '_resolve_phonenumber',
                                '_retrieve_full_contact'):
                    raise InvalidField("Query rule '%s' does not exist." %
                                       (name, ))
                else:
                    continue
            elif name.startswith('@'):
                if name[1:] not in DomainManager.get_domains():
                    raise InvalidField("Domain '%s' does not exist." %
                                       (name[1:], ))
                else:
                    continue

            if not_first:
                query = query + table_join_operator

            not_first = True

            #handle type searching
            if name.startswith('<') or name.startswith('>'):
                pos = 1
                if (name[1] == '='):
                    pos = 2
                operator = name[:pos]
                name = name[pos:]
            elif name.startswith('!'):
                operator = '!='
                name = name[1:]
            else:
                operator = '='

            if name.startswith('$'):
                field_type = name[1:]
                table = self.get_table_name_from_type(field_type)
                if not table:
                    raise InvalidField("Type '%s' does not exist." %
                                       (field_type, ))
                query = query + "SELECT DISTINCT " + self.db_prefix + "_id FROM " + \
                        table + " WHERE ("
            else:
                field_type = self.domain.field_type_from_name(name)
                table = self.get_table_name(name)
                if not table:
                    raise InvalidField(
                        "Field '%s' is reserved for internal use." % (name, ))
                query = query + "SELECT DISTINCT " + self.db_prefix + "_id FROM " + \
                        table + " WHERE field_name = ? AND ("
                params.append(str(name))
            #If multi values, make OR connections
            comp_string = self.get_value_compare_string(
                field_type, name, operator)

            if type(value) == Array or type(value) == list:
                first_val = True

                for val in value:
                    if first_val:
                        first_val = False
                    else:
                        query = query + " OR "

                    query = query + comp_string
                    params.append(
                        self.get_value_compare_object(field_type, name, val))
            else:
                query = query + comp_string
                params.append(
                    self.get_value_compare_object(field_type, name, value))

            query = query + ")"

        #If there are no restrictions get everything
        if query == "":
            query = "SELECT " + self.db_prefix + "_id FROM " + self.db_prefix
        if '_sortby' in query_desc:
            sortby = query_desc['_sortby']
            query = "SELECT DISTINCT " + self.db_prefix + "_id FROM (" + query + \
                        ") JOIN " + self.get_table_name(sortby) + " USING (" + \
                        self.db_prefix + "_id) WHERE field_name = ? ORDER BY value"
            params.append(sortby)
            if '_sortdesc' in query_desc:
                query = query + " DESC"

        limit_start = 0
        if '_limit_start' in query_desc:
            try:
                limit_start = int(query_desc['_limit_start'])
            except:
                raise InvalidField("_limit_start should be an integer value")

        limit_end = -1
        if '_limit' in query_desc:
            try:
                limit_end = int(query_desc['_limit'])
            except:
                raise InvalidField("_limit should be an integer value")

        if (limit_start != 0 or limit_end != -1):
            query = query + " LIMIT ?,?"
            params.extend([limit_start, limit_end])

        return {'Query': query, 'Parameters': params}