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)
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)
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)
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)