コード例 #1
0
ファイル: fbcore.py プロジェクト: gzip4/pyfirebirdsql
    def __init__(self, conn, names, timeout):
        self.sock = None
        self.connection = conn
        self.event_names = {}
        for name in names:
            self.event_names[name] = 0
        self.timeout = timeout
        self.connection._op_connect_request()
        (h, oid, buf) = self.connection._op_response()
        family = buf[:2]
        port = bytes_to_bint(buf[2:4], u=True)
        if family == b'\x02\x00':  # IPv4
            ip_address = '.'.join([str(byte_to_int(c)) for c in buf[4:8]])
        elif family == b'\x0a\x00':  # IPv6
            address = bytes_to_hex(buf[8:24])
            if not isinstance(address, str):  # Py3
                address = address.decode('ascii')
            ip_address = ':'.join(
                [address[i:i + 4] for i in range(0, len(address), 4)])
        self.sock = SocketStream(ip_address, port, timeout)
        self.connection.last_event_id += 1
        self.event_id = self.connection.last_event_id

        self.connection._op_que_events(self.event_names, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        (event_id, event_names) = self._wait_for_event(timeout=timeout)
        assert event_id == self.event_id  # treat only one event_id
        self.event_names.update(event_names)
コード例 #2
0
ファイル: fbcore.py プロジェクト: nakagami/pyfirebirdsql
class EventConduit(WireProtocol):
    def __init__(self, conn, names, timeout):
        self.sock = None
        self.connection = conn
        self.event_names = {}
        for name in names:
            self.event_names[name] = 0
        self.timeout = timeout
        self.connection._op_connect_request()
        (h, oid, buf) = self.connection._op_response()
        family = buf[:2]
        port = bytes_to_bint(buf[2:4], u=True)
        if family == b'\x02\x00':     # IPv4
            ip_address = '.'.join([str(byte_to_int(c)) for c in buf[4:8]])
        elif family == b'\x0a\x00':  # IPv6
            address = bytes_to_hex(buf[8:24])
            if not isinstance(address, str):    # Py3
                address = address.decode('ascii')
            ip_address = ':'.join(
                [address[i: i+4] for i in range(0, len(address), 4)]
            )
        self.sock = SocketStream(ip_address, port, timeout)
        self.connection.last_event_id += 1
        self.event_id = self.connection.last_event_id

        self.connection._op_que_events(self.event_names, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        (event_id, event_names) = self._wait_for_event(timeout=timeout)
        assert event_id == self.event_id   # treat only one event_id
        self.event_names.update(event_names)

    def wait(self, timeout=None):
        self.connection._op_que_events(self.event_names, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        r = self._wait_for_event(timeout=timeout)
        if r:
            (event_id, event_names) = r
            assert event_id == self.event_id   # treat only one event_id
            r = {}
            for k in event_names:
                r[k] = event_names[k]-self.event_names[k]
                self.event_names[k] = event_names[k]
        else:
            r = {}
            for k in self.event_names:
                r[k] = 0
        return r

    def close(self):
        self.connection._op_cancel_events(self.event_id)
        (h, oid, buf) = self.connection._op_response()
        self.sock.close()
        self.sock = None
コード例 #3
0
ファイル: fbcore.py プロジェクト: yuhisern7/pyfirebirdsql
    def __init__(
        self, dsn=None, user=None, password=None, role=None, host=None,
        database=None, charset=DEFAULT_CHARSET, port=None,
        page_size=4096, is_services=False, cloexec=False,
        timeout=None, isolation_level=None, use_unicode=None,
        auth_plugin_name=None, wire_crypt=True, create_new=False,
        timezone=None
    ):
        DEBUG_OUTPUT("Connection::__init__()")
        if auth_plugin_name is None:
            auth_plugin_name = 'Srp256'
        WireProtocol.__init__(self)
        self.sock = None
        self.db_handle = None
        (self.hostname, self.port, self.filename, self.user, self.password) = parse_dsn(dsn, host, port, database, user, password)
        self.role = role
        self.charset = charset
        self.timeout = float(timeout) if timeout is not None else None
        self.auth_plugin_name = auth_plugin_name
        self.wire_crypt = wire_crypt
        self.page_size = page_size
        self.is_services = is_services
        if isolation_level is None:
            self.isolation_level = ISOLATION_LEVEL_READ_COMMITED
        else:
            self.isolation_level = int(isolation_level)
        self.use_unicode = use_unicode
        self.timezone = timezone
        self.last_event_id = 0

        self._autocommit = False
        self._transaction = None
        self.sock = SocketStream(self.hostname, self.port, self.timeout, cloexec)

        self._op_connect(auth_plugin_name, wire_crypt)
        try:
            self._parse_connect_response()
        except OperationalError as e:
            self.sock.close()
            self.sock = None
            raise e
        if create_new:                      # create database
            self._op_create(self.page_size)
        elif self.is_services:                  # service api
            self._op_service_attach()
        else:                                   # connect
            self._op_attach()
        (h, oid, buf) = self._op_response()
        self.db_handle = h
コード例 #4
0
ファイル: fbcore.py プロジェクト: mariuz/pyfirebirdsql
class EventConduit(WireProtocol):
    def __init__(self, conn, names, timeout):
        self.sock = None
        self.connection = conn
        self.event_names = {}
        for name in names:
            self.event_names[name] = 0
        self.timeout = timeout
        self.connection._op_connect_request()
        (h, oid, buf) = self.connection._op_response()
        family = bytes_to_bint(buf[:2])
        port = bytes_to_bint(buf[2:4], u=True)
        ip_address = '.'.join([str(byte_to_int(c)) for c in buf[4:8]])

        self.sock = SocketStream(ip_address, port, timeout)
        self.connection.last_event_id += 1
        self.event_id = self.connection.last_event_id

        self.connection._op_que_events(self.event_names, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        (event_id, event_names) = self._wait_for_event(timeout=timeout)
        assert event_id == self.event_id   # treat only one event_id
        self.event_names.update(event_names)

    def wait(self, timeout=None):
        self.connection._op_que_events(self.event_names, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        r = self._wait_for_event(timeout=timeout)
        if r:
            (event_id, event_names) = r
            assert event_id == self.event_id   # treat only one event_id
            r = {}
            for k in event_names:
                r[k] = event_names[k]-self.event_names[k]
                self.event_names[k] = event_names[k]
        else:
            r = {}
            for k in self.event_names:
                r[k] = 0
        return r

    def close(self):
        self.connection._op_cancel_events(self.event_id)
        (h, oid, buf) = self.connection._op_response()
        self.sock.close()
        self.sock = None
コード例 #5
0
class EventConduit(WireProtocol):
    def __init__(self, conn, names, timeout):
        self.sock = None
        self.connection = conn
        self.event_names = {}
        for name in names:
            self.event_names[name] = 0
        self.timeout = timeout
        self.connection._op_connect_request()
        (h, oid, buf) = self.connection._op_response()
        family = bytes_to_bint(buf[:2])
        port = bytes_to_bint(buf[2:4], u=True)
        ip_address = '.'.join([str(byte_to_int(c)) for c in buf[4:8]])

        self.sock = SocketStream(ip_address, port, timeout)
        self.connection.last_event_id += 1
        self.event_id = self.connection.last_event_id

        self.connection._op_que_events(self.event_names, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        (event_id, event_names) = self._wait_for_event(timeout=timeout)
        assert event_id == self.event_id  # treat only one event_id
        self.event_names.update(event_names)

    def wait(self, timeout=None):
        self.connection._op_que_events(self.event_names, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        r = self._wait_for_event(timeout=timeout)
        if r:
            (event_id, event_names) = r
            assert event_id == self.event_id  # treat only one event_id
            r = {}
            for k in event_names:
                r[k] = event_names[k] - self.event_names[k]
                self.event_names[k] = event_names[k]
        else:
            r = {}
            for k in self.event_names:
                r[k] = 0
        return r

    def close(self):
        self.connection._op_cancel_events(self.event_id)
        (h, oid, buf) = self.connection._op_response()
        self.sock.close()
        self.sock = None
コード例 #6
0
ファイル: fbcore.py プロジェクト: tuksik/pyfirebirdsql
    def __init__(self, conn, names, timeout):
        self.sock = None
        self.connection = conn
        self.event_names = {}
        for name in names:
            self.event_names[name] = 0
        self.timeout = timeout
        (h, port, family, ip_address) = self.connection._op_connect_request()
        self.sock = SocketStream(ip_address, port, timeout)
        self.connection.last_event_id += 1
        self.event_id = self.connection.last_event_id

        self.connection._op_que_events(self.event_names, 0, 0, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        (event_id, event_names) = self._wait_for_event(timeout=timeout)
        assert event_id == self.event_id   # treat only one event_id
        self.event_names.update(event_names)
コード例 #7
0
ファイル: fbcore.py プロジェクト: tuksik/pyfirebirdsql
class EventConduit(WireProtocol):
    def __init__(self, conn, names, timeout):
        self.sock = None
        self.connection = conn
        self.event_names = {}
        for name in names:
            self.event_names[name] = 0
        self.timeout = timeout
        (h, port, family, ip_address) = self.connection._op_connect_request()
        self.sock = SocketStream(ip_address, port, timeout)
        self.connection.last_event_id += 1
        self.event_id = self.connection.last_event_id

        self.connection._op_que_events(self.event_names, 0, 0, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        (event_id, event_names) = self._wait_for_event(timeout=timeout)
        assert event_id == self.event_id   # treat only one event_id
        self.event_names.update(event_names)

    def wait(self, timeout=None):
        self.connection._op_que_events(self.event_names, 0, 0, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        r = self._wait_for_event(timeout=timeout)
        if r:
            (event_id, event_names) = r
            assert event_id == self.event_id   # treat only one event_id
            r = {}
            for k in event_names:
                r[k] = event_names[k]-self.event_names[k]
                self.event_names[k] = event_names[k]
        else:
            r = {}
            for k in self.event_names:
                r[k] = 0
        return r

    def close(self):
        self.connection._op_cancel_events(self.event_id)
        (h, oid, buf) = self.connection._op_response()
        self.sock.close()
        self.sock = None
コード例 #8
0
ファイル: fbcore.py プロジェクト: Salmista-94/pyfirebirdsql
class EventConduit(WireProtocol):
    def __init__(self, conn, names, timeout):
        self.sock = None
        self.connection = conn
        self.event_names = {}
        for name in names:
            self.event_names[name] = 0
        self.timeout = timeout
        (h, port, family, ip_address) = self.connection._op_connect_request()
        self.sock = SocketStream(ip_address, port, timeout)
        self.connection.last_event_id += 1
        self.event_id = self.connection.last_event_id

        self.connection._op_que_events(self.event_names, 0, 0, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        (event_id, event_names) = self._wait_for_event(timeout=timeout)
        assert event_id == self.event_id   # treat only one event_id
        self.event_names.update(event_names)

    def wait(self, timeout=None):
        self.connection._op_que_events(self.event_names, 0, 0, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        r = self._wait_for_event(timeout=timeout)
        if r:
            (event_id, event_names) = r
            assert event_id == self.event_id   # treat only one event_id
            r = {}
            for k in event_names:
                r[k] = event_names[k]-self.event_names[k]
                self.event_names[k] = event_names[k]
        else:
            r = {}
            for k in self.event_names:
                r[k] = 0
        return r

    def close(self):
        self.connection._op_cancel_events(self.event_id)
        (h, oid, buf) = self.connection._op_response()
        self.sock.close()
        self.sock = None
コード例 #9
0
    def __init__(self, conn, names, timeout):
        self.sock = None
        self.connection = conn
        self.event_names = {}
        for name in names:
            self.event_names[name] = 0
        self.timeout = timeout
        self.connection._op_connect_request()
        (h, oid, buf) = self.connection._op_response()
        family = bytes_to_bint(buf[:2])
        port = bytes_to_bint(buf[2:4], u=True)
        ip_address = '.'.join([str(byte_to_int(c)) for c in buf[4:8]])

        self.sock = SocketStream(ip_address, port, timeout)
        self.connection.last_event_id += 1
        self.event_id = self.connection.last_event_id

        self.connection._op_que_events(self.event_names, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        (event_id, event_names) = self._wait_for_event(timeout=timeout)
        assert event_id == self.event_id  # treat only one event_id
        self.event_names.update(event_names)
コード例 #10
0
ファイル: fbcore.py プロジェクト: KeeperDS/pyfirebirdsql
    def __init__(self, conn, names, timeout):
        self.connection = conn
        self.event_names = {}
        for name in names:
            self.event_names[name] = 0
        self.timeout = timeout
        (h, port, family, ip_address) = self.connection._op_connect_request()
        self.sock = SocketStream(ip_address, port, timeout)
        self.connection.last_event_id += 1
        self.event_id = self.connection.last_event_id

        self.connection._op_que_events(self.event_names, 0, 0, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        (event_id, event_names) = self._wait_for_event(timeout=timeout)
        assert event_id == self.event_id  # treat only one event_id
        self.event_names.update(event_names)
コード例 #11
0
ファイル: fbcore.py プロジェクト: mariuz/pyfirebirdsql
    def __init__(self, conn, names, timeout):
        self.sock = None
        self.connection = conn
        self.event_names = {}
        for name in names:
            self.event_names[name] = 0
        self.timeout = timeout
        self.connection._op_connect_request()
        (h, oid, buf) = self.connection._op_response()
        family = bytes_to_bint(buf[:2])
        port = bytes_to_bint(buf[2:4], u=True)
        ip_address = '.'.join([str(byte_to_int(c)) for c in buf[4:8]])

        self.sock = SocketStream(ip_address, port, timeout)
        self.connection.last_event_id += 1
        self.event_id = self.connection.last_event_id

        self.connection._op_que_events(self.event_names, self.event_id)
        (h, oid, buf) = self.connection._op_response()

        (event_id, event_names) = self._wait_for_event(timeout=timeout)
        assert event_id == self.event_id   # treat only one event_id
        self.event_names.update(event_names)
コード例 #12
0
ファイル: fbcore.py プロジェクト: mariuz/pyfirebirdsql
    def __init__(
        self, dsn=None, user=None, password=None, role=None, host=None,
        database=None, charset=DEFAULT_CHARSET, port=3050,
        page_size=4096, is_services=False, cloexec=False,
        timeout=None, isolation_level=None, use_unicode=None,
        auth_plugin_name=None, wire_crypt=True, create_new=False
    ):
        DEBUG_OUTPUT("Connection::__init__()")
        if auth_plugin_name is None:
            auth_plugin_name = 'Srp'
        WireProtocol.__init__(self)
        self.sock = None
        self.db_handle = None
        if dsn:
            i = dsn.find(':')
            if i < 0:
                self.hostname = host
                self.filename = dsn
            else:
                hostport = dsn[:i]
                self.filename = dsn[i+1:]
                i = hostport.find('/')
                if i < 0:
                    self.hostname = hostport
                else:
                    self.hostname = hostport[:i]
                    port = int(hostport[i+1:])
        else:
            self.hostname = host
            self.filename = database
        if self.hostname is None:
            self.hostname = 'localhost'
        self.port = port
        self.user = user
        self.password = password
        self.role = role
        self.charset = charset
        self.timeout = float(timeout) if timeout is not None else None
        self.auth_plugin_name = auth_plugin_name
        self.wire_crypt = wire_crypt
        self.page_size = page_size
        self.is_services = is_services
        if isolation_level is None:
            self.isolation_level = ISOLATION_LEVEL_READ_COMMITED
        else:
            self.isolation_level = int(isolation_level)
        self.use_unicode = use_unicode
        self.last_event_id = 0

        self._autocommit = False
        self._transaction = None
        self.sock = SocketStream(self.hostname, self.port, self.timeout, cloexec)

        self._op_connect(auth_plugin_name, wire_crypt)
        try:
            self._op_accept()
        except OperationalError as e:
            self.sock.close()
            self.sock = None
            raise e
        if create_new:                      # create database
            self._op_create(self.page_size)
        elif self.is_services:                  # service api
            self._op_service_attach()
        else:                                   # connect
            self._op_attach()
        (h, oid, buf) = self._op_response()
        self.db_handle = h
コード例 #13
0
ファイル: fbcore.py プロジェクト: mariuz/pyfirebirdsql
class Connection(WireProtocol):
    def cursor(self):
        DEBUG_OUTPUT("Connection::cursor()")
        if self._transaction is None:
            self.begin()
        return Cursor(self._transaction)

    def begin(self):
        DEBUG_OUTPUT("Connection::begin()")
        if not self.sock:
            raise InternalError
        if self._transaction is None:
            self._transaction = Transaction(self, self._autocommit)
        self._transaction.begin()

    def commit(self, retaining=False):
        DEBUG_OUTPUT("Connection::commit()")
        if self._transaction:
            self._transaction.commit(retaining=retaining)

    def savepoint(self, name):
        return self._transaction.savepoint(name)

    def rollback(self, retaining=False, savepoint=None):
        DEBUG_OUTPUT("Connection::rollback()")
        if self._transaction:
            self._transaction.rollback(retaining=retaining, savepoint=savepoint)

    def execute_immediate(self, query):
        if self._transaction is None:
            self._transaction = Transaction(self, self._autocommit)
            self._transaction.begin()
        self._transaction.check_trans_handle()
        self._op_exec_immediate(
            self._transaction.trans_handle, query=query)
        (h, oid, buf) = self._op_response()
        self._transaction.is_dirty = True

    def __init__(
        self, dsn=None, user=None, password=None, role=None, host=None,
        database=None, charset=DEFAULT_CHARSET, port=3050,
        page_size=4096, is_services=False, cloexec=False,
        timeout=None, isolation_level=None, use_unicode=None,
        auth_plugin_name=None, wire_crypt=True, create_new=False
    ):
        DEBUG_OUTPUT("Connection::__init__()")
        if auth_plugin_name is None:
            auth_plugin_name = 'Srp'
        WireProtocol.__init__(self)
        self.sock = None
        self.db_handle = None
        if dsn:
            i = dsn.find(':')
            if i < 0:
                self.hostname = host
                self.filename = dsn
            else:
                hostport = dsn[:i]
                self.filename = dsn[i+1:]
                i = hostport.find('/')
                if i < 0:
                    self.hostname = hostport
                else:
                    self.hostname = hostport[:i]
                    port = int(hostport[i+1:])
        else:
            self.hostname = host
            self.filename = database
        if self.hostname is None:
            self.hostname = 'localhost'
        self.port = port
        self.user = user
        self.password = password
        self.role = role
        self.charset = charset
        self.timeout = float(timeout) if timeout is not None else None
        self.auth_plugin_name = auth_plugin_name
        self.wire_crypt = wire_crypt
        self.page_size = page_size
        self.is_services = is_services
        if isolation_level is None:
            self.isolation_level = ISOLATION_LEVEL_READ_COMMITED
        else:
            self.isolation_level = int(isolation_level)
        self.use_unicode = use_unicode
        self.last_event_id = 0

        self._autocommit = False
        self._transaction = None
        self.sock = SocketStream(self.hostname, self.port, self.timeout, cloexec)

        self._op_connect(auth_plugin_name, wire_crypt)
        try:
            self._op_accept()
        except OperationalError as e:
            self.sock.close()
            self.sock = None
            raise e
        if create_new:                      # create database
            self._op_create(self.page_size)
        elif self.is_services:                  # service api
            self._op_service_attach()
        else:                                   # connect
            self._op_attach()
        (h, oid, buf) = self._op_response()
        self.db_handle = h

    def __enter__(self):
        return self

    def __exit__(self, exc, value, traceback):
        self.close()

    def set_isolation_level(self, isolation_level):
        self.isolation_level = int(isolation_level)

    def set_autocommit(self, is_autocommit):
        if self._autocommit != is_autocommit and self._transaction is not None:
            self.rollback()
            self._transaction = None
        self._autocommit = is_autocommit

    def _db_info(self, info_requests):
        if info_requests[-1] == isc_info_end:
            self._op_info_database(bs(info_requests))
        else:
            self._op_info_database(bs(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 _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(self, info_requests):
        DEBUG_OUTPUT("Connection::db_info()")
        if type(info_requests) == int:  # singleton
            r = self._db_info([info_requests])
            return self._db_info_convert_type(info_requests, r[0][1])
        else:
            results = {}
            rs = self._db_info(info_requests)
            for i in range(len(info_requests)):
                if rs[i][0] == isc_info_error:
                    results[info_requests[i]] = None
                else:
                    results[info_requests[i]] = self._db_info_convert_type(info_requests[i], rs[i][1])
            return results

    def trans_info(self, info_requests):
        if self._transaction:
            return self._transaction.trans_info(info_requests)
        return {}

    def close(self):
        DEBUG_OUTPUT("Connection::close()")
        if self.sock is None:
            return
        if self.db_handle:
            if self.is_services:
                self._op_service_detach()
            else:
                self._op_detach()
            (h, oid, buf) = self._op_response()
        self.sock.close()
        self.sock = None
        self.db_handle = None

    def drop_database(self):
        DEBUG_OUTPUT("Connection::drop_database()")
        self._op_drop_database()
        (h, oid, buf) = self._op_response()
        self.sock.close()
        self.sock = None
        self.db_handle = None

    def event_conduit(self, event_names, timeout=None):
        return EventConduit(self, event_names, timeout)

    def __del__(self):
        if self.sock:
            self.close()

    def is_disconnect(self):
        return self.sock is None
コード例 #14
0
ファイル: fbcore.py プロジェクト: gzip4/pyfirebirdsql
class Connection(WireProtocol):
    def cursor(self, factory=Cursor):
        DEBUG_OUTPUT("Connection::cursor()")
        if self._transaction is None:
            self.begin()
        return factory(self._transaction)

    def begin(self):
        DEBUG_OUTPUT("Connection::begin()")
        if not self.sock:
            raise InternalError
        if self._transaction is None:
            self._transaction = Transaction(self, self._autocommit)
        self._transaction.begin()

    def commit(self, retaining=False):
        DEBUG_OUTPUT("Connection::commit()")
        if self._transaction:
            self._transaction.commit(retaining=retaining)

    def savepoint(self, name):
        return self._transaction.savepoint(name)

    def rollback(self, retaining=False, savepoint=None):
        DEBUG_OUTPUT("Connection::rollback()")
        if self._transaction:
            self._transaction.rollback(retaining=retaining,
                                       savepoint=savepoint)

    def execute_immediate(self, query):
        if self._transaction is None:
            self._transaction = Transaction(self, self._autocommit)
            self._transaction.begin()
        self._transaction.check_trans_handle()
        self._op_exec_immediate(self._transaction.trans_handle, query=query)
        (h, oid, buf) = self._op_response()
        self._transaction.is_dirty = True

    def __init__(self,
                 dsn=None,
                 user=None,
                 password=None,
                 role=None,
                 host=None,
                 database=None,
                 charset=DEFAULT_CHARSET,
                 port=3050,
                 page_size=4096,
                 is_services=False,
                 cloexec=False,
                 timeout=None,
                 isolation_level=None,
                 use_unicode=None,
                 auth_plugin_name=None,
                 wire_crypt=True,
                 create_new=False,
                 timezone=None):
        DEBUG_OUTPUT("Connection::__init__()")
        if auth_plugin_name is None:
            auth_plugin_name = 'Srp256'
        WireProtocol.__init__(self)
        self.sock = None
        self.db_handle = None
        if dsn:
            i = dsn.find(':')
            if i < 0:
                self.hostname = host
                self.filename = dsn
            else:
                hostport = dsn[:i]
                self.filename = dsn[i + 1:]
                i = hostport.find('/')
                if i < 0:
                    self.hostname = hostport
                else:
                    self.hostname = hostport[:i]
                    port = int(hostport[i + 1:])
        else:
            self.hostname = host
            self.filename = database
        if self.hostname is None:
            self.hostname = 'localhost'
        self.port = port
        self.user = user
        self.password = password
        self.role = role
        self.charset = charset
        self.timeout = float(timeout) if timeout is not None else None
        self.auth_plugin_name = auth_plugin_name
        self.wire_crypt = wire_crypt
        self.page_size = page_size
        self.is_services = is_services
        if isolation_level is None:
            self.isolation_level = ISOLATION_LEVEL_READ_COMMITED
        else:
            self.isolation_level = int(isolation_level)
        self.use_unicode = use_unicode
        self.timezone = timezone
        self.last_event_id = 0

        self._autocommit = False
        self._transaction = None
        self.sock = SocketStream(self.hostname, self.port, self.timeout,
                                 cloexec)

        self._op_connect(auth_plugin_name, wire_crypt)
        try:
            self._parse_connect_response()
        except OperationalError as e:
            self.sock.close()
            self.sock = None
            raise e
        if create_new:  # create database
            self._op_create(self.page_size)
        elif self.is_services:  # service api
            self._op_service_attach()
        else:  # connect
            self._op_attach()
        (h, oid, buf) = self._op_response()
        self.db_handle = h

    def __enter__(self):
        return self

    def __exit__(self, exc, value, traceback):
        self.close()

    def set_isolation_level(self, isolation_level):
        self.isolation_level = int(isolation_level)

    def set_autocommit(self, is_autocommit):
        if self._autocommit != is_autocommit and self._transaction is not None:
            self.rollback()
            self._transaction = None
        self._autocommit = is_autocommit

    def _db_info(self, info_requests):
        if info_requests[-1] == isc_info_end:
            self._op_info_database(bs(info_requests))
        else:
            self._op_info_database(
                bs(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 _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(self, info_requests):
        DEBUG_OUTPUT("Connection::db_info()")
        if type(info_requests) == int:  # singleton
            r = self._db_info([info_requests])
            return self._db_info_convert_type(info_requests, r[0][1])
        else:
            results = {}
            rs = self._db_info(info_requests)
            for i in range(len(info_requests)):
                if rs[i][0] == isc_info_error:
                    results[info_requests[i]] = None
                else:
                    results[info_requests[i]] = self._db_info_convert_type(
                        info_requests[i], rs[i][1])
            return results

    def trans_info(self, info_requests):
        if self._transaction:
            return self._transaction.trans_info(info_requests)
        return {}

    def close(self):
        DEBUG_OUTPUT("Connection::close()")
        if self.sock is None:
            return
        if self.db_handle:
            if self.is_services:
                self._op_service_detach()
            else:
                self._op_detach()
            (h, oid, buf) = self._op_response()
        self.sock.close()
        self.sock = None
        self.db_handle = None

    def drop_database(self):
        DEBUG_OUTPUT("Connection::drop_database()")
        self._op_drop_database()
        (h, oid, buf) = self._op_response()
        self.sock.close()
        self.sock = None
        self.db_handle = None

    def event_conduit(self, event_names, timeout=None):
        return EventConduit(self, event_names, timeout)

    def __del__(self):
        if self.sock:
            self.close()

    def is_disconnect(self):
        return self.sock is None