From 2007dce4b80df8368660964d0bb1af944c756f26 Mon Sep 17 00:00:00 2001 From: Nick Sabalausky Date: Sun, 5 Oct 2014 05:20:46 -0400 Subject: [PATCH] TEXT types should be string, not ubyte[] (Fixes #33) --- source/mysql/protocol/extra_types.d | 2 +- source/mysql/protocol/packet_helpers.d | 10 ++++++-- source/mysql/result.d | 2 +- source/mysql/test/integration.d | 8 +++---- source/mysql/test/regression.d | 32 ++++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/source/mysql/protocol/extra_types.d b/source/mysql/protocol/extra_types.d index ed85910f..dd08937d 100644 --- a/source/mysql/protocol/extra_types.d +++ b/source/mysql/protocol/extra_types.d @@ -444,7 +444,7 @@ public: col.collation = isNull? "": t; break; case 14: - col.colType = cast(string) r[j].get!(ubyte[]); + col.colType = r[j].get!string(); break; case 15: col.key = t; diff --git a/source/mysql/protocol/packet_helpers.d b/source/mysql/protocol/packet_helpers.d index ab32a9f2..4421f2bd 100644 --- a/source/mysql/protocol/packet_helpers.d +++ b/source/mysql/protocol/packet_helpers.d @@ -651,7 +651,7 @@ SQLValue consumeIfComplete(T, int N=T.sizeof)(ref ubyte[] packet, bool binary, b : packet.consumeNonBinaryValueIfComplete!T(unsigned); } -SQLValue consumeIfComplete()(ref ubyte[] packet, SQLType sqlType, bool binary, bool unsigned) +SQLValue consumeIfComplete()(ref ubyte[] packet, SQLType sqlType, bool binary, bool unsigned, ushort charSet) { switch(sqlType) { @@ -714,7 +714,13 @@ SQLValue consumeIfComplete()(ref ubyte[] packet, SQLType sqlType, bool binary, b packet.popFront(); // LCB length } else - result.value = packet.consume(cast(size_t)lcb.value); + { + auto data = packet.consume(cast(size_t)lcb.value); + if(charSet == 0x3F) // CharacterSet == binary + result.value = data; // BLOB-ish + else + result.value = cast(string)data; // TEXT-ish + } // Type BIT is treated as a length coded binary (like a BLOB or VARCHAR), // not like an integral type. So convert the binary data to a bool. diff --git a/source/mysql/result.d b/source/mysql/result.d index ad166bb5..48f7a2cb 100644 --- a/source/mysql/result.d +++ b/source/mysql/result.d @@ -140,7 +140,7 @@ public: do { FieldDescription fd = rh[i]; - sqlValue = packet.consumeIfComplete(fd.type, binary, fd.unsigned); + sqlValue = packet.consumeIfComplete(fd.type, binary, fd.unsigned, fd.charSet); // TODO: Support chunk delegate if(sqlValue.isIncomplete) packet ~= con.getPacket(); diff --git a/source/mysql/test/integration.d b/source/mysql/test/integration.d index 20942b49..325456da 100644 --- a/source/mysql/test/integration.d +++ b/source/mysql/test/integration.d @@ -858,10 +858,10 @@ unittest assertBasicTests!string("VARCHAR(10)", "", "aoeu"); assertBasicTests!string("CHAR(10)", "", "aoeu"); - assertBasicTests!(ubyte[])("TINYTEXT", "", "aoeu"); - assertBasicTests!(ubyte[])("MEDIUMTEXT", "", "aoeu"); - assertBasicTests!(ubyte[])("TEXT", "", "aoeu"); - assertBasicTests!(ubyte[])("LONGTEXT", "", "aoeu"); + assertBasicTests!string("TINYTEXT", "", "aoeu"); + assertBasicTests!string("MEDIUMTEXT", "", "aoeu"); + assertBasicTests!string("TEXT", "", "aoeu"); + assertBasicTests!string("LONGTEXT", "", "aoeu"); assertBasicTests!(ubyte[])("TINYBLOB", "", "aoeu"); assertBasicTests!(ubyte[])("MEDIUMBLOB", "", "aoeu"); diff --git a/source/mysql/test/regression.d b/source/mysql/test/regression.d index 278ea284..cb698884 100644 --- a/source/mysql/test/regression.d +++ b/source/mysql/test/regression.d @@ -89,6 +89,38 @@ unittest assert(results[1][1] == Date(1950, 4, 24)); } +// Issue #33: TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT types treated as ubyte[] +debug(MYSQL_INTEGRATION_TESTS) +unittest +{ + mixin(scopedCn); + auto cmd = Command(cn); + ulong rowsAffected; + cmd.sql = + "DROP TABLE IF EXISTS `issue33`"; + cmd.execSQL(rowsAffected); + cmd.sql = + "CREATE TABLE `issue33` ( + `text` TEXT, + `blob` BLOB + ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; + cmd.execSQL(rowsAffected); + + cmd.sql = "INSERT INTO `issue33` (`text`, `blob`) VALUES ('hello', 'world')"; + cmd.execSQL(rowsAffected); + + cmd = Command(cn, "SELECT `text`, `blob` FROM `issue33`"); + cmd.prepare(); + auto results = cmd.execPreparedResult(); + assert(results.length == 1); + auto pText = results[0][0].peek!string(); + auto pBlob = results[0][1].peek!(ubyte[])(); + assert(pText); + assert(pBlob); + assert(*pText == "hello"); + assert(*pBlob == cast(ubyte[])"world".dup); +} + // Issue #39: Unsupported SQL type NEWDECIMAL debug(MYSQL_INTEGRATION_TESTS) unittest