Date: Monday, November 28, 2005 @ 10:20:40
  Author: csaba
    Path: /cvsroot/carob/libmysequoia

   Added: config/controller/controller-mysql.xml (1.1) config/mysql.sh
          (1.1) config/virtualdatabase/mysql.xml (1.1) src/Makefile (1.1)
          src/hello-libmysequoia.c (1.1) src/libmysequoia.cpp (1.1)

Added the first working prototype and te configuration files.


----------------------------------------+
 config/controller/controller-mysql.xml |   11 
 config/mysql.sh                        |   14 
 config/virtualdatabase/mysql.xml       |   59 ++++
 src/Makefile                           |   17 +
 src/hello-libmysequoia.c               |  130 ++++++++
 src/libmysequoia.cpp                   |  451 +++++++++++++++++++++++++++++++
 6 files changed, 682 insertions(+)


Index: libmysequoia/config/controller/controller-mysql.xml
diff -u /dev/null libmysequoia/config/controller/controller-mysql.xml:1.1
--- /dev/null   Mon Nov 28 10:20:40 2005
+++ libmysequoia/config/controller/controller-mysql.xml Mon Nov 28 10:20:40 2005
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE SEQUOIA-CONTROLLER PUBLIC "-//Continuent//DTD SEQUOIA-CONTROLLER 
2.3//EN"  "http://sequoia.continuent.org/dtds/sequoia-controller-2.3.dtd";>
+<SEQUOIA-CONTROLLER>
+  <Controller port="25322">
+    <Report/>
+    <JmxSettings>
+      <RmiJmxAdaptor/>
+    </JmxSettings>
+    <VirtualDatabase configFile="mysql.xml" virtualDatabaseName="db" 
autoEnableBackends="force"/>
+  </Controller>
+</SEQUOIA-CONTROLLER>
Index: libmysequoia/config/mysql.sh
diff -u /dev/null libmysequoia/config/mysql.sh:1.1
--- /dev/null   Mon Nov 28 10:20:40 2005
+++ libmysequoia/config/mysql.sh        Mon Nov 28 10:20:40 2005
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+SEQUOIA_HOME=/home/secsaba/software/sequoia
+
+cd $SEQUOIA_HOME/bin
+
+sudo /etc/init.d/mysql start
+sleep 5
+
+echo "Starting hsqldb on port 9003 (recovery)"
+./hsqldb.sh -port 9003 &
+
+echo "Starting Controller with MySQL Configuration"
+./controller.sh -f ../config/controller/controller-mysql.xml &
Index: libmysequoia/config/virtualdatabase/mysql.xml
diff -u /dev/null libmysequoia/config/virtualdatabase/mysql.xml:1.1
--- /dev/null   Mon Nov 28 10:20:40 2005
+++ libmysequoia/config/virtualdatabase/mysql.xml       Mon Nov 28 10:20:40 2005
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF8"?>
+<!DOCTYPE SEQUOIA PUBLIC "-//Continuent//DTD SEQUOIA 2.3//EN" 
"http://sequoia.continuent.org/dtds/sequoia-2.3.dtd";>
+
+<SEQUOIA>
+
+  <VirtualDatabase name="db">
+
+    <AuthenticationManager>
+      <Admin>
+               <User username="admin" password="adminpass"/>
+      </Admin> 
+      <VirtualUsers>
+        <VirtualLogin vLogin="user" vPassword="userpass"/>
+      </VirtualUsers>
+    </AuthenticationManager>
+
+    <DatabaseBackend name="csaba" driver="com.mysql.jdbc.Driver" 
url="jdbc:mysql://localhost/test" connectionTestStatement="select 1">
+      <ConnectionManager vLogin="user" rLogin="root" rPassword="rootpass">
+        <VariablePoolConnectionManager initPoolSize="10" minPoolSize="5" 
maxPoolSize="50" idleTimeout="30" waitTimeout="10"/>
+      </ConnectionManager>
+    </DatabaseBackend>
+
+    <RequestManager>
+      <RequestScheduler>
+         <RAIDb-1Scheduler level="passThrough"/>
+      </RequestScheduler>
+
+      <LoadBalancer>
+         <RAIDb-1>
+            <WaitForCompletion policy="first"/>
+            <RAIDb-1-LeastPendingRequestsFirst/>
+         </RAIDb-1>
+      </LoadBalancer>
+
+      <RecoveryLog driver="org.hsqldb.jdbcDriver"
+        url="jdbc:hsqldb:hsql://localhost:9003" login="TEST" password="">
+        <RecoveryLogTable tableName="RECOVERY" idColumnType="BIGINT NOT NULL"
+          vloginColumnType="VARCHAR NOT NULL" sqlColumnType="VARCHAR NOT NULL"
+          extraStatementDefinition=",PRIMARY KEY (id)"/>
+        <CheckpointTable tableName="CHECKPOINT"
+          checkpointNameColumnType="VARCHAR NOT NULL"/>
+        <BackendTable tableName="BACKEND"
+          databaseNameColumnType="VARCHAR NOT NULL"
+          backendNameColumnType="VARCHAR NOT NULL"
+          checkpointNameColumnType="VARCHAR NOT NULL"/>
+        <DumpTable tableName="DUMP" dumpNameColumnType="VARCHAR NOT NULL"
+          dumpDateColumnType="VARCHAR NOT NULL"
+          dumpPathColumnType="VARCHAR NOT NULL"
+          dumpFormatColumnType="VARCHAR NOT NULL"
+          checkpointNameColumnType="VARCHAR NOT NULL"
+          backendNameColumnType="VARCHAR NOT NULL"
+          tablesColumnType="VARCHAR NOT NULL"/>
+      </RecoveryLog>
+
+    </RequestManager>
+
+  </VirtualDatabase>
+
+</SEQUOIA>
Index: libmysequoia/src/Makefile
diff -u /dev/null libmysequoia/src/Makefile:1.1
--- /dev/null   Mon Nov 28 10:20:40 2005
+++ libmysequoia/src/Makefile   Mon Nov 28 10:20:40 2005
@@ -0,0 +1,17 @@
+all: hello-libmysequoia libmysqlclient.so.15.1
+
+hello-libmysequoia: hello-libmysequoia.c
+       cc -Wall -g `mysql_config --include` -o $@ $< `mysql_config --libs`
+
+libmysqlclient.so.15.1: libmysql.o
+       c++ -Wall -g -fPIC --shared -L../carob -lcarobcpp -o $@ $<
+       ln -sf $@ libmysqlclient.so.15
+
+libmysql.o: libmysequoia.cpp
+       c++ -Wall -g -o $@ -I../carob/include -I/usr/include/mysql -c $<
+
+clean:
+       rm -f libmysqlclient.so.15.1 libmysqlclient.so.15 libmysql.o 
hello-libmysequoia
+
+run: all
+       LD_LIBRARY_PATH=.:../carob ./hello-libmysequoia
Index: libmysequoia/src/hello-libmysequoia.c
diff -u /dev/null libmysequoia/src/hello-libmysequoia.c:1.1
--- /dev/null   Mon Nov 28 10:20:40 2005
+++ libmysequoia/src/hello-libmysequoia.c       Mon Nov 28 10:20:40 2005
@@ -0,0 +1,130 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <mysql.h>
+
+/*
+ * To create the table and insert some data:
+ * $ mysql -uroot -prootpass
+ * > USE test;
+ * > CREATE table t1 ( `a` int(11) NOT NULL auto_increment,
+ *                    `b` int(11) default NULL,
+ *                     PRIMARY KEY  (`a`)
+ *                  ) ENGINE=InnoDB; 
+ * > INSERT INTO t1 (b) VALUES (1),(2),(3)
+ * > exit
+ */
+
+static void
+print_error (MYSQL * conn, char *message)
+{
+  fprintf (stderr, "%s\n", message);
+  if (conn != NULL)
+    {
+      fprintf (stderr, "Error %u (%s): %s\n",
+              mysql_errno (conn), mysql_sqlstate (conn), mysql_error (conn));
+    }
+}
+
+
+void
+process_result_set (MYSQL * conn, MYSQL_RES * res_set)
+{
+  MYSQL_ROW row;
+  unsigned int i;
+
+  while ((row = mysql_fetch_row (res_set)) != NULL)
+    {
+      for (i = 0; i < mysql_num_fields (res_set); i++)
+       {
+         if (i > 0)
+           {
+             fputc ('\t', stdout);
+           }
+         printf ("%s", row[i] != NULL ? row[i] : "NULL");
+       }
+      fputc ('\n', stdout);
+    }
+  if (mysql_errno (conn) != 0)
+    print_error (conn, "mysql_fetch_row() failed");
+  else
+    printf ("%lu rows returned\n", (unsigned long) mysql_num_rows (res_set));
+}
+
+
+int
+main ()
+{
+  char *opt_host_name = "localhost";   /* server host (default=localhost) */
+  char *opt_user_name = "user";        /* username (default=login name) */
+  char *opt_password = "userpass";     /* password (default=none) */
+  unsigned int opt_port_num = 0;       /* port number (use built-in value) */
+  char *opt_socket_name = NULL;        /* socket name (use built-in value) */
+  char *opt_db_name = "db";    /* database name (default=none) */
+  unsigned int opt_flags = 0;  /* connection flags (none) */
+  MYSQL *conn;                 /* pointer to connection handler */
+  MYSQL_RES *res_set;
+
+  /* initialize connection handler */
+  conn = mysql_init (NULL);
+  if (conn == NULL)
+    {
+      fprintf (stderr, "mysql_init() failed (probably out of memory)\n");
+      exit (1);
+    }
+
+  /* connect to server */
+  if (mysql_real_connect (conn, opt_host_name, opt_user_name, opt_password,
+                         opt_db_name, opt_port_num, opt_socket_name,
+                         opt_flags) == NULL)
+    {
+      fprintf (stderr, "mysql_real_connect() failed\n");
+      mysql_close (conn);
+      exit (1);
+    }
+
+  /* the insert must succed */
+  if (mysql_query (conn, "INSERT INTO t1(b) VALUES (4)") != 0)
+    {
+      print_error (conn, "INSERT statement failed");
+    }
+  else
+    {
+      printf ("INSERT statement succeeded: %lu rows affected\n",
+             (unsigned long) mysql_affected_rows (conn));
+    }
+
+  /* the insert must fail (duplicate key) */
+/*  if (mysql_query (conn, "INSERT INTO t1 (a,b) VALUES (1,2)") != 0)
+    {
+      print_error (conn, "INSERT statement failed");
+    }
+  else
+    {
+      printf ("INSERT statement succeeded: %lu rows affected\n",
+             (unsigned long) mysql_affected_rows (conn));
+    }*/
+
+  /* simple query */
+  if (mysql_query (conn, "SELECT * from t1") != 0)
+    print_error (conn, "mysql_query() failed");
+  else
+    {
+      res_set = mysql_store_result (conn);     /* generate result set */
+      if (res_set == NULL)
+       print_error (conn, "mysql_store_result() failed");
+      else
+       {
+         /* process result set, and then deallocate it */
+         process_result_set (conn, res_set);
+//       mysql_free_result (res_set);
+       }
+    }
+
+  /* disconnect from server */
+  mysql_close (conn);
+
+  return 0;
+}
Index: libmysequoia/src/libmysequoia.cpp
diff -u /dev/null libmysequoia/src/libmysequoia.cpp:1.1
--- /dev/null   Mon Nov 28 10:20:40 2005
+++ libmysequoia/src/libmysequoia.cpp   Mon Nov 28 10:20:40 2005
@@ -0,0 +1,451 @@
+/**
+ * Sequoia: Database clustering technology.
+ * Copyright (C) 2005 Emic Networks
+ * Contact: [EMAIL PROTECTED]
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Initial developer(s): Zsolt Simon, Csaba Simon
+ * Contributor(s): 
+ */
+ 
+ /**
+  * This is only a first prototype that is demonstrating that 
+  * the libmysequoia project is doable.
+  * There is no error checking nor exception handling and no
+  * comment on the code.
+  */
+  
+/* C includes */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* MySQL includes */
+#include <my_global.h>
+#include <my_sys.h>
+#include <mysql.h>
+#include <errmsg.h>
+
+/* Carob includes */
+#include <ConnectionParameters.hpp>
+#include <ConnectionPool.hpp>
+#include <DriverResultSet.hpp>
+#include <Statement.hpp>
+
+/* C++ includes */
+#include <string>
+#include <vector>
+#include <locale>
+
+void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate);
+
+const char *client_errors[]=
+{
+  "Unknown MySQL error",
+  "Can't create UNIX socket (%d)",
+  "Can't connect to local MySQL server through socket '%-.100s' (%d)",
+  "Can't connect to MySQL server on '%-.100s' (%d)",
+  "Can't create TCP/IP socket (%d)",
+  "Unknown MySQL server host '%-.100s' (%d)",
+  "MySQL server has gone away",
+  "Protocol mismatch; server version = %d, client version = %d",
+  "MySQL client ran out of memory",
+  "Wrong host info",
+  "Localhost via UNIX socket",
+  "%-.100s via TCP/IP",
+  "Error in server handshake",
+  "Lost connection to MySQL server during query",
+  "Commands out of sync; you can't run this command now",
+  "Named pipe: %-.32s",
+  "Can't wait for named pipe to host: %-.64s  pipe: %-.32s (%lu)",
+  "Can't open named pipe to host: %-.64s  pipe: %-.32s (%lu)",
+  "Can't set state of named pipe to host: %-.64s  pipe: %-.32s (%lu)",
+  "Can't initialize character set %-.32s (path: %-.100s)",
+  "Got packet bigger than 'max_allowed_packet' bytes",
+  "Embedded server",
+  "Error on SHOW SLAVE STATUS:",
+  "Error on SHOW SLAVE HOSTS:",
+  "Error connecting to slave:",
+  "Error connecting to master:",
+  "SSL connection error",
+  "Malformed packet",
+  "This client library is licensed only for use with MySQL servers having '%s' 
license",
+  "Invalid use of null pointer",
+  "Statement not prepared",
+  "No data supplied for parameters in prepared statement",
+  "Data truncated",
+  "No parameters exist in the statement",
+  "Invalid parameter number",
+  "Can't send long data for non-string/non-binary data types (parameter: %d)",
+  "Using unsupported buffer type: %d  (parameter: %d)",
+  "Shared memory: %-.100s",
+  "Can't open shared memory; client could not create request event (%lu)",
+  "Can't open shared memory; no answer event received from server (%lu)",
+  "Can't open shared memory; server could not allocate file mapping (%lu)",
+  "Can't open shared memory; server could not get pointer to file mapping 
(%lu)",
+  "Can't open shared memory; client could not allocate file mapping (%lu)",
+  "Can't open shared memory; client could not get pointer to file mapping 
(%lu)",
+  "Can't open shared memory; client could not create %s event (%lu)",
+  "Can't open shared memory; no answer from server (%lu)",
+  "Can't open shared memory; cannot send request event to server (%lu)",
+  "Wrong or unknown protocol",
+  "Invalid connection handle",
+  "Connection using old (pre-4.1.1) authentication protocol refused (client 
option 'secure_auth' enabled)",
+  "Row retrieval was canceled by mysql_stmt_close() call",
+  "Attempt to read column without prior row fetch",
+  "Prepared statement contains no metadata",
+  "Attempt to read a row while there is no result set associated with the 
statement",
+  "This feature is not implemented yet",
+  ""
+};
+
+const char *unknown_sqlstate= "HY000";
+const char *not_error_sqlstate= "00000";
+
+class CarobMYSQL;
+
+typedef struct st_cmysql {
+       MYSQL my;
+       CarobMYSQL *carob;
+} CMYSQL;
+
+class CarobMYSQL
+{
+public:
+       CarobMYSQL();
+       ~CarobMYSQL();
+
+       bool connect(const char *host, const char *user,
+                   const char *passwd, const char *db, unsigned int port,
+                   const char *unix_socket, unsigned long clientflag);
+       bool real_query(const char *query, ulong length);
+       MYSQL_RES *get_results(int size);
+       MYSQL_ROW fetch_row();
+       
+       MYSQL *getMYSQL();
+
+private:
+       CMYSQL *mysqlPtr;
+       Connection *connectionPtr;
+       ConnectionPool *connectionPool;
+       Statement *stmtPtr;
+       DriverResultSet* drsPtr;
+       MYSQL_ROW row;
+       int nfields;
+       
+       void allocRow(int no);
+       void deleteRow();
+};
+
+CarobMYSQL::CarobMYSQL() : connectionPtr(NULL), stmtPtr(NULL), drsPtr(NULL)
+{
+       mysqlPtr = new CMYSQL();
+       memset(&mysqlPtr->my, 0, sizeof(MYSQL));
+       mysqlPtr->carob = this;
+       connectionPool = &ConnectionPool::getInstance();
+}
+
+CarobMYSQL::~CarobMYSQL()
+{
+       delete mysqlPtr;
+       if (connectionPtr) delete connectionPtr;
+       if (stmtPtr) delete stmtPtr;
+//     if (drsPtr) delete drsPtr;
+       deleteRow();
+}
+
+bool CarobMYSQL::connect(const char *host, const char *user,
+    const char *passwd, const char *db, unsigned int port,
+    const char *unix_socket, unsigned long clientflag)
+{
+       if (unix_socket)
+       {
+               set_mysql_error((MYSQL *)mysqlPtr, CR_NOT_IMPLEMENTED, 
unknown_sqlstate);
+               return false;
+       }
+       
+//TODO Fill the mysqlPtr structure
+       ConnectionParameters connectionParameters(toWString(host), port ? port 
: 25322, toWString(db), toWString(user), toWString(passwd), DEBUG_LEVEL_DEBUG);
+
+       try {
+               connectionPtr = 
connectionPool->connectToController(connectionParameters);
+               stmtPtr = connectionPtr->createStatement();
+       } catch (...) {
+               set_mysql_error((MYSQL *)mysqlPtr, CR_CONNECTION_ERROR, 
unknown_sqlstate);
+               return false;
+       }
+       
+       return true;
+}
+
+bool CarobMYSQL::real_query(const char *query, ulong length)
+{
+       try {
+               if (drsPtr) delete drsPtr;
+
+               if (stmtPtr->execute(toWString(query)))
+                       mysqlPtr->my.affected_rows = 0;
+               else
+                       mysqlPtr->my.affected_rows = stmtPtr->getUpdateCount();
+               
+               return true;
+       } catch (...) {
+               //TODO Error  : connectionPtr(NULL), stmtPtr(NULL), 
drsPtr(NULL)handling
+               return false;
+       }
+}
+
+MYSQL_RES * CarobMYSQL::get_results(int size)
+{
+       try {
+               if (stmtPtr)
+               {
+                       stmtPtr->setFetchSize(size);
+                       drsPtr = stmtPtr->getResultSet();
+                       if (drsPtr)
+                       {
+                               mysqlPtr->my.field_count = 
drsPtr->getNumberOfColumns();
+                               mysqlPtr->my.affected_rows = 
drsPtr->getNumberOfRowsInMemory();
+                       }
+                       return (MYSQL_RES *) this;
+               }
+               return NULL;
+       } catch (...) {
+               //TODO error handling
+               return NULL;
+       }
+}
+
+MYSQL_ROW CarobMYSQL::fetch_row()
+{
+       if (drsPtr)
+       {
+               deleteRow();
+               if (drsPtr->next())
+               {
+                       allocRow(mysqlPtr->my.field_count);
+                       for (unsigned i=0; i<mysqlPtr->my.field_count; i++)
+                       {
+                               char s[200];
+                               int32_t *iPtr = drsPtr->getInt(i+1);
+                               if (iPtr) {
+                                       sprintf(s,"%d",*iPtr);
+                                       row[i] = new char[strlen(s)+1];
+                                       strcpy(row[i],s);
+                               }
+                       }
+                       
+                       mysqlPtr->my.affected_rows = 
drsPtr->getNumberOfRowsInMemory();
+                       
+                       return row;
+               }
+               return 0;
+       }
+       else
+               return 0;
+}
+
+MYSQL *CarobMYSQL::getMYSQL()
+{
+       return (MYSQL *) mysqlPtr;
+}
+
+typedef char *PCHAR;
+
+void CarobMYSQL::allocRow(int no)
+{
+       row = new PCHAR[no];
+       nfields = no;
+       memset(row, sizeof(PCHAR)*no, 0);
+}
+
+void CarobMYSQL::deleteRow()
+{
+       if (row)
+       {
+               for (int i=0; i<nfields; i++)
+                       if (row[i])     delete row[i];
+               delete row;
+               row = NULL;
+       }
+}
+
+/***********************************
+ * MySQL functions
+ ***********************************/
+ 
+MYSQL *STDCALL
+mysql_init(MYSQL * mysql)
+{
+       if (!mysql)
+       {
+               CarobMYSQL *tmp = new CarobMYSQL();
+               mysql = tmp->getMYSQL();
+       }
+       
+       return mysql;
+}
+
+MYSQL *STDCALL
+mysql_real_connect (MYSQL * mysql, const char *host, const char *user,
+                   const char *passwd, const char *db, unsigned int port,
+                   const char *unix_socket, unsigned long clientflag)
+{
+       if (mysql) {
+               return ((CMYSQL *)mysql)->carob->connect(host, user, passwd, 
db, port, unix_socket, clientflag) ? mysql : 0;
+       }
+       else
+       {
+               set_mysql_error(mysql, CR_NULL_POINTER, unknown_sqlstate);
+               return 0;
+       }
+}
+
+void STDCALL
+mysql_close (MYSQL *sock)
+{
+       if (sock)
+               delete ((CMYSQL *)sock)->carob;
+}
+
+/* error handling functions */
+void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate)
+{
+  NET *net;
+
+  net= &mysql->net;
+  net->last_errno= errcode;
+  strcpy(net->last_error, ER(errcode));
+  strcpy(net->sqlstate, sqlstate);
+}
+
+unsigned int STDCALL
+mysql_errno(MYSQL *mysql)
+{
+       return mysql->net.last_errno;
+}
+
+const char * STDCALL
+mysql_error(MYSQL *mysql)
+{
+       return mysql->net.last_error;
+}
+
+const char *STDCALL
+mysql_sqlstate(MYSQL *mysql)
+{
+       return mysql->net.sqlstate;
+}
+
+int STDCALL
+mysql_query(MYSQL *mysql, const char *q)
+{
+       return mysql_real_query(mysql, q, 0);
+}
+
+int STDCALL
+mysql_real_query(MYSQL *mysql, const char *query, ulong length)
+{
+       if (mysql) {
+               //FIXME handle special strings which can contains '\0'
+               if ( ((CMYSQL *)mysql)->carob->real_query(query, length) )
+               {
+                       return 0;
+               }
+               else
+               {
+                       set_mysql_error(mysql, CR_UNKNOWN_ERROR, 
unknown_sqlstate);
+                       return CR_UNKNOWN_ERROR;
+               }
+       }
+       else
+       {
+               set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+               return CR_UNKNOWN_ERROR;
+       }
+}
+
+MYSQL_RES * STDCALL
+mysql_store_result(MYSQL *mysql)
+{
+       if (mysql) {
+               return ((CMYSQL *)mysql)->carob->get_results(0);
+       }
+       else
+       {
+               set_mysql_error(mysql, CR_NULL_POINTER, unknown_sqlstate);
+               return 0;
+       }
+}
+
+MYSQL_RES * STDCALL
+mysql_use_result(MYSQL *mysql)
+{
+       if (mysql) {
+               return ((CMYSQL *)mysql)->carob->get_results(1);
+       }
+       else
+       {
+               set_mysql_error(mysql, CR_NULL_POINTER, unknown_sqlstate);
+               return 0;
+       }
+}
+
+MYSQL_ROW      STDCALL mysql_fetch_row(MYSQL_RES *result)
+{
+       if (result) {
+               return ((CarobMYSQL *)result)->fetch_row();
+       }
+       else
+       {
+               //TODO set error
+               return 0;
+       }
+}
+
+unsigned int STDCALL mysql_num_fields(MYSQL_RES *res)
+{
+       if (res) {
+               return ((CarobMYSQL *)res)->getMYSQL()->field_count; // 
get_num_fields();
+       }
+       else
+       {
+               //TODO set error
+               return 0;
+       }
+}
+
+my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql)
+{
+       if (mysql) {
+               return mysql->affected_rows; 
+       }
+       else
+       {
+               //TODO set error
+               return 0;
+       }
+}
+
+my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res)
+{
+       if (res) {
+               return ((CarobMYSQL *)res)->getMYSQL()->affected_rows;
+       }
+       else
+       {
+               //TODO set error
+               return 0;
+       }
+}

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

Reply via email to