Esempio n. 1
0
    def filter(self, expression, value):
        """Filter the query based on an expression and a value.

    This will return a clone of the current :class:`Query`
    filtered by the expression and value provided.

    Expressions take the form of::

      .filter('<property> <operator>', <value>)

    where property is a property stored on the entity in the datastore
    and operator is one of ``OPERATORS``
    (ie, ``=``, ``<``, ``<=``, ``>``, ``>=``)::

      >>> query = Query('Person')
      >>> filtered_query = query.filter('name =', 'James')
      >>> filtered_query = query.filter('age >', 50)

    Because each call to ``.filter()`` returns a cloned ``Query`` object
    we are able to string these together::

      >>> query = Query('Person').filter('name =', 'James').filter('age >', 50)

    :type expression: string
    :param expression: An expression of a property and an operator (ie, ``=``).

    :type value: integer, string, boolean, float, None, datetime
    :param value: The value to filter on.

    :rtype: :class:`Query`
    :returns: A Query filtered by the expression and value provided.
    """
        clone = self._clone()

        # Take an expression like 'property >=', and parse it into useful pieces.
        property_name, operator = None, None
        expression = expression.strip()

        for operator_string in self.OPERATORS:
            if expression.endswith(operator_string):
                operator = self.OPERATORS[operator_string]
                property_name = expression[0:-len(operator_string)].strip()

        if not operator or not property_name:
            raise ValueError('Invalid expression: "%s"' % expression)

        # Build a composite filter AND'd together.
        composite_filter = clone._pb.filter.composite_filter
        composite_filter.operator = datastore_pb.CompositeFilter.AND

        # Add the specific filter
        property_filter = composite_filter.filter.add().property_filter
        property_filter.property.name = property_name
        property_filter.operator = operator

        # Set the value to filter on based on the type.
        attr_name, pb_value = helpers.get_protobuf_attribute_and_value(value)
        setattr(property_filter.value, attr_name, pb_value)
        return clone
Esempio n. 2
0
  def filter(self, expression, value):
    """Filter the query based on an expression and a value.

    This will return a clone of the current :class:`Query`
    filtered by the expression and value provided.

    Expressions take the form of::

      .filter('<property> <operator>', <value>)

    where property is a property stored on the entity in the datastore
    and operator is one of ``OPERATORS``
    (ie, ``=``, ``<``, ``<=``, ``>``, ``>=``)::

      >>> query = Query('Person')
      >>> filtered_query = query.filter('name =', 'James')
      >>> filtered_query = query.filter('age >', 50)

    Because each call to ``.filter()`` returns a cloned ``Query`` object
    we are able to string these together::

      >>> query = Query('Person').filter('name =', 'James').filter('age >', 50)

    :type expression: string
    :param expression: An expression of a property and an operator (ie, ``=``).

    :type value: integer, string, boolean, float, None, datetime
    :param value: The value to filter on.

    :rtype: :class:`Query`
    :returns: A Query filtered by the expression and value provided.
    """
    clone = self._clone()

    # Take an expression like 'property >=', and parse it into useful pieces.
    property_name, operator = None, None
    expression = expression.strip()

    for operator_string in self.OPERATORS:
      if expression.endswith(operator_string):
        operator = self.OPERATORS[operator_string]
        property_name = expression[0:-len(operator_string)].strip()

    if not operator or not property_name:
      raise ValueError('Invalid expression: "%s"' % expression)

    # Build a composite filter AND'd together.
    composite_filter = clone._pb.filter.composite_filter
    composite_filter.operator = datastore_pb.CompositeFilter.AND

    # Add the specific filter
    property_filter = composite_filter.filter.add().property_filter
    property_filter.property.name = property_name
    property_filter.operator = operator

    # Set the value to filter on based on the type.
    attr_name, pb_value = helpers.get_protobuf_attribute_and_value(value)
    setattr(property_filter.value, attr_name, pb_value)
    return clone
Esempio n. 3
0
  def save_entity(self, dataset_id, key_pb, properties):
    """Save an entity to the Cloud Datastore with the provided properties.

    :type dataset_id: string
    :param dataset_id: The dataset in which to save the entity.

    :type key_pb: :class:`gcloud.datastore.datastore_v1_pb2.Key`
    :param key_pb: The complete or partial key for the entity.

    :type properties: dict
    :param properties: The properties to store on the entity.
    """
    # TODO: Is this the right method name?
    # TODO: How do you delete properties? Set them to None?
    mutation = self.mutation()

    # If the Key is complete, we should upsert
    # instead of using insert_auto_id.
    path = key_pb.path_element[-1]
    auto_id = not (path.HasField('id') or path.HasField('name'))

    if auto_id:
      insert = mutation.insert_auto_id.add()
    else:
      insert = mutation.upsert.add()

    insert.key.CopyFrom(key_pb)

    for name, value in properties.iteritems():
      prop = insert.property.add()
      # Set the name of the property.
      prop.name = name

      # Set the appropriate value.
      pb_attr, pb_value = helpers.get_protobuf_attribute_and_value(value)
      setattr(prop.value, pb_attr, pb_value)

    # If this is in a transaction, we should just return True. The transaction
    # will handle assigning any keys as necessary.
    if self.transaction():
      return True

    result = self.commit(dataset_id, mutation)
    # If this was an auto-assigned ID, return the new Key.
    if auto_id:
      return result.insert_auto_id_key[0]

    return True
