Esempio n. 1
0
    def cursor(self, index):
        """Gets the cursor that points to the result at the given index.

    The index is relative to first result in .results. Since start_cursor
    points to the position before the first skipped result and the end_cursor
    points to the position after the last result, the range of indexes this
    function supports is limited to [-skipped_results, len(results)].

    Args:
      index: An int, the index relative to the first result before which the
        cursor should point.

    Returns:
      A Cursor that points just before the result at the given index which if
      used as a start_cursor will cause the first result to result[index].
    """
        if not isinstance(index, (int, long)):
            raise datastore_errors.BadArgumentError(
                'index argument should be entity_pb.Reference (%r)' %
                (index, ))
        if not -self.__skipped_results <= index <= len(self.__results):
            raise datastore_errors.BadArgumentError(
                'index argument must be in the inclusive range [%d, %d]' %
                (-self.__skipped_results, len(self.__results)))

        if index == len(self.__results):
            return self.__end_cursor
        elif index == -self.__skipped_results:
            return self.__start_cursor
        else:
            return self.__start_cursor.advance(index + self.__skipped_results,
                                               self.__query, self.__conn)
Esempio n. 2
0
    def __init__(self, op, filters):
        """Constructor.

    Args:
      op: The operator to use to combine the given filters
      filters: A list of one or more filters to combine

    Raises:
      datastore_errors.BadArgumentError if op is not in CompsiteFilter.OPERATORS
      or filters is not a non-empty list containing only FilterPredicates.
    """
        if not op in self._OPERATORS:
            raise datastore_errors.BadArgumentError('unknown operator: %r' %
                                                    (op, ))
        if not filters or not isinstance(filters, list):
            raise datastore_errors.BadArgumentError(
                'filters argument should be a non-empty list (%r)' %
                (filters, ))

        super(CompositeFilter, self).__init__()
        self._op = op
        self._filters = []
        for f in filters:
            if isinstance(f, CompositeFilter) and f._op == self._op:
                self._filters.extend(f._filters)
            elif isinstance(f, FilterPredicate):
                self._filters.append(f)
            else:
                raise datastore_errors.BadArgumentError(
                    'filters argument must be a list of FilterPredicates, found (%r)'
                    % (f, ))
    def __GetParam(self, reference, args, keyword_args):
        """Get the specified parameter from the input arguments.

    Args:
      reference: id for a filter reference in the filter list (string or
          number)
      args: positional args passed in by the user (tuple of arguments, indexed
          numerically by "reference")
      keyword_args: dict of keyword based arguments (strings in "reference")

    Returns:
      The specified param from the input list.

    Raises:
      BadArgumentError if the referenced argument doesn't exist.
    """
        num_args = len(args)
        if isinstance(reference, int):

            if reference <= num_args:
                return args[reference - 1]
            else:
                raise datastore_errors.BadArgumentError(
                    'Missing argument for bind, requires argument #%i, '
                    'but only has %i args.' % (reference, num_args))
        elif isinstance(reference, basestring):
            if reference in keyword_args:
                return keyword_args[reference]
            else:
                raise datastore_errors.BadArgumentError(
                    'Missing named arguments for bind, requires argument %s' %
                    reference)
        else:

            assert False, 'Unknown reference %s' % reference
Esempio n. 4
0
    def filter(self, property_operator, value):
        """Adds a filter to query.

        Args:
          property_operator: string with the property and operator to filter by.
          value: the filter value.

        Returns:
          Self to support method chaining.

        Raises:
          BadArgumentError if invalid property is provided or two different
          inequality properties are set for the same query.
        """
        prop, operator = match_filter(property_operator)
        if operator in INEQUALITY_OPERATORS:
            if self._inequality_prop and self._inequality_prop != prop:
                raise datastore_errors.BadArgumentError('Queries must have '
                    'only one inequality operator.')
            self._inequality_prop = prop
            self._inequality_filters[operator] = value

            # Store the property name to be used in bookmarks.
            if prop not in self._bookmark_properties:
                self._bookmark_properties.append(prop)
        elif operator in OPERATORS:
            self._filters[prop] = value
        else:
            raise datastore_errors.BadArgumentError('Filter operator is not '
                'valid, received %s.' % operator)
        return self
