Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.0.28

- Add support for unix socket on pool connection

## 0.0.27

- Add timeoutMs param to pool constructor
Expand Down
33 changes: 33 additions & 0 deletions lib/src/mysql_client/connection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import 'dart:io';
import 'dart:typed_data';
import 'package:mysql_client/mysql_protocol.dart';
import 'package:mysql_client/exception.dart';
import 'package:logger/logger.dart';

final loggingLevel = Level.debug;

final logger = Logger(
printer: PrettyPrinter(),
);

enum _MySQLConnectionState {
fresh,
Expand Down Expand Up @@ -79,7 +86,10 @@ class MySQLConnection {
String? databaseName,
String collation = 'utf8mb4_general_ci',
}) async {
Logger.level = loggingLevel;
logger.d("Establishing socket connection");
final Socket socket = await Socket.connect(host, port);
logger.d("Socket connection established");

if (socket.address.type != InternetAddressType.unix) {
// no support for extensions on sockets
Expand Down Expand Up @@ -167,6 +177,9 @@ class MySQLConnection {
}

Future<void> _processSocketData(Uint8List data) async {
logger.d("Processing socket data. Current state is $_state");
logger.v(data);

if (_state == _MySQLConnectionState.closed) {
// don't process any data if state is closed
return;
Expand All @@ -183,9 +196,12 @@ class MySQLConnection {
final authSwitchPacket =
MySQLPacket.decodeAuthSwitchRequestPacket(data);

logger.d("Processing AuthSwitchRequestPacket");

final payload =
authSwitchPacket.payload as MySQLPacketAuthSwitchRequest;

logger.d("Auth plugin name is: ${payload.authPluginName}");
_activeAuthPluginName = payload.authPluginName;

switch (payload.authPluginName) {
Expand Down Expand Up @@ -216,6 +232,7 @@ class MySQLConnection {
try {
packet = MySQLPacket.decodeGenericPacket(data);
} catch (e) {
logger.e("Skipping invalid packet: $data");
rethrow;
}

Expand Down Expand Up @@ -262,6 +279,7 @@ class MySQLConnection {
}

if (packet.isOkPacket()) {
logger.i("Got OK packet. Connection established");
_state = _MySQLConnectionState.connectionEstablished;
_connected = true;
}
Expand Down Expand Up @@ -317,6 +335,7 @@ class MySQLConnection {
}

Future<void> _processInitialHandshake(Uint8List data) async {
logger.d("Processing initial handshake");
// First packet can be error packet
if (MySQLPacket.detectPacketType(data) == MySQLGenericPacketType.error) {
final packet = MySQLPacket.decodeGenericPacket(data);
Expand All @@ -331,6 +350,7 @@ class MySQLConnection {
throw MySQLClientException("Expected MySQLPacketInitialHandshake packet");
}

logger.d(payload);
_serverCapabilities = payload.capabilityFlags;

if (_secure && (_serverCapabilities & mysqlCapFlagClientSsl == 0)) {
Expand All @@ -342,6 +362,8 @@ class MySQLConnection {
if (_secure) {
// it secure = true, initiate ssl connection
Future<void> initiateSSL() async {
logger.d("Initiating SSL connection");

final responsePayload = MySQLPacketSSLRequest.createDefault(
initialHandshakePayload: payload,
connectWithDB: _databaseName != null,
Expand All @@ -362,6 +384,8 @@ class MySQLConnection {
onBadCertificate: (certificate) => true,
);

logger.d("SSL connection established");

// switch socket
_socket = secureSocket;

Expand All @@ -383,6 +407,8 @@ class MySQLConnection {
final authPluginName = payload.authPluginName;
_activeAuthPluginName = authPluginName;

logger.d("Auth plugin name is: $authPluginName");

switch (authPluginName) {
case 'mysql_native_password':
final responsePayload =
Expand All @@ -402,6 +428,9 @@ class MySQLConnection {

_state = _MySQLConnectionState.initialHandshakeResponseSend;
_socket.add(responsePacket.encode());

logger.d("Native password response send");

break;
case 'caching_sha2_password':
final responsePayload =
Expand All @@ -421,6 +450,9 @@ class MySQLConnection {

_state = _MySQLConnectionState.initialHandshakeResponseSend;
_socket.add(responsePacket.encode());

logger.d("Caching sha2 password response send");

break;
default:
throw MySQLClientException(
Expand All @@ -429,6 +461,7 @@ class MySQLConnection {
}

void _processCommandResponse(Uint8List data) {
logger.d("Processing command response packet");
assert(_responseCallback != null);
_responseCallback!(data);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/src/mysql_client/pool.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:mysql_client/mysql_client.dart';

/// Class to create and manage pool of database connections
class MySQLConnectionPool {
final String host;
final dynamic host;
final int port;
final String userName;
final String _password;
Expand Down
17 changes: 17 additions & 0 deletions lib/src/mysql_protocol/packet/packet_initial_handshake.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,21 @@ class MySQLPacketInitialHandshake extends MySQLPacketPayload {
Uint8List encode() {
throw UnimplementedError();
}

@override
String toString() {
return """
MySQLPacketInitialHandshake:

authPluginDataPart1: $authPluginDataPart1,
authPluginDataPart2: $authPluginDataPart2,
authPluginName: $authPluginName,
capabilityFlags: $capabilityFlags,
charset: $charset,
connectionID: $connectionID,
protocolVersion: $protocolVersion,
serverVersion: $serverVersion,
statusFlags: $statusFlags
""";
}
}
5 changes: 3 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: mysql_client
description: Native MySQL client written in Dart. Tested with MySQL Percona Server (5.7, 8), MariaDB (10). Supports TLS.
version: 0.0.27
version: 0.0.28
homepage: https://github.com/zim32/mysql.dart
repository: https://github.com/zim32/mysql.dart
platforms:
Expand All @@ -21,4 +21,5 @@ dev_dependencies:
dependencies:
buffer: ^1.1.1
crypto: ^3.0.1
tuple: ^2.0.0
tuple: ^2.0.0
logger: ^1.1.0