Beispiel #1
0
    def check_and_put(self, table, row, check_column, check_value=None):
        """Put(insert) one row to the table when the given condition is satisfied.

        Atomically checks if a row/family/qualifier value matches the expected value.
        If it does, it adds the put.
        If the passed value is None(or b''), the check is for the lack of column (ie: non-existance)

        Args:
            table (str): Table name.
            row (Row): Row to insert.
            check_column (str): Column to check.
            check_value (bytes): Value to check.

        Returns:
            True: Success.
            False: Not modified. (The given condition is not satisfied.)

        Raises:
            RESTError: REST server returns other errors.

        """
        cell_set = protobuf_schema.CellSet()
        row_ = cell_set.rows.add()
        row_.key = row.key.encode()
        for column, data in row.items():
            value = row_.values.add()
            value.column = column.encode()
            value.data = data
        if check_column is not None:
            value = row_.values.add()
            value.column = check_column.encode()
            value.data = check_value if check_value is not None else b''
            url = '/'.join((self._base_url, table, 'fakerow?check=put'))
        else:
            url = '/'.join((self._base_url, table, 'fakerow'))

        response = self._session.post(url=url,
                                      headers={
                                          'Content-Type':
                                          'application/x-protobuf',
                                          'Accept': 'application/x-protobuf'
                                      },
                                      data=cell_set.SerializeToString())

        code = response.status_code
        if code == CODE_OK:
            return True  # put success
        elif code == CODE_NOT_MODIFIED:
            return False  # not modified
        else:
            raise RESTError(code, response.text)
Beispiel #2
0
    def get(self, table, key, columns=None):
        """Query to get a row object with a row key.

        Args:
            table (str): Table name.
            key (str): Row key.
            columns (tuple[str]|list[str]): Columns to fetch.

        Returns:
            Row: The row object.
            None: The row does not exist.

        Raises:
            RESTError: REST server returns other errors.

        """
        url = '/'.join((self._base_url, table, key))
        if columns is not None:
            url += '/' + ','.join(columns)
        response = self._session.get(
            url=url, headers={'Accept': 'application/x-protobuf'})

        code = response.status_code
        if code == CODE_OK:
            cell_set = protobuf_schema.CellSet()
            cell_set.ParseFromString(response.content)
            count = len(cell_set.rows)
            if count == 1:
                row = cell_set.rows[0]
                return Row(key=row.key.decode(),
                           cells={
                               value.column.decode(): value.data
                               for value in row.values
                           })
            elif count == 0:
                return None
            else:
                return [
                    Row(key=row.key.decode(),
                        cells={
                            value.column.decode(): value.data
                            for value in row.values
                        }) for row in cell_set.rows
                ]
        elif code == CODE_NOT_FOUND:
            return None
        else:
            raise RESTError(code, response.text)
Beispiel #3
0
    def iter_scanner(self, scanner_url, num_rows=None):
        """Iterate a scanner.

        Args:
            scanner_url (str): The scanner URL which returned from "create_scanner".
                If the url is None, the method will return None.
            num_rows (int): Max number of rows will be returned.

        Returns:
            list[Row]: List of row.
            None: There is not more content to be iterated.

        Raises:
            RESTError: REST server returns other errors.

        Note that the scanner will not be closed(deleted) when the rows exhausted.
        You should close it manually.

        """
        if scanner_url is None:
            return None
        if num_rows is not None:
            scanner_url = scanner_url + '?n=' + str(num_rows)
        response = self._session.get(
            url=scanner_url, headers={'Accept': 'application/x-protobuf'})

        code = response.status_code
        if code == CODE_OK:
            cell_set = protobuf_schema.CellSet()
            cell_set.ParseFromString(response.content)
            return [
                Row(key=row.key.decode(),
                    cells={
                        value.column.decode(): value.data
                        for value in row.values
                    }) for row in cell_set.rows
            ]
        elif code == CODE_NO_CONTENT:
            return None
        else:
            raise RESTError(code, response.text)
Beispiel #4
0
    def put_many(self, table, rows):
        """Put(insert) multiple rows to the table.

        Args:
            table (str): Table name.
            rows (list[Row] | collections.deque): Row to insert.

        Returns:
            True: Success.

        Raises:
            RESTError: REST server returns other errors.

        """
        cell_set = protobuf_schema.CellSet()
        for row in rows:
            row_ = cell_set.rows.add()
            row_.key = row.key.encode()
            for column, data in row.items():
                value = row_.values.add()
                value.column = column.encode()
                value.data = data

        response = self._session.post(url='/'.join(
            (self._base_url, table, 'fakerow')),
                                      headers={
                                          'Content-Type':
                                          'application/x-protobuf',
                                          'Accept': 'application/x-protobuf'
                                      },
                                      data=cell_set.SerializeToString())

        code = response.status_code
        if code == CODE_OK:
            return True
        else:
            raise RESTError(code, response.text)