Esempio n. 5
0
    def __init__(self,
                 app=None,
                 namespace=None,
                 kind=None,
                 ancestor=None,
                 filter_predicate=None,
                 order=None):
        """Constructor.

    Args:
      app: Optional app to query, derived from the environment if not specified.
      namespace: Optional namespace to query, derived from the environment if
        not specified.
      kind: Optional kind to query.
      ancestor: Optional ancestor to query.
      filter_predicate: Optional FilterPredicate by which to restrict the query.
      order: Optional Order in which to return results.

    Raises:
      datastore_errors.BadArgumentError if any argument is invalid.
    """
        if kind is not None:
            datastore_types.ValidateString(kind, 'kind',
                                           datastore_errors.BadArgumentError)
        if ancestor is not None and not isinstance(ancestor,
                                                   entity_pb.Reference):
            raise datastore_errors.BadArgumentError(
                'ancestor argument should be entity_pb.Reference (%r)' %
                (ancestor, ))

        if filter_predicate is not None and not isinstance(
                filter_predicate, FilterPredicate):
            raise datastore_errors.BadArgumentError(
                'filter_predicate should be datastore_query.FilterPredicate (%r)'
                % (ancestor, ))

        super(Query, self).__init__()
        if isinstance(order, CompositeOrder):
            if order.size() == 0:
                order = None
        elif isinstance(order, Order):
            order = CompositeOrder([order])
        elif order is not None:
            raise datastore_errors.BadArgumentError(
                'order should be Order (%r)' % (order, ))

        self.__app = datastore_types.ResolveAppId(app)
        self.__namespace = datastore_types.ResolveNamespace(namespace)
        self.__kind = kind
        self.__ancestor = ancestor
        self.__order = order
        self.__filter_predicate = filter_predicate
  def __init__(self, encoded=None):
    """Constructor. Creates a Key from a string.

    Args:
      # a base64-encoded primary key, generated by Key.__str__
      encoded: str
    """
    if encoded is not None:
      if not isinstance(encoded, basestring):
        try:
          repr_encoded = repr(encoded)
        except:
          repr_encoded = "<couldn't encode>"
        raise datastore_errors.BadArgumentError(
          'Key() expects a string; received %s (a %s).' %
          (repr_encoded, typename(encoded)))
      try:
        modulo = len(encoded) % 4
        if modulo != 0:
          encoded += ('=' * (4 - modulo))

        encoded_pb = base64.urlsafe_b64decode(str(encoded))
        self.__reference = entity_pb.Reference(encoded_pb)
        assert self.__reference.IsInitialized()

      except (AssertionError, TypeError), e:
        raise datastore_errors.BadKeyError(
          'Invalid string key %s. Details: %s' % (encoded, e))
      except Exception, e:
        if e.__class__.__name__ == 'ProtocolBufferDecodeError':
          raise datastore_errors.BadKeyError('Invalid string key %s.' % encoded)
        else:
          raise
Esempio n. 7
0
    def run_async(self, conn, query_options=None):
        """Runs the query using the provided datastore_rpc.Connection.

    Args:
      conn: the datastore_rpc.Connection on which to run the query.
      query_options: Optional QueryOptions with which to run the query.

    Returns:
      An async object that can be used to grab the first Batch. Additional
      batches can be retrieved by calling Batch.next_batch/next_batch_async.

    Raises:
      datastore_errors.BadArgumentError if any of the arguments are invalid.
    """
        if not isinstance(conn, datastore_rpc.BaseConnection):
            raise datastore_errors.BadArgumentError(
                'conn should be a datastore_rpc.BaseConnection (%r)' %
                (conn, ))

        if not isinstance(query_options, QueryOptions):
            query_options = QueryOptions(config=query_options)

        start_cursor = query_options.start_cursor
        if not start_cursor and query_options.produce_cursors:
            start_cursor = Cursor()

        batch0 = Batch(query_options, self, conn, start_cursor)
        req = self._to_pb(conn, query_options)
        return batch0._make_query_result_rpc_call('RunQuery', query_options,
                                                  req)
Esempio n. 8
0
    def __normalize_and_convert_keys(cls, keys):
        """Normalize and convert all keys to BlobKey type.

    This method is based on datastore.NormalizeAndTypeCheck().

    Args:
      keys: A single key or a list/tuple of keys.  Keys may be a string
        or BlobKey

    Returns:
      Single key or list with all strings replaced by BlobKey instances.
    """
        if isinstance(keys, (list, tuple)):
            multiple = True

            keys = list(keys)
        else:
            multiple = False
            keys = [keys]

        for index, key in enumerate(keys):
            if not isinstance(key, (basestring, BlobKey)):
                raise datastore_errors.BadArgumentError(
                    'Expected str or BlobKey; received %s (a %s)' %
                    (key, datastore.typename(key)))
            keys[index] = datastore.Key.from_path(cls.kind(),
                                                  str(key),
                                                  namespace='')

        if multiple:
            return keys
        else:
            return keys[0]
