Date: Friday, March 24, 2006 @ 10:02:40
  Author: zsolt
    Path: /cvsroot/carob/libmysequoia

Modified: include/CarobMySQL.hpp (1.30 -> 1.31) include/Utils.hpp (1.19 ->
          1.20) src/CarobMySQL.cpp (1.64 -> 1.65) src/Utils.cpp (1.35 ->
          1.36)

enabled "query parsing". now it recognize the "set names xy" query, and sets 
the corresponding character set.


------------------------+
 include/CarobMySQL.hpp |    5 ++--
 include/Utils.hpp      |   12 +++++++++++
 src/CarobMySQL.cpp     |   50 ++++++++++++++++++++++++++++++++++-------------
 src/Utils.cpp          |   28 ++++++++++++++++++++++++++
 4 files changed, 80 insertions(+), 15 deletions(-)


Index: libmysequoia/include/CarobMySQL.hpp
diff -u libmysequoia/include/CarobMySQL.hpp:1.30 
libmysequoia/include/CarobMySQL.hpp:1.31
--- libmysequoia/include/CarobMySQL.hpp:1.30    Tue Mar  7 14:46:58 2006
+++ libmysequoia/include/CarobMySQL.hpp Fri Mar 24 10:02:40 2006
@@ -104,10 +104,11 @@
      * returns an error. If a query was n
      * @param query the sql query to be executed, can contain null characters
      * @param length the length of the query parameter
+     * @param parse set to true if the query need to be parsed
      * @return true if the query was executed otherwise false and set the
      *                  corresponding mysql error
      */
-  bool real_query (const char *query, ulong length);
+  bool real_query (const char *query, ulong length, bool parse = true);
 
     /**
      * Gets the result of the query in MYSQL_RES format, and set the 
correspondent
@@ -209,7 +210,7 @@
   /**
    * Set the character set for the connection
    */
-  int set_character_set(const char *name);
+  int set_character_set(const char *name, bool runquery = true);
   
   /**
    * Creates a prepared statement
Index: libmysequoia/include/Utils.hpp
diff -u libmysequoia/include/Utils.hpp:1.19 libmysequoia/include/Utils.hpp:1.20
--- libmysequoia/include/Utils.hpp:1.19 Fri Mar  3 10:57:48 2006
+++ libmysequoia/include/Utils.hpp      Fri Mar 24 10:02:40 2006
@@ -38,6 +38,8 @@
 #define FREE_AND_NULL(p) {delete (p); (p)=0;}
 #define FREE_AND_NULL_ARRAY(p) {delete[] (p); (p)=0;}
 
+#define MAX_CHARSET_LEN 40
+
 /**
  * Creates a duplicate of a null terminated string and return the pointer to 
it.
  * @param src pointer to the source string
@@ -123,4 +125,14 @@
  */
 bool str_to_MYSQL_TIME(const char *s, MYSQL_TIME *t);
 
+/**
+ * compare the given strings ignore the leading whitespace and case
+ */
+bool string_match(const char *&src, const char *dst);
+
+/**
+ * get the next string (token) ignoring leading whitespace
+ */
+const char *get_next_string(const char *&src);
+
 #endif /* _UTILS_HPP */
Index: libmysequoia/src/CarobMySQL.cpp
diff -u libmysequoia/src/CarobMySQL.cpp:1.64 
libmysequoia/src/CarobMySQL.cpp:1.65
--- libmysequoia/src/CarobMySQL.cpp:1.64        Fri Mar 10 13:37:00 2006
+++ libmysequoia/src/CarobMySQL.cpp     Fri Mar 24 10:02:40 2006
@@ -273,7 +273,7 @@
 }
 
 bool
