--- sql/mysql/parser3mysql.C 2008/06/30 14:00:19 1.34 +++ sql/mysql/parser3mysql.C 2010/10/18 21:48:22 1.37 @@ -1,16 +1,16 @@ /** @file Parser MySQL driver. - Copyright(c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) + Copyright(c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) - 2001.07.30 using MySQL 3.23.22b + 2001-07-30 using MySQL 3.23.22b - 2001.11.06 numrows on "HP-UX istok1 B.11.00 A 9000/869 448594332 two-user license" + 2001-11-06 numrows on "HP-UX istok1 B.11.00 A 9000/869 448594332 two-user license" 3.23.42 & 4.0.0.alfa never worked, both subst & .sl version returned 0 */ -static const char *RCSId="$Id: parser3mysql.C,v 1.34 2008/06/30 14:00:19 misha Exp $"; +static const char *RCSId="$Id: parser3mysql.C,v 1.37 2010/10/18 21:48:22 moko Exp $"; #include "config_includes.h" @@ -28,6 +28,19 @@ static const char *RCSId="$Id: parser3my # define strcasecmp _stricmp #endif +// for mysql < 4.1 +#if !defined(CLIENT_MULTI_RESULTS) || !defined(CLIENT_MULTI_STATEMENTS) +# define OLD_MYSQL_CLIENT 1 +#endif + +#ifndef CLIENT_MULTI_RESULTS +# define CLIENT_MULTI_RESULTS (1UL << 17) +#endif + +#ifndef CLIENT_MULTI_STATEMENTS +# define CLIENT_MULTI_STATEMENTS (1UL << 16) +#endif + static char *lsplit(char *string, char delim){ if(string) { if(char *v=strchr(string, delim)){ @@ -77,10 +90,12 @@ public: MySQL_Driver() : SQL_Driver() {} +#ifndef FREEBSD4 ~MySQL_Driver() { if(mysql_server_end) mysql_server_end(); } +#endif /// get api version int api_version() { return SQL_DRIVER_API_VERSION; } @@ -100,8 +115,8 @@ public: compress=0& named_pipe=1& autocommit=1& - multi_statements=0 // allow more then one statement in one query - old_client=1 // simulate 3.xx client. not compatible with multi_statements option + multi_statements=0 // allows more then one statement in one query + old_client=1 // simulates 3.xx client. not compatible with multi_statements option 3.x, 4.0 only option for charset is cp1251_koi8. 4.1+ accept not 'cp1251_koi8' but 'cp1251', 'utf8' and much more @@ -130,7 +145,12 @@ public: char *options=lsplit(db, '?'); char *charset=0; + +#ifdef OLD_MYSQL_CLIENT + int client_flag=0; +#else int client_flag=CLIENT_MULTI_RESULTS; +#endif Connection& connection=*(Connection *)services.malloc(sizeof(Connection)); *connection_ref=&connection; @@ -164,15 +184,23 @@ public: if(atoi(value)==0) connection.autocommit=false; } else if(strcasecmp(key, "multi_statements")==0){ +#ifdef OLD_MYSQL_CLIENT + services._throw("driver was built with old mysql includes so multi_statements option can't be used"); +#else if(!(client_flag==CLIENT_MULTI_RESULTS || client_flag==CLIENT_MULTI_STATEMENTS)) services._throw("you can't specify together options old_client and multi_statements"); if(atoi(value)!=0) client_flag=CLIENT_MULTI_STATEMENTS; +#endif } else if(strcasecmp(key, "old_client")==0){ +#ifdef OLD_MYSQL_CLIENT + services._throw("driver was built with old mysql includes so old_client option can't be used"); +#else if(!(client_flag==CLIENT_MULTI_RESULTS || client_flag==0)) services._throw("you can't specify together options old_client and multi_statements"); if(atoi(value)!=0) client_flag=0; +#endif } else services._throw("unknown connect option" /*key*/); } else @@ -225,16 +253,63 @@ public: return mysql_ping(connection.handle)==0; } - const char* quote(void *aconnection, const char *from, unsigned int length) { + // charset here is services.request_charset(), not connection.client_charset + // thus we can't use the sql server quoting support + const char* quote(void *aconnection, const char *str, unsigned int length) { + const char* from; + const char* from_end=str+length; + + size_t quoted=0; + + for(from=str; from(aconnection); - /* - 3.23.22b - You must allocate the to buffer to be at least length*2+1 bytes long. - (In the worse case, each character may need to be encoded as using two bytes, - and you need room for the terminating null byte.) - */ - char *result=(char*)connection.services->malloc_atomic(length*2+1); - mysql_escape_string(result, from, length); + char *result=(char*)connection.services->malloc_atomic(length + quoted + 1); + char *to = result; + + for(from=str; from