Esempio n. 9
0
    def __GetParam(self, param, args, keyword_args, used_args=None):
        """Get the specified parameter from the input arguments.

    If param is an index or named reference, args and keyword_args are used. If
    param is a cast operator tuple, will use __Operate to return the cast value.

    Args:
      param: represents either an id for a filter reference in the filter list
          (string or number) or a tuple (cast operator, params)
      args: positional args passed in by the user (tuple of arguments, indexed
          numerically by "param")
      keyword_args: dict of keyword based arguments (strings in "param")
      used_args: Index arguments passed from __Operate to determine which index
          references have been used. Default is None.

    Returns:
      The specified param from the input list.

    Raises:
      BadArgumentError: if the referenced argument doesn't exist or no type cast
      operator is present.
    """
        num_args = len(args)
        if isinstance(param, int):

            if param <= num_args:
                return args[param - 1]
            else:
                raise datastore_errors.BadArgumentError(
                    'Missing argument for bind, requires argument #%i, '
                    'but only has %i args.' % (param, num_args))
        elif isinstance(param, basestring):
            if param in keyword_args:
                return keyword_args[param]
            else:
                raise datastore_errors.BadArgumentError(
                    'Missing named arguments for bind, requires argument %s' %
                    param)
        elif isinstance(param, tuple) and len(param) == 2:
            cast_op, params = param
            return self.__Operate(args, keyword_args, used_args, cast_op,
                                  params)
        else:

            assert False, 'Unknown parameter %s' % param
  def __init__(self, orders):
    """Constructor.

    Args:
      orders: A list of Orders which are applied in order.
    """
    if not isinstance(orders, list):
      raise datastore_errors.BadArgumentError(
          'orders argument should be list (%r)' % (orders,))

    self.__orders = []
    for order in orders:
      if isinstance(order, CompositeOrder):
        self.__orders.extend(order.__orders)
      elif isinstance(order, Order):
        self.__orders.append(order)
      else:
        raise datastore_errors.BadArgumentError(
            'orders argument should only contain Order (%r)' % (order,))
Esempio n. 11
0
    def produce_cursors(value):
        """If a Cursor should be returned with the fetched results.

    Raises:
      datastore_errors.BadArgumentError if value is not a bool.
    """
        if not isinstance(value, bool):
            raise datastore_errors.BadArgumentError(
                'produce_cursors argument should be bool (%r)' % (value, ))
        return value
Esempio n. 12
0
    def keys_only(value):
        """If the query should only return keys.

    Raises:
      datastore_errors.BadArgumentError if value is not a bool.
    """
        if not isinstance(value, bool):
            raise datastore_errors.BadArgumentError(
                'keys_only argument should be bool (%r)' % (value, ))
        return value
Esempio n. 13
0
    def hint(value):
        """Hint on how the datastore should plan the query.

    Raises:
      datastore_errors.BadArgumentError if value is not a known hint.
    """
        if value not in QueryOptions._HINTS:
            raise datastore_errors.BadArgumentError('Unknown query hint (%r)' %
                                                    (value, ))
        return value
