예제 #1
0
  def _Dynamic_Transaction(self, request, response):
    """Handle a Transaction request.

    We handle transactions by accumulating Put and Delete requests on the client
    end, as well as recording the key and hash of Get requests. When Commit is
    called, Transaction is invoked, which verifies that all the entities in the
    precondition list still exist and their hashes match, then performs a
    transaction of its own to make the updates.
    """

    begin_request = datastore_pb.BeginTransactionRequest()
    begin_request.set_app(os.environ['APPLICATION_ID'])
    begin_request.set_allow_multiple_eg(request.allow_multiple_eg())
    tx = datastore_pb.Transaction()
    self.__call('datastore_v3', 'BeginTransaction', begin_request, tx)


    preconditions = request.precondition_list()
    if preconditions:
      get_request = datastore_pb.GetRequest()
      get_request.mutable_transaction().CopyFrom(tx)
      for precondition in preconditions:
        key = get_request.add_key()
        key.CopyFrom(precondition.key())
      get_response = datastore_pb.GetResponse()
      self.__call('datastore_v3', 'Get', get_request, get_response)
      entities = get_response.entity_list()
      assert len(entities) == request.precondition_size()
      for precondition, entity in zip(preconditions, entities):
        if precondition.has_hash() != entity.has_entity():
          raise apiproxy_errors.ApplicationError(
              datastore_pb.Error.CONCURRENT_TRANSACTION,
              "Transaction precondition failed.")
        elif entity.has_entity():
          entity_hash = hashlib.sha1(entity.entity().Encode()).digest()
          if precondition.hash() != entity_hash:
            raise apiproxy_errors.ApplicationError(
                datastore_pb.Error.CONCURRENT_TRANSACTION,
                "Transaction precondition failed.")


    if request.has_puts():
      put_request = request.puts()
      put_request.mutable_transaction().CopyFrom(tx)
      self.__call('datastore_v3', 'Put', put_request, response)


    if request.has_deletes():
      delete_request = request.deletes()
      delete_request.mutable_transaction().CopyFrom(tx)
      self.__call('datastore_v3', 'Delete', delete_request,
                  datastore_pb.DeleteResponse())


    self.__call('datastore_v3', 'Commit', tx, datastore_pb.CommitResponse())
  def __delete_v1_key(self, v1_key, v1_txn):
    """Deletes an entity from a v1 key in a transaction."""
    v3_key = entity_pb.Reference()
    self.__entity_converter.v1_to_v3_reference(v1_key, v3_key)
    v3_txn = datastore_pb.Transaction()
    self.__service_converter.v1_to_v3_txn(v1_txn, v3_txn)

    v3_delete_req = datastore_pb.DeleteRequest()
    v3_delete_req.mutable_transaction().CopyFrom(v3_txn)
    v3_delete_req.add_key().CopyFrom(v3_key)
    v3_delete_resp = datastore_pb.DeleteResponse()
    self.__make_v3_call('Delete', v3_delete_req, v3_delete_resp)
예제 #3
0
def _delete_entities(ds_access, entity_keys):
  """ Deletes a list of datastore entities.

  Args:
    ds_access: A DatastoreDistributed client.
    entity_keys: A list of datastore.Key objects.
  Raises:
    ApplicationError if unable to delete entities.
  """
  request = datastore_pb.DeleteRequest()
  for entity_key in entity_keys:
    key = request.add_key()
    key.CopyFrom(entity_key._ToPb())

  response = datastore_pb.DeleteResponse()
  ds_access._Dynamic_Delete(request, response)
예제 #4
0
    def __delete_v3_reference(self, v3_key, v3_txn):
        """Deletes a v3 entity.

    Args:
      v3_key: an entity_pb.Reference
      v3_txn: a datastore_pb.Transaction or None

    Returns:
      the number of index writes that occurred
    """
        v3_delete_req = datastore_pb.DeleteRequest()
        if v3_txn:
            v3_delete_req.mutable_transaction().CopyFrom(v3_txn)
        v3_delete_req.add_key().CopyFrom(v3_key)
        v3_delete_resp = datastore_pb.DeleteResponse()
        self.__make_v3_call('Delete', v3_delete_req, v3_delete_resp)
        return v3_delete_resp.cost().index_writes()
    def __apply_v4_deprecated_mutation(self, v4_deprecated_mutation, v4_txn):
        """Applies a v4 DeprecatedMutation.

    Args:
      v4_deprecated_mutation: a datastore_v4_pb.DeprecatedMutation
      v4_txn: an optional v4 transaction handle or None

    Returns:
      a datastore_v4_pb.DeprecatedMutationResult
    """
        index_writes = 0
        v3_txn = None
        if v4_txn:
            v3_txn = datastore_pb.Transaction()
            self.__service_converter.v4_to_v3_txn(v4_txn, v3_txn)

        for v4_entity in v4_deprecated_mutation.insert_list():
            v3_entity = entity_pb.EntityProto()
            self.__entity_converter.v4_to_v3_entity(v4_entity, v3_entity)
            index_writes += self.__insert_v3_entity(v3_entity, v3_txn)

        for v4_entity in v4_deprecated_mutation.update_list():
            v3_entity = entity_pb.EntityProto()
            self.__entity_converter.v4_to_v3_entity(v4_entity, v3_entity)
            index_writes += self.__update_v3_entity(v3_entity, v3_txn)

        v3_insert_auto_req = datastore_pb.PutRequest()
        if v3_txn:
            v3_insert_auto_req.mutable_transaction().CopyFrom(v3_txn)
        for v4_entity in v4_deprecated_mutation.insert_auto_id_list():
            v3_entity = entity_pb.EntityProto()
            self.__entity_converter.v4_to_v3_entity(v4_entity, v3_entity)
            v3_insert_auto_req.entity_list().append(v3_entity)
        v3_insert_auto_id_resp = datastore_pb.PutResponse()
        self.__make_v3_call('Put', v3_insert_auto_req, v3_insert_auto_id_resp)
        index_writes += v3_insert_auto_id_resp.cost().index_writes()

        v3_upsert_req = datastore_pb.PutRequest()
        if v3_txn:
            v3_upsert_req.mutable_transaction().CopyFrom(v3_txn)
        for v4_entity in v4_deprecated_mutation.upsert_list():
            v3_entity = entity_pb.EntityProto()
            self.__entity_converter.v4_to_v3_entity(v4_entity, v3_entity)
            v3_upsert_req.entity_list().append(v3_entity)
        v3_upsert_resp = datastore_pb.PutResponse()
        self.__make_v3_call('Put', v3_upsert_req, v3_upsert_resp)
        index_writes += v3_upsert_resp.cost().index_writes()

        v3_delete_req = datastore_pb.DeleteRequest()
        if v3_txn:
            v3_delete_req.mutable_transaction().CopyFrom(v3_txn)
        for v4_key in v4_deprecated_mutation.delete_list():
            self.__entity_converter.v4_to_v3_reference(v4_key,
                                                       v3_delete_req.add_key())
        v3_delete_resp = datastore_pb.DeleteResponse()
        self.__make_v3_call('Delete', v3_delete_req, v3_delete_resp)
        index_writes += v3_delete_resp.cost().index_writes()

        v4_deprecated_mutation_result = datastore_v4_pb.DeprecatedMutationResult(
        )
        for v3_ref in v3_insert_auto_id_resp.key_list():
            self.__entity_converter.v3_to_v4_key(
                v3_ref, v4_deprecated_mutation_result.add_insert_auto_id_key())
        v4_deprecated_mutation_result.set_index_updates(index_writes)

        return v4_deprecated_mutation_result