@@ -664,8 +664,9 @@ class SPB_ATTACH:
664664 """
665665 def __init__ (self , * , user : str = None , password : str = None , trusted_auth : bool = False ,
666666 config : str = None , auth_plugin_list : str = None , expected_db : str = None ,
667- encoding : str = 'ascii' , role : str = None ):
667+ encoding : str = 'ascii' , errors : str = 'strict' , role : str = None ):
668668 self .encoding : str = encoding
669+ self .errors : str = errors
669670 self .user : str = user
670671 self .password : str = password
671672 self .trusted_auth : bool = trusted_auth
@@ -689,38 +690,43 @@ def parse_buffer(self, buffer: bytes) -> None:
689690 while not spb .is_eof ():
690691 tag = spb .get_tag ()
691692 if tag == SPBItem .CONFIG :
692- self .config = spb .get_string (encoding = self .encoding )
693+ self .config = spb .get_string (encoding = self .encoding , errors = self . errors )
693694 elif tag == SPBItem .AUTH_PLUGIN_LIST :
694695 self .auth_plugin_list = spb .get_string ()
695696 elif tag == SPBItem .TRUSTED_AUTH :
696697 self .trusted_auth = True
697698 elif tag == SPBItem .USER_NAME :
698- self .user = spb .get_string (encoding = self .encoding )
699+ self .user = spb .get_string (encoding = self .encoding , errors = self . errors )
699700 elif tag == SPBItem .PASSWORD :
700- self .password = spb .get_string (encoding = self .encoding )
701+ self .password = spb .get_string (encoding = self .encoding , errors = self . errors )
701702 elif tag == SPBItem .SQL_ROLE_NAME :
702- self .role = spb .get_string (encoding = self .encoding )
703+ self .role = spb .get_string (encoding = self .encoding , errors = self . errors )
703704 elif tag == SPBItem .EXPECTED_DB :
704- self .expected_db = spb .get_string (encoding = self .encoding )
705+ self .expected_db = spb .get_string (encoding = self .encoding , errors = self . errors )
705706 def get_buffer (self ) -> bytes :
706707 """Create SPB_ATTACH from stored information.
707708 """
708709 with a .get_api ().util .get_xpb_builder (XpbKind .SPB_ATTACH ) as spb :
709710 if self .config is not None :
710- spb .insert_string (SPBItem .CONFIG , self .config , encoding = self .encoding )
711+ spb .insert_string (SPBItem .CONFIG , self .config , encoding = self .encoding ,
712+ errors = self .errors )
711713 if self .trusted_auth :
712714 spb .insert_tag (SPBItem .TRUSTED_AUTH )
713715 else :
714716 if self .user is not None :
715- spb .insert_string (SPBItem .USER_NAME , self .user , encoding = self .encoding )
717+ spb .insert_string (SPBItem .USER_NAME , self .user , encoding = self .encoding ,
718+ errors = self .errors )
716719 if self .password is not None :
717- spb .insert_string (SPBItem .PASSWORD , self .password , encoding = self .encoding )
720+ spb .insert_string (SPBItem .PASSWORD , self .password ,
721+ encoding = self .encoding , errors = self .errors )
718722 if self .role is not None :
719- spb .insert_string (SPBItem .SQL_ROLE_NAME , self .role , encoding = self .encoding )
723+ spb .insert_string (SPBItem .SQL_ROLE_NAME , self .role , encoding = self .encoding ,
724+ errors = self .errors )
720725 if self .auth_plugin_list is not None :
721726 spb .insert_string (SPBItem .AUTH_PLUGIN_LIST , self .auth_plugin_list )
722727 if self .expected_db is not None :
723- spb .insert_string (SPBItem .EXPECTED_DB , self .expected_db , encoding = self .encoding )
728+ spb .insert_string (SPBItem .EXPECTED_DB , self .expected_db ,
729+ encoding = self .encoding , errors = self .errors )
724730 result = spb .get_buffer ()
725731 return result
726732
@@ -5232,7 +5238,8 @@ class Server(LoggingIdMixin):
52325238 Note:
52335239 Implements context manager protocol to call `.close()` automatically.
52345240 """
5235- def __init__ (self , svc : iService , spb : bytes , host : str , encoding : str ):
5241+ def __init__ (self , svc : iService , spb : bytes , host : str , encoding : str ,
5242+ encoding_errors : str ):
52365243 self ._svc : iService = svc
52375244 #: Service Parameter Buffer (SPB) used to connect the service manager
52385245 self .spb : bytes = spb
@@ -5244,8 +5251,10 @@ def __init__(self, svc: iService, spb: bytes, host: str, encoding: str):
52445251 self .response : CBuffer = CBuffer (USHRT_MAX )
52455252 self ._eof : bool = False
52465253 self .__line_buffer : List [str ] = []
5247- #: Encoding for string values
5254+ #: Encoding used for text data exchange with server
52485255 self .encoding : str = encoding
5256+ #: Handler used for encoding errors. See: `codecs#error-handlers`
5257+ self .encoding_errors : str = encoding_errors
52495258 #
52505259 self .__ev : float = None
52515260 self .__info : ServerInfoProvider = None
@@ -5308,7 +5317,7 @@ def _read_output(self, *, init: str='', timeout: int=-1) -> None:
53085317 tag = self .response .get_tag ()
53095318 if tag != self .mode : # pragma: no cover
53105319 raise InterfaceError (f"Service responded with error code: { tag } " )
5311- data = self .response .read_sized_string (encoding = self .encoding )
5320+ data = self .response .read_sized_string (encoding = self .encoding , errors = self . encoding_errors )
53125321 init += data
53135322 if data and self .mode is SrvInfoCode .LINE :
53145323 init += '\n '
@@ -5438,7 +5447,8 @@ def user(self) -> ServerUserServices:
54385447
54395448def connect_server (server : str , * , user : str = None , password : str = None ,
54405449 crypt_callback : iCryptKeyCallbackImpl = None ,
5441- expected_db : str = None , role : str = None , encoding : str = 'ascii' ) -> Server :
5450+ expected_db : str = None , role : str = None , encoding : str = None ,
5451+ encoding_errors : str = None ) -> Server :
54425452 """Establishes a connection to server's service manager.
54435453
54445454 Arguments:
@@ -5449,7 +5459,10 @@ def connect_server(server: str, *, user: str=None, password: str=None,
54495459 expected_db: Database that would be accessed (for using services with non-default
54505460 security database)
54515461 role: SQL role used for connection.
5452- encoding: Encoding for string values passed in parameter buffer.
5462+ encoding: Encoding for string values passed in parameter buffer. Default is
5463+ `.ServerConfig.encoding`.
5464+ encoding_errors: Error handler used for encoding errors. Default is
5465+ `.ServerConfig.encoding_errors`.
54535466
54545467 Hooks:
54555468 Event `.ServerHook.ATTACHED`: Executed before `Service` instance is
@@ -5484,7 +5497,8 @@ def connect_server(server: str, *, user: str=None, password: str=None,
54845497 if crypt_callback is not None :
54855498 provider .set_dbcrypt_callback (crypt_callback )
54865499 svc = provider .attach_service_manager (host , spb_buf )
5487- con = Server (svc , spb_buf , host , encoding )
5500+ con = Server (svc , spb_buf , host , srv_config .encoding .value if encoding is None else encoding ,
5501+ srv_config .encoding_errors .value if encoding_errors is None else encoding_errors )
54885502 for hook in get_callbacks (ServerHook .ATTACHED , con ):
54895503 hook (con )
54905504 return con
0 commit comments