def __init__(self, query_string, _app=None):
        """Ctor.

    Parses the input query into the class as a pre-compiled query, allowing
    for a later call to Bind() to bind arguments as defined in the
    documentation.

    Args:
      query_string: properly formatted GQL query string.

    Raises:
      datastore_errors.BadQueryError: if the query is not parsable.
    """
        self._entity = ''
        self.__filters = {}
        self.__bound_filters = {}
        self.__has_ancestor = False
        self.__orderings = []
        self.__offset = -1
        self.__limit = -1
        self.__hint = ''
        self.__app = _app

        self.__symbols = self.TOKENIZE_REGEX.findall(query_string)
        self.__next_symbol = 0
        if not self.__Select():
            raise datastore_errors.BadQueryError('Unable to parse query')
        else:
            pass
Ejemplo n.º 2
0
    def __init__(self,
                 query_string,
                 _app=None,
                 _auth_domain=None,
                 namespace=None):
        """Ctor.

    Parses the input query into the class as a pre-compiled query, allowing
    for a later call to Bind() to bind arguments as defined in the
    documentation.

    Args:
      query_string: properly formatted GQL query string.
      namespace: the namespace to use for this query.

    Raises:
      datastore_errors.BadQueryError: if the query is not parsable.
    """

        self.__filters = {}

        self.__orderings = []

        self.__app = _app

        self.__namespace = namespace

        self.__auth_domain = _auth_domain

        self.__symbols = self.TOKENIZE_REGEX.findall(query_string)
        self.__next_symbol = 0
        if not self.__Select():

            raise datastore_errors.BadQueryError('Unable to parse query')
    def __Error(self, error_message):
        """Generic query error.

    Args:
      error_message: string to emit as part of the 'Parse Error' string.

    Raises:
      BadQueryError and passes on an error message from the caller. Will raise
      BadQueryError on all calls to __Error()
    """
        if self.__next_symbol >= len(self.__symbols):
            raise datastore_errors.BadQueryError(
                'Parse Error: %s at end of string' % error_message)
        else:
            raise datastore_errors.BadQueryError(
                'Parse Error: %s at symbol %s' %
                (error_message, self.__symbols[self.__next_symbol]))
Ejemplo n.º 4
0
 def count_async(self, limit, options=None):
     conn = tasklets.get_context()._conn
     options = QueryOptions(offset=limit, limit=0, config=options)
     dsqry, post_filters = self._get_query(conn)
     if post_filters:
         raise datastore_errors.BadQueryError(
             'Post-filters are not supported for count().')
     rpc = dsqry.run_async(conn, options)
     total = 0
     while rpc is not None:
         batch = yield rpc
         rpc = batch.next_batch_async(options)
         total += batch.skipped_results
     raise tasklets.Return(total)
    def __CastError(self, operator, values, error_message):
        """Query building error for type cast operations.

    Args:
      operator: the failed cast operation
      values: value list passed to the cast operator
      error_message: string to emit as part of the 'Cast Error' string.

    Raises:
      BadQueryError and passes on an error message from the caller. Will raise
      BadQueryError on all calls.
    """
        raise datastore_errors.BadQueryError(
            'Type Cast Error: unable to cast %r with operation %s (%s)' %
            (values, operator.upper(), error_message))
Ejemplo n.º 6
0
 def _filter_func(self, value, entity):
   if isinstance(entity, Key):
     raise datastore_errors.BadQueryError(
       'StructuredProperty filter cannot be used with keys_only query')
   subentities = getattr(entity, self._code_name, None)
   if subentities is None:
     return False
   if not isinstance(subentities, list):
     subentities = [subentities]
   for subentity in subentities:
     for name, prop in value._properties.iteritems():
       val = prop.RetrieveValue(value)
       if val is not None:
         if prop.RetrieveValue(subentity) != val:
           break
     else:
       return True
   return False
    def __AddMultiQuery(self, identifier, condition, value,
                        enumerated_queries):
        """Helper function to add a muti-query to previously enumerated queries.

    Args:
      identifier: property being filtered by this condition
      condition: filter condition (e.g. !=,in)
      value: value being bound
      enumerated_queries: in/out list of already bound queries -> expanded list
        with the full enumeration required to satisfy the condition query
    Raises:
      BadArgumentError if the filter is invalid (namely non-list with IN)
    """
        if condition.lower() in ('!=', 'in') and self._keys_only:
            raise datastore_errors.BadQueryError(
                'Keys only queries do not support IN or != filters.')

        def CloneQueries(queries, n):
            """Do a full copy of the queries and append to the end of the queries.

      Does an in-place replication of the input list and sorts the result to
      put copies next to one-another.

      Args:
        queries: list of all filters to clone
        n: number of copies to make

      Returns:
        Number of iterations needed to fill the structure
      """
            if not enumerated_queries:
                for i in xrange(n):
                    queries.append({})
                return 1
            else:
                old_size = len(queries)
                tmp_queries = []
                for i in xrange(n - 1):
                    [
                        tmp_queries.append(filter_map.copy())
                        for filter_map in queries
                    ]
                queries.extend(tmp_queries)
                queries.sort()
                return old_size

        if condition == '!=':
            if len(enumerated_queries) * 2 > self.MAX_ALLOWABLE_QUERIES:
                raise datastore_errors.BadArgumentError(
                    'Cannot satisfy query -- too many IN/!= values.')

            num_iterations = CloneQueries(enumerated_queries, 2)
            for i in xrange(num_iterations):
                enumerated_queries[2 * i]['%s <' % identifier] = value
                enumerated_queries[2 * i + 1]['%s >' % identifier] = value
        elif condition.lower() == 'in':
            if not isinstance(value, list):
                raise datastore_errors.BadArgumentError(
                    'List expected for "IN" filter')

            in_list_size = len(value)
            if len(enumerated_queries
                   ) * in_list_size > self.MAX_ALLOWABLE_QUERIES:
                raise datastore_errors.BadArgumentError(
                    'Cannot satisfy query -- too many IN/!= values.')

            num_iterations = CloneQueries(enumerated_queries, in_list_size)
            for clone_num in xrange(num_iterations):
                for value_num in xrange(len(value)):
                    list_val = value[value_num]
                    query_num = in_list_size * clone_num + value_num
                    filt = '%s =' % identifier
                    enumerated_queries[query_num][filt] = list_val
Ejemplo n.º 8
0
 def _to_filter(self, bindings):
     # Because there's no point submitting a query that will never
     # return anything.
     raise datastore_errors.BadQueryError(
         'Cannot convert FalseNode to predicate')