-CarobMYSQL::real_query (const char *query, ulong length)
+CarobMYSQL::real_query (const char *query, ulong length, bool parse)
 {
   LOG4CXX_DEBUG(logger, "Entering real_query: query=" << query << " length=" 
<< length);
 
@@ -317,6 +317,18 @@
       info[sizeof(info)-1] = 0;
       mysqlPtr->info = cstrdup(info);
       LOG4CXX_INFO(logger, "Executed query. Affected_rows=" << 
mysqlPtr->affected_rows);
+      
+      //if there are no affected rows, the query need to be parsed, to see if 
not a "set names ..." type
+      if (parse && mysqlPtr->affected_rows == 0)
+      {
+        const char *p = query, *q = 0;
+        if (string_match(p, "set") && string_match(p, "names") && (q = 
get_next_string(p)) && (p - q < MAX_CHARSET_LEN))
+        {
+          char charset[MAX_CHARSET_LEN+1];
+          strncpy(charset,q,p-q); charset[p-q]=0;
+          set_character_set(charset, false);
+        }
+      }
     }
 
     reset_error();
@@ -674,7 +686,7 @@
 
   if (wild)
     query = query + " LIKE '"+wild+"'";
-  if (real_query(query.c_str(),query.length()))
+  if (real_query(query.c_str(),query.length()),false)
     result = get_results(true);
   else
     result = 0;
@@ -693,7 +705,7 @@
   std::string query="SHOW DATABASES";
   if (wild)
     query = query + " LIKE '"+wild+"'";
-  if (real_query(query.c_str(),query.length()))
+  if (real_query(query.c_str(),query.length()),false)
     result = get_results(true);
   else
     result = 0;
@@ -712,7 +724,7 @@
   std::string query="SHOW TABLES";
   if (wild)
     query = query + "LIKE '"+wild+"'";
-  if (real_query(query.c_str(),query.length()))
+  if (real_query(query.c_str(),query.length()),false)
     result = get_results(true);
   else
     result = 0;
@@ -731,22 +743,34 @@
 }
 
 int
-CarobMYSQL::set_character_set(const char *name)
+CarobMYSQL::set_character_set(const char *name, bool runquery)
 {
   LOG4CXX_DEBUG(logger, "Entering set_character_set: name=" << name);
   
-  bool result = false;
-  char buff[254];
+  bool result = true;
   
-  snprintf(buff, sizeof(buff), "SET NAMES %s", name);
-  if ((result=real_query(buff, strlen(buff)) && conv.set_code(name)))
+  if (runquery)
   {
-    cstrdupcond(mysqlPtr->options.charset_name, name);
+    char buff[254];
+  
+    snprintf(buff, sizeof(buff), "SET NAMES %s", name);
+    result=real_query(buff, strlen(buff), false);
   }
-  else
-  {
+  
+  if (result)
+    try
+    {
+      result = conv.set_code(name);
+    }
+    catch (ConverterException &ex)
+    {
+      result=false;
+    }
+
+  if (!result)
     set_error(CR_CANT_READ_CHARSET, SQLT_UNKNOWN);
-  }
+  else
+    reset_error();
 
   LOG4CXX_DEBUG(logger, "Leaving set_character_set: result=" << result);
   return result == true ? 0 : 1;  
Index: libmysequoia/src/Utils.cpp
diff -u libmysequoia/src/Utils.cpp:1.35 libmysequoia/src/Utils.cpp:1.36
--- libmysequoia/src/Utils.cpp:1.35     Fri Mar  3 10:57:48 2006
+++ libmysequoia/src/Utils.cpp  Fri Mar 24 10:02:40 2006
@@ -36,6 +36,7 @@
 #include <cmath>
 #include <ctime>
 #include <sstream>
+#include <ctype.h>
 
 using namespace CarobNS;
 using namespace std;
@@ -1218,3 +1219,30 @@
   
   return result;
 }
+
+bool string_match(const char *&src, const char *dst)
+{
+  if (src)
+  {
+    while (isspace(*src)) src++;
+    int len=strlen(dst);
+    bool result = strncasecmp(src,dst,len) == 0;
+    if (result) src+=len;
+    return result;
+  }
+  else
+    return false;
+}
+
+const char *get_next_string(const char *&src)
+{
+  if (src)
+  {
+    while (isspace(*src)) src++;
+    const char *result = src;
+    while (*src && !isspace(*src)) src++;
+    return result;
+  }
+  else  
+    return 0;
+}

_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits

Reply via email to