Branch: Tag:

2007-05-03

2007-05-03 13:57:35 by Martin Stjernholm <mast@lysator.liu.se>

Added more methods to enable the buggy unicode decode support in Mysql.mysql:

o "broken-unicode" as charset to create() or set_charset().
o set_unicode_decode_mode (-1).

Note that all this only applies when compiling with a mysql client lib older
than 4.1.0. Otherwise these methods are aliases to enabling the normal
unicode decode support. This means that no code using broken-unicode should
rely on the BINARY flag on text fields to avoid utf-8 decoding.

Rev: lib/modules/Sql.pmod/mysql.pike:1.32
Rev: lib/modules/Sql.pmod/sql_util.pmod:1.17

1:   /* -  * $Id: mysql.pike,v 1.31 2006/12/05 11:48:21 grubba Exp $ +  * $Id: mysql.pike,v 1.32 2007/05/03 13:57:35 mast Exp $    *    * Glue for the Mysql-module    */
23:   #define CH_DEBUG(X...)   #endif    + #ifndef (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR) + // Recognition constant to tell that the unicode decode mode would use + // the buggy MySQLBrokenUnicodeWrapper if it would be enabled through + // any of the undocumented methods. + constant unicode_decode_mode_is_broken = 1; + #endif +    // Set to the above if the connection is requested to be in one of the   // unicode modes. latin1 unicode encode mode is enabled by default; it   // should be compatible with earlier pike versions.
109:   //! is @expr{latin1@}, the charset accepted by @[big_query] is not   //! quite Unicode since @expr{latin1@} is based on @expr{cp1252@}.   //! The differences are in the range @expr{0x80..0x9f@} where - //! Unicode have control chars. + //! Unicode has control chars.   //!   //! This small discrepancy is not present when the connection   //! charset is @expr{unicode@}.
156:   //! the statement above fails. The MySQL system variable   //! @expr{character_set_results@} was added in MySQL 4.1.1.   //! - //! @note - //! This function is only available if Pike has been compiled with - //! MySQL client library 4.1.0 or later, or if the environment - //! variable @tt{PIKE_BROKEN_MYSQL_UNICODE_MODE@} is set. + //! An error is also thrown if Pike has been compiled with a MySQL + //! client library older than 4.1.0, which lack the necessary + //! support for this.   //!   //! @seealso   //! @[set_unicode_encode_mode]   {   #if !constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR) -  if (!getenv("PIKE_BROKEN_MYSQL_UNICODE_MODE")) { -  predef::error("set_unicode_decode_mode not available.\n"); +  // Undocumented feature for old mysql libs. See +  // MySQLBrokenUnicodeWrapper for details. +  if (!(<0, -1>)[enable] && !getenv("PIKE_BROKEN_MYSQL_UNICODE_MODE")) { +  predef::error ("Unicode decode mode not supported - " +  "compiled with MySQL client library < 4.1.0.\n");    }   #endif -  +     if (enable) {    CH_DEBUG("Enabling unicode decode mode.\n");    ::big_query ("SET character_set_results = utf8");
260:       CH_DEBUG("Setting charset to %O.\n", charset);    +  int broken_unicode = charset == "broken-unicode"; +  if (broken_unicode) charset = "unicode"; +     ::set_charset (charset == "unicode" ? "utf8" : charset);       if (charset == "unicode" ||
270: Inside #if constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
  #if constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)    utf8_mode |= UNICODE_DECODE_MODE;   #else -  if (set_unicode_decode_mode) +  if (broken_unicode || getenv ("PIKE_BROKEN_MYSQL_UNICODE_MODE")) +  // Undocumented feature for old mysql libs. See +  // MySQLBrokenUnicodeWrapper for details.    utf8_mode |= UNICODE_DECODE_MODE;    else    predef::error ("Unicode decode mode not supported - "
310:   //! @[set_charset]   {    if (utf8_mode & UTF8_UNICODE_ENCODE_MODE && send_charset) +  // We don't try to be symmetric with set_charset when the +  // broken-unicode kludge is in use. That since this reflects the +  // setting on the encode side only.    return "unicode";    return ::get_charset();   }
710:    mapping(string:string|int)|void options)   {    if (options) { -  string charset = options->mysql_charset_name || "latin1"; +  string charset = options->mysql_charset_name ? +  lower_case (options->mysql_charset_name) : "latin1"; +  +  int broken_unicode = charset == "broken-unicode"; +  if (broken_unicode) charset = "unicode"; +     if (charset == "unicode")    options->mysql_charset_name = "utf8";   
719:    update_unicode_encode_mode_from_charset (lower_case (charset));      #if !constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR) -  if (set_unicode_encode_mode) { +  // Undocumented feature for old mysql libs. See +  // MySQLBrokenUnicodeWrapper for details. +  if (broken_unicode || getenv ("PIKE_BROKEN_MYSQL_UNICODE_MODE")) {   #endif    if (charset == "unicode")    utf8_mode |= UNICODE_DECODE_MODE;