Beispiel #1
0
    def transaction(self):
        """Proxy to :class:`gcloud.datastore.transaction.Transaction`.

        Passes our ``dataset_id``.
        """
        return Transaction(dataset_id=self.dataset_id,
                           connection=self.connection)
Beispiel #2
0
    def next_page(self):
        """Fetch a single "page" of query results.

        Low-level API for fine control:  the more convenient API is
        to iterate on the current Iterator.

        :rtype: tuple, (entities, more_results, cursor)
        """
        pb = _pb_from_query(self._query)

        start_cursor = self._start_cursor
        if start_cursor is not None:
            pb.start_cursor = base64.b64decode(start_cursor)

        end_cursor = self._end_cursor
        if end_cursor is not None:
            pb.end_cursor = base64.b64decode(end_cursor)

        if self._limit is not None:
            pb.limit = self._limit

        pb.offset = self._offset

        transaction = Transaction.current()

        query_results = self._connection.run_query(
            query_pb=pb,
            dataset_id=self._query.dataset_id,
            namespace=self._query.namespace,
            transaction_id=transaction and transaction.id,
        )
        # NOTE: `query_results` contains an extra value that we don't use,
        #       namely `skipped_results`.
        #
        # NOTE: The value of `more_results` is not currently useful because
        #       the back-end always returns an enum
        #       value of MORE_RESULTS_AFTER_LIMIT even if there are no more
        #       results. See
        #       https://github.com/GoogleCloudPlatform/gcloud-python/issues/280
        #       for discussion.
        entity_pbs, cursor_as_bytes, more_results_enum = query_results[:3]

        self._start_cursor = base64.b64encode(cursor_as_bytes)
        self._end_cursor = None

        if more_results_enum == self._NOT_FINISHED:
            self._more_results = True
        elif more_results_enum in self._FINISHED:
            self._more_results = False
        else:
            raise ValueError('Unexpected value returned for `more_results`.')

        self._page = [
            helpers.entity_from_protobuf(entity) for entity in entity_pbs
        ]
        return self._page, self._more_results, self._start_cursor
Beispiel #3
0
    def next_page(self):
        """Fetch a single "page" of query results.

        Low-level API for fine control:  the more convenient API is
        to iterate on the current Iterator.

        :rtype: tuple, (entities, more_results, cursor)
        """
        pb = _pb_from_query(self._query)

        start_cursor = self._start_cursor
        if start_cursor is not None:
            pb.start_cursor = base64.b64decode(start_cursor)

        end_cursor = self._end_cursor
        if end_cursor is not None:
            pb.end_cursor = base64.b64decode(end_cursor)

        if self._limit is not None:
            pb.limit = self._limit

        pb.offset = self._offset

        transaction = Transaction.current()

        query_results = self._connection.run_query(
            query_pb=pb,
            dataset_id=self._query.dataset_id,
            namespace=self._query.namespace,
            transaction_id=transaction and transaction.id,
            )
        # NOTE: `query_results` contains an extra value that we don't use,
        #       namely `skipped_results`.
        #
        # NOTE: The value of `more_results` is not currently useful because
        #       the back-end always returns an enum
        #       value of MORE_RESULTS_AFTER_LIMIT even if there are no more
        #       results. See
        #       https://github.com/GoogleCloudPlatform/gcloud-python/issues/280
        #       for discussion.
        entity_pbs, cursor_as_bytes, more_results_enum = query_results[:3]

        self._start_cursor = base64.b64encode(cursor_as_bytes)
        self._end_cursor = None

        if more_results_enum == self._NOT_FINISHED:
            self._more_results = True
        elif more_results_enum in self._FINISHED:
            self._more_results = False
        else:
            raise ValueError('Unexpected value returned for `more_results`.')

        self._page = [
            helpers.entity_from_protobuf(entity)
            for entity in entity_pbs]
        return self._page, self._more_results, self._start_cursor
Beispiel #4
0
def delete_report(employee_id, report_id, force):
    with Transaction():
        report = _get_report(employee_id, report_id, False)
        if report is None:
            raise NoSuchReport()
        if report['status'] != 'pending' and not force:
            raise BadReportStatus(report['status'])
        count = _purge_report_items(report)
        datastore.delete([report.key])
    return count