Esempio n. 14
0
def _ReferenceFromPairs(pairs, reference=None, app=None, namespace=None):
    """Construct a Reference from a list of pairs.

  If a Reference is passed in as the second argument, it is modified
  in place.  The app and namespace are set from the corresponding
  keyword arguments, with the customary defaults.
  """
    if reference is None:
        reference = entity_pb.Reference()
    path = reference.mutable_path()
    last = False
    for kind, idorname in pairs:
        if last:
            raise datastore_errors.BadArgumentError(
                'Incomplete Key entry must be last')
        if not isinstance(kind, basestring):
            if isinstance(kind, type):
                # Late import to avoid cycles.
                from ndb.model import Model
                modelclass = kind
                assert issubclass(modelclass, Model), repr(modelclass)
                kind = modelclass._get_kind()
            assert isinstance(kind, basestring), (repr(modelclass), repr(kind))
        if isinstance(kind, unicode):
            kind = kind.encode('utf8')
        assert 1 <= len(kind) <= 500
        elem = path.add_element()
        elem.set_type(kind)
        if isinstance(idorname, (int, long)):
            assert 1 <= idorname < 2**63
            elem.set_id(idorname)
        elif isinstance(idorname, basestring):
            if isinstance(idorname, unicode):
                idorname = idorname.encode('utf8')
            assert 1 <= len(idorname) <= 500
            elem.set_name(idorname)
        elif idorname is None:
            elem.set_id(0)
            last = True
        else:
            assert False, 'bad idorname (%r)' % (idorname, )
    # An empty app id means to use the default app id.
    if not app:
        app = _DefaultAppId()
    # Always set the app id, since it is mandatory.
    reference.set_app(app)
    # An empty namespace overrides the default namespace.
    if namespace is None:
        namespace = _DefaultNamespace()
    # Only set the namespace if it is not empty.
    if namespace:
        reference.set_name_space(namespace)
    return reference
  def __init__(self, op, value):
    """Constructor.

    Args:
      op: A string representing the operator to use.
      value: A entity_pb.Property, the property and value to compare against.

    Raises:
      BadArgumentError if op has an unsupported value or value is not an
      entity_pb.Property.
    """
    if not op in self._OPERATORS:
      raise datastore_errors.BadArgumentError('unknown operator: %r' % (op,))
    if not isinstance(value, entity_pb.Property):
      raise datastore_errors.BadArgumentError(
          'value argument should be entity_pb.Property (%r)' % (value,))

    super(PropertyFilter, self).__init__()
    self.__filter = datastore_pb.Query_Filter()
    self.__filter.set_op(self._OPERATORS[op])
    self.__filter.add_property().CopyFrom(value)
Esempio n. 16
0
    def end_cursor(value):
        """Cursor to use as an end position.

    Ignored if present on datastore_rpc.Connection.config.

    Raises:
      datastore_errors.BadArgumentError if value is not a Cursor.
    """
        if not isinstance(value, Cursor):
            raise datastore_errors.BadArgumentError(
                'end_cursor argument should be datastore_query.Cursor (%r)' %
                (value, ))
        return value
Esempio n. 17
0
    def cursor_after(self):
        """Return the cursor after the current item.

    You must pass a QueryOptions object with produce_cursors=True
    for this to work.

    If there is no cursor or no current item, raise BadArgumentError.
    Before next() has returned there is no cursor.    Once the loop is
    exhausted, this returns the cursor after the last item.
    """
        if self._batch is None:
            raise datastore_errors.BadArgumentError(
                'There is no cursor currently')
        return self._batch.cursor(self._index + 1)
Esempio n. 18
0
    def __init__(self, batcher):
        """Constructor.

    Args:
      batcher: A datastore_query.Bather
    """
        if not isinstance(batcher, Batcher):
            raise datastore_errors.BadArgumentError(
                'batcher argument should be datastore_query.Batcher (%r)' %
                (batcher, ))

        self.__batcher = batcher
        self.__current_batch = None
        self.__current_pos = 0
  def __init__(self, _cursor_pb=None):
    """Constructor.

    A Cursor constructed with no arguments points the first result of any
    query. If such a Cursor is used as an end_cursor no results will ever be
    returned.
    """
    if _cursor_pb is not None:
      if not isinstance(_cursor_pb, datastore_pb.CompiledCursor):
        raise datastore_errors.BadArgumentError(
            '_cursor_pb argument should be datastore_pb.CompiledCursor (%r)' %
            (_cursor_pb,))
      self.__compiled_cursor = _cursor_pb
    else:
      self.__compiled_cursor = datastore_pb.CompiledCursor()
Esempio n. 20
0
    def cursor_before(self):
        """Return the cursor before the current item.

    You must pass a QueryOptions object with produce_cursors=True
    for this to work.

    If there is no cursor or no current item, raise BadArgumentError.
    Before next() has returned there is no cursor.  Once the loop is
    exhausted, this returns the cursor after the last item.
    """
        if self._batch is None:
            raise datastore_errors.BadArgumentError(
                'There is no cursor currently')
        # TODO: if cursor_after() was called for the previous item
        # reuse that result instead of computing it from scratch.
        # (Some cursor() calls make a datastore roundtrip.)
        return self._batch.cursor(self._index + self._exhausted)
  def _FromPb(pb):
    """Static factory method. Creates a Key from an entity_pb.Reference.

    Not intended to be used by application developers. Enforced by hiding the
    entity_pb classes.

    Args:
      pb: entity_pb.Reference
    """
    if not isinstance(pb, entity_pb.Reference):
      raise datastore_errors.BadArgumentError(
        'Key constructor takes an entity_pb.Reference; received %s (a %s).' %
        (pb, typename(pb)))

    key = Key()
    key.__reference = entity_pb.Reference()
    key.__reference.CopyFrom(pb)
    return key