Esempio n. 4
0
    def save_entity(self, dataset_id, key_pb, properties):
        """Save an entity to the Cloud Datastore with the provided properties.

    :type dataset_id: string
    :param dataset_id: The dataset in which to save the entity.

    :type key_pb: :class:`gcloud.datastore.datastore_v1_pb2.Key`
    :param key_pb: The complete or partial key for the entity.

    :type properties: dict
    :param properties: The properties to store on the entity.
    """
        # TODO: Is this the right method name?
        # TODO: How do you delete properties? Set them to None?
        mutation = self.mutation()

        # If the Key is complete, we should upsert
        # instead of using insert_auto_id.
        path = key_pb.path_element[-1]
        auto_id = not (path.HasField('id') or path.HasField('name'))

        if auto_id:
            insert = mutation.insert_auto_id.add()
        else:
            insert = mutation.upsert.add()

        insert.key.CopyFrom(key_pb)

        for name, value in properties.iteritems():
            prop = insert.property.add()
            # Set the name of the property.
            prop.name = name

            # Set the appropriate value.
            pb_attr, pb_value = helpers.get_protobuf_attribute_and_value(value)
            setattr(prop.value, pb_attr, pb_value)

        # If this is in a transaction, we should just return True. The transaction
        # will handle assigning any keys as necessary.
        if self.transaction():
            return True

        result = self.commit(dataset_id, mutation)
        # If this was an auto-assigned ID, return the new Key.
        if auto_id:
            return result.insert_auto_id_key[0]

        return True
Esempio n. 5
0
  def test_get_protobuf_attribute(self):
    mapping = (
        (str(), 'string_value'),
        (unicode(), 'string_value'),
        (int(), 'integer_value'),
        (long(), 'integer_value'),
        (float(), 'double_value'),
        (bool(), 'boolean_value'),
        (datetime.now(), 'timestamp_microseconds_value'),
        (Key(), 'key_value'),
        )

    for test_value, expected_name in mapping:
      actual_name, _ = helpers.get_protobuf_attribute_and_value(test_value)
      self.assertEqual(expected_name, actual_name,
          'Test value "%s" expected %s, got %s' % (
            test_value, expected_name, actual_name))
Esempio n. 6
0
  def test_get_protobuf_value(self):
    now = datetime.utcnow()

    mapping = (
        (str('string'), 'string'),
        (unicode('string'), 'string'),
        (int(), int()),
        (long(), int()),
        (float(), float()),
        (bool(), bool()),
        (now, long(calendar.timegm(now.timetuple()) * 1e6 + now.microsecond)),
        (Key(), Key().to_protobuf()),
        )

    for test_value, expected_value in mapping:
      _, actual_value = helpers.get_protobuf_attribute_and_value(test_value)
      self.assertEqual(expected_value, actual_value,
          'Test value "%s" expected %s, got %s.' % (
            test_value, expected_value, actual_value))
Esempio n. 7
0
    def test_get_protobuf_attribute(self):
        mapping = (
            (str(), 'string_value'),
            (unicode(), 'string_value'),
            (int(), 'integer_value'),
            (long(), 'integer_value'),
            (float(), 'double_value'),
            (bool(), 'boolean_value'),
            (datetime.now(), 'timestamp_microseconds_value'),
            (Key(), 'key_value'),
        )

        for test_value, expected_name in mapping:
            actual_name, _ = helpers.get_protobuf_attribute_and_value(
                test_value)
            self.assertEqual(
                expected_name, actual_name,
                'Test value "%s" expected %s, got %s' %
                (test_value, expected_name, actual_name))
Esempio n. 8
0
    def test_get_protobuf_value(self):
        now = datetime.utcnow()

        mapping = (
            (str('string'), 'string'),
            (unicode('string'), 'string'),
            (int(), int()),
            (long(), int()),
            (float(), float()),
            (bool(), bool()),
            (now,
             long(calendar.timegm(now.timetuple()) * 1e6 + now.microsecond)),
            (Key(), Key().to_protobuf()),
        )

        for test_value, expected_value in mapping:
            _, actual_value = helpers.get_protobuf_attribute_and_value(
                test_value)
            self.assertEqual(
                expected_value, actual_value,
                'Test value "%s" expected %s, got %s.' %
                (test_value, expected_value, actual_value))
Esempio n. 9
0
 def _callFUT(self, val):
     from gcloud.datastore.helpers import get_protobuf_attribute_and_value
     return get_protobuf_attribute_and_value(val)