diff --git a/source/mysql/protocol/comms.d b/source/mysql/protocol/comms.d index 94dfc9df..a1e28997 100644 --- a/source/mysql/protocol/comms.d +++ b/source/mysql/protocol/comms.d @@ -21,6 +21,7 @@ Next tasks for this sub-package's cleanup: module mysql.protocol.comms; import std.algorithm; +import std.array; import std.conv; import std.digest.sha; import std.exception; @@ -45,7 +46,7 @@ package struct ProtocolPrepared import std.datetime; import std.variant; import mysql.types; - + static ubyte[] makeBitmap(in Variant[] inParams) { size_t bml = (inParams.length+7)/8; @@ -451,7 +452,7 @@ package struct ProtocolPrepared Variant[] inParams, ParameterSpecialization[] psa) { conn.autoPurge(); - + ubyte[] packet; conn.resetPacket(); @@ -771,7 +772,7 @@ body } conn.autoPurge(); - + conn.resetPacket(); ubyte[] header; @@ -810,7 +811,7 @@ body // Request a conventional maximum packet length. 1.packInto(packet[8..12]); - packet ~= 33; // Set UTF-8 as default charSet + packet ~= getDefaultCollation(conn._serverVersion); // There's a statutory block of zero bytes here - fill them in. foreach(i; 0 .. 23) @@ -967,7 +968,7 @@ package(mysql) SvrCapFlags setClientFlags(SvrCapFlags serverCaps, SvrCapFlags ca // didn't supply it cCaps |= SvrCapFlags.PROTOCOL41; cCaps |= SvrCapFlags.SECURE_CONNECTION; - + return cCaps; } @@ -998,7 +999,7 @@ package(mysql) PreparedServerInfo performRegister(Connection conn, const(char[]) scope(failure) conn.kill(); PreparedServerInfo info; - + conn.sendCmd(CommandType.STMT_PREPARE, sql); conn._fieldCount = 0; @@ -1112,3 +1113,30 @@ package(mysql) void enableMultiStatements(Connection conn, bool on) auto packet = conn.getPacket(); enforce!MYXProtocol(packet[0] == 254 && packet.length == 5, "Unexpected response to SET_OPTION command"); } + +private ubyte getDefaultCollation(string serverVersion) +{ + // MySQL >= 5.5.3 supports utf8mb4 + const v = serverVersion + .splitter('.') + .map!(a => a.parse!ushort) + .array; + + if (v[0] < 5) + return 33; // Set utf8_general_ci as default + if (v[1] < 5) + return 33; // Set utf8_general_ci as default + if (v[2] < 3) + return 33; // Set utf8_general_ci as default + + return 45; // Set utf8mb4_general_ci as default +} + +unittest +{ + assert(getDefaultCollation("5.5.3") == 45); + assert(getDefaultCollation("5.5.2") == 33); + + // MariaDB: https://mariadb.com/kb/en/connection/#initial-handshake-packet + assert(getDefaultCollation("5.5.5-10.0.7-MariaDB") == 45); +}