Esempio n. 22
0
    def __init__(self, property, direction=ASCENDING):
        """Constructor.

    Args:
      property: the name of the property by which to sort.
      direction: the direction in which to sort the given property.

    Raises:
      BadArgumentError if the property name or direction is invalid.
    """
        datastore_types.ValidateString(property, 'property',
                                       datastore_errors.BadArgumentError)
        if not direction in self._DIRECTIONS:
            raise datastore_errors.BadArgumentError('unknown direction: %r' %
                                                    (direction, ))

        self.__order = datastore_pb.Query_Order()
        self.__order.set_property(property.encode('utf-8'))
        self.__order.set_direction(direction)
  def advance(self, offset, query, conn):
    """Advances a Cursor by the given offset.

    Args:
      offset: The amount to advance the current query.
      query: A Query identical to the one this cursor was created from.
      conn: The datastore_rpc.Connection to use.

    Returns:
      A new cursor that is advanced by offset using the given query.
    """
    datastore_types.ValidateInteger(offset,
                                    'offset',
                                    datastore_errors.BadArgumentError)
    if not isinstance(query, Query):
      raise datastore_errors.BadArgumentError(
          'query argument should be datastore_query.Query (%r)' % (query,))

    query_options = QueryOptions(
        start_cursor=self, offset=offset, limit=0, produce_cursors=True)
    return query.run(conn, query_options).next_batch(0).cursor(0)
