f6bbe2 | 1997-03-06 | Henrik Grubbström (Grubba) | | |
824d4d | 2006-08-22 | Henrik Grubbström (Grubba) | | * $Id: mysql.pike,v 1.24 2006/08/22 11:24:16 grubba Exp $
|
f6bbe2 | 1997-03-06 | Henrik Grubbström (Grubba) | | *
* Glue for the Mysql-module
*/
|
36d2b8 | 2001-09-06 | Martin Nilsson | |
|
418221 | 1998-03-20 | Henrik Grubbström (Grubba) | |
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | #pike __REAL_VERSION__
|
a20af6 | 2000-09-26 | Fredrik Hübinette (Hubbe) | |
|
6f7b20 | 2004-04-16 | Henrik Grubbström (Grubba) | | #if constant(Mysql.mysql)
|
53675a | 1998-10-17 | Henrik Grubbström (Grubba) | |
|
f6bbe2 | 1997-03-06 | Henrik Grubbström (Grubba) | | inherit Mysql.mysql;
|
2f9cc3 | 1998-03-19 | Henrik Grubbström (Grubba) | |
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | #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
static int utf8_mode;
static string send_charset;
static void update_unicode_encode_mode_from_charset (string charset)
{
switch (charset) {
case "latin1":
utf8_mode |= LATIN1_UNICODE_ENCODE_MODE;
utf8_mode &= ~UTF8_UNICODE_ENCODE_MODE;
send_charset = "latin1";
break;
case "unicode":
utf8_mode |= UTF8_UNICODE_ENCODE_MODE;
utf8_mode &= ~LATIN1_UNICODE_ENCODE_MODE;
send_charset = "utf8";
break;
default:
utf8_mode |= LATIN1_UNICODE_ENCODE_MODE|UTF8_UNICODE_ENCODE_MODE;
send_charset = 0;
break;
}
}
int(0..1) set_unicode_encode_mode (int enable)
{
if (enable)
update_unicode_encode_mode_from_charset (lower_case (get_charset()));
else {
utf8_mode &= ~(LATIN1_UNICODE_ENCODE_MODE|UTF8_UNICODE_ENCODE_MODE);
send_charset = 0;
}
return !!send_charset;
}
int get_unicode_encode_mode()
{
return !!send_charset;
}
void set_unicode_decode_mode (int enable)
{
if (enable) {
::big_query ("SET character_set_results = utf8");
utf8_mode |= UNICODE_DECODE_MODE;
}
else {
::big_query ("SET character_set_results = " + get_charset());
utf8_mode &= ~UNICODE_DECODE_MODE;
}
}
int get_unicode_decode_mode()
{
return utf8_mode & UNICODE_DECODE_MODE;
}
void set_charset (string charset)
{
charset = lower_case (charset);
::set_charset (charset == "unicode" ? "utf8" : charset);
if (charset == "unicode" ||
utf8_mode & (LATIN1_UNICODE_ENCODE_MODE|UTF8_UNICODE_ENCODE_MODE))
update_unicode_encode_mode_from_charset (charset);
if (charset == "unicode")
utf8_mode |= UNICODE_DECODE_MODE;
else if (utf8_mode & UNICODE_DECODE_MODE && charset != "utf8")
::big_query ("SET character_set_results = utf8");
}
string get_charset()
{
if (utf8_mode & UTF8_UNICODE_ENCODE_MODE && send_charset)
return "unicode";
return ::get_charset();
}
|
4c1442 | 2002-01-02 | Per Hedbor | | #if constant( Mysql.mysql.MYSQL_NO_ADD_DROP_DB )
void create_db( string db )
{
::big_query( "CREATE DATABASE "+db );
}
void drop_db( string db )
{
::big_query( "DROP DATABASE "+db );
}
#endif
|
36d2b8 | 2001-09-06 | Martin Nilsson | |
|
6279f6 | 1998-03-19 | Henrik Grubbström (Grubba) | | string quote(string s)
|
2f9cc3 | 1998-03-19 | Henrik Grubbström (Grubba) | | {
|
18096f | 2003-08-22 | Martin Nilsson | | return replace(s,
|
2f9cc3 | 1998-03-19 | Henrik Grubbström (Grubba) | | ({ "\\", "\"", "\0", "\'", "\n", "\r" }),
|
18096f | 2003-08-22 | Martin Nilsson | | ({ "\\\\", "\\\"", "\\0", "\\\'", "\\n", "\\r" }));
|
2f9cc3 | 1998-03-19 | Henrik Grubbström (Grubba) | | }
|
93f544 | 1998-07-03 | Martin Stjernholm | |
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | string latin1_to_utf8 (string s)
{
return string_to_utf8 (replace (s, ([
"\x80": "\u20AC", "\x82": "\u201A", "\x83": "\u0192",
"\x84": "\u201E", "\x85": "\u2026", "\x86": "\u2020", "\x87": "\u2021",
"\x88": "\u02C6", "\x89": "\u2030", "\x8a": "\u0160", "\x8b": "\u2039",
"\x8c": "\u0152", "\x8e": "\u017D",
"\x91": "\u2018", "\x92": "\u2019", "\x93": "\u201C",
"\x94": "\u201D", "\x95": "\u2022", "\x96": "\u2013", "\x97": "\u2014",
"\x98": "\u02DC", "\x99": "\u2122", "\x9a": "\u0161", "\x9b": "\u203A",
"\x9c": "\u0153", "\x9e": "\u017E", "\x9f": "\u0178",
])));
}
string utf8_encode_query (string q, function(string:string) encode_fn)
{
string e = "";
while (1) {
sscanf(q, "%[^\'\"]%s", string prefix, string suffix);
e += encode_fn (prefix);
if (suffix == "") break;
string quote = suffix[..0];
int start = 1;
int end;
while ((end = search(suffix, quote, start)) >= 0) {
if (suffix[end-1] == '\\') {
int i;
for (i = 2; i < end; i++) {
if (suffix[end - i] != '\\') break;
}
if (!(i & 1)) {
start = end+1;
continue;
}
}
if (sizeof(suffix) == end+1) break;
if (suffix[end+1] == quote[0]) {
start = end+2;
continue;
}
break;
}
#define IS_IDENTIFIER_CHAR(chr) (Unicode.is_wordchar (chr) || \
(<'_', '$'>)[chr])
int intpos = -1;
if (has_suffix (prefix, "_binary"))
intpos = sizeof (prefix) - sizeof ("_binary");
else if (has_suffix (prefix, "_binary "))
intpos = sizeof (prefix) - sizeof ("_binary ");
else {
int i = sizeof(prefix);
while (i--) {
if (!(< ' ', '\n', '\r', '\t' >)[prefix[i]]) break;
}
if (i >= 0) {
if ((<'n', 'N'>)[prefix[i]])
intpos = i;
else {
sscanf (reverse (prefix[i - 33..i]), "%[a-zA-Z0-9_$]%s",
string rev_intro, string rest);
if (sizeof (rev_intro) && rev_intro[-1] == '_' && sizeof (rest))
intpos = i - sizeof (rev_intro) + 1;
}
}
}
int got_introducer;
if (intpos == 0)
got_introducer = 1;
else if (intpos > 0) {
int prechar = prefix[intpos - 1];
if (!IS_IDENTIFIER_CHAR (prechar))
got_introducer = 1;
}
if (got_introducer) {
string s = suffix[..end];
if (String.width (s) > 8) {
string encoding = prefix[intpos..];
if (has_prefix (encoding, "_"))
sscanf (encoding[1..], "%[a-zA-Z0-9]", encoding);
else
encoding = "utf8";
s = s[1..sizeof (s) - 2];
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]);
}
q = suffix[end+1..];
}
return e;
}
|
93f544 | 1998-07-03 | Martin Stjernholm | |
private constant timezone = localtime (0)->timezone;
|
36d2b8 | 2001-09-06 | Martin Nilsson | |
|
93f544 | 1998-07-03 | Martin Stjernholm | | 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);
}
else return sprintf ("%02d%02d%02d", time / 3600 % 24, time / 60 % 60, time % 60);
}
|
36d2b8 | 2001-09-06 | Martin Nilsson | |
|
93f544 | 1998-07-03 | Martin Stjernholm | | 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);
}
|
36d2b8 | 2001-09-06 | Martin Nilsson | |
|
93f544 | 1998-07-03 | Martin Stjernholm | | 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);
}
|
36d2b8 | 2001-09-06 | Martin Nilsson | |
|
93f544 | 1998-07-03 | Martin Stjernholm | | 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;
}
|
36d2b8 | 2001-09-06 | Martin Nilsson | |
|
93f544 | 1998-07-03 | Martin Stjernholm | | 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;
}
|
36d2b8 | 2001-09-06 | Martin Nilsson | |
|
93f544 | 1998-07-03 | Martin Stjernholm | | 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);
}
}
|
53675a | 1998-10-17 | Henrik Grubbström (Grubba) | |
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | Mysql.mysql_result big_query (string query,
mapping(string|int:mixed)|void bindings,
void|string charset)
|
6458a7 | 2000-04-29 | Francesco Chemolli | | {
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | if (bindings)
query = .sql_util.emulate_bindings(query,bindings,this);
string restore_charset;
if (charset) {
restore_charset = send_charset || get_charset();
|
824d4d | 2006-08-22 | Henrik Grubbström (Grubba) | | if (charset != restore_charset) {
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | ::big_query ("SET character_set_client=" + charset);
|
824d4d | 2006-08-22 | Henrik Grubbström (Grubba) | | ::big_query ("SET character_set_connection=" + charset);
} else
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | restore_charset = 0;
}
else if (send_charset) {
string new_send_charset;
|
6458a7 | 2000-04-29 | Francesco Chemolli | |
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | if (utf8_mode & LATIN1_UNICODE_ENCODE_MODE) {
if (String.width (query) == 8)
new_send_charset = "latin1";
else {
query = utf8_encode_query (query, latin1_to_utf8);
new_send_charset = "utf8";
}
}
else {
if (_can_send_as_latin1 (query))
new_send_charset = "latin1";
else {
query = utf8_encode_query (query, string_to_utf8);
new_send_charset = "utf8";
}
}
if (new_send_charset != send_charset) {
|
a1ff6c | 2006-08-15 | Henrik Grubbström (Grubba) | | mixed err;
|
824d4d | 2006-08-22 | Henrik Grubbström (Grubba) | | if (err = catch {
::big_query("SET character_set_client=" + new_send_charset);
::big_query("SET character_set_connection=" + new_send_charset);
}) {
|
a1ff6c | 2006-08-15 | Henrik Grubbström (Grubba) | | if (new_send_charset == "utf8")
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | predef::error ("The query is a wide string "
"and the MySQL server doesn't support UTF-8: %s\n",
describe_error (err));
|
a1ff6c | 2006-08-15 | Henrik Grubbström (Grubba) | | throw(err);
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | }
send_charset = new_send_charset;
}
}
int|object res = ::big_query(query);
if (restore_charset) {
if (send_charset && (<"latin1", "utf8">)[charset])
send_charset = charset;
|
824d4d | 2006-08-22 | Henrik Grubbström (Grubba) | | else {
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | ::big_query("SET character_set_client=" + restore_charset);
|
824d4d | 2006-08-22 | Henrik Grubbström (Grubba) | | ::big_query("SET character_set_connection=" + restore_charset);
}
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | }
if (!objectp(res)) return res;
if (utf8_mode & UNICODE_DECODE_MODE) {
return .sql_util.UnicodeWrapper(res);
}
return res;
}
|
d7bd0e | 2003-12-31 | Martin Nilsson | |
|
0e5be1 | 2002-01-17 | Martin Nilsson | | int(0..1) is_keyword( string name )
{
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | |
|
0e5be1 | 2002-01-17 | Martin Nilsson | | return (<
"action", "add", "aggregate", "all", "alter", "after", "and", "as",
"asc", "avg", "avg_row_length", "auto_increment", "between", "bigint",
"bit", "binary", "blob", "bool", "both", "by", "cascade", "case",
"char", "character", "change", "check", "checksum", "column",
"columns", "comment", "constraint", "create", "cross", "current_date",
"current_time", "current_timestamp", "data", "database", "databases",
"date", "datetime", "day", "day_hour", "day_minute", "day_second",
"dayofmonth", "dayofweek", "dayofyear", "dec", "decimal", "default",
"delayed", "delay_key_write", "delete", "desc", "describe", "distinct",
"distinctrow", "double", "drop", "end", "else", "escape", "escaped",
"enclosed", "enum", "explain", "exists", "fields", "file", "first",
"float", "float4", "float8", "flush", "foreign", "from", "for", "full",
"function", "global", "grant", "grants", "group", "having", "heap",
"high_priority", "hour", "hour_minute", "hour_second", "hosts",
"identified", "ignore", "in", "index", "infile", "inner", "insert",
"insert_id", "int", "integer", "interval", "int1", "int2", "int3",
"int4", "int8", "into", "if", "is", "isam", "join", "key", "keys",
"kill", "last_insert_id", "leading", "left", "length", "like",
"lines", "limit", "load", "local", "lock", "logs", "long", "longblob",
"longtext", "low_priority", "max", "max_rows", "match", "mediumblob",
"mediumtext", "mediumint", "middleint", "min_rows", "minute",
"minute_second", "modify", "month", "monthname", "myisam", "natural",
"numeric", "no", "not", "null", "on", "optimize", "option",
"optionally", "or", "order", "outer", "outfile", "pack_keys",
"partial", "password", "precision", "primary", "procedure", "process",
"processlist", "privileges", "read", "real", "references", "reload",
"regexp", "rename", "replace", "restrict", "returns", "revoke",
"rlike", "row", "rows", "second", "select", "set", "show", "shutdown",
"smallint", "soname", "sql_big_tables", "sql_big_selects",
"sql_low_priority_updates", "sql_log_off", "sql_log_update",
"sql_select_limit", "sql_small_result", "sql_big_result",
"sql_warnings", "straight_join", "starting", "status", "string",
"table", "tables", "temporary", "terminated", "text", "then", "time",
"timestamp", "tinyblob", "tinytext", "tinyint", "trailing", "to",
"type", "use", "using", "unique", "unlock", "unsigned", "update",
"usage", "values", "varchar", "variables", "varying", "varbinary",
"with", "write", "when", "where", "year", "year_month", "zerofill",
>)[ lower_case(name) ];
}
|
98cdce | 2006-08-15 | Henrik Grubbström (Grubba) | | 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")
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);
} else {
::create(host||"", database||"", user||"", password||"");
update_unicode_encode_mode_from_charset ("latin1");
}
}
|
ffaf45 | 2004-04-14 | Martin Nilsson | | #else
constant this_program_does_not_exist=1;
|
53675a | 1998-10-17 | Henrik Grubbström (Grubba) | | #endif /* constant(Mysql.mysql) */
|