0
# Utilities and Advanced Features
1
2
Low-level utilities, configuration management, platform detection, and advanced functionality for specialized use cases and system integration.
3
4
## Binary Data Utilities
5
6
### Integer Packing Functions
7
8
```python { .api }
9
def intread(buf: bytes) -> int:
10
"""
11
Read integer from buffer using MySQL protocol format.
12
13
Args:
14
buf: Bytes buffer containing integer
15
16
Returns:
17
Integer value read from buffer
18
"""
19
pass
20
21
def int1store(value: int) -> bytes:
22
"""
23
Pack integer into 1-byte buffer.
24
25
Args:
26
value: Integer value (0-255)
27
28
Returns:
29
1-byte buffer containing packed integer
30
"""
31
pass
32
33
def int2store(value: int) -> bytes:
34
"""
35
Pack integer into 2-byte buffer (little-endian).
36
37
Args:
38
value: Integer value (0-65535)
39
40
Returns:
41
2-byte buffer containing packed integer
42
"""
43
pass
44
45
def int3store(value: int) -> bytes:
46
"""
47
Pack integer into 3-byte buffer (little-endian).
48
49
Args:
50
value: Integer value (0-16777215)
51
52
Returns:
53
3-byte buffer containing packed integer
54
"""
55
pass
56
57
def int4store(value: int) -> bytes:
58
"""
59
Pack integer into 4-byte buffer (little-endian).
60
61
Args:
62
value: Integer value (0-4294967295)
63
64
Returns:
65
4-byte buffer containing packed integer
66
"""
67
pass
68
69
def int8store(value: int) -> bytes:
70
"""
71
Pack integer into 8-byte buffer (little-endian).
72
73
Args:
74
value: Integer value (0-18446744073709551615)
75
76
Returns:
77
8-byte buffer containing packed integer
78
"""
79
pass
80
81
def intstore(value: int) -> bytes:
82
"""
83
Pack integer into variable-length buffer.
84
85
Args:
86
value: Integer value
87
88
Returns:
89
Variable-length buffer containing packed integer
90
"""
91
pass
92
93
def lc_int(value: int) -> bytes:
94
"""
95
Pack integer using length-coded format.
96
97
Args:
98
value: Integer value
99
100
Returns:
101
Length-coded buffer containing integer
102
"""
103
pass
104
```
105
106
### Buffer Reading Functions
107
108
```python { .api }
109
def read_bytes(buf: bytes, size: int) -> Tuple[bytes, int]:
110
"""
111
Read specified number of bytes from buffer.
112
113
Args:
114
buf: Source buffer
115
size: Number of bytes to read
116
117
Returns:
118
Tuple of (read_bytes, new_position)
119
"""
120
pass
121
122
def read_lc_string(buf: bytes) -> Tuple[bytes, int]:
123
"""
124
Read length-coded string from buffer.
125
126
Args:
127
buf: Buffer containing length-coded string
128
129
Returns:
130
Tuple of (string_bytes, new_position)
131
"""
132
pass
133
134
def read_string(buf: bytes, end: bytes, charset: str = 'utf8') -> str:
135
"""
136
Read string from buffer until end marker.
137
138
Args:
139
buf: Buffer containing string data
140
end: End marker bytes
141
charset: Character encoding (default: 'utf8')
142
143
Returns:
144
Decoded string
145
"""
146
pass
147
148
def read_int(buf: bytes, size: int) -> Tuple[int, int]:
149
"""
150
Read integer from buffer.
151
152
Args:
153
buf: Buffer containing integer data
154
size: Size of integer in bytes (1, 2, 3, 4, or 8)
155
156
Returns:
157
Tuple of (integer_value, new_position)
158
"""
159
pass
160
161
def read_lc_int(buf: bytes) -> Tuple[int, int]:
162
"""
163
Read length-coded integer from buffer.
164
165
Args:
166
buf: Buffer containing length-coded integer
167
168
Returns:
169
Tuple of (integer_value, new_position)
170
"""
171
pass
172
```
173
174
## Platform and System Utilities
175
176
### Platform Detection
177
178
```python { .api }
179
def get_platform() -> str:
180
"""
181
Get platform information string.
182
183
Returns:
184
Platform identifier string (e.g., 'Linux-x86_64', 'Windows-AMD64')
185
"""
186
pass
187
188
def linux_distribution() -> Tuple[str, str, str]:
189
"""
190
Get Linux distribution information.
191
192
Returns:
193
Tuple of (distribution_name, version, codename)
194
Returns empty tuple on non-Linux platforms
195
"""
196
pass
197
```
198
199
### Module and Object Utilities
200
201
```python { .api }
202
def import_object(fullpath: str) -> Any:
203
"""
204
Import object from module path.
205
206
Args:
207
fullpath: Full module path (e.g., 'package.module.ClassName')
208
209
Returns:
210
Imported object (class, function, etc.)
211
212
Raises:
213
ImportError: If module or object cannot be imported
214
"""
215
pass
216
```
217
218
## Unicode and Security Utilities
219
220
### Unicode Normalization
221
222
```python { .api }
223
def normalize_unicode_string(string: str) -> str:
224
"""
225
Normalize Unicode string for security and consistency.
226
227
Args:
228
string: Input Unicode string
229
230
Returns:
231
Normalized Unicode string
232
"""
233
pass
234
235
def validate_normalized_unicode_string(string: str) -> bool:
236
"""
237
Validate that Unicode string is properly normalized.
238
239
Args:
240
string: Unicode string to validate
241
242
Returns:
243
True if string is normalized, False otherwise
244
"""
245
pass
246
```
247
248
## Configuration Management
249
250
### MySQL Option Files
251
252
```python { .api }
253
class MySQLOptionsParser:
254
"""
255
MySQL option file parser for my.cnf files.
256
Handles MySQL configuration file parsing and option extraction.
257
"""
258
259
def __init__(self) -> None:
260
"""Initialize option file parser."""
261
pass
262
263
def read_option_files(self, files: List[str]) -> Dict[str, Dict[str, str]]:
264
"""
265
Read MySQL option files and extract configuration.
266
267
Args:
268
files: List of option file paths to read
269
270
Returns:
271
Dictionary with sections and their options
272
"""
273
pass
274
275
def read_groups(self, groups: List[str]) -> Dict[str, str]:
276
"""
277
Read specific option groups from files.
278
279
Args:
280
groups: List of option group names to read
281
282
Returns:
283
Dictionary with merged options from specified groups
284
"""
285
pass
286
287
def get_groups(self) -> List[str]:
288
"""
289
Get list of available option groups.
290
291
Returns:
292
List of option group names found in files
293
"""
294
pass
295
296
def read_option_files(files: List[str]) -> Dict[str, Dict[str, str]]:
297
"""
298
Convenience function to read MySQL option files.
299
300
Args:
301
files: List of option file paths
302
303
Returns:
304
Dictionary with parsed options organized by section
305
"""
306
pass
307
```
308
309
## Network Utilities
310
311
### Socket Classes
312
313
```python { .api }
314
class MySQLSocket:
315
"""
316
Base socket class for MySQL connections.
317
Provides common socket functionality for different connection types.
318
"""
319
320
def __init__(self) -> None:
321
"""Initialize base socket."""
322
pass
323
324
def open_connection(self) -> None:
325
"""Open socket connection."""
326
pass
327
328
def close_connection(self) -> None:
329
"""Close socket connection."""
330
pass
331
332
def send(self, data: bytes) -> int:
333
"""Send data through socket."""
334
pass
335
336
def recv(self, size: int) -> bytes:
337
"""Receive data from socket."""
338
pass
339
340
def set_connection_timeout(self, timeout: int) -> None:
341
"""Set connection timeout in seconds."""
342
pass
343
344
class MySQLTCPSocket(MySQLSocket):
345
"""
346
TCP socket implementation for MySQL connections.
347
Handles TCP/IP connections to MySQL server.
348
"""
349
350
def __init__(self, host: str = 'localhost', port: int = 3306) -> None:
351
"""
352
Initialize TCP socket.
353
354
Args:
355
host: MySQL server hostname
356
port: MySQL server port number
357
"""
358
pass
359
360
class MySQLUnixSocket(MySQLSocket):
361
"""
362
Unix socket implementation for MySQL connections.
363
Handles Unix domain socket connections to local MySQL server.
364
"""
365
366
def __init__(self, unix_socket: str) -> None:
367
"""
368
Initialize Unix socket.
369
370
Args:
371
unix_socket: Path to MySQL Unix socket file
372
"""
373
pass
374
```
375
376
## Logging Utilities
377
378
### MySQL Connector Logging
379
380
```python { .api }
381
class MySQLLogger:
382
"""
383
MySQL Connector logging utilities.
384
Provides structured logging for MySQL operations.
385
"""
386
387
def __init__(self, name: str = 'mysql.connector') -> None:
388
"""
389
Initialize MySQL logger.
390
391
Args:
392
name: Logger name
393
"""
394
pass
395
396
def log_connection(self, host: str, user: str, database: str) -> None:
397
"""Log connection attempt."""
398
pass
399
400
def log_query(self, query: str, params: Optional[Tuple] = None) -> None:
401
"""Log SQL query execution."""
402
pass
403
404
def log_error(self, error: Exception, context: str = '') -> None:
405
"""Log error with context."""
406
pass
407
```
408
409
## Advanced Protocol Utilities
410
411
### MySQL Protocol Classes
412
413
```python { .api }
414
class MySQLProtocol:
415
"""
416
MySQL client/server protocol implementation.
417
Handles low-level MySQL protocol communication.
418
"""
419
420
def __init__(self) -> None:
421
"""Initialize protocol handler."""
422
pass
423
424
def parse_handshake(self, packet: bytes) -> Dict[str, Any]:
425
"""
426
Parse MySQL handshake packet.
427
428
Args:
429
packet: Handshake packet bytes
430
431
Returns:
432
Dictionary with handshake information
433
"""
434
pass
435
436
def make_auth_response(self, handshake: Dict[str, Any], user: str, password: str, database: str) -> bytes:
437
"""
438
Create authentication response packet.
439
440
Args:
441
handshake: Handshake information
442
user: Username
443
password: Password
444
database: Database name
445
446
Returns:
447
Authentication response packet bytes
448
"""
449
pass
450
451
def parse_ok_packet(self, packet: bytes) -> Dict[str, Any]:
452
"""
453
Parse MySQL OK packet.
454
455
Args:
456
packet: OK packet bytes
457
458
Returns:
459
Dictionary with OK packet information
460
"""
461
pass
462
463
def parse_error_packet(self, packet: bytes) -> Dict[str, Any]:
464
"""
465
Parse MySQL error packet.
466
467
Args:
468
packet: Error packet bytes
469
470
Returns:
471
Dictionary with error information
472
"""
473
pass
474
475
def parse_result_set_header(self, packet: bytes) -> int:
476
"""
477
Parse result set header packet.
478
479
Args:
480
packet: Result set header packet bytes
481
482
Returns:
483
Number of columns in result set
484
"""
485
pass
486
487
def parse_column_definition(self, packet: bytes) -> Dict[str, Any]:
488
"""
489
Parse column definition packet.
490
491
Args:
492
packet: Column definition packet bytes
493
494
Returns:
495
Dictionary with column information
496
"""
497
pass
498
499
def parse_row_data(self, packet: bytes, columns: int) -> List[bytes]:
500
"""
501
Parse row data packet.
502
503
Args:
504
packet: Row data packet bytes
505
columns: Number of columns
506
507
Returns:
508
List of column values as bytes
509
"""
510
pass
511
```
512
513
## Usage Examples
514
515
### Binary Data Manipulation
516
517
```python
518
from mysql.connector.utils import int1store, int2store, int4store, intread
519
520
# Pack integers for protocol communication
521
one_byte = int1store(255) # b'\xff'
522
two_bytes = int2store(65535) # b'\xff\xff' (little-endian)
523
four_bytes = int4store(4294967295) # b'\xff\xff\xff\xff'
524
525
print(f"1-byte: {one_byte.hex()}")
526
print(f"2-byte: {two_bytes.hex()}")
527
print(f"4-byte: {four_bytes.hex()}")
528
529
# Read integer from buffer
530
buffer = b'\x42\x00\x00\x00' # 66 in little-endian 4-byte format
531
value = intread(buffer)
532
print(f"Read value: {value}")
533
```
534
535
### String Buffer Operations
536
537
```python
538
from mysql.connector.utils import read_lc_string, read_string
539
540
# Example MySQL protocol buffer with length-coded string
541
# Format: [length][string_data]
542
buffer = b'\x0bHello World' # Length 11, followed by "Hello World"
543
544
string_data, new_pos = read_lc_string(buffer)
545
print(f"Read string: {string_data.decode('utf-8')}")
546
print(f"New position: {new_pos}")
547
548
# Read null-terminated string
549
null_term_buffer = b'Hello World\x00more data'
550
string_value = read_string(null_term_buffer, b'\x00', 'utf-8')
551
print(f"Null-terminated string: {string_value}")
552
```
553
554
### Platform Information
555
556
```python
557
from mysql.connector.utils import get_platform, linux_distribution
558
559
# Get platform information
560
platform = get_platform()
561
print(f"Platform: {platform}")
562
563
# Get Linux distribution info (if on Linux)
564
try:
565
dist_info = linux_distribution()
566
if dist_info:
567
name, version, codename = dist_info
568
print(f"Linux Distribution: {name} {version} ({codename})")
569
except:
570
print("Not running on Linux or distribution info unavailable")
571
```
572
573
### Dynamic Module Import
574
575
```python
576
from mysql.connector.utils import import_object
577
578
# Import specific class or function
579
try:
580
MySQLConnection = import_object('mysql.connector.connection.MySQLConnection')
581
print(f"Imported class: {MySQLConnection}")
582
583
# Import authentication plugin
584
sha2_plugin = import_object('mysql.connector.plugins.caching_sha2_password')
585
print(f"Imported plugin: {sha2_plugin}")
586
587
except ImportError as err:
588
print(f"Import failed: {err}")
589
```
590
591
### MySQL Option File Reading
592
593
```python
594
from mysql.connector.optionfiles import MySQLOptionsParser, read_option_files
595
596
# Read MySQL configuration files
597
option_files = [
598
'/etc/mysql/my.cnf',
599
'/etc/my.cnf',
600
'~/.my.cnf'
601
]
602
603
try:
604
# Using parser class
605
parser = MySQLOptionsParser()
606
options = parser.read_option_files([f for f in option_files if os.path.exists(f)])
607
608
print("MySQL Configuration:")
609
for section, section_options in options.items():
610
print(f"[{section}]")
611
for key, value in section_options.items():
612
print(f" {key} = {value}")
613
print()
614
615
# Read specific groups
616
client_options = parser.read_groups(['client', 'mysql_connector_python'])
617
print(f"Client options: {client_options}")
618
619
except Exception as err:
620
print(f"Failed to read option files: {err}")
621
```
622
623
### Unicode String Processing
624
625
```python
626
from mysql.connector.utils import normalize_unicode_string, validate_normalized_unicode_string
627
628
# Unicode normalization for security
629
user_input = "café" # May contain different Unicode representations
630
normalized = normalize_unicode_string(user_input)
631
632
print(f"Original: {user_input}")
633
print(f"Normalized: {normalized}")
634
print(f"Is normalized: {validate_normalized_unicode_string(normalized)}")
635
636
# Validate user input before database operations
637
def safe_insert_user(name: str, email: str):
638
"""Safely insert user with Unicode normalization."""
639
if not validate_normalized_unicode_string(name):
640
name = normalize_unicode_string(name)
641
642
if not validate_normalized_unicode_string(email):
643
email = normalize_unicode_string(email)
644
645
# Proceed with database insert
646
print(f"Inserting user: {name}, {email}")
647
648
safe_insert_user("José", "josé@example.com")
649
```
650
651
### Custom Socket Implementation
652
653
```python
654
import mysql.connector
655
from mysql.connector.network import MySQLTCPSocket
656
657
# Custom socket configuration
658
class CustomMySQLSocket(MySQLTCPSocket):
659
"""Custom socket with additional logging."""
660
661
def send(self, data: bytes) -> int:
662
print(f"Sending {len(data)} bytes")
663
return super().send(data)
664
665
def recv(self, size: int) -> bytes:
666
data = super().recv(size)
667
print(f"Received {len(data)} bytes")
668
return data
669
670
# Use custom socket (conceptual - actual integration may vary)
671
# This demonstrates how you might extend socket functionality
672
```
673
674
### Protocol Packet Analysis
675
676
```python
677
from mysql.connector.protocol import MySQLProtocol
678
679
# Analyze MySQL protocol packets (conceptual example)
680
protocol = MySQLProtocol()
681
682
# Example handshake packet (would come from actual MySQL server)
683
handshake_packet = b'\x0a8.0.32\x00...' # Truncated for example
684
685
try:
686
handshake_info = protocol.parse_handshake(handshake_packet)
687
print(f"Server version: {handshake_info.get('server_version')}")
688
print(f"Thread ID: {handshake_info.get('thread_id')}")
689
print(f"Server capabilities: {handshake_info.get('server_capabilities')}")
690
except Exception as err:
691
print(f"Failed to parse handshake: {err}")
692
```
693
694
### Connection Debugging Utilities
695
696
```python
697
import mysql.connector
698
from mysql.connector.utils import get_platform
699
import logging
700
701
# Configure detailed debugging
702
logging.basicConfig(level=logging.DEBUG)
703
logger = logging.getLogger('mysql.connector')
704
705
def debug_connection(config: dict):
706
"""Create connection with detailed debugging information."""
707
708
print(f"Platform: {get_platform()}")
709
print(f"MySQL Connector version: {mysql.connector.__version__}")
710
711
try:
712
connection = mysql.connector.connect(**config)
713
714
# Connection details
715
print(f"Connected to: {connection.server_host}:{connection.server_port}")
716
print(f"Server version: {connection.server_version}")
717
print(f"Connection ID: {connection.connection_id}")
718
print(f"Character set: {connection.charset}")
719
print(f"Collation: {connection.collation}")
720
print(f"SQL mode: {connection.sql_mode}")
721
print(f"Autocommit: {connection.autocommit}")
722
print(f"In transaction: {connection.in_transaction}")
723
724
# Server status
725
cursor = connection.cursor()
726
cursor.execute("SHOW STATUS LIKE 'Threads_connected'")
727
result = cursor.fetchone()
728
print(f"Server threads connected: {result[1]}")
729
730
# SSL information if enabled
731
cursor.execute("SHOW STATUS LIKE 'Ssl_cipher'")
732
result = cursor.fetchone()
733
if result and result[1]:
734
print(f"SSL cipher: {result[1]}")
735
736
cursor.close()
737
connection.close()
738
739
except mysql.connector.Error as err:
740
print(f"Connection debug failed: {err}")
741
logger.error(f"Connection error details: {err}")
742
743
# Debug connection
744
config = {
745
'host': 'localhost',
746
'user': 'myuser',
747
'password': 'mypassword',
748
'database': 'mydatabase'
749
}
750
751
debug_connection(config)
752
```
753
754
### Performance Utilities
755
756
```python
757
import time
758
import mysql.connector
759
from mysql.connector.utils import get_platform
760
761
def benchmark_connection_methods():
762
"""Compare performance of different connection methods."""
763
764
config = {
765
'host': 'localhost',
766
'user': 'myuser',
767
'password': 'mypassword',
768
'database': 'mydatabase'
769
}
770
771
methods = [
772
('Pure Python', {'use_pure': True}),
773
('C Extension', {'use_pure': False}),
774
('Compressed', {'compress': True, 'use_pure': False}),
775
('Buffered', {'buffered': True, 'use_pure': False})
776
]
777
778
for method_name, method_config in methods:
779
test_config = {**config, **method_config}
780
781
try:
782
start_time = time.time()
783
784
connection = mysql.connector.connect(**test_config)
785
cursor = connection.cursor()
786
787
# Perform test operations
788
for i in range(100):
789
cursor.execute("SELECT %s", (i,))
790
cursor.fetchone()
791
792
cursor.close()
793
connection.close()
794
795
end_time = time.time()
796
duration = end_time - start_time
797
798
print(f"{method_name}: {duration:.3f} seconds")
799
800
except mysql.connector.Error as err:
801
print(f"{method_name}: Failed - {err}")
802
803
print(f"Running benchmarks on {get_platform()}")
804
benchmark_connection_methods()
805
```