Date: Wednesday, November 30, 2005 @ 10:18:22
  Author: gilles
    Path: /cvsroot/carob/carob

Modified: contrib/PHP/sample_carob_request.cpp (1.4 -> 1.5)
          contrib/PHP/test_carob_read.php (1.1 -> 1.2)
          include/BigDecimal.hpp (1.4 -> 1.5) include/DriverResultSet.hpp
          (1.11 -> 1.12) include/SQLDataSerialization.hpp (1.3 -> 1.4)
          src/BigDecimal.cpp (1.6 -> 1.7) src/DriverResultSet.cpp (1.9 ->
          1.10) src/SQLDataSerialization.cpp (1.7 -> 1.8)
          test/TestExecReadRequest.cpp (1.10 -> 1.11)
          test/TestStatement.cpp (1.7 -> 1.8)

ResultSet refactoring:
. Added toString() implementation for all types (that are currently supported 
by serialization)
. Changed ResultSet data storage implementation: instead of using void* for all 
data-types,
a union ResultSetDataType has been introduced to store basic types (int, float, 
...)
Complex types are still using void* but inside this union.
Implications:
  - columnTypeTags vector has been introduced to store the data-types of the 
columns
  - deserializers now return the union instead of void*
  - creation of a 'null values matrix' to store null values (we can't return 
NULL anymore)
  - introduction of isNull(int) and wasNull() functions
  - getXXX (for now getString and getInt) now return values instead of pointers
  - all tests and contribs have been modified to take the getXXX change into 
account


--------------------------------------+
 contrib/PHP/sample_carob_request.cpp |   13 --
 contrib/PHP/test_carob_read.php      |    2 
 include/BigDecimal.hpp               |    5 
 include/DriverResultSet.hpp          |   48 ++++++-
 include/SQLDataSerialization.hpp     |   23 +++
 src/BigDecimal.cpp                   |   10 -
 src/DriverResultSet.cpp              |  205 ++++++++++++++-------------------
 src/SQLDataSerialization.cpp         |  130 +++++++-------------
 test/TestExecReadRequest.cpp         |    7 -
 test/TestStatement.cpp               |   14 --
 10 files changed, 223 insertions(+), 234 deletions(-)


Index: carob/contrib/PHP/sample_carob_request.cpp
diff -u carob/contrib/PHP/sample_carob_request.cpp:1.4 
carob/contrib/PHP/sample_carob_request.cpp:1.5
--- carob/contrib/PHP/sample_carob_request.cpp:1.4      Wed Nov 23 15:16:36 2005
+++ carob/contrib/PHP/sample_carob_request.cpp  Wed Nov 30 10:18:22 2005
@@ -130,7 +130,8 @@
     connectionPtr = connectionPool.connectToController(connectionPrms);
 
     // Create request object
-    RequestWithResultSetParameters readReq(wreq, true, L"", false, 2);
+    RequestWithResultSetParameters readReq(wreq);
+    readReq.setEscapeProcessing(false).setTimeoutInSeconds(2);
        
     // efree(req); // segfaults
 
