def _db_info(self, info_requests): if info_requests[-1] == isc_info_end: self._op_info_database(bytes(info_requests)) else: self._op_info_database( bytes(info_requests+type(info_requests)([isc_info_end]))) (h, oid, buf) = self._op_response() i = 0 i_request = 0 r = [] while i < len(buf): req = byte_to_int(buf[i]) if req == isc_info_end: break assert req == info_requests[i_request] if req == isc_info_user_names: user_names = [] while req == isc_info_user_names: l = bytes_to_int(buf[i+1:i+3]) user_names.append(buf[i+3:i+3+l]) i = i + 3 + l req = byte_to_int(buf[i]) r.append(user_names) else: l = bytes_to_int(buf[i+1:i+3]) r.append(buf[i+3:i+3+l]) i = i + 3 + l i_request += 1 return r
def _db_info(self, info_requests): if info_requests[-1] == isc_info_end: self._op_info_database(bytes(info_requests)) else: self._op_info_database( bytes(info_requests + type(info_requests)([isc_info_end]))) (h, oid, buf) = self._op_response() i = 0 i_request = 0 r = [] while i < len(buf): req = byte_to_int(buf[i]) if req == isc_info_end: break assert req == info_requests[i_request] or req == isc_info_error if req == isc_info_user_names: user_names = [] while req == isc_info_user_names: l = bytes_to_int(buf[i + 1:i + 3]) user_names.append(buf[i + 3:i + 3 + l]) i = i + 3 + l req = byte_to_int(buf[i]) r.append((req, user_names)) else: l = bytes_to_int(buf[i + 1:i + 3]) r.append((req, buf[i + 3:i + 3 + l])) i = i + 3 + l i_request += 1 return r
def parse_select_items(buf, xsqlda, connection): index = 0 i = 0 item = byte_to_int(buf[i]) while item != isc_info_end: if item == isc_info_sql_sqlda_seq: l = bytes_to_int(buf[i + 1:i + 3]) index = bytes_to_int(buf[i + 3:i + 3 + l]) xsqlda[index - 1] = XSQLVAR(connection.bytes_to_str) i = i + 3 + l elif item == isc_info_sql_type: l = bytes_to_int(buf[i + 1:i + 3]) xsqlda[index - 1].sqltype = bytes_to_int(buf[i + 3:i + 3 + l]) & ~1 i = i + 3 + l elif item == isc_info_sql_sub_type: l = bytes_to_int(buf[i + 1:i + 3]) xsqlda[index - 1].sqlsubtype = bytes_to_int(buf[i + 3:i + 3 + l]) i = i + 3 + l elif item == isc_info_sql_scale: l = bytes_to_int(buf[i + 1:i + 3]) xsqlda[index - 1].sqlscale = bytes_to_int(buf[i + 3:i + 3 + l]) i = i + 3 + l elif item == isc_info_sql_length: l = bytes_to_int(buf[i + 1:i + 3]) xsqlda[index - 1].sqllen = bytes_to_int(buf[i + 3:i + 3 + l]) i = i + 3 + l elif item == isc_info_sql_null_ind: l = bytes_to_int(buf[i + 1:i + 3]) xsqlda[index - 1].null_ok = bytes_to_int(buf[i + 3:i + 3 + l]) i = i + 3 + l elif item == isc_info_sql_field: l = bytes_to_int(buf[i + 1:i + 3]) xsqlda[index - 1].fieldname = connection.bytes_to_str(buf[i + 3:i + 3 + l]) i = i + 3 + l elif item == isc_info_sql_relation: l = bytes_to_int(buf[i + 1:i + 3]) xsqlda[index - 1].relname = connection.bytes_to_str(buf[i + 3:i + 3 + l]) i = i + 3 + l elif item == isc_info_sql_owner: l = bytes_to_int(buf[i + 1:i + 3]) xsqlda[index - 1].ownname = connection.bytes_to_str(buf[i + 3:i + 3 + l]) i = i + 3 + l elif item == isc_info_sql_alias: l = bytes_to_int(buf[i + 1:i + 3]) xsqlda[index - 1].aliasname = connection.bytes_to_str(buf[i + 3:i + 3 + l]) i = i + 3 + l elif item == isc_info_truncated: return index # return next index elif item == isc_info_sql_describe_end: i = i + 1 else: print('\t', item, 'Invalid item [%02x] ! i=%d' % (buf[i], i)) i = i + 1 item = byte_to_int(buf[i]) return -1 # no more info
def parse_select_items(buf, xsqlda, connection): index = 0 i = 0 item = byte_to_int(buf[i]) while item != isc_info_end: if item == isc_info_sql_sqlda_seq: l = bytes_to_int(buf[i+1:i+3]) index = bytes_to_int(buf[i+3:i+3+l]) xsqlda[index-1] = XSQLVAR(connection.bytes_to_ustr if connection.use_unicode else connection.bytes_to_str) xsqlda[index-1] = XSQLVAR(connection.bytes_to_str) i = i + 3 + l elif item == isc_info_sql_type: l = bytes_to_int(buf[i+1:i+3]) xsqlda[index-1].sqltype = bytes_to_int(buf[i+3:i+3+l]) & ~ 1 i = i + 3 + l elif item == isc_info_sql_sub_type: l = bytes_to_int(buf[i+1:i+3]) xsqlda[index-1].sqlsubtype = bytes_to_int(buf[i+3:i+3+l]) i = i + 3 + l elif item == isc_info_sql_scale: l = bytes_to_int(buf[i+1:i+3]) xsqlda[index-1].sqlscale = bytes_to_int(buf[i+3:i+3+l]) i = i + 3 + l elif item == isc_info_sql_length: l = bytes_to_int(buf[i+1:i+3]) xsqlda[index-1].sqllen = bytes_to_int(buf[i+3:i+3+l]) i = i + 3 + l elif item == isc_info_sql_null_ind: l = bytes_to_int(buf[i+1:i+3]) xsqlda[index-1].null_ok = bytes_to_int(buf[i+3:i+3+l]) i = i + 3 + l elif item == isc_info_sql_field: l = bytes_to_int(buf[i+1:i+3]) xsqlda[index-1].fieldname = connection.bytes_to_str(buf[i+3:i+3+l]) i = i + 3 + l elif item == isc_info_sql_relation: l = bytes_to_int(buf[i+1:i+3]) xsqlda[index-1].relname = connection.bytes_to_str(buf[i+3:i+3+l]) i = i + 3 + l elif item == isc_info_sql_owner: l = bytes_to_int(buf[i+1:i+3]) xsqlda[index-1].ownname = connection.bytes_to_str(buf[i+3:i+3+l]) i = i + 3 + l elif item == isc_info_sql_alias: l = bytes_to_int(buf[i+1:i+3]) xsqlda[index-1].aliasname = connection.bytes_to_str(buf[i+3:i+3+l]) i = i + 3 + l elif item == isc_info_truncated: return index # return next index elif item == isc_info_sql_describe_end: i = i + 1 else: print('\t', item, 'Invalid item [%02x] ! i=%d' % (buf[i], i)) i = i + 1 item = byte_to_int(buf[i]) return -1 # no more info
def trans_info(self, info_requests): if type(info_requests) == int: # singleton r = self._trans_info([info_requests]) return {info_requests: r[0]} else: results = {} rs = self._trans_info(info_requests) for i in range(len(info_requests)): if info_requests[i] == isc_info_tra_isolation: v = (byte_to_int(rs[i][0]), byte_to_int(rs[i][1])) else: v = bytes_to_int(rs[i]) results[info_requests[i]] = v return results
def __init__(self, cur, sql, explain_plan=False): self.cur = cur self.sql = sql transaction = self.cur.transaction connection = transaction.connection connection._op_allocate_statement() (h, oid, buf) = connection._op_response() self.stmt_handle = h if explain_plan: connection._op_prepare_statement( self.stmt_handle, transaction.trans_handle, sql, option_items=bytes([isc_info_sql_get_plan])) else: connection._op_prepare_statement( self.stmt_handle, transaction.trans_handle, sql) self.plan = None (h, oid, buf) = connection._op_response() i = 0 if byte_to_int(buf[i]) == isc_info_sql_get_plan: l = bytes_to_int(buf[i+1:i+3]) self.plan = connection.bytes_to_str(buf[i+3:i+3+l]) i += 3 + l assert buf[i:i+3] == bytes([0x15,0x04,0x00]) # isc_info_sql_stmt_type (4 bytes) self.statement_type = bytes_to_int(buf[i+3:i+7]) self._xsqlda = parse_xsqlda(buf[i:], connection, self.stmt_handle)
def __init__(self, cur, sql, explain_plan=False): self.cur = cur self.sql = sql transaction = self.cur.transaction connection = transaction.connection connection._op_allocate_statement() (h, oid, buf) = connection._op_response() self.stmt_handle = h if explain_plan: connection._op_prepare_statement(self.stmt_handle, transaction.trans_handle, sql, option_items=bytes( [isc_info_sql_get_plan])) else: connection._op_prepare_statement(self.stmt_handle, transaction.trans_handle, sql) self.plan = None (h, oid, buf) = connection._op_response() i = 0 if byte_to_int(buf[i]) == isc_info_sql_get_plan: l = bytes_to_int(buf[i + 1:i + 3]) self.plan = connection.bytes_to_str(buf[i + 3:i + 3 + l]) i += 3 + l assert buf[i:i + 3] == bytes([0x15, 0x04, 0x00 ]) # isc_info_sql_stmt_type (4 bytes) self.statement_type = bytes_to_int(buf[i + 3:i + 7]) self._xsqlda = parse_xsqlda(buf[i:], connection, self.stmt_handle)
def trans_info(self, info_requests): if type(info_requests) == int: # singleton r = self._trans_info([info_requests]) return {info_requests: r[1][0]} else: results = {} rs = self._trans_info(info_requests) for i in range(len(info_requests)): if rs[i][0] == isc_info_tra_isolation: v = (byte_to_int(rs[i][1][0]), byte_to_int(rs[i][1][1])) elif rs[i][0] == isc_info_error: v = None else: v = bytes_to_int(rs[i][1]) results[info_requests[i]] = v return results
def value(self, raw_value): if self.sqltype == SQL_TYPE_TEXT: return self.bytes_to_str(raw_value).rstrip() elif self.sqltype == SQL_TYPE_VARYING: return self.bytes_to_str(raw_value) elif self.sqltype in (SQL_TYPE_SHORT, SQL_TYPE_LONG, SQL_TYPE_INT64): n = bytes_to_bint(raw_value) if self.sqlscale: return decimal.Decimal(str(n) + 'e' + str(self.sqlscale)) else: return n elif self.sqltype == SQL_TYPE_DATE: yyyy, mm, dd = self._parse_date(raw_value) return datetime.date(yyyy, mm, dd) elif self.sqltype == SQL_TYPE_TIME: h, m, s, ms = self._parse_time(raw_value) return datetime.time(h, m, s, ms) elif self.sqltype == SQL_TYPE_TIMESTAMP: yyyy, mm, dd = self._parse_date(raw_value[:4]) h, m, s, ms = self._parse_time(raw_value[4:]) return datetime.datetime(yyyy, mm, dd, h, m, s, ms) elif self.sqltype == SQL_TYPE_FLOAT: return struct.unpack('!f', raw_value)[0] elif self.sqltype == SQL_TYPE_DOUBLE: return struct.unpack('!d', raw_value)[0] elif self.sqltype == SQL_TYPE_BOOLEAN: return True if byte_to_int(raw_value[0]) != 0 else False else: return raw_value
def _trans_info(self, info_requests): if info_requests[-1] == isc_info_end: self.connection._op_info_transaction(self.trans_handle, bytes(info_requests)) else: self.connection._op_info_transaction(self.trans_handle, bytes(info_requests+type(info_requests)([isc_info_end]))) (h, oid, buf) = self.connection._op_response() i = 0 i_request = 0 r = [] while i < len(buf): req = byte_to_int(buf[i]) if req == isc_info_end: break assert req == info_requests[i_request] l = bytes_to_int(buf[i+1:i+3]) r.append(buf[i+3:i+3+l]) i = i + 3 + l i_request += 1 return r
def _trans_info(self, info_requests): if info_requests[-1] == isc_info_end: self.connection._op_info_transaction(self.trans_handle, bytes(info_requests)) else: self.connection._op_info_transaction( self.trans_handle, bytes(info_requests + type(info_requests)([isc_info_end]))) (h, oid, buf) = self.connection._op_response() i = 0 i_request = 0 r = [] while i < len(buf): req = byte_to_int(buf[i]) if req == isc_info_end: break assert req == info_requests[i_request] or req == isc_info_error l = bytes_to_int(buf[i + 1:i + 3]) r.append((req, buf[i + 3:i + 3 + l])) i = i + 3 + l i_request += 1 return r
def _db_info_convert_type(self, info_request, v): REQ_INT = set([ isc_info_allocation, isc_info_no_reserve, isc_info_db_sql_dialect, isc_info_ods_minor_version, isc_info_ods_version, isc_info_page_size, isc_info_current_memory, isc_info_forced_writes, isc_info_max_memory, isc_info_num_buffers, isc_info_sweep_interval, isc_info_limbo, isc_info_attachment_id, isc_info_fetches, isc_info_marks, isc_info_reads, isc_info_writes, isc_info_set_page_buffers, isc_info_db_read_only, isc_info_db_size_in_pages, isc_info_page_errors, isc_info_record_errors, isc_info_bpage_errors, isc_info_dpage_errors, isc_info_ipage_errors, isc_info_ppage_errors, isc_info_tpage_errors, # may not be available in some versions of Firebird isc_info_oldest_transaction, isc_info_oldest_active, isc_info_oldest_snapshot, isc_info_next_transaction, isc_info_active_tran_count ]) REQ_COUNT = set([ isc_info_backout_count, isc_info_delete_count, isc_info_expunge_count, isc_info_insert_count, isc_info_purge_count, isc_info_read_idx_count, isc_info_read_seq_count, isc_info_update_count ]) if info_request in (isc_info_base_level, ): # IB6 API guide p52 return byte_to_int(v[1]) elif info_request in (isc_info_db_id, ): # IB6 API guide p52 conn_code = byte_to_int(v[0]) len1 = byte_to_int(v[1]) filename = self.bytes_to_str(v[2:2+len1]) len2 = byte_to_int(v[2+len1]) sitename = self.bytes_to_str(v[3+len1:3+len1+len2]) return (conn_code, filename, sitename) elif info_request in (isc_info_implementation, ): return (byte_to_int(v[1]), byte_to_int(v[2])) elif info_request in (isc_info_version, isc_info_firebird_version): # IB6 API guide p53 return self.bytes_to_str(v[2:2+byte_to_int(v[1])]) elif info_request in (isc_info_user_names, ): # IB6 API guide p54 user_names = [] for u in v: user_names.append(self.bytes_to_str(u[1:])) return user_names elif info_request in REQ_INT: return bytes_to_int(v) elif info_request in REQ_COUNT: counts = {} i = 0 while i < len(v): counts[bytes_to_int(v[i:i+2])] = bytes_to_int(v[i+2:i+6]) i += 6 return counts elif info_request in (isc_info_creation_date,): nday = bytes_to_int(v[:4]) + 2400001 - 1721119 century = (4 * nday - 1) // 146097 nday = 4 * nday - 1 - 146097 * century dd = nday // 4 nday = (4 * dd + 3) // 1461 dd = 4 * dd + 3 - 1461 * nday dd = (dd + 4) // 4 mm = (5 * dd - 3) // 153 dd = 5 * dd - 3 - 153 * mm dd = (dd + 5) // 5 yyyy = 100 * century + nday; if mm < 10: mm += 3 else: mm -= 9 yyyy += 1 ntime = bytes_to_int(v[4:]) h = ntime // (3600 * ISC_TIME_SECONDS_PRECISION) ntime %= 3600 * ISC_TIME_SECONDS_PRECISION m = ntime // (60 * ISC_TIME_SECONDS_PRECISION) ntime %= 60 * ISC_TIME_SECONDS_PRECISION s = ntime // ISC_TIME_SECONDS_PRECISION ms = ntime % ISC_TIME_SECONDS_PRECISION * 100 return datetime.datetime(yyyy, mm, dd, h, m, s, ms) else: return v
def _db_info_convert_type(self, info_request, v): REQ_INT = set([ isc_info_allocation, isc_info_no_reserve, isc_info_db_sql_dialect, isc_info_ods_minor_version, isc_info_ods_version, isc_info_page_size, isc_info_current_memory, isc_info_forced_writes, isc_info_max_memory, isc_info_num_buffers, isc_info_sweep_interval, isc_info_limbo, isc_info_attachment_id, isc_info_fetches, isc_info_marks, isc_info_reads, isc_info_writes, isc_info_set_page_buffers, isc_info_db_read_only, isc_info_db_size_in_pages, isc_info_page_errors, isc_info_record_errors, isc_info_bpage_errors, isc_info_dpage_errors, isc_info_ipage_errors, isc_info_ppage_errors, isc_info_tpage_errors, # may not be available in some versions of Firebird isc_info_oldest_transaction, isc_info_oldest_active, isc_info_oldest_snapshot, isc_info_next_transaction, isc_info_active_tran_count ]) REQ_COUNT = set([ isc_info_backout_count, isc_info_delete_count, isc_info_expunge_count, isc_info_insert_count, isc_info_purge_count, isc_info_read_idx_count, isc_info_read_seq_count, isc_info_update_count ]) if info_request in (isc_info_base_level, ): # IB6 API guide p52 return byte_to_int(v[1]) elif info_request in (isc_info_db_id, ): # IB6 API guide p52 conn_code = byte_to_int(v[0]) len1 = byte_to_int(v[1]) filename = self.bytes_to_str(v[2:2 + len1]) len2 = byte_to_int(v[2 + len1]) sitename = self.bytes_to_str(v[3 + len1:3 + len1 + len2]) return (conn_code, filename, sitename) elif info_request in (isc_info_implementation, ): return (byte_to_int(v[1]), byte_to_int(v[2])) elif info_request in (isc_info_version, isc_info_firebird_version): # IB6 API guide p53 return self.bytes_to_str(v[2:2 + byte_to_int(v[1])]) elif info_request in (isc_info_user_names, ): # IB6 API guide p54 user_names = [] for u in v: user_names.append(self.bytes_to_str(u[1:])) return user_names elif info_request in REQ_INT: return bytes_to_int(v) elif info_request in REQ_COUNT: counts = {} i = 0 while i < len(v): counts[bytes_to_int(v[i:i + 2])] = bytes_to_int(v[i + 2:i + 6]) i += 6 return counts elif info_request in (isc_info_creation_date, ): nday = bytes_to_int(v[:4]) + 2400001 - 1721119 century = (4 * nday - 1) // 146097 nday = 4 * nday - 1 - 146097 * century dd = nday // 4 nday = (4 * dd + 3) // 1461 dd = 4 * dd + 3 - 1461 * nday dd = (dd + 4) // 4 mm = (5 * dd - 3) // 153 dd = 5 * dd - 3 - 153 * mm dd = (dd + 5) // 5 yyyy = 100 * century + nday if mm < 10: mm += 3 else: mm -= 9 yyyy += 1 ntime = bytes_to_int(v[4:]) h = ntime // (3600 * ISC_TIME_SECONDS_PRECISION) ntime %= 3600 * ISC_TIME_SECONDS_PRECISION m = ntime // (60 * ISC_TIME_SECONDS_PRECISION) ntime %= 60 * ISC_TIME_SECONDS_PRECISION s = ntime // ISC_TIME_SECONDS_PRECISION ms = ntime % ISC_TIME_SECONDS_PRECISION * 100 return datetime.datetime(yyyy, mm, dd, h, m, s, ms) else: return v