pike.git / lib / modules / Sql.pmod / mysql.pike

version» Context lines:

pike.git/lib/modules/Sql.pmod/mysql.pike:1:   /* -  * $Id: mysql.pike,v 1.19 2006/08/22 09:47:11 grubba Exp $ +  * $Id: mysql.pike,v 1.20 2006/09/15 13:13:26 mast Exp $    *    * Glue for the Mysql-module    */      //! Implements the glue needed to access the Mysql-module from the generic   //! SQL module.      #pike __REAL_VERSION__      #if constant(Mysql.mysql)      inherit Mysql.mysql;      #define UNICODE_DECODE_MODE 1 // Unicode decode mode   #define LATIN1_UNICODE_ENCODE_MODE 2 // Unicode encode mode with latin1 charset   #define UTF8_UNICODE_ENCODE_MODE 4 // Unicode encode mode with utf8 charset - #define BINARY_LATIN1_MODE 8 // Don't special-case latin1 control chars +       #ifdef MYSQL_CHARSET_DEBUG   #define CH_DEBUG(X...) werror("Sql.mysql: " + X)   #else   #define CH_DEBUG(X...)   #endif    - // Set to the above if the connection is in utf8-mode. Enable latin1 - // unicode encode mode by default; it should be compatible with - // earlier pike versions. + // 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.   static int utf8_mode;      // The charset, either "latin1" or "utf8", currently assigned to   // character_set_client when unicode encode mode is enabled. Zero when   // the connection charset has been set to something else than "latin1"   // or "unicode".   static string send_charset;      static void update_unicode_encode_mode_from_charset (string charset)   {    switch (charset) { // Lowercase assumed.    case "latin1":    utf8_mode |= LATIN1_UNICODE_ENCODE_MODE;    utf8_mode &= ~UTF8_UNICODE_ENCODE_MODE;    send_charset = "latin1"; -  CH_DEBUG("Entering latin1 mode.\n"); +  CH_DEBUG ("Entering latin1 encode mode.\n");    break;    case "unicode":    utf8_mode |= UTF8_UNICODE_ENCODE_MODE;    utf8_mode &= ~LATIN1_UNICODE_ENCODE_MODE;    send_charset = "utf8"; -  CH_DEBUG("Entering utf8 mode.\n"); +  CH_DEBUG ("Entering unicode encode mode.\n");    break;    default:    // Wrong charset - the mode can't be used.    utf8_mode |= LATIN1_UNICODE_ENCODE_MODE|UTF8_UNICODE_ENCODE_MODE;    send_charset = 0; -  CH_DEBUG("Entering other mode.\n"); +  CH_DEBUG ("Not entering latin1/unicode encode mode " +  "due to incompatible charset %O.\n", charset);    break;    }   }      int(0..1) set_unicode_encode_mode (int enable)   //! Enables or disables unicode encode mode.   //!   //! In this mode, if the server supports UTF-8 and the connection   //! charset is @expr{latin1@} (the default) or @expr{unicode@} then   //! @[big_query] handles wide unicode queries. Enabled by default.
pike.git/lib/modules/Sql.pmod/mysql.pike:110:   //! quite Unicode since @expr{latin1@} is based on @expr{cp1252@}.   //! The differences are in the range @expr{0x80..0x9f@} where   //! Unicode have control chars.   //!   //! This small discrepancy is not present when the connection   //! charset is @expr{unicode@}.   //!   //! @seealso   //! @[set_unicode_decode_mode], @[set_charset]   { -  if (enable) { -  CH_DEBUG("Enabling unicode encode mode.\n"); +  if (enable)    update_unicode_encode_mode_from_charset (lower_case (get_charset())); -  } else { +  else {    utf8_mode &= ~(LATIN1_UNICODE_ENCODE_MODE|UTF8_UNICODE_ENCODE_MODE);    send_charset = 0;    CH_DEBUG("Disabling unicode encode mode.\n");    }    return !!send_charset;   }      int get_unicode_encode_mode()   //! Returns nonzero if unicode encode mode is enabled, zero otherwise.   //!
pike.git/lib/modules/Sql.pmod/mysql.pike:313: Inside #if constant( Mysql.mysql.MYSQL_NO_ADD_DROP_DB )
   ::big_query( "DROP DATABASE "+db );   }   #endif      //! Quote a string so that it can safely be put in a query.   //!   //! @param s   //! String to quote.   string quote(string s)   { -  return(replace(s, +  return replace(s,    ({ "\\", "\"", "\0", "\'", "\n", "\r" }), -  ({ "\\\\", "\\\"", "\\0", "\\\'", "\\n", "\\r" }))); +  ({ "\\\\", "\\\"", "\\0", "\\\'", "\\n", "\\r" }));   }      string latin1_to_utf8 (string s)   //! Converts a string in MySQL @expr{latin1@} format to UTF-8.   { -  CH_DEBUG("Converting latin1 query to utf8.\n"); +     return string_to_utf8 (replace (s, ([    "\x80": "\u20AC", /*"\x81": "\u0081",*/ "\x82": "\u201A", "\x83": "\u0192",    "\x84": "\u201E", "\x85": "\u2026", "\x86": "\u2020", "\x87": "\u2021",    "\x88": "\u02C6", "\x89": "\u2030", "\x8a": "\u0160", "\x8b": "\u2039",    "\x8c": "\u0152", /*"\x8d": "\u008D",*/ "\x8e": "\u017D", /*"\x8f": "\u008F",*/    /*"\x90": "\u0090",*/ "\x91": "\u2018", "\x92": "\u2019", "\x93": "\u201C",    "\x94": "\u201D", "\x95": "\u2022", "\x96": "\u2013", "\x97": "\u2014",    "\x98": "\u02DC", "\x99": "\u2122", "\x9a": "\u0161", "\x9b": "\u203A",    "\x9c": "\u0153", /*"\x9d": "\u009D",*/ "\x9e": "\u017E", "\x9f": "\u0178",    ])));