@@ -149,16 +150,14 @@
       //      for (int i=0; i<5; i++) // TODO: put a while loop in here
     {
       i++;
-      int32_t* iPtr = drsPtr->getInt(1);
-      wstring* wsPtr = drsPtr->getString(2);
-      wstring* ws2Ptr = drsPtr->getString(3);
-    
+
       std::wostringstream wide_oss;
     
 #define WTABBING L"<TD>"
 
-      wide_oss << L"<TR>" << WTABBING << i << WTABBING << *iPtr << WTABBING
-               << *wsPtr << WTABBING << *ws2Ptr << endl;
+      wide_oss << L"<TR>" << WTABBING << i << WTABBING << drsPtr->getInt(1)
+                          << WTABBING << drsPtr->getString(2)
+                          << WTABBING << drsPtr->getString(3) << endl;
 
       std::string narrow_row;
       ws2s(wide_oss.str().c_str(), narrow_row);
Index: carob/contrib/PHP/test_carob_read.php
diff -u carob/contrib/PHP/test_carob_read.php:1.1 
carob/contrib/PHP/test_carob_read.php:1.2
--- carob/contrib/PHP/test_carob_read.php:1.1   Wed Oct 26 01:05:39 2005
+++ carob/contrib/PHP/test_carob_read.php       Wed Nov 30 10:18:22 2005
@@ -7,7 +7,7 @@
 <?php
 
 
- $ret = carob_read("select * from product where ID<11;");
+ $ret = carob_read("select * from address where ID<11;");
 
  // echo "returned value is: $ret\n";
 ?>
Index: carob/include/BigDecimal.hpp
diff -u carob/include/BigDecimal.hpp:1.4 carob/include/BigDecimal.hpp:1.5
--- carob/include/BigDecimal.hpp:1.4    Thu Nov  3 15:29:02 2005
+++ carob/include/BigDecimal.hpp        Wed Nov 30 10:18:22 2005
@@ -24,6 +24,7 @@
 
 #include "Common.hpp"
 #include "DriverSocket.hpp"
+#include "SQLDataSerialization.hpp"
 
 /**
  * Java math.BigDecimal equivalent class for storing immutable, 
@@ -57,8 +58,8 @@
    * @return pointer to BigDecimal as a void*
    * @throws SocketIOException if an error occurs on the stream
    */
-  static void* deserializer(const DriverSocket& input) throw 
(SocketIOException,
-      UnexpectedException);
+  static ResultSetDataType deserializer(const DriverSocket& input)
+      throw (SocketIOException, UnexpectedException);
   /**
    * Convertion to string. Handy for displaying the number
    * FIXME: This is dummy code for now (testing state), correct it
Index: carob/include/DriverResultSet.hpp
diff -u carob/include/DriverResultSet.hpp:1.11 
carob/include/DriverResultSet.hpp:1.12
--- carob/include/DriverResultSet.hpp:1.11      Mon Nov 28 13:55:24 2005
+++ carob/include/DriverResultSet.hpp   Wed Nov 30 10:18:22 2005
@@ -138,7 +138,7 @@
    * @return the column value, null for SQL NULL
    * @throw SQLException if a database access error occurs
    */
-  wstring*                    getString(int32_t columnIndex) throw 
(SQLException,
+  wstring                     getString(int32_t columnIndex) throw 
(SQLException,
                                   UnexpectedException);
   /**
    * Get the value of a column in the current row as an int.
@@ -147,7 +147,7 @@
    * @return the column value; NULL if SQL NULL
    * @throw SQLException if a database access error occurs
    */
-  int32_t*                    getInt(int32_t columnIndex) throw (SQLException,
+  int32_t                     getInt(int32_t columnIndex) throw (SQLException,
                                   UnexpectedException);
   /**
    * Closes the remote ResultSet if the ResultSet was streamed else just closes
@@ -169,6 +169,29 @@
     * @return number of rows fetched until now
     */
     int32_t                   getNumberOfRowsInMemory() { return nbOfRows; }
+    /**
+     * A column may have the value of SQL NULL; wasNull() reports whether the
+     * last column read had this special value.
+     * Note that you must first call getXXX on a column to try to read its 
value
+     * and then call wasNull() to find if the value was SQL NULL
+     * If you need to know if a value is NULL beforehand, use isNull(int32_t)
+     * 
+     * @return <code>true</code> if the last column read was SQL NULL
+     * @see #isNull(int32_t)
+     */
+    bool                      wasNull() const { return wasNullFlag; }
+    /**
+     * A column may have the value of SQL NULL; isNull(int32_t) reports whether
+     * the value at the given column and current row is NULL.
+     * 
+     * @param columnIndex the first column is 1, the second is 2,...
+     * @return <code>true</code> if the current row's value for the given 
column
+     *         is SQL NULL
+     * @exception SQLException if the ResultSet is closed or the cursor is out
+     *            of bounds
+     */
+    bool                      isNull(int32_t columnIndex) const
+                                  throw (SQLException, UnexpectedException);
 protected:
   /**
    * De-serialize only data rows, not any metadata.
@@ -192,9 +215,22 @@
    /** Number of columns */
   int32_t                     nbOfColumns;
   /** The results */
-  vector< vector<void*> >     data;
-  /** Indicates that no data has been read */
+  vector< vector<ResultSetDataType> >  data;
+  /** Indicates that no data has been read yet */
   bool                        dataIsNull;
+  /**
+   * Matrix for null results.
+   * Should be optimized with a bitfield array.
+   * bitfield class would be used as follows:
+   * if (bitfield[n])...
+   * and implemented like
+   * operator[] => switch (n%8) { case 0: return bit_struct.b0;
+   *                           ...case x: return bit_struct.bx;
+   * bit_struct would be: typedef struct { bool b0:1; bool b1:1; ...}
+   */
+  vector< vector<bool> >      nulls;
+  /** Type of columns as defined by the controller */
+  vector<TypeTag>             columnTypeTags;
   /** True if there is more data to fetch from the controller */
   bool                        hasMoreData;
   /** The fetch size */
@@ -229,13 +265,13 @@
    * Checks that the cursor is on row in the ResultSet
    * @throw SQLException if the cursor is out of bounds
    */
-  void                        checkRowPos() throw (SQLException,
+  void                        checkRowPos() const throw (SQLException,
                                   UnexpectedException);
   /**
    * Check if the ResultSet if closed and throws a SQLException if so.
    * @throw SQLException if the ResultSet is closed
    */
-  void                        checkIfClosed() throw (SQLException,
+  void                        checkIfClosed() const throw (SQLException,
                                   UnexpectedException);
   /**
    * Sanity checks for result parsing
Index: carob/include/SQLDataSerialization.hpp
diff -u carob/include/SQLDataSerialization.hpp:1.3 
carob/include/SQLDataSerialization.hpp:1.4
--- carob/include/SQLDataSerialization.hpp:1.3  Wed Sep 21 12:08:15 2005
+++ carob/include/SQLDataSerialization.hpp      Wed Nov 30 10:18:22 2005
@@ -26,8 +26,29 @@
 
 #include "TypeTag.hpp"
 
+/**
+ * Union to store ResultSets data
+ */
+union ResultSetDataType
+{
+  /** for booleans and bits */
+  bool    as_bool;
+  /** for bytes */
+  uint8_t as_byte;
+  /** for integers */
+  int32_t as_int;
+  /** for longs */
+  int64_t as_long;
+  /** for floats */
+  float   as_float;
+  /** for doubles */
+  double  as_double;
+  /** for all other types */
+  void*   as_other;
+};
+
 /** To ease and simplify deserialization function pointers declaration */
-typedef void* (*deserializerPtr)(const DriverSocket&);
+typedef ResultSetDataType (*deserializerPtr)(const DriverSocket&);
 
 /**
  * This class defines Serializers for SQL Data: one function
Index: carob/src/BigDecimal.cpp
diff -u carob/src/BigDecimal.cpp:1.6 carob/src/BigDecimal.cpp:1.7
--- carob/src/BigDecimal.cpp:1.6        Mon Nov  7 18:48:51 2005
+++ carob/src/BigDecimal.cpp    Wed Nov 30 10:18:22 2005
@@ -17,11 +17,11 @@
 }
 
 // TODO: why not a constructor here?
-void* BigDecimal::deserializer(const DriverSocket& input)
+ResultSetDataType BigDecimal::deserializer(const DriverSocket& input)
     throw (SocketIOException, UnexpectedException)
 {
   BigDecimal* retVal = new BigDecimal();
-
+  ResultSetDataType res;
   //1. Read intVal:
   //1.1 Read intValLength
   input>>retVal->byteArrayLength;
@@ -68,10 +68,8 @@
   input>>retVal->scale;
 
   
-//FIXME: TEMP !!! 
-  wstring* ps = new wstring((wstring)*retVal);
-  return ps;
-  //return retVal;
+  res.as_other = (void*)retVal;
+  return res;
 }
 
 int* BigDecimal::toIntArray(int& intArrayLength)
Index: carob/src/DriverResultSet.cpp
diff -u carob/src/DriverResultSet.cpp:1.9 carob/src/DriverResultSet.cpp:1.10
--- carob/src/DriverResultSet.cpp:1.9   Mon Nov 28 15:58:55 2005
+++ carob/src/DriverResultSet.cpp       Wed Nov 30 10:18:22 2005
@@ -58,6 +58,7 @@
   {
     fields.push_back(new Field(socket));
   }
+  columnTypeTags.reserve(nbOfColumns);
   TypeTag colTypes(socket);
   if (colTypes != TT_COL_TYPES)
   {
@@ -73,6 +74,7 @@
     {
       TypeTag tag(socket);
       deserializers.push_back(SQLDataSerialization::getDeserializer(tag));
+      columnTypeTags.push_back(tag);
     }
     receiveRows();
   }
@@ -142,7 +144,7 @@
   return true;
 }
 
-wstring* DriverResultSet::getString(int32_t columnIndex) throw (SQLException,
+wstring DriverResultSet::getString(int32_t columnIndex) throw (SQLException,
     UnexpectedException)
 {
   checkRowAndColPosAndSetNullFlag(columnIndex);
@@ -152,100 +154,63 @@
   wostringstream buffer;
 
   //TODO: big switch on column data type
-  switch (fields[columnIndex - 1]->getSqlType())
+  switch (columnTypeTags[columnIndex - 1])
   {
-    case SQLT_TINYINT:
-      buffer << *(int8_t*)((data[currentRow])[columnIndex - 1]);
+    case TT_STRING:
+      buffer << *((wstring*)(data[currentRow][columnIndex - 1].as_other));
     break;
-    case SQLT_SMALLINT:
-      buffer << *(int16_t*)((data[currentRow])[columnIndex - 1]);
+    case TT_BIGDECIMAL:
+      throw NotImplementedException(L"BigDecimal to string conversion not 
implemented yet.");
     break;
-    case SQLT_INTEGER:
-      buffer << *(int32_t*)((data[currentRow])[columnIndex - 1]);
+    case TT_BOOLEAN:
+      buffer << ((data[currentRow])[columnIndex - 1]).as_bool;
+    break;
+    case TT_INTEGER:
+      buffer << ((data[currentRow])[columnIndex - 1]).as_int;
+    break;
+    case TT_LONG:
+      buffer << ((data[currentRow])[columnIndex - 1]).as_long;
+    break;
+    case TT_FLOAT:
+      buffer << ((data[currentRow])[columnIndex - 1]).as_float;
+    break;
+    case TT_DOUBLE:
+      buffer << ((data[currentRow])[columnIndex - 1]).as_double;
+    break;
+    case TT_BYTE_ARRAY:
+      throw NotImplementedException(L"ByteArray to string conversion not 
implemented yet.");
+    break;
+    case TT_SQL_DATE:
+      throw NotImplementedException(L"SQL Date to string conversion not 
implemented yet.");
+    break;
+    case TT_SQL_TIME:
+      throw NotImplementedException(L"SQL Time to string conversion not 
implemented yet.");
+    break;
+    case TT_SQL_TIMESTAMP:
+      throw NotImplementedException(L"SQL TimeStamp to string conversion not 
implemented yet.");
+    break;
+    case TT_BLOB:
+      throw NotImplementedException(L"Blob to string conversion not 
implemented yet.");
+    break;
+    case TT_JAVA_SERIALIZABLE:
+      throw NotImplementedException(L"SQL TimeStamp to string conversion not 
implemented yet.");
     break;
-    case SQLT_BIGINT:
-      buffer << *(int64_t*)((data[currentRow])[columnIndex - 1]);
-    break;
-    case SQLT_REAL:
-      buffer << *(float*)((data[currentRow])[columnIndex - 1]);
-    break;
-    case SQLT_FLOAT:
-    case SQLT_DOUBLE:
-      buffer << *(double*)((data[currentRow])[columnIndex - 1]);
-    break;
-    case SQLT_CHAR:
-    case SQLT_VARCHAR:
-    case SQLT_LONGVARCHAR:
-      buffer << *(wstring*)((data[currentRow])[columnIndex - 1]);
-    break;
-    case SQLT_BIT:
-      buffer << (*(int8_t*)((data[currentRow])[columnIndex - 1]) == 0 ? 0 : 1);
-    break;
-    case SQLT_BOOLEAN:
-      buffer << (*(bool*)((data[currentRow])[columnIndex - 1]) == 0 ? L"false" 
: L"true");
-    break;
- 
-    case SQLT_DECIMAL:
-      //BigDecimal
-    case SQLT_NUMERIC:
-      //BigDecimal
-    case SQLT_DATE:
-    case SQLT_TIME:
-    case SQLT_TIMESTAMP:
-    case SQLT_BINARY:
-    case SQLT_VARBINARY:
-    case SQLT_LONGVARBINARY:
-    case SQLT_OTHER:
-    case SQLT_JAVA_OBJECT:
-    case SQLT_DISTINCT:
-    case SQLT_STRUCT:
-    case SQLT_ARRAY:
-    case SQLT_BLOB:
-    case SQLT_CLOB:
-    case SQLT_REF:
-    case SQLT_DATALINK:
     default:
-      throw NotImplementedException(L"Type not supported yet");
+      throw NotImplementedException(L"to string conversion not implemented for 
this type yet.");
   }
-  return (new wstring(buffer.str()));
-
-//  return (wstring*)((data[currentRow])[columnIndex - 1]);
+  return buffer.str();
 }
 
-int32_t* DriverResultSet::getInt(int32_t columnIndex) throw (SQLException, 
+int32_t DriverResultSet::getInt(int32_t columnIndex) throw (SQLException, 
     UnexpectedException)
 {
   checkRowAndColPosAndSetNullFlag(columnIndex);
 
-  if (wasNullFlag)
+/*  if (wasNullFlag)
     return NULL;
-
-/*  Object obj;
-  if (inserting || updating)
-    obj = tempRow[columnIndex - 1];
-  else
-
-    obj = ((Object[]) data.get(currentRow))[columnIndex - 1];
-
-  if (obj instanceof Number)
-  {
-    return ((Number) obj).intValue();
-  }
-
-  // the object is not of type number we parse the string representation
-  try
-  {
-    String string = obj.toString();
-    string = string.trim();
-    return Integer.parseInt(string);
-  }
-  catch (NumberFormatException e)
-  {
-    throw new SQLException("the value " + obj.toString()
-        + " is not a valid int number");
-  }
 */
-  return (int32_t*)((data[currentRow])[columnIndex - 1]);
+  //TODO: implement getInt for types other than int...
+  return (data[currentRow][columnIndex - 1].as_int);
 }
 
 void DriverResultSet::close() throw (SQLException, UnexpectedException)
@@ -258,19 +223,30 @@
 void DriverResultSet::receiveRows() throw (SocketIOException, 
ProtocolException,
     UnexpectedException)
 {
-  //reset data
+  //empty all data
   dataIsNull = true;
+  size_t cnt = 0;
+  for (cnt=0; cnt<data.size(); cnt++)
+    data[cnt].clear();
   data.clear();
+  columnTypeTags.clear();
+  for (cnt=0; cnt<nulls.size(); cnt++)
+    nulls[cnt].clear();
+  nulls.clear();
   
   const DriverSocket& socket = connectionPtr->getDriverSocket();
   socket>>nbOfRows;
 
-  vector<bool> nulls;
-  nulls.reserve(nbOfColumns);
-  // Receive the actual data
+  vector<bool> nullsForThisRow;
+  vector<ResultSetDataType> rowOfData;
+  //Reserve memory now so it won't be done during iterations
+  nullsForThisRow.reserve(nbOfColumns);
+  rowOfData.reserve(nbOfColumns);
+  nulls.reserve(nbOfRows);
   data.reserve(nbOfRows);
 
-  for (int32_t r = 0; r<nbOfRows; r++)
+  // Receive the actual data
+  for (int32_t rowCnt = 0; rowCnt<nbOfRows; rowCnt++)
   {
     TypeTag tt(socket);
     if (tt != TT_ROW)
@@ -279,31 +255,32 @@
     }
 
     // First let's flag null values using a burst of booleans
-    for (int32_t col = 0; col < nbOfColumns; col++)
+    for (int32_t colCnt = 0; colCnt < nbOfColumns; colCnt++)
     {
       bool b;
       socket>>b;
-      nulls[col] = b;
+      nullsForThisRow.push_back(b);
     }
-
-    vector<void*> row(nbOfColumns);
-
-    for (int32_t col = 0; col < nbOfColumns; col++)
+    nulls.push_back(nullsForThisRow);
+    //now the values are copied, so remove these elements
+    nullsForThisRow.clear();
+    
+    for (int32_t colCnt2 = 0; colCnt2 < nbOfColumns; colCnt2++)
     {
-      if (nulls[col])
-        row[col] = NULL;
-      else
-        row[col] = deserializers[col](socket);
+      rowOfData.push_back(deserializers[colCnt2](socket));
     }
-    data.push_back(row);
+    data.push_back(rowOfData);
+    //now the values are copied, so remove these elements
+    rowOfData.clear();
     //now we have some data
-    dataIsNull = false;
+    if (dataIsNull)
+      dataIsNull = false;
   }
-
   socket>>hasMoreData;
 }
 
-void DriverResultSet::checkRowPos() throw (SQLException, UnexpectedException)
+void DriverResultSet::checkRowPos() const throw (SQLException,
+    UnexpectedException)
 {
   if (currentRow < 0)
     throw SQLException(L"Before start of result set");
@@ -312,15 +289,18 @@
     throw SQLException(L"After end of result set");
 }
 
-void DriverResultSet::checkIfClosed() throw (SQLException, UnexpectedException)
+void DriverResultSet::checkIfClosed() const throw (SQLException, 
+    UnexpectedException)
 {
   if (isClosed)
     throw SQLException(L"Trying to access a closed ResultSet");
 }
 
-void DriverResultSet::checkRowAndColPosAndSetNullFlag(int32_t columnIndex)
-    throw (SQLException, UnexpectedException)
+bool DriverResultSet::isNull(int32_t columnIndex) const throw (SQLException,
+    UnexpectedException)
 {
+  bool answer = false;
+
   checkIfClosed();
 
   checkRowPos();
@@ -332,18 +312,17 @@
     throw SQLException(L"Column Index out of range ( "
         + toWString(columnIndex) + L" > " + toWString(nbOfColumns) + L").");
 
-  void* obj;
   if ((int32_t)data[currentRow].size()<columnIndex-1)
-    wasNullFlag = true;
+    answer = true;
   else
-  {
-    obj = (data[currentRow])[columnIndex - 1];
-  
-    if (obj == NULL)
-      wasNullFlag = true;
-    else
-      wasNullFlag = false;
-  }
+    answer = nulls[currentRow][columnIndex - 1];
+  return answer;
+}
+
+void DriverResultSet::checkRowAndColPosAndSetNullFlag(int32_t columnIndex)
+    throw (SQLException, UnexpectedException)
+{
+    wasNullFlag = isNull(columnIndex);
 }
 
 
Index: carob/src/SQLDataSerialization.cpp
diff -u carob/src/SQLDataSerialization.cpp:1.7 
carob/src/SQLDataSerialization.cpp:1.8
--- carob/src/SQLDataSerialization.cpp:1.7      Thu Nov 24 12:18:18 2005
+++ carob/src/SQLDataSerialization.cpp  Wed Nov 30 10:18:22 2005
@@ -25,36 +25,38 @@
 #include "CarobException.hpp"
 #include "SQLDataSerialization.hpp"
 
-void* stringDeserializer(const DriverSocket& input) throw (SocketIOException,
-    UnexpectedException)
+ResultSetDataType stringDeserializer(const DriverSocket& input)
+    throw (SocketIOException, UnexpectedException)
 {
   wstring* strRead = new wstring;
   input>>*strRead;
-  return (void*)strRead;
+  ResultSetDataType res;
+  res.as_other = (void*)strRead;
+  return res;
 }
 // Big Decimal => see BigDecimal class
-void* integerDeserializer(const DriverSocket& input) throw (SocketIOException,
-    UnexpectedException)
+ResultSetDataType integerDeserializer(const DriverSocket& input)
+    throw (SocketIOException, UnexpectedException)
 {
-  int32_t* intRead = new int32_t;
-  input>>*intRead;
-  return intRead;
+  ResultSetDataType res;
+  input>>res.as_int;
+  return res;
 }
 
-void* booleanDeserializer(const DriverSocket& input) throw (SocketIOException,
-    UnexpectedException)
+ResultSetDataType booleanDeserializer(const DriverSocket& input)
+    throw (SocketIOException, UnexpectedException)
 {
-  bool* boolRead = new bool;
-  input>>*boolRead;
-  return boolRead;
+  ResultSetDataType res;
+  input>>res.as_bool;
+  return res;
 }
 
-void* longDeserializer(const DriverSocket& input) throw (SocketIOException,
-    UnexpectedException)
+ResultSetDataType longDeserializer(const DriverSocket& input)
+    throw (SocketIOException, UnexpectedException)
 {
-  int64_t* longRead = new int64_t;
-  input>>*longRead;
-  return longRead;
+  ResultSetDataType res;
+  input>>res.as_long;
+  return res;
 }
 
 /**
@@ -65,45 +67,22 @@
  * and bits 22-0 (masked by 0x007fffff) are the mantissa.
  * This function leaves NaN alone.
  */
-void* floatDeserializer(const DriverSocket& input) throw (SocketIOException,
-    UnexpectedException)
+ResultSetDataType floatDeserializer(const DriverSocket& input)
+    throw (SocketIOException, UnexpectedException)
 {
-  float* floatComputed = new float;
+  ResultSetDataType res;
   int32_t intRead = 0;
 
   //Receive the float as an integer (intbits)
   input>>intRead;
-/*
-  if (intRead == 0x7f800000)
-    *floatComputed = 0x7f800000; //positive infinity
-  else if (intRead == 0xff800000) //4286578688
-    *floatComputed = 0xff800000; //negative infinity
-  else if ((   intRead >= 0x7f800001 
-            && intRead <= 0x7fffffff)
-           || (intRead >= 0xff800001
-            && intRead <= 0xffffffff))
-    *floatComputed = 0x7fc00000; //NaN
-  else
-  {
-    int32_t s = ((intRead >> 31) == 0) ? 1 : -1;
-    int32_t e = ((intRead >> 23) & 0xff);
-    int32_t m = (e == 0) ?
-                   (intRead & 0x7fffff) << 1 :
-                   (intRead & 0x7fffff) | 0x800000;
-  
-    *floatComputed = (float)s * (float)m * (float)pow(2, e-150);
-  }
-*/
 // OTHER IMPLEM:
   int s = ((intRead & 0x80000000) == 0) ? 1 : -1;
   int e = ((intRead & 0x7f800000) >> 23);
   int m =  (intRead & 0x007fffff);
   m |= 0x00800000;
-  *floatComputed = (float)s * (float)m * (float)pow(2, e-1075);
-
-
+  res.as_float = (float)s * (float)m * (float)pow(2, e-1075);
 
-  return floatComputed;
+  return res;
 }
 
 /**
@@ -113,48 +92,28 @@
  * and bits 51-0 (masked by 0x000fffffffffffffL) are the mantissa.
  * This function leaves NaN alone.
  */
-void* doubleDeserializer(const DriverSocket& input) throw (SocketIOException,
-    UnexpectedException)
+ResultSetDataType doubleDeserializer(const DriverSocket& input)
+    throw (SocketIOException, UnexpectedException)
 {
-  double* doubleComputed = new double;
+  ResultSetDataType res;
   int64_t longRead = 0;
 
   //Receive the float as an integer (intbits)
   input>>longRead;
 
-/*  if (longRead == 0x7ff0000000000000LL)
-    *doubleComputed = 0x7ff0000000000000LL; //positive infinity
-  else if (longRead == 0xfff0000000000000LL)
-    *doubleComputed = 0xfff0000000000000LL; //negative infinity
-  else if ( (longRead >= 0x7ff0000000000001LL
-          && longRead <= 0x7fffffffffffffffLL)
-         || (longRead >= 0xfff0000000000001LL
-          && longRead <= 0xffffffffffffffffLL))
-    *doubleComputed = (double)0x7ff8000000000000LL; //NaN
-  else
-  {
-    int32_t s = ((longRead >> 63) == 0) ? 1 : -1;
-    int32_t e = (int)((longRead >> 52) & 0x7ffL);
-    int64_t m = (e == 0) ?
-                   (longRead & 0xfffffffffffffLL) << 1 :
-                   (longRead & 0xfffffffffffffLL) | 0x10000000000000LL;
-    *doubleComputed = (double)s * (double)m * (double)pow(2, e-1075);
-  }
-*/
-/* OTHER IMPLEM: */
   long s = ((longRead & 0x8000000000000000LL) == 0) ? 1 : -1;
   long e = ((longRead & 0x7ff0000000000000LL) >> 23);
   long m =  (longRead & 0x000fffffffffffffLL);
   m |= 0x0010000000000000LL;
-  *doubleComputed = (double)s * (double)m * (double)pow(2, e-1075);
-
+  res.as_double = (double)s * (double)m * (double)pow(2, e-1075);
 
-  return doubleComputed;
+  return res;
 }
 
-void* byteArrayDeserializer(const DriverSocket& input) throw 
(SocketIOException,
-    UnexpectedException)
+ResultSetDataType byteArrayDeserializer(const DriverSocket& input)
+    throw (SocketIOException, UnexpectedException)
 {
+  ResultSetDataType res;
   int32_t baLength = 0;
   input>>baLength;
   uint8_t* byteArrayRead = new uint8_t[baLength];
@@ -164,29 +123,30 @@
     input>>byteRead;
     byteArrayRead[i] = byteRead&0xFF;
   }
-  return byteArrayRead;
+  res.as_other = (void*) byteArrayRead;
+  return res;
 }
 
 /**
  * For now, we just return a long
  */
-void* SQLDateDeserializer(const DriverSocket& input) throw (SocketIOException,
-    UnexpectedException)
+ResultSetDataType SQLDateDeserializer(const DriverSocket& input)
+    throw (SocketIOException, UnexpectedException)
 {
-  int64_t* dateRead = new int64_t;
-  input>>*dateRead;
-  return dateRead;
+  ResultSetDataType res;
+  input>>res.as_long;
+  return res;
 }
 
 /**
  * For now, we just return an int
  */
-void* SQLTimeDeserializer(const DriverSocket& input) throw (SocketIOException,
-    UnexpectedException)
+ResultSetDataType SQLTimeDeserializer(const DriverSocket& input)
+    throw (SocketIOException, UnexpectedException)
 {
-  int32_t* timeRead = new int32_t;
-  input>>*timeRead;
-  return timeRead;
+  ResultSetDataType res;
+  input>>res.as_int;
+  return res;
 }
 
 deserializerPtr SQLDataSerialization::getDeserializer(TypeTag ttPrm)
Index: carob/test/TestExecReadRequest.cpp
diff -u carob/test/TestExecReadRequest.cpp:1.10 
carob/test/TestExecReadRequest.cpp:1.11
--- carob/test/TestExecReadRequest.cpp:1.10     Mon Nov 28 13:50:12 2005
+++ carob/test/TestExecReadRequest.cpp  Wed Nov 30 10:18:22 2005
@@ -98,10 +98,9 @@
   for (int i=0; i<50; i++)
   {
     drsPtr->next();
-    int32_t* iPtr = drsPtr->getInt(1);
-    wstring* wsPtr = drsPtr->getString(2);
-    wstring* ws2Ptr = drsPtr->getString(3);
-    wcerr<<i+1<<L"\t"<<*iPtr<<L"\t"<<*wsPtr<<L"\t\t"<<*ws2Ptr<<endl;
+    wcerr<<i+1<<L"\t"<<drsPtr->getInt(1)
+              <<L"\t"<<drsPtr->getString(2)
+              <<L"\t\t"<<drsPtr->getString(3)<<endl;
   }
 }
 
Index: carob/test/TestStatement.cpp
diff -u carob/test/TestStatement.cpp:1.7 carob/test/TestStatement.cpp:1.8
--- carob/test/TestStatement.cpp:1.7    Mon Nov 28 16:01:17 2005
+++ carob/test/TestStatement.cpp        Wed Nov 30 10:18:22 2005
@@ -99,17 +99,14 @@
   {
     logDebug(fctName, L"Read succeeded. Displaying 50 rows:");
   }
-  //Display 50 rows for debugging...
-  //Use metadata and to string
+  //Display 50 rows using metadata and toString
   ResultSetMetaData rsmd(drsPtr);
-//    wcerr<<L"Row\tId\tName\tCost"<<endl;
-  wcerr<<L"Row\tId\tFirstName\tLastName"<<endl;
   for (int i=0; i<50; i++)
   {
     drsPtr->next();
     wcerr<<i+1<<L"\t";
     for (int j=0; j<rsmd.getColumnCount(); j++)
-      wcerr<<*(drsPtr->getString(j+1))<<L"\t";
+      wcerr<<drsPtr->getString(j+1)<<L"\t";
     wcerr<<endl;
   }
   delete statementPtr;
@@ -209,10 +206,9 @@
   //wcerr<<L"Row\tId\tName\t\tCost"<<endl;
   wcerr<<L"Id\tFirstName\tLastName"<<endl;
   CPPUNIT_ASSERT(drsPtr->next() == true);
-  int32_t* iPtr = drsPtr->getInt(1);
-  wstring* wsPtr = drsPtr->getString(2);
-  wstring* ws2Ptr = drsPtr->getString(3);
-  wcerr<<*iPtr<<L"\t"<<*wsPtr<<L"\t\t"<<*ws2Ptr<<endl;
+  wcerr<<drsPtr->getInt(1)
+       <<L"\t"<<drsPtr->getString(2)
+       <<L"\t\t"<<drsPtr->getString(3)<<endl;
     
   //This next() should return false because we asked just 1 row
   CPPUNIT_ASSERT(drsPtr->next() == false);

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

Reply via email to