Beispiel #5
0
def create_report(employee_id, report_id, rows, description):
    with Transaction():
        if _get_report(employee_id, report_id, False) is not None:
            raise DuplicateReport()
        report = _upsert_report(employee_id, report_id, rows)
        report['status'] = 'pending'
        if description is not None:
            report['description'] = description
        report['created'] = report['updated'] = datetime.datetime.utcnow()
        datastore.put([report])
Beispiel #6
0
def reject_report(employee_id, report_id, reason):
    with Transaction():
        report = _get_report(employee_id, report_id, False)
        if report is None:
            raise NoSuchReport()
        if report['status'] != 'pending':
            raise BadReportStatus(report['status'])
        report['updated'] = datetime.datetime.utcnow()
        report['status'] = 'rejected'
        report['reason'] = reason
        datastore.put([report])
Beispiel #7
0
def approve_report(employee_id, report_id, check_number):
    with Transaction():
        report = _get_report(employee_id, report_id, False)
        if report is None:
            raise NoSuchReport()
        if report['status'] != 'pending':
            raise BadReportStatus(report['status'])
        report['updated'] = datetime.datetime.utcnow()
        report['status'] = 'paid'
        report['check_number'] = check_number
        datastore.put([report])
Beispiel #8
0
    def transaction(self, *args, **kwargs):
        """Create a transaction bound to this dataset.

        :param args: positional arguments, passed through to the Transaction

        :param kw: keyword arguments, passed through to the Transaction

        :rtype: :class:`gcloud.datastore.transaction.Transaction`
        :returns: a new Transaction instance, bound to this dataset.
        """
        kwargs['dataset'] = self
        return Transaction(*args, **kwargs)
Beispiel #9
0
def update_report(employee_id, report_id, rows, description):
    with Transaction():
        report = _get_report(employee_id, report_id, False)
        if report is None:
            raise NoSuchReport()
        if report['status'] != 'pending':
            raise BadReportStatus(report['status'])
        _upsert_report(employee_id, report_id, rows)
        if description is not None:
            report['description'] = description
        report['updated'] = datetime.datetime.utcnow()
        datastore.put([report])
Beispiel #10
0
def get(keys, missing=None, deferred=None, connection=None):
    """Retrieves entities, along with their attributes.

    :type keys: list of :class:`gcloud.datastore.key.Key`
    :param keys: The keys to be retrieved from the datastore.

    :type missing: an empty list or None.
    :param missing: If a list is passed, the key-only entities returned
                    by the backend as "missing" will be copied into it.
                    Use only as a keyword param.

    :type deferred: an empty list or None.
    :param deferred: If a list is passed, the keys returned
                     by the backend as "deferred" will be copied into it.
                     Use only as a keyword param.

    :type connection: :class:`gcloud.datastore.connection.Connection`
    :param connection: Optional. The connection used to connect to datastore.

    :rtype: list of :class:`gcloud.datastore.entity.Entity`
    :returns: The requested entities.
    """
    if not keys:
        return []

    connection = _require_connection(connection)
    dataset_id = _get_dataset_id_from_keys(keys)

    transaction = Transaction.current()

    entity_pbs = connection.lookup(
        dataset_id=dataset_id,
        key_pbs=[k.to_protobuf() for k in keys],
        missing=missing, deferred=deferred,
        transaction_id=transaction and transaction.id,
    )

    if missing is not None:
        missing[:] = [
            helpers.entity_from_protobuf(missed_pb)
            for missed_pb in missing]

    if deferred is not None:
        deferred[:] = [
            helpers.key_from_protobuf(deferred_pb)
            for deferred_pb in deferred]

    entities = []
    for entity_pb in entity_pbs:
        entities.append(helpers.entity_from_protobuf(entity_pb))

    return entities
 def __init__(self, client, transaction_id='TRANSACTION'):
     from gcloud.datastore.transaction import Transaction
     self._client = client
     xact = self._transaction = Transaction(client)
     xact._id = transaction_id
Beispiel #12
0
 def transaction(self, *args, **kwargs):
   from gcloud.datastore.transaction import Transaction
   kwargs['dataset'] = self
   return Transaction(*args, **kwargs)