pike.git/lib/modules/Sql.pmod/mysql.pike:559:   Mysql.mysql_result big_query (string query,    mapping(string|int:mixed)|void bindings,    void|string charset)   {    if (bindings)    query = .sql_util.emulate_bindings(query,bindings,this);       string restore_charset;    if (charset) {    restore_charset = send_charset || get_charset(); -  CH_DEBUG("Restore charset is %O.\n", restore_charset); +     if (charset != restore_charset) { -  +  CH_DEBUG ("Switching charset from %O to %O (due to charset arg).\n", +  restore_charset, charset);    ::big_query ("SET character_set_client=" + charset); -  ::big_query ("SET character_set_connection=" + charset); +  /* Can't be changed automatically - has side effects. /mast */ +  /* ::big_query("SET character_set_connection=" + charset); */    } else    restore_charset = 0;    }       else if (send_charset) {    string new_send_charset;       if (utf8_mode & LATIN1_UNICODE_ENCODE_MODE) {    if (String.width (query) == 8)    new_send_charset = "latin1";    else { -  +  CH_DEBUG ("Converting (mysql-)latin1 query to utf8.\n");    query = utf8_encode_query (query, latin1_to_utf8);    new_send_charset = "utf8";    }    }       else { /* utf8_mode & UTF8_UNICODE_ENCODE_MODE */    if (_can_send_as_latin1 (query))    new_send_charset = "latin1";    else { -  +  CH_DEBUG ("Converting query to utf8.\n");    query = utf8_encode_query (query, string_to_utf8);    new_send_charset = "utf8";    }    }    -  CH_DEBUG("New send charset is %O.\n", new_send_charset); -  +     if (new_send_charset != send_charset) { -  CH_DEBUG("Send charset was %O.\n", send_charset); -  mixed err; -  if (err = catch { -  ::big_query("SET character_set_client=" + new_send_charset); -  ::big_query("SET character_set_connection=" + new_send_charset); +  CH_DEBUG ("Switching charset from %O to %O.\n", +  send_charset, new_send_charset); +  if (mixed err = catch { +  ::big_query ("SET character_set_client=" + new_send_charset); +  /* Can't be changed automatically - has side effects. /mast */ +  /* ::big_query("SET character_set_connection=" + +  new_send_charset); */    }) {    if (new_send_charset == "utf8")    predef::error ("The query is a wide string "    "and the MySQL server doesn't support UTF-8: %s\n",    describe_error (err)); -  throw(err); +  else +  throw err;    }    send_charset = new_send_charset;    }    }    -  CH_DEBUG("Sending query %O.\n", query); +  CH_DEBUG ("Sending query with charset %O: %O.\n", +  charset || send_charset, query);       int|object res = ::big_query(query);       if (restore_charset) {    if (send_charset && (<"latin1", "utf8">)[charset])    send_charset = charset;    else { -  CH_DEBUG("Restoring charset to %O.\n", restore_charset); -  ::big_query("SET character_set_client=" + restore_charset); -  ::big_query("SET character_set_connection=" + restore_charset); +  CH_DEBUG ("Restoring charset %O.\n", restore_charset); +  ::big_query ("SET character_set_client=" + restore_charset); +  /* Can't be changed automatically - has side effects. /mast */ +  /* ::big_query("SET character_set_connection=" + restore_charset); */    }    }       if (!objectp(res)) return res;       if (utf8_mode & UNICODE_DECODE_MODE) { -  CH_DEBUG("Adding UnicodeWrapper.\n"); +  CH_DEBUG ("Using UnicodeWrapper for result.\n");    return .sql_util.UnicodeWrapper(res);    }    return res;   }      int(0..1) is_keyword( string name )   //! Return 1 if the argument @[name] is a mysql keyword.   {    // FIXME: Document which version of MySQL this is up-to-date with.    return (<
pike.git/lib/modules/Sql.pmod/mysql.pike:681:    "with", "write", "when", "where", "year", "year_month", "zerofill",    >)[ lower_case(name) ];   }      static void create(string|void host, string|void database,    string|void user, string|void password,    mapping(string:string|int)|void options)   {    if (options) {    string charset = options->mysql_charset_name || "latin1"; -  if (charset == "unicode") { +  if (charset == "unicode")    options->mysql_charset_name = "utf8"; -  } +        ::create(host||"", database||"", user||"", password||"", options);       update_unicode_encode_mode_from_charset (lower_case (charset));       if (charset == "unicode")    utf8_mode |= UNICODE_DECODE_MODE;    else if (options->unicode_decode_mode)    set_unicode_decode_mode (1); -  if (options->binary_latin1_mode) -  utf8_mode |= BINARY_LATIN1_MODE; +        } else {    ::create(host||"", database||"", user||"", password||"");       update_unicode_encode_mode_from_charset ("latin1");    }   }      #endif /* constant(Mysql.mysql) */