2 @message |
Permission error
I/O error
firebird.driver.types.DatabaseError: I/O error during "CreateFile (open)" operation for file "gh_8429_alias_c"
-Error while trying to open file
-The process cannot access the file because it is being used by another process.
LOG DETAILS:
2025-02-25 10:48:29.757
2025-02-25 10:48:29.757 act_a = <firebird.qa.plugin.Action object at [hex]>
2025-02-25 10:48:29.757 act_b = <firebird.qa.plugin.Action object at [hex]>
2025-02-25 10:48:29.757 act_c = <firebird.qa.plugin.Action object at [hex]>
2025-02-25 10:48:29.757 usr_x = <firebird.qa.plugin.User object at [hex]>
2025-02-25 10:48:29.757 usr_y = <firebird.qa.plugin.User object at [hex]>
2025-02-25 10:48:29.757 usr_z = <firebird.qa.plugin.User object at [hex]>
2025-02-25 10:48:29.757 capsys = <_pytest.capture.CaptureFixture object at [hex]>
2025-02-25 10:48:29.757
2025-02-25 10:48:29.758 @pytest.mark.es_eds
2025-02-25 10:48:29.758 @pytest.mark.encryption
2025-02-25 10:48:29.758 @pytest.mark.version('>=4.0.6')
2025-02-25 10:48:29.758 def test_1(act_a: Action, act_b: Action, act_c: Action, usr_x: User, usr_y: User, usr_z: User, capsys):
2025-02-25 10:48:29.758
2025-02-25 10:48:29.758 dbfile_a = get_filename_by_alias(act_a)
2025-02-25 10:48:29.758 dbfile_b = get_filename_by_alias(act_b)
2025-02-25 10:48:29.758 dbfile_c = get_filename_by_alias(act_c)
2025-02-25 10:48:29.758
2025-02-25 10:48:29.758 dbfile_a.unlink(missing_ok = True)
2025-02-25 10:48:29.758 dbfile_b.unlink(missing_ok = True)
2025-02-25 10:48:29.758 dbfile_c.unlink(missing_ok = True)
2025-02-25 10:48:29.758
2025-02-25 10:48:29.758 with create_database(act_a.db.db_path, user = act_a.db.user, password = act_a.db.password) as con_a, \
2025-02-25 10:48:29.758 create_database(act_b.db.db_path, user = act_b.db.user, password = act_b.db.password) as con_b, \
2025-02-25 10:48:29.758 create_database(act_c.db.db_path, user = act_c.db.user, password = act_c.db.password) as con_c:
2025-02-25 10:48:29.758
2025-02-25 10:48:29.758 sql = f"""
2025-02-25 10:48:29.758 create procedure sp_a (a_who varchar(31)) returns (o_info varchar(512)) as
2025-02-25 10:48:29.759 begin
2025-02-25 10:48:29.759 -- e1-meta.sql:
2025-02-25 10:48:29.759 execute statement 'select * from sp_b(''' || a_who || ''')' as user '{usr_x.name}' password '{usr_x.password}' on external 'gh_8429_alias_b' into o_info;
2025-02-25 10:48:29.759 suspend;
2025-02-25 10:48:29.759 end
2025-02-25 10:48:29.759 ^
2025-02-25 10:48:29.759 grant execute on procedure sp_a to public
2025-02-25 10:48:29.759 ^
2025-02-25 10:48:29.759 alter database set linger to 0
2025-02-25 10:48:29.759 ^
2025-02-25 10:48:29.759 """
2025-02-25 10:48:29.759 for x in sql.split('^'):
2025-02-25 10:48:29.759 if (s := x.strip()):
2025-02-25 10:48:29.759 con_a.execute_immediate(s)
2025-02-25 10:48:29.759 con_a.commit()
2025-02-25 10:48:29.759
2025-02-25 10:48:29.759 # ..................................................
2025-02-25 10:48:29.759
2025-02-25 10:48:29.759 sql = f"""
2025-02-25 10:48:29.759 create procedure sp_b (a_who varchar(31)) returns (o_info varchar(512)) as
2025-02-25 10:48:29.760 begin
2025-02-25 10:48:29.760 execute statement 'select * from sp_c' as user a_who password a_who on external 'gh_8429_alias_c' into o_info;
2025-02-25 10:48:29.760 suspend;
2025-02-25 10:48:29.760 end
2025-02-25 10:48:29.760 ^
2025-02-25 10:48:29.760 grant execute on procedure sp_b to public
2025-02-25 10:48:29.760 ^
2025-02-25 10:48:29.760 alter database set linger to 0
2025-02-25 10:48:29.760 ^
2025-02-25 10:48:29.760 """
2025-02-25 10:48:29.760 for x in sql.split('^'):
2025-02-25 10:48:29.760 if (s := x.strip()):
2025-02-25 10:48:29.760 con_b.execute_immediate(s)
2025-02-25 10:48:29.760 con_b.commit()
2025-02-25 10:48:29.760
2025-02-25 10:48:29.760 # ..................................................
2025-02-25 10:48:29.760
2025-02-25 10:48:29.760 sql = f"""
2025-02-25 10:48:29.760 create procedure sp_c returns (o_info varchar(512)) as
2025-02-25 10:48:29.761 begin
2025-02-25 10:48:29.761 o_info = lower(current_user);
2025-02-25 10:48:29.761 -- o_info = lower(rdb$get_context('SYSTEM', 'DB_NAME')) || ':' || lower(current_user);
2025-02-25 10:48:29.761 suspend;
2025-02-25 10:48:29.761 end
2025-02-25 10:48:29.761 ^
2025-02-25 10:48:29.761 grant execute on procedure sp_c to public
2025-02-25 10:48:29.761 ^
2025-02-25 10:48:29.761 alter database set linger to 0
2025-02-25 10:48:29.761 ^
2025-02-25 10:48:29.761 """
2025-02-25 10:48:29.761 for x in sql.split('^'):
2025-02-25 10:48:29.761 if (s := x.strip()):
2025-02-25 10:48:29.761 con_c.execute_immediate(s)
2025-02-25 10:48:29.761 con_c.commit()
2025-02-25 10:48:29.761
2025-02-25 10:48:29.761 ############################################
2025-02-25 10:48:29.761 ### E N C R Y P T D A T A B A S E ###
2025-02-25 10:48:29.761 ############################################
2025-02-25 10:48:29.762 > run_encr_decr(act_c, 'encrypt', MAX_WAITING_ENCR_FINISH, capsys)
2025-02-25 10:48:29.762
2025-02-25 10:48:29.762 tests\bugs\gh_8429_test.py:272:
2025-02-25 10:48:29.762 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-02-25 10:48:29.762
2025-02-25 10:48:29.762 act = <firebird.qa.plugin.Action object at [hex]>, mode = 'encrypt'
2025-02-25 10:48:29.762 max_wait_encr_thread_finish = 10000
2025-02-25 10:48:29.762 capsys = <_pytest.capture.CaptureFixture object at [hex]>
2025-02-25 10:48:29.762
2025-02-25 10:48:29.762 def run_encr_decr(act: Action, mode, max_wait_encr_thread_finish, capsys):
2025-02-25 10:48:29.762 if mode == 'encrypt':
2025-02-25 10:48:29.762 # See letter from Alex, 15.12.2023 16:16 demo-plugin can not transfer named key over network.
2025-02-25 10:48:29.762 # Because of that, we have to use 'ALTER DATABASE ENCRYPT WITH <plugin>' _WITHOUT_ adding 'key "{ENCRYPTION_KEY}"'.
2025-02-25 10:48:29.762 # ::: NB ::: One need to be sure that $FB_HOME/plugins.conf contains following lines:
2025-02-25 10:48:29.762 # Plugin = KH2 {
2025-02-25 10:48:29.762 # Module = $(dir_plugins)/fbSampleKeyHolder
2025-02-25 10:48:29.762 # RegisterName = fbSampleKeyHolder
2025-02-25 10:48:29.762 # Config = KH2
2025-02-25 10:48:29.762 # }
2025-02-25 10:48:29.763 # Config = KH2 {
2025-02-25 10:48:29.763 # Auto = false
2025-02-25 10:48:29.763 # }
2025-02-25 10:48:29.763 # Otherwise error will raise:
2025-02-25 10:48:29.763 # unsuccessful metadata update
2025-02-25 10:48:29.763 # -ALTER DATABASE failed
2025-02-25 10:48:29.763 # -Missing database encryption key for your attachment
2025-02-25 10:48:29.763 # -Plugin fbSampleDbCrypt:
2025-02-25 10:48:29.763 # -Crypt key not set
2025-02-25 10:48:29.763 #
2025-02-25 10:48:29.763 alter_db_sttm = f'alter database encrypt with "{ENCRYPTION_PLUGIN}"' # <<< ::: NB ::: DO NOT add '... key "{ENCRYPTION_KEY}"' here!
2025-02-25 10:48:29.763 wait_for_state = 'Database encrypted'
2025-02-25 10:48:29.763 elif mode == 'decrypt':
2025-02-25 10:48:29.763 alter_db_sttm = 'alter database decrypt'
2025-02-25 10:48:29.763 wait_for_state = 'Database not encrypted'
2025-02-25 10:48:29.763
2025-02-25 10:48:29.763
2025-02-25 10:48:29.763 e_thread_finished = False
2025-02-25 10:48:29.763
2025-02-25 10:48:29.764 # 0 = non crypted;
2025-02-25 10:48:29.764 # 1 = has been encrypted;
2025-02-25 10:48:29.764 # 2 = is DEcrypting;
2025-02-25 10:48:29.764 # 3 = is Encrypting;
2025-02-25 10:48:29.764 #
2025-02-25 10:48:29.764 REQUIRED_CRYPT_STATE = 1 if mode == 'encrypt' else 0
2025-02-25 10:48:29.764 current_crypt_state = -1
2025-02-25 10:48:29.764 d1 = py_dt.timedelta(0)
2025-02-25 10:48:29.764 > with act.db.connect() as con:
2025-02-25 10:48:29.764
2025-02-25 10:48:29.764 tests\bugs\gh_8429_test.py:147:
2025-02-25 10:48:29.764 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-02-25 10:48:29.764
2025-02-25 10:48:29.764 database = 'gh_8429_alias_c'
2025-02-25 10:48:29.764
2025-02-25 10:48:29.764 def connect(database: str, *, user: str=None, password: str=None, role: str=None,
2025-02-25 10:48:29.764 no_gc: bool=None, no_db_triggers: bool=None, dbkey_scope: DBKeyScope=None,
2025-02-25 10:48:29.764 crypt_callback: iCryptKeyCallbackImpl=None, charset: str=None,
2025-02-25 10:48:29.764 auth_plugin_list: str=None, session_time_zone: str=None) -> Connection:
2025-02-25 10:48:29.764 """Establishes a connection to the database.
2025-02-25 10:48:29.765
2025-02-25 10:48:29.765 Arguments:
2025-02-25 10:48:29.765 database: DSN or Database configuration name.
2025-02-25 10:48:29.765 user: User name.
2025-02-25 10:48:29.765 password: User password.
2025-02-25 10:48:29.765 role: User role.
2025-02-25 10:48:29.765 no_gc: Do not perform garbage collection for this connection.
2025-02-25 10:48:29.765 no_db_triggers: Do not execute database triggers for this connection.
2025-02-25 10:48:29.765 dbkey_scope: DBKEY scope override for connection.
2025-02-25 10:48:29.765 crypt_callback: Callback that provides encryption key for the database.
2025-02-25 10:48:29.765 charset: Character set for connection.
2025-02-25 10:48:29.765 auth_plugin_list: List of authentication plugins override
2025-02-25 10:48:29.765 session_time_zone: Session time zone [Firebird 4]
2025-02-25 10:48:29.765
2025-02-25 10:48:29.765 Hooks:
2025-02-25 10:48:29.765 Event `.ConnectionHook.ATTACH_REQUEST`: Executed after all parameters
2025-02-25 10:48:29.765 are preprocessed and before `Connection` is created. Hook
2025-02-25 10:48:29.765 must have signature::
2025-02-25 10:48:29.766
2025-02-25 10:48:29.766 hook_func(dsn: str, dpb: bytes) -> Optional[Connection]
2025-02-25 10:48:29.766
2025-02-25 10:48:29.766 Hook may return `Connection` instance or None.
2025-02-25 10:48:29.766 First instance returned by any hook will become the return value
2025-02-25 10:48:29.766 of this function and other hooks are not called.
2025-02-25 10:48:29.766
2025-02-25 10:48:29.766 Event `.ConnectionHook.ATTACHED`: Executed before `Connection` instance is
2025-02-25 10:48:29.766 returned. Hook must have signature::
2025-02-25 10:48:29.766
2025-02-25 10:48:29.766 hook_func(connection: Connection) -> None
2025-02-25 10:48:29.766
2025-02-25 10:48:29.766 Any value returned by hook is ignored.
2025-02-25 10:48:29.766 """
2025-02-25 10:48:29.766 db_config = driver_config.get_database(database)
2025-02-25 10:48:29.766 if db_config is None:
2025-02-25 10:48:29.766 db_config = driver_config.db_defaults
2025-02-25 10:48:29.766 else:
2025-02-25 10:48:29.766 database = db_config.database.value
2025-02-25 10:48:29.767 if db_config.server.value is None:
2025-02-25 10:48:29.767 srv_config = driver_config.server_defaults
2025-02-25 10:48:29.767 else:
2025-02-25 10:48:29.767 srv_config = driver_config.get_server(db_config.server.value)
2025-02-25 10:48:29.767 if srv_config is None:
2025-02-25 10:48:29.767 raise ValueError(f"Configuration for server '{db_config.server.value}' not found")
2025-02-25 10:48:29.767 if user is None:
2025-02-25 10:48:29.767 user = db_config.user.value
2025-02-25 10:48:29.767 if user is None:
2025-02-25 10:48:29.767 user = srv_config.user.value
2025-02-25 10:48:29.767 if password is None:
2025-02-25 10:48:29.767 password = db_config.password.value
2025-02-25 10:48:29.767 if password is None:
2025-02-25 10:48:29.767 password = srv_config.password.value
2025-02-25 10:48:29.767 if role is None:
2025-02-25 10:48:29.767 role = db_config.role.value
2025-02-25 10:48:29.767 if charset is None:
2025-02-25 10:48:29.767 charset = db_config.charset.value
2025-02-25 10:48:29.767 if charset:
2025-02-25 10:48:29.768 charset = charset.upper()
2025-02-25 10:48:29.768 if auth_plugin_list is None:
2025-02-25 10:48:29.768 auth_plugin_list = db_config.auth_plugin_list.value
2025-02-25 10:48:29.768 if session_time_zone is None:
2025-02-25 10:48:29.768 session_time_zone = db_config.session_time_zone.value
2025-02-25 10:48:29.768 dsn = _connect_helper(db_config.dsn.value, srv_config.host.value, srv_config.port.value,
2025-02-25 10:48:29.768 database, db_config.protocol.value)
2025-02-25 10:48:29.768 dpb = DPB(user=user, password=password, role=role, trusted_auth=db_config.trusted_auth.value,
2025-02-25 10:48:29.768 sql_dialect=db_config.sql_dialect.value, timeout=db_config.timeout.value,
2025-02-25 10:48:29.768 charset=charset, cache_size=db_config.cache_size.value,
2025-02-25 10:48:29.768 no_linger=db_config.no_linger.value, utf8filename=db_config.utf8filename.value,
2025-02-25 10:48:29.768 no_gc=no_gc, no_db_triggers=no_db_triggers, dbkey_scope=dbkey_scope,
2025-02-25 10:48:29.768 dummy_packet_interval=db_config.dummy_packet_interval.value,
2025-02-25 10:48:29.768 config=db_config.config.value, auth_plugin_list=auth_plugin_list,
2025-02-25 10:48:29.768 session_time_zone=session_time_zone, set_bind=db_config.set_bind.value,
2025-02-25 10:48:29.768 decfloat_round=db_config.decfloat_round.value,
2025-02-25 10:48:29.768 decfloat_traps=db_config.decfloat_traps.value,
2025-02-25 10:48:29.768 parallel_workers=db_config.parallel_workers.value)
2025-02-25 10:48:29.768 > return __make_connection(False, dsn, db_config.utf8filename.value, dpb.get_buffer(),
2025-02-25 10:48:29.768 db_config.sql_dialect.value, charset, crypt_callback)
2025-02-25 10:48:29.769
2025-02-25 10:48:29.769 C:\Python3x\Lib\site-packages\firebird\driver\core.py:2149:
2025-02-25 10:48:29.769 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-02-25 10:48:29.769
2025-02-25 10:48:29.769 create = False, dsn = 'localhost/33337:gh_8429_alias_c', utf8filename = False
2025-02-25 10:48:29.769 dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x00', sql_dialect = 3
2025-02-25 10:48:29.769 charset = None, crypt_callback = None
2025-02-25 10:48:29.769
2025-02-25 10:48:29.769 def __make_connection(create: bool, dsn: str, utf8filename: bool, dpb: bytes,
2025-02-25 10:48:29.769 sql_dialect: int, charset: str,
2025-02-25 10:48:29.769 crypt_callback: iCryptKeyCallbackImpl) -> Connection:
2025-02-25 10:48:29.769 with a.get_api().master.get_dispatcher() as provider:
2025-02-25 10:48:29.769 if crypt_callback is not None:
2025-02-25 10:48:29.769 provider.set_dbcrypt_callback(crypt_callback)
2025-02-25 10:48:29.769 if create:
2025-02-25 10:48:29.769 att = provider.create_database(dsn, dpb, 'utf-8' if utf8filename else FS_ENCODING)
2025-02-25 10:48:29.769 con = Connection(att, dsn, dpb, sql_dialect, charset)
2025-02-25 10:48:29.769 else:
2025-02-25 10:48:29.769 con = None
2025-02-25 10:48:29.769 for hook in get_callbacks(ConnectionHook.ATTACH_REQUEST, Connection):
2025-02-25 10:48:29.769 try:
2025-02-25 10:48:29.770 con = hook(dsn, dpb)
2025-02-25 10:48:29.770 except Exception as e:
2025-02-25 10:48:29.770 raise InterfaceError("Error in DATABASE_ATTACH_REQUEST hook.", *e.args) from e
2025-02-25 10:48:29.770 if con is not None:
2025-02-25 10:48:29.770 break
2025-02-25 10:48:29.770 if con is None:
2025-02-25 10:48:29.770 > att = provider.attach_database(dsn, dpb, 'utf-8' if utf8filename else FS_ENCODING)
2025-02-25 10:48:29.770
2025-02-25 10:48:29.770 C:\Python3x\Lib\site-packages\firebird\driver\core.py:2064:
2025-02-25 10:48:29.770 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-02-25 10:48:29.770
2025-02-25 10:48:29.770 self = <firebird.driver.interfaces.iProvider object at [hex]>
2025-02-25 10:48:29.770 filename = 'localhost/33337:gh_8429_alias_c'
2025-02-25 10:48:29.770 dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x00'
2025-02-25 10:48:29.770 encoding = 'utf-8'
2025-02-25 10:48:29.770
2025-02-25 10:48:29.770 def attach_database(self, filename: str, dpb: Optional[bytes] = None, encoding: str = 'ascii') -> iAttachment:
2025-02-25 10:48:29.770 "Replaces `isc_attach_database()`"
2025-02-25 10:48:29.770 result = self.vtable.attachDatabase(self, self.status, filename.encode(encoding),
2025-02-25 10:48:29.770 0 if dpb is None else len(dpb), dpb)
2025-02-25 10:48:29.771 > self._check()
2025-02-25 10:48:29.771
2025-02-25 10:48:29.771 C:\Python3x\Lib\site-packages\firebird\driver\interfaces.py:1295:
2025-02-25 10:48:29.771 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-02-25 10:48:29.771
2025-02-25 10:48:29.771 self = <firebird.driver.interfaces.iProvider object at [hex]>
2025-02-25 10:48:29.771
2025-02-25 10:48:29.771 def _check(self) -> None:
2025-02-25 10:48:29.771 state = self.status.get_state()
2025-02-25 10:48:29.771 if StateFlag.ERRORS in state:
2025-02-25 10:48:29.771 > raise self.__report(DatabaseError, self.status.get_errors())
2025-02-25 10:48:29.771 E firebird.driver.types.DatabaseError: I/O error during "CreateFile (open)" operation for file "gh_8429_alias_c"
2025-02-25 10:48:29.771 E -Error while trying to open file
2025-02-25 10:48:29.771 E -The process cannot access the file because it is being used by another process.
2025-02-25 10:48:29.771
2025-02-25 10:48:29.771 C:\Python3x\Lib\site-packages\firebird\driver\interfaces.py:113: DatabaseError
2025-02-25 10:48:29.771 ---------------------------- Captured stdout setup ----------------------------
2025-02-25 10:48:29.771 Creating db: localhost:H:\QA\temp\qa2024.tmp\fbqa\test_11705\test.fdb [page_size=None, sql_dialect=None, charset='NONE', user=SYSDBA, password=masterkey]
2025-02-25 10:48:29.771 CREATE user: TMP_8429_X PLUGIN: Srp
2025-02-25 10:48:29.771 CREATE user: TMP_8429_Y PLUGIN: Srp
2025-02-25 10:48:29.772 CREATE user: TMP_8429_Z PLUGIN: Srp
2025-02-25 10:48:29.772 -------------------------- Captured stdout teardown ---------------------------
2025-02-25 10:48:29.772 DROP user: TMP_8429_Z PLUGIN: Srp
2025-02-25 10:48:29.772 DROP user: TMP_8429_Y PLUGIN: Srp
2025-02-25 10:48:29.772 DROP user: TMP_8429_X PLUGIN: Srp
|
3 #text |
act_a = <firebird.qa.plugin.Action pytest object at [hex]>
act_b = <firebird.qa.plugin.Action pytest object at [hex]>
act_c = <firebird.qa.plugin.Action pytest object at [hex]>
usr_x = <firebird.qa.plugin.User pytest object at [hex]>
usr_y = <firebird.qa.plugin.User pytest object at [hex]>
usr_z = <firebird.qa.plugin.User pytest object at [hex]>
capsys = <_pytest.capture.CaptureFixture pytest object at [hex]>
@pytest.mark.es_eds
@pytest.mark.encryption
@pytest.mark.version('>=4.0.6')
def test_1(act_a: Action, act_b: Action, act_c: Action, usr_x: User, usr_y: User, usr_z: User, capsys):
dbfile_a = get_filename_by_alias(act_a)
dbfile_b = get_filename_by_alias(act_b)
dbfile_c = get_filename_by_alias(act_c)
dbfile_a.unlink(missing_ok = True)
dbfile_b.unlink(missing_ok = True)
dbfile_c.unlink(missing_ok = True)
with create_database(act_a.db.db_path, user = act_a.db.user, password = act_a.db.password) as con_a, \
create_database(act_b.db.db_path, user = act_b.db.user, password = act_b.db.password) as con_b, \
create_database(act_c.db.db_path, user = act_c.db.user, password = act_c.db.password) as con_c:
sql = f"""
create procedure sp_a (a_who varchar(31)) returns (o_info varchar(512)) as
begin
-- e1-meta.sql:
execute statement 'select * from sp_b(''' || a_who || ''')' as user '{usr_x.name}' password '{usr_x.password}' on external 'gh_8429_alias_b' into o_info;
suspend;
end
^
grant execute on procedure sp_a to public
^
alter database set linger to 0
^
"""
for x in sql.split('^'):
if (s := x.strip()):
con_a.execute_immediate(s)
con_a.commit()
# ..................................................
sql = f"""
create procedure sp_b (a_who varchar(31)) returns (o_info varchar(512)) as
begin
execute statement 'select * from sp_c' as user a_who password a_who on external 'gh_8429_alias_c' into o_info;
suspend;
end
^
grant execute on procedure sp_b to public
^
alter database set linger to 0
^
"""
for x in sql.split('^'):
if (s := x.strip()):
con_b.execute_immediate(s)
con_b.commit()
# ..................................................
sql = f"""
create procedure sp_c returns (o_info varchar(512)) as
begin
o_info = lower(current_user);
-- o_info = lower(rdb$get_context('SYSTEM', 'DB_NAME')) || ':' || lower(current_user);
suspend;
end
^
grant execute on procedure sp_c to public
^
alter database set linger to 0
^
"""
for x in sql.split('^'):
if (s := x.strip()):
con_c.execute_immediate(s)
con_c.commit()
############################################
### E N C R Y P T D A T A B A S E ###
############################################
> run_encr_decr(act_c, 'encrypt', MAX_WAITING_ENCR_FINISH, capsys)
tests\bugs\gh_8429_test.py:272:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
act = <firebird.qa.plugin.Action pytest object at [hex]>, mode = 'encrypt'
max_wait_encr_thread_finish = 10000
capsys = <_pytest.capture.CaptureFixture pytest object at [hex]>
def run_encr_decr(act: Action, mode, max_wait_encr_thread_finish, capsys):
if mode == 'encrypt':
# See letter from Alex, 15.12.2023 16:16 demo-plugin can not transfer named key over network.
# Because of that, we have to use 'ALTER DATABASE ENCRYPT WITH <plugin>' _WITHOUT_ adding 'key "{ENCRYPTION_KEY}"'.
# ::: NB ::: One need to be sure that $FB_HOME/plugins.conf contains following lines:
# Plugin = KH2 {
# Module = $(dir_plugins)/fbSampleKeyHolder
# RegisterName = fbSampleKeyHolder
# Config = KH2
# }
# Config = KH2 {
# Auto = false
# }
# Otherwise error will raise:
# unsuccessful metadata update
# -ALTER DATABASE failed
# -Missing database encryption key for your attachment
# -Plugin fbSampleDbCrypt:
# -Crypt key not set
#
alter_db_sttm = f'alter database encrypt with "{ENCRYPTION_PLUGIN}"' # <<< ::: NB ::: DO NOT add '... key "{ENCRYPTION_KEY}"' here!
wait_for_state = 'Database encrypted'
elif mode == 'decrypt':
alter_db_sttm = 'alter database decrypt'
wait_for_state = 'Database not encrypted'
e_thread_finished = False
# 0 = non crypted;
# 1 = has been encrypted;
# 2 = is DEcrypting;
# 3 = is Encrypting;
#
REQUIRED_CRYPT_STATE = 1 if mode == 'encrypt' else 0
current_crypt_state = -1
d1 = py_dt.timedelta(0)
> with act.db.connect() as con:
tests\bugs\gh_8429_test.py:147:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
database = 'gh_8429_alias_c'
def connect(database: str, *, user: str=None, password: str=None, role: str=None,
no_gc: bool=None, no_db_triggers: bool=None, dbkey_scope: DBKeyScope=None,
crypt_callback: iCryptKeyCallbackImpl=None, charset: str=None,
auth_plugin_list: str=None, session_time_zone: str=None) -> Connection:
"""Establishes a connection to the database.
Arguments:
database: DSN or Database configuration name.
user: User name.
password: User password.
role: User role.
no_gc: Do not perform garbage collection for this connection.
no_db_triggers: Do not execute database triggers for this connection.
dbkey_scope: DBKEY scope override for connection.
crypt_callback: Callback that provides encryption key for the database.
charset: Character set for connection.
auth_plugin_list: List of authentication plugins override
session_time_zone: Session time zone [Firebird 4]
Hooks:
Event `.ConnectionHook.ATTACH_REQUEST`: Executed after all parameters
are preprocessed and before `Connection` is created. Hook
must have signature::
hook_func(dsn: str, dpb: bytes) -> Optional[Connection]
Hook may return `Connection` instance or None.
First instance returned by any hook will become the return value
of this function and other hooks are not called.
Event `.ConnectionHook.ATTACHED`: Executed before `Connection` instance is
returned. Hook must have signature::
hook_func(connection: Connection) -> None
Any value returned by hook is ignored.
"""
db_config = driver_config.get_database(database)
if db_config is None:
db_config = driver_config.db_defaults
else:
database = db_config.database.value
if db_config.server.value is None:
srv_config = driver_config.server_defaults
else:
srv_config = driver_config.get_server(db_config.server.value)
if srv_config is None:
raise ValueError(f"Configuration for server '{db_config.server.value}' not found")
if user is None:
user = db_config.user.value
if user is None:
user = srv_config.user.value
if password is None:
password = db_config.password.value
if password is None:
password = srv_config.password.value
if role is None:
role = db_config.role.value
if charset is None:
charset = db_config.charset.value
if charset:
charset = charset.upper()
if auth_plugin_list is None:
auth_plugin_list = db_config.auth_plugin_list.value
if session_time_zone is None:
session_time_zone = db_config.session_time_zone.value
dsn = _connect_helper(db_config.dsn.value, srv_config.host.value, srv_config.port.value,
database, db_config.protocol.value)
dpb = DPB(user=user, password=password, role=role, trusted_auth=db_config.trusted_auth.value,
sql_dialect=db_config.sql_dialect.value, timeout=db_config.timeout.value,
charset=charset, cache_size=db_config.cache_size.value,
no_linger=db_config.no_linger.value, utf8filename=db_config.utf8filename.value,
no_gc=no_gc, no_db_triggers=no_db_triggers, dbkey_scope=dbkey_scope,
dummy_packet_interval=db_config.dummy_packet_interval.value,
config=db_config.config.value, auth_plugin_list=auth_plugin_list,
session_time_zone=session_time_zone, set_bind=db_config.set_bind.value,
decfloat_round=db_config.decfloat_round.value,
decfloat_traps=db_config.decfloat_traps.value,
parallel_workers=db_config.parallel_workers.value)
> return __make_connection(False, dsn, db_config.utf8filename.value, dpb.get_buffer(),
db_config.sql_dialect.value, charset, crypt_callback)
C:\Python3x\Lib\site-packages\firebird\driver\core.py:2149:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
create = False, dsn = 'localhost/33337:gh_8429_alias_c', utf8filename = False
dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x00', sql_dialect = 3
charset = None, crypt_callback = None
def __make_connection(create: bool, dsn: str, utf8filename: bool, dpb: bytes,
sql_dialect: int, charset: str,
crypt_callback: iCryptKeyCallbackImpl) -> Connection:
with a.get_api().master.get_dispatcher() as provider:
if crypt_callback is not None:
provider.set_dbcrypt_callback(crypt_callback)
if create:
att = provider.create_database(dsn, dpb, 'utf-8' if utf8filename else FS_ENCODING)
con = Connection(att, dsn, dpb, sql_dialect, charset)
else:
con = None
for hook in get_callbacks(ConnectionHook.ATTACH_REQUEST, Connection):
try:
con = hook(dsn, dpb)
except Exception as e:
raise InterfaceError("Error in DATABASE_ATTACH_REQUEST hook.", *e.args) from e
if con is not None:
break
if con is None:
> att = provider.attach_database(dsn, dpb, 'utf-8' if utf8filename else FS_ENCODING)
C:\Python3x\Lib\site-packages\firebird\driver\core.py:2064:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <firebird.driver.interfaces.iProvider pytest object at [hex]>
filename = 'localhost/33337:gh_8429_alias_c'
dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x00'
encoding = 'utf-8'
def attach_database(self, filename: str, dpb: Optional[bytes] = None, encoding: str = 'ascii') -> iAttachment:
"Replaces `isc_attach_database()`"
result = self.vtable.attachDatabase(self, self.status, filename.encode(encoding),
0 if dpb is None else len(dpb), dpb)
> self._check()
C:\Python3x\Lib\site-packages\firebird\driver\interfaces.py:1295:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <firebird.driver.interfaces.iProvider pytest object at [hex]>
def _check(self) -> None:
state = self.status.get_state()
if StateFlag.ERRORS in state:
> raise self.__report(DatabaseError, self.status.get_errors())
E firebird.driver.types.DatabaseError: I/O error during "CreateFile (open)" operation for file "gh_8429_alias_c"
E -Error while trying to open file
E -The process cannot access the file because it is being used by another process.
C:\Python3x\Lib\site-packages\firebird\driver\interfaces.py:113: DatabaseError
|