Beispiel #13
0
def get_multi(keys, missing=None, deferred=None,
              connection=None, dataset_id=None):
    """Retrieves entities, along with their attributes.

    :type keys: list of :class:`gcloud.datastore.key.Key`
    :param keys: The keys to be retrieved from the datastore.

    :type missing: an empty list or None.
    :param missing: If a list is passed, the key-only entities returned
                    by the backend as "missing" will be copied into it.
                    Use only as a keyword param.

    :type deferred: an empty list or None.
    :param deferred: If a list is passed, the keys returned
                     by the backend as "deferred" will be copied into it.
                     Use only as a keyword param.

    :type connection: :class:`gcloud.datastore.connection.Connection`
    :param connection: Optional. The connection used to connect to datastore.
                       If not passed, inferred from the environment.

    :type dataset_id: :class:`gcloud.datastore.connection.Connection`
    :param dataset_id: Optional. The dataset ID used to connect to datastore.
                       If not passed, inferred from the environment.

    :rtype: list of :class:`gcloud.datastore.entity.Entity`
    :returns: The requested entities.
    :raises: EnvironmentError if ``connection`` or ``dataset_id`` not passed,
             and cannot be inferred from the environment.  ValueError if
             one or more of ``keys`` has a dataset ID which does not match
             the passed / inferred dataset ID.
    """
    if not keys:
        return []

    connection = _require_connection(connection)
    dataset_id = _require_dataset_id(dataset_id, keys[0])

    if list(set([key.dataset_id for key in keys])) != [dataset_id]:
        raise ValueError('Keys do not match dataset ID')

    transaction = Transaction.current()

    entity_pbs = _extended_lookup(
        connection,
        dataset_id=dataset_id,
        key_pbs=[k.to_protobuf() for k in keys],
        missing=missing,
        deferred=deferred,
        transaction_id=transaction and transaction.id,
    )

    if missing is not None:
        missing[:] = [
            helpers.entity_from_protobuf(missed_pb)
            for missed_pb in missing]

    if deferred is not None:
        deferred[:] = [
            helpers.key_from_protobuf(deferred_pb)
            for deferred_pb in deferred]

    entities = []
    for entity_pb in entity_pbs:
        entities.append(helpers.entity_from_protobuf(entity_pb))

    return entities
Beispiel #14
0
 def __init__(self, dataset_id, connection, transaction_id):
     from gcloud.datastore.transaction import Transaction
     xact = self._transaction = Transaction(dataset_id, connection)
     xact._id = transaction_id
Beispiel #15
0
 def transaction(self):
     """Proxy to :class:`gcloud.datastore.transaction.Transaction`."""
     return Transaction(self)
Beispiel #16
0
def get(keys, missing=None, deferred=None, connection=None, dataset_id=None):
    """Retrieves entities, along with their attributes.

    :type keys: list of :class:`gcloud.datastore.key.Key`
    :param keys: The keys to be retrieved from the datastore.

    :type missing: an empty list or None.
    :param missing: If a list is passed, the key-only entities returned
                    by the backend as "missing" will be copied into it.
                    Use only as a keyword param.

    :type deferred: an empty list or None.
    :param deferred: If a list is passed, the keys returned
                     by the backend as "deferred" will be copied into it.
                     Use only as a keyword param.

    :type connection: :class:`gcloud.datastore.connection.Connection`
    :param connection: Optional. The connection used to connect to datastore.
                       If not passed, inferred from the environment.

    :type dataset_id: :class:`gcloud.datastore.connection.Connection`
    :param dataset_id: Optional. The dataset ID used to connect to datastore.
                       If not passed, inferred from the environment.

    :rtype: list of :class:`gcloud.datastore.entity.Entity`
    :returns: The requested entities.
    :raises: EnvironmentError if ``connection`` or ``dataset_id`` not passed,
             and cannot be inferred from the environment.  ValueError if
             one or more of ``keys`` has a dataset ID which does not match
             the passed / inferred dataset ID.
    """
    if not keys:
        return []

    connection = _require_connection(connection)
    dataset_id = _require_dataset_id(dataset_id, keys[0])

    if list(set([key.dataset_id for key in keys])) != [dataset_id]:
        raise ValueError('Keys do not match dataset ID')

    transaction = Transaction.current()

    entity_pbs = _extended_lookup(
        connection,
        dataset_id=dataset_id,
        key_pbs=[k.to_protobuf() for k in keys],
        missing=missing,
        deferred=deferred,
        transaction_id=transaction and transaction.id,
    )

    if missing is not None:
        missing[:] = [
            helpers.entity_from_protobuf(missed_pb)
            for missed_pb in missing]

    if deferred is not None:
        deferred[:] = [
            helpers.key_from_protobuf(deferred_pb)
            for deferred_pb in deferred]

    entities = []
    for entity_pb in entity_pbs:
        entities.append(helpers.entity_from_protobuf(entity_pb))

    return entities