Esempio n. 24
0
def to_key(values):
    """Coerces a value or list of values to `db.Key` instances.

    :param value:
        A datastore key as string, `db.Model` or `db.Key` instances, or a list
        of them. None values of model instances that still don't have a key
        available will be appended to the result as None.
    :returns:
        A `db.Key` or a list of `db.Key` instances.
    """
    if values is None:
        return None

    if not isinstance(values, list):
        multiple = False
        values = [values]
    else:
        multiple = True

    res = []
    for value in values:
        if value is None:
            res.append(None)
        elif isinstance(value, db.Model):
            if value.has_key():
                res.append(value.key())
            else:
                res.append(None)
        elif isinstance(value, basestring):
            res.append(db.Key(value))
        elif isinstance(value, db.Key):
            res.append(value)
        else:
            raise datastore_errors.BadArgumentError('Expected model, key or '
                                                    'string.')

    if multiple:
        return res

    return res[0]
  def _to_pb(self, fetch_options=None):
    req = datastore_pb.NextRequest()

    count = None
    produce_cursors = None

    if fetch_options is not None:
      if not isinstance(fetch_options, FetchOptions):
        raise datastore_errors.BadArgumentError(
            'fetch_options argument should be datastore_query.FetchOptions '
            '(%r)' % (fetch_options,))
      count = fetch_options.batch_size
      produce_cursors = fetch_options.produce_cursors
      if fetch_options.offset:
        req.set_offset(fetch_options.offset)

    if produce_cursors is None:
      produce_cursors = self.__query_options.produce_cursors
    if count is None:
      count = self.__query_options.batch_size

    if isinstance(self.__conn.config, FetchOptions):
      if produce_cursors is None:
        produce_cursors = self.__conn.config.produce_cursors
      if count is None:
        count = self.__conn.config.batch_size

    req.mutable_cursor().CopyFrom(self.__datastore_cursor)
    self.__datastore_cursor = None

    if count is not None:
      req.set_count(count)
    if produce_cursors:
      req.set_compile(True)

    return req
    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
    def Bind(self, args, keyword_args, cursor=None, end_cursor=None):
        """Bind the existing query to the argument list.

    Assumes that the input args are first positional, then a dictionary.
    So, if the query contains references to :1, :2 and :name, it is assumed
    that arguments are passed as (:1, :2, dict) where dict contains a mapping
    [name] -> value.

    Args:
      args: the arguments to bind to the object's unbound references.
      keyword_args: dictionary-based arguments (for named parameters).

    Raises:
      datastore_errors.BadArgumentError: when arguments are left unbound
        (missing from the inputs arguments) or when arguments do not match the
        expected type.

    Returns:
      The bound datastore.Query object. This may take the form of a MultiQuery
      object if the GQL query will require multiple backend queries to statisfy.
    """
        num_args = len(args)
        input_args = frozenset(xrange(num_args))
        used_args = set()

        queries = []
        enumerated_queries = self.EnumerateQueries(used_args, args,
                                                   keyword_args)
        if enumerated_queries:
            query_count = len(enumerated_queries)
        else:
            query_count = 1

        for i in xrange(query_count):
            queries.append(
                datastore.Query(self._entity,
                                _app=self.__app,
                                keys_only=self._keys_only,
                                namespace=self.__namespace,
                                cursor=cursor,
                                end_cursor=end_cursor))

        logging.log(LOG_LEVEL,
                    'Binding with %i positional args %s and %i keywords %s',
                    len(args), args, len(keyword_args), keyword_args)

        for ((identifier, condition),
             value_list) in self.__filters.iteritems():
            for (operator, params) in value_list:
                value = self.__Operate(args, keyword_args, used_args, operator,
                                       params)
                if not self.__IsMultiQuery(condition):
                    for query in queries:
                        self.__AddFilterToQuery(identifier, condition, value,
                                                query)

        unused_args = input_args - used_args
        if unused_args:
            unused_values = [unused_arg + 1 for unused_arg in unused_args]
            raise datastore_errors.BadArgumentError(
                'Unused positional arguments %s' % unused_values)

        if enumerated_queries:
            logging.log(LOG_LEVEL, 'Multiple Queries Bound: %s',
                        enumerated_queries)

            for (query, enumerated_query) in zip(queries, enumerated_queries):
                query.update(enumerated_query)

        if self.__orderings:
            for query in queries:
                query.Order(*tuple(self.__orderings))

        if query_count > 1:

            return MultiQuery(queries, self.__orderings)
        else:
            return queries[0]
    def Bind(self, args, keyword_args):
        """Bind the existing query to the argument list.

    Assumes that the input args are first positional, then a dictionary.
    So, if the query contains references to :1, :2 and :name, it is assumed
    that arguments are passed as (:1, :2, dict) where dict contains a mapping
    [name] -> value.

    Args:
      args: the arguments to bind to the object's unbound references.
      keyword_args: dictionary-based arguments (for named parameters).

    Raises:
      datastore_errors.BadArgumentError: when arguments are left unbound
        (missing from the inputs arguments).

    Returns:
      The bound datastore.Query object.
    """
        num_args = len(args)
        input_args = frozenset(xrange(num_args))
        used_args = set()

        query = datastore.Query(self._entity, _app=self.__app)

        logging.log(LOG_LEVEL, 'Copying %i pre-bound filters',
                    len(self.__bound_filters))
        for (condition, value) in self.__bound_filters.iteritems():
            logging.log(LOG_LEVEL, 'Pre-bound filter: %s %s', condition, value)
            query[condition] = value

        logging.log(LOG_LEVEL, 'Binding with %i args %s', len(args), args)
        for (param, filters) in self.__filters.iteritems():
            for (identifier, condition) in filters:
                if isinstance(param, int):
                    if param <= num_args:
                        self.__AddFilter(identifier, condition,
                                         args[param - 1], query)
                        used_args.add(param - 1)
                        logging.log(LOG_LEVEL, 'binding: %i %s', param,
                                    args[param - 1])
                    else:
                        raise datastore_errors.BadArgumentError(
                            'Missing argument for bind, requires argument #%i, '
                            'but only has %i args.' % (param, num_args))
                elif isinstance(param, str):
                    if param in keyword_args:
                        self.__AddFilter(identifier, condition,
                                         keyword_args[param], query)
                        logging.log(LOG_LEVEL, 'binding: %s %s', param,
                                    keyword_args)
                    else:
                        raise datastore_errors.BadArgumentError(
                            'Missing named arguments for bind, requires argument %s'
                            % param)
                else:
                    assert False, 'Unknown parameter %s' % param

        if self.__orderings:
            query.Order(*tuple(self.__orderings))

        unused_args = input_args - used_args
        if unused_args:
            unused_values = [unused_arg + 1 for unused_arg in unused_args]
            raise datastore_errors.BadArgumentError(
                'Unused positional arguments %s' % unused_values)

        return query
Esempio n. 29
0
 def use_datastore(value):
     if not isinstance(value, bool):
         raise datastore_errors.BadArgumentError(
             'use_datastore should be a bool (%r)' % (value, ))
     return value
Esempio n. 30
0
 def max_memcache_items(value):
     if not isinstance(value, (int, long)):
         raise datastore_errors.BadArgumentError(
             'max_memcache_items should be an integer (%r)' % (value, ))
     return value