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

version» Context lines:

pike.git/lib/modules/Sql.pmod/mysql.pike:43:   //! unix timestamps on integer form.   //!   //! @item String types   //! All string types are returned as pike strings. The MySQL glue   //! can handle charset conversions for text strings - see   //! @[set_charset] and @[set_unicode_decode_mode].   //!   //! @enddl   //!   //! @endsection + //! + //! @seealso + //! @[Sql.Connection], @[Sql.Sql()]      #pike __REAL_VERSION__ -  + #require constant(Mysql.mysql)    - // Cannot dump this since the #if constant(...) check below may depend - // on the presence of system libs at runtime. - constant dont_dump_program = 1; + // Cannot dump this since the #require check may depend on the + // presence of system libs at runtime. + optional constant dont_dump_program = 1;    - #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      #ifdef MYSQL_CHARSET_DEBUG   #define CH_DEBUG(X...) \    werror(replace (sprintf ("%O", this), "%", "%%") + ": " + X)   #else
pike.git/lib/modules/Sql.pmod/mysql.pike:399:   //!   //! @param s   //! String to quote.   string quote(string s)   {    return replace(s,    ({ "\\", "\"", "\0", "\'", "\n", "\r" }),    ({ "\\\\", "\\\"", "\\0", "\\\'", "\\n", "\\r" }));   }    - string latin1_to_utf8 (string s) + string latin1_to_utf8 (string s, int extended)   //! Converts a string in MySQL @expr{latin1@} format to UTF-8.   {    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", -  ]))); +  ])), extended);   }    - string utf8_encode_query (string q, function(string:string) encode_fn) + string utf8_encode_query (string q, +  function(string, mixed|void...:string) encode_fn, +  mixed ... extras)   //! Encodes the appropriate sections of the query with @[encode_fn].   //! Everything except strings prefixed by an introducer (i.e.   //! @expr{_something@} or @expr{N@}) is encoded.   {    // We need to find the segments that shouldn't be encoded.    string e = "";    while (1) {    sscanf(q, "%[^\'\"]%s", string prefix, string suffix); -  e += encode_fn (prefix); +  e += encode_fn (prefix, @extras);       if (suffix == "") break;       string quote = suffix[..0];    int start = 1;    int end;    while ((end = search(suffix, quote, start)) >= 0) {    if (suffix[end-1] == '\\') {    // Count the number of preceding back-slashes.    // if odd, continue searching after the quote.
pike.git/lib/modules/Sql.pmod/mysql.pike:519:    else    encoding = "utf8"; // Gotta be "N".    s = s[1..<1];    if (sizeof (s) > 40) s = sprintf ("%O...", s[..37]);    else s = sprintf ("%O", s);    predef::error ("A string in the query should be %s encoded "    "but it is wide: %s\n", encoding, s);    }    e += s;    } else { -  e += encode_fn (suffix[..end]); +  e += encode_fn (suffix[..end], @extras);    }       q = suffix[end+1..];    }    return e;   }    - // The following time conversion functions assumes the SQL server - // handles time in this local timezone. They map the special zero - // time/date spec to 0. -  - private constant timezone = localtime (0)->timezone; -  +    //! Converts a system time value to an appropriately formatted time   //! spec for the database.   //!   //! @param time   //! Time to encode.   //!   //! @param date   //! If nonzero then time is taken as a "full" unix time spec   //! (where the date part is ignored), otherwise it's converted as a   //! seconds-since-midnight value.   string encode_time (int time, void|int date)   { -  if (date) { -  if (!time) return "000000"; -  mapping(string:int) ct = localtime (time); -  return sprintf ("%02d%02d%02d", ct->hour, ct->min, ct->sec); +  return ::encode_time(time, date) - ":";   } -  else return sprintf ("%02d%02d%02d", time / 3600 % 24, time / 60 % 60, time % 60); - } +       //! Converts a system time value to an appropriately formatted   //! date-only spec for the database.   //!   //! @param time   //! Time to encode.   string encode_date (int time)   { -  if (!time) return "00000000"; -  mapping(string:int) ct = localtime (time); -  return sprintf ("%04d%02d%02d", ct->year + 1900, ct->mon + 1, ct->mday); +  return ::encode_date(time) - "-";   }      //! Converts a system time value to an appropriately formatted   //! date and time spec for the database.   //!   //! @param time   //! Time to encode.   string encode_datetime (int time)   { -  if (!time) return "00000000000000"; -  mapping(string:int) ct = localtime (time); -  return sprintf ("%04d%02d%02d%02d%02d%02d", -  ct->year + 1900, ct->mon + 1, ct->mday, -  ct->hour, ct->min, ct->sec); +  return replace(::encode_datetime(time), "-:T"/"", ({"", "", ""}));   }    - //! Converts a database time spec to a system time value. - //! - //! @param timestr - //! Time spec to decode. - //! - //! @param date - //! Take the date part from this system time value. If zero, a - //! seconds-since-midnight value is returned. - int decode_time (string timestr, void|int date) - { -  int hour = 0, min = 0, sec = 0; -  if (sscanf (timestr, "%d:%d:%d", hour, min, sec) <= 1) -  sscanf (timestr, "%2d%2d%2d", hour, min, sec); -  if (date && (hour || min || sec)) { -  mapping(string:int) ct = localtime (date); -  return mktime (sec, min, hour, ct->mday, ct->mon, ct->year, ct->isdst, ct->timezone); -  } -  else return (hour * 60 + min) * 60 + sec; - } -  - //! Converts a database date-only spec to a system time value. - //! Assumes 4-digit years. - //! - //! @param datestr - //! Date spec to decode. - int decode_date (string datestr) - { -  int year = 0, mon = 0, mday = 0, n; -  n = sscanf (datestr, "%d-%d-%d", year, mon, mday); -  if (n <= 1) n = sscanf (datestr, "%4d%2d%2d", year, mon, mday); -  if (year || mon || mday) -  return mktime (0, 0, 0, n == 3 ? mday : 1, n >= 2 && mon - 1, year - 1900, -  -1, timezone); -  else return 0; - } -  - //! Converts a database date and time spec to a system time value. - //! Can decode strings missing the time part. - //! - //! @param datestr - //! Date and time spec to decode. - int decode_datetime (string timestr) - { -  array(string) a = timestr / " "; -  if (sizeof (a) == 2) -  return decode_date (a[0]) + decode_time (a[1]); -  else { -  int n = sizeof (timestr); -  if (n >= 12) -  return decode_date (timestr[..n-7]) + decode_time (timestr[n-6..n-1]); -  else -  return decode_date (timestr); -  } - } -  +    #if constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)   #define HAVE_MYSQL_FIELD_CHARSETNR_IFELSE(TRUE, FALSE) TRUE   #else   #define HAVE_MYSQL_FIELD_CHARSETNR_IFELSE(TRUE, FALSE) FALSE   #endif      #define QUERY_BODY(do_query) \    if (bindings) \    query = .sql_util.emulate_bindings(query,bindings,this); \    \
pike.git/lib/modules/Sql.pmod/mysql.pike:665:    } \    \    else if (send_charset) { \    string new_send_charset = 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); \ +  query = utf8_encode_query (query, latin1_to_utf8, 2); \    new_send_charset = "utf8"; \    } \    } \    \    else { /* utf8_mode & UTF8_UNICODE_ENCODE_MODE */ \    /* NB: The send_charset may only be upgraded from \    * "latin1" to "utf8", not the other way around. \    * This is to avoid extraneous charset changes \    * where the charset is changed from query to query. \    */ \    if ((send_charset == "utf8") || !_can_send_as_latin1(query)) { \    CH_DEBUG ("Converting query to utf8.\n"); \ -  query = utf8_encode_query (query, string_to_utf8); \ +  query = utf8_encode_query (query, string_to_utf8, 2); \    new_send_charset = "utf8"; \    } \    } \    \    if (new_send_charset != 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 */ \
pike.git/lib/modules/Sql.pmod/mysql.pike:733:    \    if (utf8_mode & UNICODE_DECODE_MODE) { \    CH_DEBUG ("Using unicode wrapper for result.\n"); \    return \    HAVE_MYSQL_FIELD_CHARSETNR_IFELSE ( \    .sql_util.MySQLUnicodeWrapper(res), \    .sql_util.MySQLBrokenUnicodeWrapper (res)); \    } \    return res;    - Mysql.mysql_result big_query (string query, + variant Result big_query (string query,    mapping(string|int:mixed)|void bindings,    void|string charset)   //! Sends a query to the server.   //!   //! @param query   //! The SQL query.   //!   //! @param bindings   //! An optional bindings mapping. See @[Sql.query] for details about   //! this.
pike.git/lib/modules/Sql.pmod/mysql.pike:760:   //! @endcode   //! is sent to the server first, then @[query] is sent as-is, and then   //! the connection charset is restored again (if necessary).   //!   //! Primarily useful with @[charset] set to @expr{"latin1"@} if   //! unicode encode mode (see @[set_unicode_encode_mode]) is enabled   //! (the default) and you have some large queries (typically blob   //! inserts) where you want to avoid the query parsing overhead.   //!   //! @returns - //! A @[Mysql.mysql_result] object is returned if the query is of a + //! A @[Result] object is returned if the query is of a   //! kind that returns a result. Zero is returned otherwise.   //!   //! The individual fields are returned as strings except for @tt{NULL@},   //! which is returned as @[UNDEFINED].   //!   //! @seealso   //! @[Sql.big_query()], @[big_typed_query()], @[streaming_query()]   {    QUERY_BODY (big_query);   }    - Mysql.mysql_result streaming_query (string query, + variant Result streaming_query (string query,    mapping(string|int:mixed)|void bindings,    void|string charset)   //! Makes a streaming SQL query.   //!   //! This function sends the SQL query @[query] to the Mysql-server.   //! The result of the query is streamed through the returned - //! @[Mysql.mysql_result] object. Note that the involved database + //! @[Result] object. Note that the involved database   //! tables are locked until all the results has been read.   //!   //! In all other respects, it behaves like @[big_query].   //!   //! @seealso   //! @[big_query()], @[streaming_typed_query()]   {    QUERY_BODY (streaming_query);   }    - Mysql.mysql_result big_typed_query (string query, + variant Result big_typed_query (string query,    mapping(string|int:mixed)|void bindings,    void|string charset)   //! Makes a typed SQL query.   //!   //! This function sends the SQL query @[query] to the MySQL server and   //! returns a result object in typed mode, which means that the types   //! of the result fields depend on the corresponding SQL types. See   //! the class docs for details.   //!   //! In all other respects, it behaves like @[big_query].   //!   //! @seealso   //! @[big_query()], @[streaming_typed_query()]   {    QUERY_BODY (big_typed_query);   }    - Mysql.mysql_result streaming_typed_query (string query, + variant Result streaming_typed_query (string query,    mapping(string|int:mixed)|void bindings,    void|string charset)   //! Makes a streaming typed SQL query.   //!   //! This function acts as the combination of @[streaming_query()]   //! and @[big_typed_query()].   //!   //! @seealso   //! @[big_typed_query()], @[streaming_typed_query()]   {    QUERY_BODY (streaming_typed_query);   }    -  + array(string) list_dbs(string|void wild) + { +  Result res = ::list_dbs(wild); +  array(string) ret = ({}); +  array(string) row; +  while((row = res->fetch_row()) && sizeof(row)) { +  ret += ({ row[0] }); +  } +  return ret; + } +  + array(string) list_tables(string|void wild) + { +  Result res = ::list_tables(wild); +  array(string) ret = ({}); +  array(string) row; +  while((row = res->fetch_row()) && sizeof(row)) { +  ret += ({ row[0] }); +  } +  return ret; + } +    int(0..1) is_keyword( string name )   //! Return 1 if the argument @[name] is a mysql keyword that needs to   //! be quoted in a query. The list is currently up-to-date with MySQL   //! 5.1.   {    return ([    "accessible": 1, "add": 1, "all": 1, "alter": 1, "analyze": 1, "and": 1,    "as": 1, "asc": 1, "asensitive": 1, "before": 1, "between": 1, "bigint": 1,    "binary": 1, "blob": 1, "both": 1, "by": 1, "call": 1, "cascade": 1,    "case": 1, "change": 1, "char": 1, "character": 1, "check": 1, "collate": 1,
pike.git/lib/modules/Sql.pmod/mysql.pike:938: Inside #if !constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
   predef::error ("Unicode decode mode not supported - "    "compiled with MySQL client library < 4.1.0.\n");   #endif       } else {    ::create(host||"", database||"", user||"", password||"");       update_unicode_encode_mode_from_charset ("latin1");    }   } -  - #else - constant this_program_does_not_exist=1; - #endif /* constant(Mysql.mysql) */ +