[gnome-db] Some changes in C++ binding



I made some changes in gda-client c++ binding library.
Please, check them in, if you don't mind. Patches should be applied to bindings/c++ and testing directiories, respectively. Patches are based on libgda-0.2.92 tar distribution.

List of changes:

 - c++.diff file
1. Get rid of most of C types from library objects (especially strings!), so that you don't have to bother of memory allocation/free.
2. C++ objects now keeps proper (?) reference counting on contained GObjects. It made library a little messy, but I'll try to clean that up in the future.

 - testing.diff file
1. Added gda-test-cpp.cpp file (gda-test.c rewritten using C++ binding).

And here are the patches:
c++.diff
----------------------------------------------------------------------
diff -bBwNu c++/Makefile.am c++.new/Makefile.am
--- c++/Makefile.am	Sun Oct  7 11:07:24 2001
+++ c++.new/Makefile.am	Sat Oct 27 22:23:30 2001
@@ -4,9 +4,10 @@
 	-I$(includedir) \
 	-I$(top_srcdir)/lib/gda-common \
 	-I$(top_builddir)/lib/gda-common \
-	-I$(top_srcdir)/lib/gda-client \
 	-I$(top_builddir)/lib/gda-client \
-	$(GDA_CLIENT_CFLAGS)
+	-I$(top_builddir)/lib/gda-client \
+	$(GDA_CLIENT_CFLAGS) \
+	$(ORBITCPP_CFLAGS)

 source_headers = \
 	gdaBatch.h \
@@ -17,9 +18,10 @@
 	gdaField.h \
 	gdaIncludes.h \
 	gdaRecordset.h \
-	gdaValue.h
+	gdaValue.h \
+	gdaHelpers.h

-gdaincludedir=$(includedir)/libgda-$(VERSION)/gda++
+gdaincludedir=$(includedir)/gda/gda++
 gdainclude_HEADERS=$(source_headers)

 libgda_clientcpp_la_SOURCES = \
@@ -31,7 +33,8 @@
 	gdaErrorList.cpp \
 	gdaField.cpp \
 	gdaRecordset.cpp \
-	gdaValue.cpp
+	gdaValue.cpp \
+	gdaHelpers.cpp

 libgda_clientcpp_la_LIBADD = \
 	$(GDA_CLIENT_LIBS)
diff -bBwNu c++/TODO c++.new/TODO
--- c++/TODO	Thu Aug 10 05:32:53 2000
+++ c++.new/TODO	Wed Nov  7 16:11:00 2001
@@ -1,2 +1,3 @@

-Use assignment functions for gdaField! (ie. field = i; or somesuch)
+1. Use assignment functions for gdaField! (ie. field = i; or somesuch)
+2. C++ wrappers for functions from lib/gda-common files (?)
diff -bBwNu c++/gdaBatch.cpp c++.new/gdaBatch.cpp
--- c++/gdaBatch.cpp	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaBatch.cpp	Sat Oct 27 22:23:30 2001
@@ -17,18 +17,35 @@
  */

 #include "config.h"
-#include "gdaBatch.h"
+#include "gdaIncludes.h"
+#include "gdaHelpers.h"

 using namespace gda;

 Batch::Batch ()
 {
-	_gda_batch = gda_batch_new ();
+	_gda_batch = NULL;
+	setCStruct (gda_batch_new ());
 }

-Batch::Batch (GdaBatch * a)
+Batch::Batch (const Batch& job)
 {
-	_gda_batch = a;
+	_gda_batch = NULL;
+    setCStruct (job.getCStruct ());
+
+	_connection = job._connection;
+}
+
+// take ownership of C object (GdaBatch); not of
+// contained C object (GdaConnection)
+//
+Batch::Batch (GdaBatch* job)
+{
+	_gda_batch = NULL;
+	setCStruct (job);
+
+	_connection.setCStruct (gda_batch_get_connection (job));
+	_connection.ref ();
 }

 Batch::~Batch ()
@@ -37,28 +54,27 @@
 		gda_batch_free (_gda_batch);
 }

-void
-Batch::setCStruct (GdaBatch * job)
+Batch&
+Batch::operator=(const Batch& batch)
 {
-	_gda_batch = job;
-}
+    setCStruct (batch.getCStruct ());
+	_connection = batch._connection;

-GdaBatch *
-Batch::getCStruct ()
-{
-	return _gda_batch;
+	return *this;
 }

-gboolean
-Batch::loadFile (const gchar * filename, gboolean clean)
+bool
+Batch::loadFile (const string& filename, bool clean)
 {
-	return gda_batch_load_file (_gda_batch, filename, clean);
+	return gda_batch_load_file (
+		_gda_batch, const_cast<gchar*>(filename.c_str ()), clean);
 }

 void
-Batch::addCommand (const gchar * cmd)
+Batch::addCommand (const string& cmdText)
 {
-	gda_batch_add_command (_gda_batch, cmd);
+	gda_batch_add_command (
+		_gda_batch, const_cast<gchar*>(cmdText.c_str ()));
 }

 void
@@ -67,7 +83,7 @@
 	gda_batch_clear (_gda_batch);
 }

-gboolean
+bool
 Batch::start ()
 {
 	return gda_batch_start (_gda_batch);
@@ -79,32 +95,73 @@
 	gda_batch_stop (_gda_batch);
 }

-gboolean
+bool
 Batch::isRunning ()
 {
 	return gda_batch_is_running (_gda_batch);
 }

-Connection *
+Connection
 Batch::getConnection ()
 {
-	return cnc;
+	return _connection;
 }

 void
-Batch::setConnection (Connection * a)
+Batch::setConnection (const Connection& cnc)
 {
-	cnc = a;
+	gda_batch_set_connection (_gda_batch, cnc.getCStruct (false));
+	_connection = cnc;
 }

-gboolean
+bool
 Batch::getTransactionMode ()
 {
 	return gda_batch_get_transaction_mode (_gda_batch);
 }

 void
-Batch::setTransactionMode (gboolean mode)
+Batch::setTransactionMode (bool mode)
 {
 	gda_batch_set_transaction_mode (_gda_batch, mode);
 }
+
+GdaBatch*
+Batch::getCStruct (bool refn = true) const
+{
+	if (refn)
+	  ref ();
+
+	return _gda_batch;
+}
+
+void
+Batch::setCStruct (GdaBatch *batch)
+{
+    unref ();
+	_gda_batch = batch;
+}
+
+void
+Batch::ref () const
+{
+	if (NULL == _gda_batch) {
+		g_warning ("gda::Batch::ref () received NULL pointer");
+	}
+	else {
+#ifdef HAVE_GOBJECT
+		g_object_ref (G_OBJECT (_gda_batch));
+#else
+		gtk_object_ref (GTK_OBJECT (_gda_batch));
+#endif
+	}
+}
+
+void
+Batch::unref ()
+{
+	if (_gda_batch != NULL) {
+		gda_batch_free (_gda_batch);
+	}
+}
+
diff -bBwNu c++/gdaBatch.h c++.new/gdaBatch.h
--- c++/gdaBatch.h	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaBatch.h	Mon Nov  5 16:35:55 2001
@@ -19,38 +19,43 @@
 #ifndef __gda_bindings_cpp_gdaBatchH
 #define __gda_bindings_cpp_gdaBatchH

-#include "gdaIncludes.h"
+#include "gdaConnection.h"
+#include "gdaValue.h"

-namespace gda
-{
+namespace gda {

-	class Batch
-	{
+class Batch {
 	      public:
 		Batch ();
-		Batch (GdaBatch * a);
+        Batch (const Batch& job);
+		Batch (GdaBatch* job);
 		~Batch ();

-		GdaBatch *getCStruct ();
-		void setCStruct (GdaBatch * job);
+        Batch& operator=(const Batch& job);
+

-		gboolean loadFile (const gchar * filename, gboolean clean);
-		void addCommand (const gchar * cmd);
+		bool loadFile (const string& filename, bool clean);
+		void addCommand (const string& cmdText);
 		void clear ();

-		gboolean start ();
+		bool start ();
 		void stop ();
-		gboolean isRunning ();
+		bool isRunning ();

-		Connection *getConnection ();
-		void setConnection (Connection * cnc);
-		gboolean getTransactionMode ();
-		void setTransactionMode (gboolean mode);
+		Connection getConnection ();
+		void setConnection (const Connection& cnc);
+		bool getTransactionMode ();
+		void setTransactionMode (bool mode);

 	      private:
-		  GdaBatch * _gda_batch;
-		Connection *cnc;
+		GdaBatch* getCStruct (bool refn = true) const;
+		void setCStruct (GdaBatch* job);
+
+		void ref () const;
+		void unref ();

+		GdaBatch* _gda_batch;
+		Connection _connection;
 	};

 };
diff -bBwNu c++/gdaCommand.cpp c++.new/gdaCommand.cpp
--- c++/gdaCommand.cpp	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaCommand.cpp	Sat Oct 27 22:23:30 2001
@@ -17,57 +17,76 @@
  */

 #include "config.h"
-#include "gdaCommand.h"
+#include "gdaIncludes.h"
+#include "gdaHelpers.h"

 using namespace gda;

 Command::Command ()
 {
-	_gda_command = gda_command_new ();
+	_gda_command = NULL;
+	setCStruct (gda_command_new ());
 }

-Command::~Command ()
+Command::Command (const Command& cmd)
 {
-	if (_gda_command)
-		gda_command_free (_gda_command);
+	_gda_command = NULL;
+    setCStruct (cmd.getCStruct ());
+
+	_connection = cmd._connection;
 }

-GdaCommand *
-Command::getCStruct ()
+// we take ownership of C object (GdaCommand);
+// not of contained C object (GdaConnection)
+//
+Command::Command (GdaCommand* cmd)
 {
-	return _gda_command;
+	_gda_command = NULL;
+    setCStruct (cmd);
+
+	_connection.setCStruct (gda_command_get_connection (cmd));
+	_connection.ref ();
 }

-void
-Command::setCStruct (GdaCommand * cmd)
+Command::~Command ()
 {
-	_gda_command = cmd;
+	if (_gda_command)
+		gda_command_free (_gda_command);
+}
+
+Command&
+Command::operator=(const Command& cmd)
+{
+    setCStruct (cmd.getCStruct ());
+	return *this;
 }

-Connection *
+Connection
 Command::getConnection ()
 {
-	return cnc;
+	return _connection;
 }

 gint
-Command::setConnection (Connection * a)
+Command::setConnection (const Connection& cnc)
 {
-	cnc = a;
-	gda_command_set_connection (_gda_command, cnc->getCStruct ());
+    gda_command_set_connection (_gda_command, cnc.getCStruct ());
+
+	_connection = cnc;
+
 	return 0;
 }

-gchar *
+string
 Command::getText ()
 {
-	return gda_command_get_text (_gda_command);
+	return gda_return_string (gda_command_get_text (_gda_command));
 }

 void
-Command::setText (gchar * text)
+Command::setText (const string& text)
 {
-	gda_command_set_text (_gda_command, text);
+	gda_command_set_text (_gda_command, const_cast<gchar*>(text.c_str ()));
 }

 GDA_CommandType
@@ -82,25 +101,94 @@
 	gda_command_set_cmd_type (_gda_command, type);
 }

-Recordset *
-Command::execute (gulong * reccount, gulong flags)
+Recordset
+Command::execute (gulong& reccount, gulong flags)
+{
+	GdaRecordset *gdaRecordset = NULL;
+	gdaRecordset = gda_command_execute (_gda_command, &reccount, flags);
+
+    Recordset recordset (gdaRecordset);
+
+	return recordset;
+}
+
+void
+Command::createParameter (
+	const string& name, GDA_ParameterDirection inout, const Value& value)
 {
-	GdaRecordset *pGdaRecordset = NULL;
-	pGdaRecordset = gda_command_execute (_gda_command, reccount, flags);
+	_parameters_values.insert (_parameters_values.end (), value);

-	Recordset *pRecordset = NULL;
-	if (pGdaRecordset != NULL) {
-		pRecordset = new Recordset (pGdaRecordset, cnc);
+	gda_command_create_parameter (
+		_gda_command,
+		const_cast<gchar*>(name.c_str ()),
+		inout,
+		_parameters_values [_parameters_values.size () - 1]._gda_value);
+}
+/*
+glong
+Command::getTimeout ()
+{
+	return gda_command_get_timeout (_gda_command);
+}
+
+void
+Command::setTimeout (glong timeout)
+{
+	gda_command_set_timeout (_gda_command, timeout);
+}
+*/
+
+GdaCommand*
+Command::getCStruct (bool refn = true) const
+{
+	if (refn)
+		ref ();
+
+	return _gda_command;
+}
+
+
+void
+Command::setCStruct (GdaCommand *cmd)
+{
+    unref ();
+	_gda_command = cmd;
+}
+
+
+void
+Command::ref () const
+{
+	if (NULL == _gda_command) {
+		g_warning ("gda::Command::ref () received NULL pointer");
 	}
 	else {
-		pRecordset = new Recordset ();
+#ifdef HAVE_GOBJECT
+		g_object_ref (G_OBJECT (_gda_command));
+		GdaConnection* cnc = gda_command_get_connection (_gda_command);
+		if (NULL != cnc) {
+			g_object_ref (G_OBJECT (cnc));
+		}
+#else
+		gtk_object_ref (GTK_OBJECT (_gda_command));
+		GdaConnection* cnc = gda_command_get_connection (_gda_command);
+		if (NULL != cnc) {
+			gtk_object_ref (GTK_OBJECT (cnc));
+		}
+#endif
+	}
 	}

-	return pRecordset;
+void
+Command::unref ()
+{
+	if (_gda_command != NULL) {
+		GdaConnection* cnc = gda_command_get_connection (_gda_command);
+		if (cnc != NULL) {
+			gda_connection_free (cnc);
+		}
+
+		gda_command_free (_gda_command);
+	}
 }

-//void Command::createParameter(gchar* name, GDA_ParameterDirection inout, Value *value) {
-// FIXME If we don't use GDA_Value, how do use use the c function gda_command_create_parameter?
-//      GDA_Value v(value->getCValue());
-//      gda_command_create_parameter(_gda_command,name,inout,&v);
-//}
diff -bBwNu c++/gdaCommand.h c++.new/gdaCommand.h
--- c++/gdaCommand.h	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaCommand.h	Sat Oct 27 22:23:30 2001
@@ -19,37 +19,50 @@
 #ifndef __gda_bindings_cpp_gdaCommandH
 #define __gda_bindings_cpp_gdaCommandH

-#include "gdaIncludes.h"
+namespace gda {

-namespace gda
-{
+class Recordset;
+class Value;
+
+class Command {
+
+	friend class Recordset;

-	class Command
-	{
 	      public:
 		Command ();
+        Command (const Command& cmd);
 		Command (GdaCommand * cmd);
 		~Command ();

-		GdaCommand *getCStruct ();
-		void setCStruct (GdaCommand * cmd);
+        Command& operator=(const Command& cmd);

-		Connection *getConnection ();
-		gint setConnection (Connection * a);
-		gchar *getText ();
-		void setText (gchar * text);
+		Connection getConnection ();
+		gint setConnection (const Connection& cnc);
+		string getText ();
+		void setText (const string& text);
 		GDA_CommandType getCmdType ();
 		void setCmdType (GDA_CommandType type);
-		Recordset *execute (gulong * reccount, gulong flags);
-		void createParameter (gchar * name,
+		Recordset execute (gulong& reccount, gulong flags);
+		void createParameter (
+			const string& name,
 				      GDA_ParameterDirection inout,
-				      Value * value);
+			const Value& value);
+//		glong getTimeout ();
+//		void setTimeout (glong timeout);

 	      private:
-		  Connection * cnc;
+		GdaCommand *getCStruct (bool refn = true) const;
+		void setCStruct (GdaCommand *cmd);
+
+		void ref () const;
+		void unref ();
+
 		GdaCommand *_gda_command;
+		Connection _connection;
+		vector<Value> _parameters_values;
 	};

 };

-#endif
+#endif // __gda_bindings_cpp_gdaCommandH
+
diff -bBwNu c++/gdaConnection.cpp c++.new/gdaConnection.cpp
--- c++/gdaConnection.cpp	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaConnection.cpp	Tue Oct 30 14:56:38 2001
@@ -18,7 +18,8 @@
  */

 #include "config.h"
-#include "gdaConnection.h"
+#include "gdaIncludes.h"
+#include "gdaHelpers.h"

 using namespace gda;

@@ -27,62 +28,71 @@
 	_gda_connection = NULL;
 }

-Connection::Connection (GdaConnection * a)
+Connection::Connection (GdaConnection *cnc)
 {
-	_gda_connection = a;
+	_gda_connection = NULL;
+	setCStruct (cnc);
 }

-Connection::Connection (CORBA_ORB orb)
+Connection::Connection (const Connection& cnc)
 {
-	_gda_connection = gda_connection_new (orb);
+	_gda_connection = NULL;
+	setCStruct (cnc.getCStruct ());
 }

-Connection::~Connection ()
+Connection::Connection (CORBA_ORB orb)
 {
-	if (_gda_connection)
-		gda_connection_free (_gda_connection);
+	_gda_connection = NULL;
+	setCStruct (gda_connection_new (orb));
 }

-GdaConnection *
-Connection::getCStruct ()
+Connection::~Connection()
 {
-	return _gda_connection;
+	unref ();
 }

-void
-Connection::setCStruct (GdaConnection * cnc)
+Connection&
+Connection::operator=(const Connection& cnc)
 {
-	_gda_connection = cnc;
+	setCStruct (cnc.getCStruct ());
+	return *this;
 }

 void
-Connection::setProvider (gchar * name)
+Connection::setProvider (const string& name)
 {
-	gda_connection_set_provider (_gda_connection, name);
+	gda_connection_set_provider (
+		_gda_connection, const_cast<gchar*>(name.c_str ()));
 }

-const gchar *
+string
 Connection::getProvider ()
 {
-	return gda_connection_get_provider (_gda_connection);
+	return gda_return_string (
+		(gchar*)gda_connection_get_provider (_gda_connection));
 }

-gboolean
+bool
 Connection::supports (GDA_Connection_Feature feature)
 {
 	return gda_connection_supports (_gda_connection, feature);
 }

 void
-Connection::setDefaultDB (gchar * dsn)
+Connection::setDefaultDB (const string& dsn)
 {
-	gda_connection_set_default_db (_gda_connection, dsn);
+	gda_connection_set_default_db (
+		_gda_connection, const_cast<gchar*>(dsn.c_str ()));
 }

 gint
-Connection::open (gchar * dsn, gchar * user, gchar * pwd)
+Connection::open (const string& dsn, const string& user, const string& pwd)
 {
-	return gda_connection_open (_gda_connection, dsn, user, pwd);
+	return gda_connection_open (
+		_gda_connection,
+		const_cast<gchar*>(dsn.c_str ()),
+		const_cast<gchar*>(user.c_str ()),
+		const_cast<gchar*>(pwd.c_str ()));
 }

 void
@@ -91,12 +101,64 @@
 	gda_connection_close (_gda_connection);
 }

-ErrorList *
+Recordset
+Connection::openSchema (GDA_Connection_QType t, ...)
+{
+	va_list ap;
+	GDA_Connection_ConstraintType constraint_type;
+	gint                          index;
+	Recordset					empty;
+
+	g_return_val_if_fail(isOpen (), empty);
+	g_return_val_if_fail(_gda_connection->connection != NULL, empty);
+
+	vector<GDA_Connection_ConstraintType> types;
+	vector<string> values;
+
+	va_start (ap, t);
+	while (1) {
+		constraint_type = static_cast<GDA_Connection_ConstraintType>(va_arg(ap, int));
+		if (constraint_type == GDA_Connection_no_CONSTRAINT)
+		  break;
+
+		types.insert (types.end (), constraint_type);
+		values.insert (values.end (), va_arg(ap, const char*));
+	}
+
+	GdaConstraint_Element* elements = g_new0 (GdaConstraint_Element, types.size () + 1);
+
+	index = 0;
+	while (index < types.size ()) {
+		elements [index].type = GDA_Connection_QType(types [index]); // something wrong here: conversion betwee GDA_Connection_ConstraintType and GDA_Connection_QType
+		elements [index].value = const_cast<gchar*>(values [index].c_str ());
+	}
+
+	elements [index].type = GDA_Connection_QType (GDA_Connection_no_CONSTRAINT); // something wrong here: conversion betwee GDA_Connection_ConstraintType and GDA_Connection_QType
+
+	return openSchemaArray (t, elements);
+}
+
+Recordset
+Connection::openSchemaArray (GDA_Connection_QType t, GdaConstraint_Element* elems)
+{
+	Recordset recordset (gda_connection_open_schema_array (_gda_connection, t, elems));
+
+	return recordset;
+}
+
+glong
+Connection::modifySchema (GDA_Connection_QType t, ...)
+{
+	g_return_val_if_fail(isOpen (), -1);
+	g_return_val_if_fail(_gda_connection->connection != NULL, -1);
+}
+
+ErrorList
 Connection::getErrors ()
 {
-	ErrorList *a = NULL;
-	a = new ErrorList (gda_connection_get_errors (_gda_connection));
-	return a;
+	ErrorList errorList (gda_connection_get_errors (_gda_connection));
+
+	return errorList;
 }

 gint
@@ -117,20 +179,27 @@
 	return gda_connection_rollback_transaction (_gda_connection);
 }

-Recordset *
-Connection::execute (gchar * txt, gulong * reccount, gulong flags)
+Recordset
+Connection::execute (const string& txt, gulong& reccount, gulong flags)
 {
-	GdaRecordset *b = NULL;
-	Recordset *a = NULL;
-	b = gda_connection_execute (_gda_connection, txt, reccount, flags);
-	a = new Recordset (b, this);
-	return a;
+	GdaRecordset *gdaRst = NULL;
+	//Recordset *rst = NULL;
+	gdaRst = gda_connection_execute (
+		_gda_connection, const_cast<gchar*>(txt.c_str ()), &reccount, flags);
+	if (gdaRst != NULL) {
+  		ref (); // the same connection gobject is inside returned recordset
+	}
+	
+	Recordset rst (gdaRst);
+
+	return rst;
 }

 gint
-Connection::startLogging (gchar * filename)
+Connection::startLogging (const string& filename)
 {
-	return gda_connection_start_logging (_gda_connection, filename);
+	return gda_connection_start_logging (
+		_gda_connection, const_cast<gchar*>(filename.c_str ()));
 }

 gint
@@ -140,38 +209,124 @@
 }

 void
-Connection::addSingleError (Error * error)
+Connection::addSingleError (Error& error)
 {
-	gda_connection_add_single_error (_gda_connection,
-					 error->getCStruct ());
+	gda_connection_add_single_error (_gda_connection, error.getCStruct ());
 }

 void
-Connection::addErrorlist (ErrorList * list)
+Connection::addErrorlist (ErrorList& list)
 {
-	gda_connection_add_error_list (_gda_connection, list->errors ());
+	gda_connection_add_error_list (_gda_connection, list.errors ());
 }

-gboolean
+bool
 Connection::isOpen ()
 {
 	return gda_connection_is_open (_gda_connection);
 }

-gchar *
+string
 Connection::getDSN ()
 {
-	return gda_connection_get_dsn (_gda_connection);
+	return gda_return_string (gda_connection_get_dsn (_gda_connection));
 }

-gchar *
+string
 Connection::getUser ()
 {
-	return gda_connection_get_user (_gda_connection);
+	return gda_return_string (gda_connection_get_user (_gda_connection));
+}
+
+/*
+glong
+Connection::getFlags ()
+{
+	return gda_connection_get_flags (_gda_connection);
 }

-gchar *
+void
+Connection::setFlags (glong flags)
+{
+	gda_connection_set_flags (_gda_connection, flags);
+}
+
+glong
+Connection::getCmdTimeout ()
+{
+	return gda_connection_get_cmd_timeout (_gda_connection);
+}
+
+void
+Connection::setCmdTimeout (glong cmdTimeout)
+{
+	gda_connection_set_cmd_timeout (_gda_connection, cmdTimeout);
+}
+
+glong
+Connection::getConnectTimeout ()
+{
+	return gda_connection_get_connect_timeout (_gda_connection);
+}
+
+void
+Connection::setConnectTimeout (glong timeout)
+{
+	gda_connection_set_connect_timeout (_gda_connection, timeout);
+}
+
+GDA_CursorLocation
+Connection::getCursorLocation ()
+{
+	return gda_connection_get_cursor_location (_gda_connection);
+}
+
+void
+Connection::setCursorLocation (GDA_CursorLocation cursor)
+{
+	gda_connection_set_cursor_location (_gda_connection, cursor);
+}
+*/
+
+string
 Connection::getVersion ()
 {
 	return gda_connection_get_version (_gda_connection);
 }
+
+GdaConnection* Connection::getCStruct (bool refn = true) const
+{
+	if (refn) ref ();
+	return _gda_connection;
+}
+
+void Connection::setCStruct (GdaConnection *cnc)
+{
+	unref ();
+	_gda_connection = cnc;
+}
+
+
+void
+Connection::ref () const
+{
+	if (NULL == _gda_connection) {
+		g_warning ("gda::Connection::ref () received NULL pointer");
+	}
+	else {
+#ifdef HAVE_GOBJECT
+		g_object_ref (G_OBJECT (_gda_connection));
+#else
+		gtk_object_ref (GTK_OBJECT (_gda_connection));
+#endif
+	}
+}
+
+void
+Connection::unref ()
+{
+	if (_gda_connection != NULL) {
+		gda_connection_free (_gda_connection);
+	}
+}
+
diff -bBwNu c++/gdaConnection.h c++.new/gdaConnection.h
--- c++/gdaConnection.h	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaConnection.h	Sat Oct 27 22:23:30 2001
@@ -20,47 +20,68 @@
 #ifndef __gda_bindings_cpp_gdaConnectionH
 #define __gda_bindings_cpp_gdaConnectionH

-#include "gdaIncludes.h"
+namespace gda {

-namespace gda
-{
+class Recordset;
+class Error;
+class ErrorList;
+
+class Connection {
+
+	friend class Batch;
+	friend class Command;
+	friend class Recordset;

-	class Connection
-	{
 	      public:
 		Connection ();
-		Connection (GdaConnection * a);
+		Connection (const Connection& cnc);
+		Connection (GdaConnection *cnc);
 		Connection (CORBA_ORB orb);
 		~Connection ();

-		GdaConnection *getCStruct ();
-		void setCStruct (GdaConnection * cnc);
+		Connection& operator=(const Connection& cnc);

-		void setProvider (gchar * name);
-		const gchar *getProvider ();
-		gboolean supports (GDA_Connection_Feature feature);
-		void setDefaultDB (gchar * dsn);
-		gint open (gchar * dsn, gchar * user, gchar * pwd);
+		void setProvider (const string& name);
+		string getProvider ();
+		bool supports (GDA_Connection_Feature feature);
+		void setDefaultDB (const string& dsn);
+		gint open (const string& dsn, const string& user, const string& pwd);
 		void close ();
-		ErrorList *getErrors ();
+		Recordset openSchema (GDA_Connection_QType t, ...);
+		Recordset openSchemaArray (GDA_Connection_QType t, GdaConstraint_Element* constraint);
+		glong modifySchema (GDA_Connection_QType t, ...);
+		ErrorList getErrors ();
 		gint beginTransaction ();
 		gint commitTransaction ();
 		gint rollbackTransaction ();
-		Recordset *execute (gchar * txt, gulong * reccount,
-				    gulong flags);
-		gint startLogging (gchar * filename);
+		Recordset execute (const string& txt, gulong& reccount, gulong flags);
+		gint startLogging (const string& filename);
 		gint stopLogging ();

-		void addSingleError (Error * error);
-		void addErrorlist (ErrorList * list);
-
-		gboolean isOpen ();
-		gchar *getDSN ();
-		gchar *getUser ();
+		void addSingleError (Error& xError);
+		void addErrorlist (ErrorList& xList);

-		gchar *getVersion ();
+		bool isOpen ();
+		string getDSN ();
+		string getUser ();
+
+//		glong getFlags ();
+//		void setFlags (glong flags);
+//		glong getCmdTimeout ();
+//		void setCmdTimeout (glong cmdTimeout);
+//		glong getConnectTimeout ();
+//		void setConnectTimeout (glong timeout);
+//		GDA_CursorLocation getCursorLocation ();
+//		void setCursorLocation (GDA_CursorLocation cursor);
+		string getVersion ();

 	      private:
+		GdaConnection* getCStruct (bool ref = true) const;
+		void setCStruct (GdaConnection *cnc);
+
+		void ref () const;
+		void unref ();
+
 		  GdaConnection * _gda_connection;
 	};

diff -bBwNu c++/gdaError.cpp c++.new/gdaError.cpp
--- c++/gdaError.cpp	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaError.cpp	Tue Oct 30 16:02:41 2001
@@ -17,77 +17,120 @@
  */

 #include "config.h"
-#include "gdaError.h"
+#include "gdaIncludes.h"
+#include "gdaHelpers.h"

 using namespace gda;

 Error::Error ()
 {
-	_gda_error = gda_error_new ();
+	_gda_error = NULL;
+	setCStruct (gda_error_new ());
 }

-Error::Error (GdaError * e)
+Error::Error (const Error& error)
 {
-	_gda_error = e;
+	_gda_error = NULL;
+	setCStruct (error.getCStruct ());
 }

-Error::~Error ()
+Error::Error (GdaError *e)
 {
-	if (_gda_error)
-		gda_error_free (_gda_error);
+	_gda_error = NULL;
+	setCStruct (e);
 }

-GdaError *
-Error::getCStruct ()
+Error::~Error ()
 {
-	return _gda_error;
+	unref ();
+	//if (_gda_error) gda_error_free (_gda_error);
 }

-void
-Error::setCStruct (GdaError * e)
+Error&
+Error::operator=(const Error& error)
 {
-	_gda_error = e;
+	setCStruct (error.getCStruct ());
+
+	return *this;
 }


-const gchar *
+string
 Error::description ()
 {
-	return gda_error_get_description (_gda_error);
+	return gda_return_string (g_strdup (gda_error_get_description (_gda_error)));
 }

-const glong
+glong
 Error::number ()
 {
 	return gda_error_get_number (_gda_error);
 }

-const gchar *
+string
 Error::source ()
 {
-	return gda_error_get_source (_gda_error);
+	return gda_return_string (g_strdup (gda_error_get_source (_gda_error)));
 }

-const gchar *
+string
 Error::helpurl ()
 {
-	return gda_error_get_help_url (_gda_error);
+	return gda_return_string (g_strdup (gda_error_get_help_url (_gda_error)));
 }

-const gchar *
+string
 Error::sqlstate ()
 {
-	return gda_error_get_sqlstate (_gda_error);
+	return gda_return_string (g_strdup (gda_error_get_sqlstate (_gda_error)));
 }

-const gchar *
+string
 Error::nativeMsg ()
 {
-	return gda_error_get_native (_gda_error);
+	return gda_return_string (g_strdup (gda_error_get_native (_gda_error)));
 }

-const gchar *
+string
 Error::realcommand ()
 {
-	return gda_error_get_real_command (_gda_error);
+	return gda_return_string (g_strdup (gda_error_get_real_command (_gda_error)));
+}
+
+GdaError*
+Error::getCStruct (bool refn = true) const
+{
+	if (refn) ref ();
+	return _gda_error;
+}
+
+void
+Error::setCStruct (GdaError *e)
+{
+	unref ();
+	_gda_error = e;
+}
+
+void
+Error::ref () const
+{
+	if (NULL == _gda_error) {
+		g_warning ("gda::Error::ref () received NULL pointer");
 }
+	else {
+#ifdef HAVE_GOBJECT
+		g_object_ref (G_OBJECT (_gda_error));
+#else
+		gtk_object_ref (GTK_OBJECT (_gda_error));
+#endif
+	}
+}
+
+void
+Error::unref ()
+{
+	if (_gda_error != NULL) {
+		gda_error_free (_gda_error);
+	}
+}
+
diff -bBwNu c++/gdaError.h c++.new/gdaError.h
--- c++/gdaError.h	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaError.h	Tue Oct 30 16:03:25 2001
@@ -19,33 +19,45 @@
 #ifndef __gda_bindings_cpp_gdaErrorH
 #define __gda_bindings_cpp_gdaErrorH

-#include "gdaIncludes.h"
+namespace gda {

-namespace gda
-{
+class Connection;
+class ErrorList;
+
+class Error {
+
+	friend class Connection;
+	friend class ErrorList;

-	class Error
-	{
 	      public:
 		Error ();
+		Error (const Error& error);
 		Error (GdaError * e);
 		~Error ();

-		GdaError *getCStruct ();
-		void setCStruct (GdaError * e);
+		Error& operator=(const Error& error);
+		

-		const gchar *description ();
-		const glong number ();
-		const gchar *source ();
-		const gchar *helpurl ();
-		const gchar *sqlstate ();
-		const gchar *nativeMsg ();
-		const gchar *realcommand ();
+		string description ();
+		glong number ();
+		string source ();
+		string helpurl ();
+		string sqlstate();
+		string nativeMsg();
+		string realcommand();

 	      private:
+		// manual operations on contained C object not allowed; sorry folks!
+		//
+		GdaError *getCStruct (bool refn = true) const;
+		void setCStruct (GdaError *e);
+
+		void ref () const;
+		void unref ();
+
 		  GdaError * _gda_error;
 	};

 };

-#endif
+#endif // __gda_bindings_cpp_gdaErrorH
diff -bBwNu c++/gdaErrorList.cpp c++.new/gdaErrorList.cpp
--- c++/gdaErrorList.cpp	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaErrorList.cpp	Wed Nov  7 15:54:57 2001
@@ -17,7 +17,7 @@
  */

 #include "config.h"
-#include "gdaErrorList.h"
+#include "gdaIncludes.h"

 // Okay, this class doesn't exist in the C version - it is a list of errors
 // from a CORBA exception. C uses the functions gda_errors_from_exception
@@ -27,36 +27,83 @@

 using namespace gda;

+ErrorList::ErrorList ()
+{
+}
+
 ErrorList::ErrorList (CORBA_Environment * ev)
 {
-	_errors = gda_error_list_from_exception (ev);
+	*this = glist2vector (gda_error_list_from_exception (ev));
 }

 ErrorList::ErrorList (GList * errorList)
 {
-	_errors = errorList;
+	*this = glist2vector (errorList, true);
+}
+
+ErrorList::ErrorList (const ErrorList& errorList)
+{
+	operator=(errorList);
 }

 ErrorList::~ErrorList ()
 {
-	if (_errors)
-		gda_error_list_free (_errors);
 }

-GList *
-ErrorList::getCStruct ()
+ErrorList&
+ErrorList::operator=(const ErrorList& errorList)
 {
-	return _errors;
+	dynamic_cast<vector<Error>* >(this)->operator=(errorList);
+
+	return *this;
 }

 GList *
 ErrorList::errors ()
 {
-	return _errors;
+	return vector2glist (*this);
 }

-void
-ErrorList::setCStruct (GList * errorList)
+ErrorList
+ErrorList::glist2vector (GList* errorList, bool freeList)
 {
-	_errors = errorList;
+	GList* node;
+	ErrorList ret;
+	Error error;
+
+	if (NULL != errorList) {
+		for (node = g_list_first (errorList);
+			node != NULL;
+			node = g_list_next (node))
+		{
+			error.setCStruct (static_cast<GdaError*>(node->data));;
+
+			ret.insert (ret.end (), error);
+			if (false == freeList) {
+				error.ref ();
+			}
+		}
+
+		// this ain't mistake - the ownership of list's elements is taken
+		// by Error objects stored in ret vector
+		if (true == freeList) {
+			g_list_free (errorList);
+		}
+	}
+
+	return ret;
+}
+
+GList*
+ErrorList::vector2glist (ErrorList& errorList)
+{
+	GList* ret = g_list_alloc ();
+	GdaError* error;
+
+	for (int i = 0; i < errorList.size (); i++) {
+		error = errorList [i].getCStruct ();
+		g_list_append (ret, error);
+	}
+
+	return ret;
 }
diff -bBwNu c++/gdaErrorList.h c++.new/gdaErrorList.h
--- c++/gdaErrorList.h	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaErrorList.h	Tue Oct 30 15:50:49 2001
@@ -19,26 +19,33 @@
 #ifndef __gda_bindings_cpp_gdaErrorListH
 #define __gda_bindings_cpp_gdaErrorListH

-#include "gdaIncludes.h"
-
 namespace gda
 {

+class Error;
+
 	class ErrorList
+: public vector<Error>
 	{
+
+	friend class Connection;
+
 	      public:
+		ErrorList ();
 		ErrorList (CORBA_Environment * ev);
 		ErrorList (GList * errorList);
+		ErrorList (const ErrorList& errorList);
 		~ErrorList ();

-		GList *getCStruct ();
-		void setCStruct (GList * errorList);
-		GList *errors ();
+		ErrorList& operator=(const ErrorList& errorList);

 	      private:
-		  GList * _errors;
+		ErrorList glist2vector (GList* errorList, bool freeList = false);
+		GList* vector2glist (ErrorList& errorList);
+
+		GList* errors ();
 	};

 };

-#endif
+#endif // __gda_bindings_cpp_gdaErrorListH
diff -bBwNu c++/gdaField.cpp c++.new/gdaField.cpp
--- c++/gdaField.cpp	Sat Sep 15 13:38:30 2001
+++ c++.new/gdaField.cpp	Mon Nov  5 16:23:46 2001
@@ -17,107 +17,210 @@
  */

 #include "config.h"
-#include "gdaField.h"
+#include "gdaIncludes.h"
+#include "gdaHelpers.h"

 using namespace gda;

 Field::Field ()
 {
 	_gda_field = NULL;
+	_gda_recordset = NULL;
+
+	setCStruct (gda_field_new ());
+	allocBuffers ();
+}
+
+Field::Field (const Field& field)
+{
+	_gda_field = NULL;
+	_gda_recordset = NULL;
+
+	setCStruct (field.getCStruct ());
+
+	_gda_recordset = field._gda_recordset;
 }

 Field::Field (GdaField * f)
 {
-	_gda_field = f;
+	_gda_field = NULL;
+	_gda_recordset = NULL;
+
+	setCStruct (f);
+}
+
+Field::Field (GdaField* f, GdaRecordset* recordset)
+{
+	_gda_field = NULL;
+	_gda_recordset = NULL;
+
+	setCStruct (f);
+
+	_gda_recordset = recordset;
 }

 Field::~Field ()
 {
-	if (_gda_field)
-		gda_field_free (_gda_field);
+	// since there is no gda_field_free ()
+	//
+	unref ();
+
+	_gda_field = NULL;
 }

-GdaField *
-Field::getCStruct ()
+Field&
+Field::operator=(const Field& field)
 {
-	return _gda_field;
+	// order is meaningful
+	//
+	setCStruct (field.getCStruct ());
+	_gda_recordset = field._gda_recordset;
+
+	return *this;
 }

-void
-Field::setCStruct (GdaField * f)
+bool
+Field::isValid ()
 {
-	_gda_field = f;
+	return (NULL != _gda_field);
 }

 bool
 Field::isNull ()
 {
+	g_assert (isValid ());
+
 	return gda_field_is_null (_gda_field);
 }

-Value *
-Field::realValue ()
-{
-	Value *v = new Value (_gda_field->real_value);
-	return v;
-}
+//Value
+//Field::realValue ()
+//{
+//	g_assert (isValid ());a
+//
+//	Value v (_gda_field->real_value);
+//	v.ref ();
+//
+//	return v;
+//}

-Value *
-Field::origValue ()
-{
-	Value *v = new Value (_gda_field->original_value);
-	return v;
-}
+//Value
+//Field::origValue ()
+//{
+//	g_assert (isValid ());
+//
+//	Value v (_gda_field->original_value);
+//	v.ref ();
+//
+//	return v;
+//}

 GDA_ValueType
 Field::typeCode ()
 {
+	g_assert (isValid ());
+
 	return _gda_field->real_value->_u.v._d;
 }

-gchar *
+string
 Field::typeCodeString ()
 {
-	// Convenience function to get the string of the field's value type
-	// without resorting to the C commands...
-	gchar *a = 0;
-	GDA_ValueType t;
-
-	// Create a string, then get the type, then put the type into the
-	// string and return the string.
-	a = (gchar *) g_malloc (256);
-	t = typeCode ();
-	gda_fieldtype_2_string (a, 256, t);
-	return a;
+	g_assert (isValid ());
+
+	return Field::fieldType2String (typeCode ());
+}
+
+Value
+Field::getValue ()
+{
+	g_assert (isValid ());
+
+	{
+		Value value;
+
+		if (true == isValid () && _gda_field->real_value != NULL && _gda_field->real_value->_d) {
+			Value::copyValue (&(_gda_field->real_value->_u.v), value._gda_value);
+		}
+
+		return value;
+	}
 }

 gchar
-Field::getTinyint ()
+Field::getTinyInt ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_tinyint_value (_gda_field);
 }

 glong
-Field::getBigint ()
+Field::getBigInt ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_bigint_value (_gda_field);
 }

 bool
 Field::getBoolean ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_boolean_value (_gda_field);
 }

-GDate *
+GDate
 Field::getDate ()
 {
-	return gda_field_get_date_value (_gda_field);
+	g_assert (isValid ());
+
+	GDate* gdate =  gda_field_get_date_value (_gda_field);
+	if (NULL == gdate) {
+		gdate = g_date_new ();
 }

+	GDate date = *gdate;
+
+	g_date_free (gdate);
+
+	return date;
+}
+
+/*
+GDA_DbDate
+Field::getDBDate ()
+{
+	g_assert (isValid ());
+
+	return gda_field_get_dbdate_value (_gda_field);
+}
+*/
+/*
+GDA_DbTime
+Field::getDBTime ()
+{
+	g_assert (isValid ());
+
+	return gda_field_get_dbtime_value (_gda_field);
+}
+*/
+/*
+GDA_DbTimestamp
+Field::getDBTStamp ()
+{
+	g_assert (isValid ());
+
+	return gda_field_get_timestamp_value (_gda_field);
+}
+*/
+
 time_t
 Field::getTime ()
 {
+	g_assert (isValid ());
+
 	//return gda_field_get_time_value (_gda_field);
 	return -1;
 }
@@ -125,51 +228,125 @@
 time_t
 Field::getTimestamp ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_timestamp_value (_gda_field);
 }

 gdouble
 Field::getDouble ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_double_value (_gda_field);
 }

 glong
 Field::getInteger ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_integer_value (_gda_field);
 }

-gchar *
+VarBinString
+Field::getBinary ()
+{
+	g_assert (isValid ());
+
+	VarBinString varBinString;
+	varBinString = _gda_field->real_value->_u.v._u.lvb;
+
+	return varBinString;
+}
+
+/*
+GDA_VarBinString Field::getVarLenString ()
+{
+ g_assert (isValid ());
+
+ return gda_field_varbin (_gda_field);
+}
+
+GDA_VarBinString Field::getFixLenString ()
+{
+ g_assert (isValid ());
+
+ return gda_field_fixbin (_gda_field);
+}
+
+string
+Field::getLongVarChar ()
+{
+	g_assert (isValid ());
+
+	return gda_return_string (gda_field_longvarchar (_gda_field));
+}
+*/
+
+string
 Field::getString ()
 {
-	return gda_field_get_string_value (_gda_field);
+	g_assert (isValid ());
+
+	//return gda_return_string (gda_field_get_string_value (_gda_field));
+	return "";
 }

 gfloat
 Field::getSingle ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_single_value (_gda_field);
+	// return _gda_field->real_value->_u.v._u.f;
 }

 gint
 Field::getSmallInt ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_smallint_value (_gda_field);
 }

+/*
 gulong
 Field::getUBigInt ()
 {
-	return gda_field_get_bigint_value (_gda_field);
+	g_assert (isValid ());
+
+	return gda_field_get_ubingint_value (_gda_field);
 }
+*/

 guint
 Field::getUSmallInt ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_usmallint_value (_gda_field);
 }

+string
+Field::fieldType2String (GDA_ValueType type)
+{
+	return gda_return_string (gda_fieldtype_2_string (NULL, 0, type));
+}
+
+GDA_ValueType
+Field::string2FieldType (const string& type)
+{
+	return gda_string_2_fieldtype (const_cast<gchar*>(type.c_str ()));
+}
+
+string
+Field::stringifyValue ()
+{
+	return gda_return_string (gda_stringify_value (NULL, 0, _gda_field));
+}
+
+
 //gchar *Field::getText() {
 //      return getNewString();
 //}
@@ -186,50 +363,165 @@
 //      return a;
 //}

-gchar *
-Field::putInString (gchar * bfr, gint maxLength)
-{
-	return gda_stringify_value (bfr, maxLength, _gda_field);
-}
+//gchar*
+//Field::putInString (gchar *bfr, gint maxLength)
+//{
+//	return gda_stringify_value (bfr, maxLength, _gda_field);
+//}

 gint
 Field::actualSize ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_actual_size (_gda_field);
 }

 glong
 Field::definedSize ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_defined_size (_gda_field);
 }

-gchar *
+string
 Field::name ()
 {
-	return gda_field_get_name (_gda_field);
+	g_assert (isValid ());
+
+	string name = const_cast<const char*>(gda_field_get_name (_gda_field));
+
+	return name;
 }

 glong
 Field::scale ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_scale (_gda_field);
 }

 GDA_ValueType
 Field::gdaType ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_gdatype (_gda_field);
 }

 glong
 Field::cType ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_ctype (_gda_field);
 }

 glong
 Field::nativeType ()
 {
+	g_assert (isValid ());
+
 	return gda_field_get_nativetype (_gda_field);
+}
+
+GdaField*
+Field::getCStruct (bool refn = true) const
+{
+	if (refn) ref ();
+	return _gda_field;
+}
+
+void
+Field::setCStruct (GdaField *f)
+{
+	unref ();
+	_gda_field = f;
+}
+
+
+
+void
+Field::ref () const
+{
+	if (NULL == _gda_field) {
+		g_warning ("gda::Field::ref () received NULL pointer");
+	}
+	else {
+#ifdef HAVE_GOBJECT
+		g_object_ref (G_OBJECT (_gda_field));
+#else
+		gtk_object_ref (GTK_OBJECT (_gda_field));
+#endif
+	}
+}
+
+void
+Field::unref ()
+{
+	if (_gda_field != NULL) {
+		// When field created with Recordset::fieldIdx () or fieldName ()
+		// method, the buffers are part of recordset - we leave them alone.
+		// Possible time hazard here with ref_count incremented from other
+		// thread
+		//
+		if (_gda_recordset != NULL) {
+			if (1 == GTK_OBJECT(_gda_field)->ref_count) {
+				detachBuffers ();
+			}
+
+			_gda_recordset = NULL;
+		}
+		else {
+
+			freeBuffers ();
+		}
+
+		// since there is no gda_field_free ()
+		//
+#ifdef HAVE_GOBJECT
+		g_object_unref (G_OBJECT(_gda_field));
+#else
+		gtk_object_unref (GTK_OBJECT (_gda_field));
+#endif
+	}
+}
+
+void
+Field::allocBuffers ()
+{
+	g_assert (_gda_recordset == NULL);
+
+	if (_gda_field != NULL) {
+		_gda_field->attributes = GDA_FieldAttributes__alloc ();
+		_gda_field->real_value = GDA_FieldValue__alloc ();
+		_gda_field->shadow_value = GDA_FieldValue__alloc ();
+		_gda_field->original_value = GDA_FieldValue__alloc ();
+	}
+}
+
+void
+Field::detachBuffers ()
+{
+	g_assert (_gda_recordset != NULL);
+
+	if (_gda_field != NULL) {
+	  _gda_field->attributes = NULL;
+	  _gda_field->real_value = NULL;
+	  _gda_field->shadow_value = NULL;
+	  _gda_field->original_value = NULL;
+	}
+}
+
+void
+Field::freeBuffers ()
+{
+	g_assert (_gda_recordset == NULL);
+
+	CORBA_free (_gda_field->attributes);
+	CORBA_free (_gda_field->real_value);
+	CORBA_free (_gda_field->shadow_value);
+	CORBA_free (_gda_field->original_value);
 }
diff -bBwNu c++/gdaField.h c++.new/gdaField.h
--- c++/gdaField.h	Thu Sep  6 18:52:40 2001
+++ c++.new/gdaField.h	Mon Nov  5 16:36:05 2001
@@ -19,57 +19,90 @@
 #ifndef __gda_bindings_cpp_gdaFieldH
 #define __gda_bindings_cpp_gdaFieldH

-#include "gdaIncludes.h"
+namespace gda {

-namespace gda
-{
+class Field {
+
+	friend class Recordset;

-	class Field
-	{
 	      public:
 		Field ();
+		Field (const Field& field);
 		Field (GdaField * f);
 		~Field ();

-		GdaField *getCStruct ();
-		void setCStruct (GdaField * f);
+		Field& operator=(const Field& field);
+		

-		Value *realValue ();
-		Value *origValue ();
+		//Value realValue ();
+		//Value origValue ();
 		// What's shadowValue for? FIXME

+		// this function does not exist in C implementation; function returns
+		// true if contained GdaField object is not NULL
+		//
+		bool isValid ();
+
 		bool isNull ();
 		GDA_ValueType typeCode ();
-		gchar *typeCodeString ();
+		string typeCodeString ();

-		gchar getTinyint ();
-		glong getBigint ();
+		Value getValue ();
+		gchar getTinyInt ();
+		glong getBigInt ();
 		bool getBoolean ();
-		GDate *getDate ();
+		GDate getDate ();		//###
+	//	GDA_DbDate getDBDate ();	//###
+	//	GDA_DbTime getDBTime ();	//###
+	//	GDA_DbTimestamp getDBTStamp ();	//###
 		time_t getTime ();
 		time_t getTimestamp ();
 		gdouble getDouble ();
 		glong getInteger ();
-		gchar *getString ();
+		VarBinString getBinary ();
+	//	GDA_VarBinString getVarLenString();
+	//	GDA_VarBinString getFixLenString();
+	//	string getLongVarChar ();
+		string getString ();
 		gfloat getSingle ();
 		gint getSmallInt ();
-		gulong getUBigInt ();
+	//	gulong getUBigInt ();
+
 		guint getUSmallInt ();

-		//      gchar *getText();
+		static string fieldType2String (GDA_ValueType type);
+		static GDA_ValueType string2FieldType (const string& type);
+
+		string stringifyValue ();
+	//	gchar *getText
 		//      gchar *getNewString();
-		gchar *putInString (gchar * bfr, gint maxLength);
+	//	gchar *putInString (gchar *bfr, gint maxLength);

 		gint actualSize ();
 		glong definedSize ();
-		gchar *name ();
+		string name ();
 		glong scale ();
 		GDA_ValueType gdaType ();
 		glong cType ();
 		glong nativeType ();

 	      private:
+		Field (GdaField* f, GdaRecordset* recordset);
+
+		// manual operations on contained C object not allowed; sorry folks!
+		//
+		GdaField *getCStruct (bool refn = true) const;
+		void setCStruct (GdaField *f);
+
+		void ref () const;
+		void unref ();
+
+		void allocBuffers ();
+		void detachBuffers ();
+		void freeBuffers ();
+
 		  GdaField * _gda_field;
+		GdaRecordset* _gda_recordset;
 	};

 };
diff -bBwNu c++/gdaHelpers.cpp c++.new/gdaHelpers.cpp
--- c++/gdaHelpers.cpp	Wed Dec 31 19:00:00 1969
+++ c++.new/gdaHelpers.cpp	Mon Nov  5 16:00:56 2001
@@ -0,0 +1,37 @@
+/* GNOME DB libary
+ * Copyright (C) 2000 Chris Wiegand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <string>
+#include "config.h"
+#include "glib.h"
+#include "gdaHelpers.h"
+
+//using namespace gda;
+
+string
+gda::gda_return_string (gchar* pszString)
+{
+	if (NULL == pszString) {
+		return "";
+	}
+
+	string szString = const_cast<const char*>(pszString);
+	g_free (pszString);
+
+	return szString;
+}
diff -bBwNu c++/gdaHelpers.h c++.new/gdaHelpers.h
--- c++/gdaHelpers.h	Wed Dec 31 19:00:00 1969
+++ c++.new/gdaHelpers.h	Mon Nov  5 16:00:15 2001
@@ -0,0 +1,25 @@
+/* GNOME DB libary
+ * Copyright (C) 2000 Chris Wiegand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//#ifndef __gda_helpers_cpp_gdaHelpersH
+//#define __gda_helpers_cpp_gdaHelpersH
+
+namespace gda {
+string gda_return_string (gchar* pszString);
+};
+//#endif // __gda_helpers_cpp_gdaHelpersH
diff -bBwNu c++/gdaIncludes.h c++.new/gdaIncludes.h
--- c++/gdaIncludes.h	Sat Jul 21 18:59:50 2001
+++ c++.new/gdaIncludes.h	Sat Oct 27 22:23:30 2001
@@ -16,8 +16,10 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */

-namespace gda
-{
+#ifndef __gda_bindings_cpp_gdaIncludesH
+#define __gda_bindings_cpp_gdaIncludesH
+/*
+namespace gda {
 	class Batch;
 	class Command;
 	class Connection;
@@ -27,8 +29,17 @@
 	class Recordset;
 	class Value;
 };
+*/
+extern "C" {

+// hack to remove nasty compiler warnings
+//
+//
+#define export
+
+#include "glib.h"
 #include "gda-client.h"
+
 #include "gda-batch.h"
 #include "gda-command.h"
 #include "gda-connection.h"
@@ -36,6 +47,12 @@
 #include "gda-field.h"
 #include "gda-recordset.h"

+#undef export
+}
+
+#include <string>
+#include <vector>
+
 #include "gdaBatch.h"
 #include "gdaCommand.h"
 #include "gdaConnection.h"
@@ -44,3 +61,5 @@
 #include "gdaField.h"
 #include "gdaRecordset.h"
 #include "gdaValue.h"
+
+#endif // __gda_bindings_cpp_gdaIncludesH
diff -bBwNu c++/gdaRecordset.cpp c++.new/gdaRecordset.cpp
--- c++/gdaRecordset.cpp	Sun Sep  2 20:08:20 2001
+++ c++.new/gdaRecordset.cpp	Sat Oct 27 22:23:30 2001
@@ -1,4 +1,4 @@
-/* GDA C++ bindings
+/* GNOME DB libary
  * Copyright (C) 2000 Chris Wiegand
  *
  * This library is free software; you can redistribute it and/or
@@ -17,57 +17,68 @@
  */

 #include "config.h"
-#include "gdaRecordset.h"
+#include "gdaIncludes.h"
+#include "gdaHelpers.h"
+

 using namespace gda;

 Recordset::Recordset ()
 {
-	_gda_recordset = (GdaRecordset *) gda_recordset_new ();
-	cnc = NULL;
+	_gda_recordset = NULL;
+	setCStruct (gda_recordset_new ());
 }

-Recordset::Recordset (GdaRecordset * rst, Connection * cnca)
+Recordset::Recordset (const Recordset& rst)
 {
-	_gda_recordset = rst;
-	cnc = cnca;
+	_gda_recordset = NULL;
+	setCStruct (rst.getCStruct ());
+
+	_cnc = rst._cnc;
 }

-Recordset::Recordset (GdaRecordset * rst, GdaConnection * cnca)
+// we take ownership of C object; not of contained C object
+//
+Recordset::Recordset (GdaRecordset* rst)
 {
-	_gda_recordset = rst;
-	cnc = new Connection ();
-	cnc->setCStruct (cnca);
+	_gda_recordset = NULL;
+	setCStruct (rst);
+
+	_cnc.setCStruct (gda_recordset_get_connection (rst));
+	_cnc.ref ();
 }

 Recordset::~Recordset ()
 {
-	if (_gda_recordset)
-		gda_recordset_free (_gda_recordset);
+	if (_gda_recordset) gda_recordset_free (_gda_recordset);
 }

-GdaRecordset *
-Recordset::getCStruct ()
+Recordset&
+Recordset::operator=(const Recordset& rst)
 {
-	return _gda_recordset;
+	setCStruct (rst.getCStruct ());
+	return *this;
 }

-void
-Recordset::setCStruct (GdaRecordset * rst)
+bool
+Recordset::isValid ()
 {
-	_gda_recordset = rst;
+	return _gda_recordset != NULL;
 }

 void
-Recordset::setName (gchar * name)
+Recordset::setName (const string& name)
 {
-	gda_recordset_set_name (_gda_recordset, name);
+	//gda_recordset_set_name(_gda_recordset, const_cast<gchar*>(name.c_str ()));
 }

-void
-Recordset::getName (gchar * name)
+string
+Recordset::getName ()
 {
-	gda_recordset_get_name (_gda_recordset, name);
+    //gchar* name;
+	//gda_recordset_get_name (_gda_recordset, name);
+	string name;
+    return name; //gda_return_string (name);
 }

 void
@@ -76,20 +87,19 @@
 	gda_recordset_close (_gda_recordset);
 }

-Field *
-Recordset::field (gchar * name)
+Field
+Recordset::field (const string& name)
 {
-	Field *a = NULL;
-	a = new Field (gda_recordset_field_name (_gda_recordset, name));
-	return a;
+	Field field (gda_recordset_field_name (_gda_recordset, const_cast<gchar*>(name.c_str ())), _gda_recordset);
+	
+	return field;
 }

-Field *
+Field
 Recordset::field (gint idx)
 {
-	Field *a = NULL;
-	a = new Field (gda_recordset_field_idx (_gda_recordset, idx));
-	return a;
+	Field field (gda_recordset_field_idx (_gda_recordset, idx), _gda_recordset);
+	return field;
 }

 gint
@@ -147,53 +157,35 @@
 }

 gint
-Recordset::open (Command * cmd, GDA_CursorType cursor_type,
-		 GDA_LockType lock_type, gulong options)
+Recordset::open (const Command& cmd, GDA_CursorType cursor_type, GDA_LockType lock_type, gulong options)
 {
-	return gda_recordset_open (_gda_recordset, cmd->getCStruct (),
-				   cursor_type, lock_type, options);
-}
+	_cnc = cmd._connection;

-gint
-Recordset::open (gchar * txt, GDA_CursorType cursor_type,
-		 GDA_LockType lock_type, gulong options)
-{
-	return gda_recordset_open_txt (_gda_recordset, txt, cursor_type,
-				       lock_type, options);
-}
+	// Not neccessary. Connection is copied from GdaCommand object in
+	// gda_recordset_open ()
+	//
+	//###gda_recordset_set_connection (_gda_recordset, _cnc.getCStruct (false));

-gint
-Recordset::open (Command * cmd, Connection * cnac, GDA_CursorType cursor_type,
-		 GDA_LockType lock_type, gulong options)
-{
-	if (cnac)
-		setConnection (cnac);
-	return gda_recordset_open (_gda_recordset, cmd->getCStruct (),
-				   cursor_type, lock_type, options);
+	return gda_recordset_open (_gda_recordset, cmd.getCStruct (false), cursor_type, lock_type, options);
 }

 gint
-Recordset::open (gchar * txt, Connection * cnac, GDA_CursorType cursor_type,
-		 GDA_LockType lock_type, gulong options)
+Recordset::open (const string& txt, GDA_CursorType cursor_type, GDA_LockType lock_type, gulong options)
 {
-	if (cnac)
-		setConnection (cnac);
-	return gda_recordset_open_txt (_gda_recordset, txt, cursor_type,
-				       lock_type, options);
+	return gda_recordset_open_txt (_gda_recordset, const_cast<gchar*>(txt.c_str ()), cursor_type, lock_type, options);
 }

 gint
-Recordset::setConnection (Connection * a)
+Recordset::setConnection (const Connection& cnc)
 {
-	cnc = a;
-	return gda_recordset_set_connection (_gda_recordset,
-					     cnc->getCStruct ());
+	return gda_recordset_set_connection (_gda_recordset, cnc.getCStruct (false));
+	_cnc = cnc;
 }

-Connection *
+Connection
 Recordset::getConnection ()
 {
-	return cnc;
+	return _cnc;
 }

 gint
@@ -226,12 +218,87 @@
 	gda_recordset_set_cursortype (_gda_recordset, type);
 }

-GList* Recordset::getRow ()
+// should be gda_recordset_get_row (), but:
+// 1. it generates memory leaks
+// 2. there is no wrapper for GList around
+//
+vector<string>
+Recordset::getRow ()
+{
+	Field field;
+	vector<string> ret;
+
+	for (gint i = 0; i < rowsize (); i++) {
+		field = this->field (i);
+		ret.insert (ret.end (), field.stringifyValue ());
+	}
+
+	return ret;
+}
+
+// should be gda_recordset_get_row (), but
+// it generates memory leaks
+//
+string
+Recordset::getRowAsString ()
+{
+	Field field;
+	string ret;
+
+	for (gint i = 0; i < rowsize (); i++) {
+		field = this->field (i);
+		ret = ret + field.stringifyValue ();
+	}
+
+	return ret;
+}
+
+GdaRecordset*
+Recordset::getCStruct (bool refn = true) const
+{
+	if (refn) ref ();
+	return _gda_recordset;
+}
+
+void
+Recordset::setCStruct (GdaRecordset *rst)
+{
+	_gda_recordset = rst;
+}
+
+void
+Recordset::ref () const
 {
-	return gda_recordset_get_row (_gda_recordset);
+	if (NULL == _gda_recordset) {
+		g_warning ("gda::Recordset::ref () received NULL pointer");
+	}
+	else {
+#ifdef HAVE_GOBJECT
+		g_object_ref (G_OBJECT (_gda_recordset));
+		GdaConnection* cnc = gda_recordset_get_connection (_gda_recordset);
+		if (NULL != cnc) {
+			g_object_ref (G_OBJECT (cnc));
+		}
+#else
+		gtk_object_ref (GTK_OBJECT (_gda_recordset));
+		GdaConnection* cnc = gda_recordset_get_connection (_gda_recordset);
+		if (NULL != cnc) {
+			gtk_object_ref (GTK_OBJECT (cnc));
+		}
+#endif
+	}
 }

-gchar* Recordset::getRowAsString ()
+void
+Recordset::unref ()
 {
-	return gda_recordset_get_row_as_string (_gda_recordset);
+	if (_gda_recordset != NULL) {
+		GdaConnection* cnc = gda_recordset_get_connection (_gda_recordset);
+		if (cnc != NULL) {
+			gda_connection_free (cnc);
+		}
+
+		gda_recordset_free (_gda_recordset);
+	}
 }
+
diff -bBwNu c++/gdaRecordset.h c++.new/gdaRecordset.h
--- c++/gdaRecordset.h	Sun Sep  2 20:08:20 2001
+++ c++.new/gdaRecordset.h	Sat Oct 27 22:23:30 2001
@@ -1,6 +1,5 @@
-/* GDA C++ bindings
+/* GNOME DB libary
  * Copyright (C) 2000 Chris Wiegand
- * Copyright (C) 2001 Rodrigo Moya
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -20,28 +19,28 @@
 #ifndef __gda_bindings_cpp_gdaRecordsetH
 #define __gda_bindings_cpp_gdaRecordsetH

-#include "gdaIncludes.h"
+namespace gda {

-namespace gda
-{
+class Connection;
+class Command;
+class Field;

-	class Recordset
-	{
+class Recordset {
 	      public:
 		Recordset ();
-		Recordset (GdaRecordset * rst, Connection * cnc);	// convenience functions!
-		Recordset (GdaRecordset * rst, GdaConnection * cnc);	// convenience functions!
+		Recordset (const Recordset& rst);
+		Recordset (GdaRecordset *rst);
 		~Recordset ();

-		GdaRecordset *getCStruct ();
-		void setCStruct (GdaRecordset * rst);
+		Recordset& operator=(const Recordset& rst);

-		void setName (gchar * name);
-		void getName (gchar * name);
+		bool isValid ();
+		void setName (const string& name);
+		string getName ();
 		void close ();
-		Field *field (gchar * name);
+		Field field (const string& name);
 		// FIXME: possibly add a fieldText() func?
-		Field *field (gint idx);
+		Field field (gint idx);
 		gint bof ();
 		gint eof ();
 		gulong move (gint count, gpointer bookmark);
@@ -51,26 +50,29 @@
 		gulong movePrev ();
 		gint rowsize ();
 		gulong affectedRows ();
-		gint open (Command * cmd, GDA_CursorType cursor_type, GDA_LockType lock_type, gulong options);	// FIXME: defaults
-		gint open (gchar * txt, GDA_CursorType cursor_type,
-			   GDA_LockType lock_type, gulong options);
-		gint open (Command * cmd, Connection * cnc, GDA_CursorType cursor_type, GDA_LockType lock_type, gulong options);	// FIXME: defaults
-		gint open (gchar * txt, Connection * cnc,
-			   GDA_CursorType cursor_type, GDA_LockType lock_type,
-			   gulong options);
-		gint setConnection (Connection * cnc);
-		Connection *getConnection ();
+		gint open (const Command& cmd, GDA_CursorType cursor_type, GDA_LockType lock_type, gulong options); // FIXME: defaults
+		gint open (const string& txt, GDA_CursorType cursor_type, GDA_LockType lock_type, gulong options);
+		gint setConnection (const Connection& cnc);
+		Connection getConnection ();
 		gint addField (GdaField * field);
 		GDA_CursorLocation getCursorloc ();
 		void setCursorloc (GDA_CursorLocation loc);
 		GDA_CursorType getCursortype ();
 		void setCursortype (GDA_CursorType type);
-		GList *getRow ();
-		gchar *getRowAsString ();
+		vector<string> getRow ();
+		string getRowAsString ();

 	      private:
-		  Connection * cnc;
+		// manual operations on contained C object not allowed; sorry folks!
+		//
+		GdaRecordset* getCStruct (bool refn = true) const;
+		void setCStruct (GdaRecordset *rst);
+
+		void ref () const;
+		void unref ();
+
 		GdaRecordset *_gda_recordset;
+		Connection _cnc;
 	};

 };
diff -bBwNu c++/gdaValue.cpp c++.new/gdaValue.cpp
--- c++/gdaValue.cpp	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaValue.cpp	Mon Nov  5 16:22:18 2001
@@ -17,223 +17,392 @@
  */

 #include "config.h"
-#include "gdaValue.h"
+#include "gdaIncludes.h"
+#include "gdaHelpers.h"

 using namespace gda;

-Value::Value ()
+VarBinString::VarBinString ()
 {
-	_gda_fieldvalue = NULL;
+	_GDA_VarBinString = NULL;
 }

-Value::Value (GDA_FieldValue * fv)
+VarBinString::VarBinString (const GDA_VarBinString& varBinString)
 {
-	_gda_fieldvalue = fv;
+	this->operator=(varBinString);
 }

-Value::~Value ()
+VarBinString::VarBinString (const VarBinString& varBinString)
 {
-	// no free function!
+	this->operator=(varBinString);
 }

-GDA_FieldValue *
-Value::getCStruct ()
+VarBinString::~VarBinString ()
 {
-	return _gda_fieldvalue;
+	freeBuffers ();
 }

-//GDA_Value Value::getCValue() {
-//      return _gda_fieldvalue->_u.v;
-//}
+VarBinString&
+VarBinString::operator=(const GDA_VarBinString& varBinString)
+{
+	freeBuffers ();
+	if (varBinString._length != 0 && varBinString._buffer != NULL) {
+		_GDA_VarBinString = GDA_VarBinString__alloc ();
+		_GDA_VarBinString->_buffer =
+			CORBA_sequence_CORBA_octet_allocbuf (varBinString._length);
+		memcpy (
+			_GDA_VarBinString->_buffer,
+			varBinString._buffer,
+			varBinString._length);
+		_GDA_VarBinString->_length = varBinString._length;
+	}
+
+	return *this;
+}
+
+VarBinString&
+VarBinString::operator=(const VarBinString& varBinString)
+{
+	if (NULL == varBinString._GDA_VarBinString) {
+		freeBuffers ();
+	}
+	else {
+		this->operator=(*(varBinString._GDA_VarBinString));
+	}
+
+	return *this;
+}
+
+CORBA_octet&
+VarBinString::operator[](unsigned int index)
+{
+	g_assert (_GDA_VarBinString != NULL);
+	g_assert (index >= 0);
+	g_assert (index < length ());
+
+	return _GDA_VarBinString->_buffer [index];
+}
+
+unsigned int
+VarBinString::length ()
+{
+	if (NULL == _GDA_VarBinString) {
+		return 0;
+	}
+	else {
+		return _GDA_VarBinString->_length;
+	}
+}

 void
-Value::setCStruct (GDA_FieldValue * v)
+VarBinString::freeBuffers ()
+{
+	if (_GDA_VarBinString != NULL &&
+		_GDA_VarBinString->_length > 0 &&
+		_GDA_VarBinString->_buffer != NULL) {
+		CORBA_free (_GDA_VarBinString);
+		_GDA_VarBinString = NULL;
+	}
+}
+
+
+Value::Value ()
+{
+	_gda_value = GDA_Value__alloc ();;
+}
+
+Value::Value (const Value& value)
+{
+	_gda_value = GDA_Value__alloc ();
+	copyValue (value._gda_value, _gda_value);
+}
+
+Value::Value (GDA_FieldValue *fv)
+{
+	_gda_value = GDA_Value__alloc ();
+
+	if (fv != NULL && fv->_d) {
+		copyValue (&(fv->_u.v), _gda_value);
+	}
+}
+
+Value::Value (GDA_Value *v)
+{
+	_gda_value = v;
+
+	if (NULL == _gda_value) {
+		_gda_value = GDA_Value__alloc ();
+	}
+}
+
+Value::~Value()
 {
-	_gda_fieldvalue = v;
+	CORBA_free (_gda_value);
+}
+
+Value&
+Value::operator=(const Value& value)
+{
+	_gda_value = GDA_Value__alloc ();
+	copyValue (value._gda_value, _gda_value);
+
+	return *this;
 }

 gchar
-Value::getTinyint ()
+Value::getTinyInt ()
 {
-	return _gda_fieldvalue->_u.v._u.c;
+	return _gda_value->_u.c;
 }

 glong
-Value::getBigint ()
+Value::getBigInt ()
 {
-	return _gda_fieldvalue->_u.v._u.ll;
+	return _gda_value->_u.ll;
 }

 bool
 Value::getBoolean ()
 {
-	return _gda_fieldvalue->_u.v._u.b;
+	return _gda_value->_u.b;
 }

 GDA_Date
 Value::getDate ()
 {
-	return _gda_fieldvalue->_u.v._u.d;
+	return _gda_value->_u.d;
 }

 GDA_DbDate
-Value::getDBdate ()
+Value::getDBDate ()
 {
-	return _gda_fieldvalue->_u.v._u.dbd;
+	return _gda_value->_u.dbd;
 }

 GDA_DbTime
-Value::getDBtime ()
+Value::getDBTime ()
 {
-	return _gda_fieldvalue->_u.v._u.dbt;
+	return _gda_value->_u.dbt;
 }

 GDA_DbTimestamp
-Value::getDBtstamp ()
+Value::getDBTStamp ()
 {
-	return _gda_fieldvalue->_u.v._u.dbtstamp;
+	return _gda_value->_u.dbtstamp;
 }

 gdouble
 Value::getDouble ()
 {
-	return _gda_fieldvalue->_u.v._u.dp;
+	return _gda_value->_u.dp;
 }

 glong
 Value::getInteger ()
 {
-	return _gda_fieldvalue->_u.v._u.i;
+	return _gda_value->_u.i;
 }

-GDA_VarBinString
-Value::getVarLenString ()
-{
-	return _gda_fieldvalue->_u.v._u.lvb;
-}
+//GDA_VarBinString
+//Value::getVarLenString ()
+//{
+//	return _gda_fieldvalue._u.v._u.lvb;
+//}

-GDA_VarBinString
-Value::getFixLenString ()
-{
-	return _gda_fieldvalue->_u.v._u.fb;
-}
+//GDA_VarBinString
+//Value::getFixLenString ()
+//{
+//	return _gda_fieldvalue._u.v._u.fb;
+//}

-gchar *
+string
 Value::getLongVarChar ()
 {
-	return g_strdup (_gda_fieldvalue->_u.v._u.lvc);
+	return gda_return_string (g_strdup (_gda_value->_u.lvc));
 }

 gfloat
 Value::getFloat ()
 {
-	return _gda_fieldvalue->_u.v._u.f;
+	return _gda_value->_u.f;
 }

 gint
 Value::getSmallInt ()
 {
-	return _gda_fieldvalue->_u.v._u.si;
+	return _gda_value->_u.si;
 }

 gulong
 Value::getULongLongInt ()
 {
-	return _gda_fieldvalue->_u.v._u.ull;
+	return _gda_value->_u.ull;
 }

 guint
 Value::getUSmallInt ()
 {
-	return _gda_fieldvalue->_u.v._u.us;
+	return _gda_value->_u.us;
 }

 void
 Value::set (gchar a)
 {
-	_gda_fieldvalue->_u.v._u.c = a;
+	_gda_value->_u.c = a;
 }

-//void Value::set(glong a) {
-//      _gda_fieldvalue->_u.v._u.ll = a;
-//}
+void Value::set (glong a)
+{
+	_gda_value->_u.ll = a;
+}

 void
 Value::set (bool a)
 {
-	_gda_fieldvalue->_u.v._u.b = a;
+	_gda_value->_u.b = a;
 }

 void
 Value::set (GDA_Date a)
 {
-	_gda_fieldvalue->_u.v._u.d = a;
+	_gda_value->_u.d = a;
 }

 void
 Value::set (GDA_DbDate a)
 {
-	_gda_fieldvalue->_u.v._u.dbd = a;
+	_gda_value->_u.dbd = a;
 }

 void
 Value::set (GDA_DbTime a)
 {
-	_gda_fieldvalue->_u.v._u.dbt = a;
+	_gda_value->_u.dbt = a;
 }

 void
 Value::set (GDA_DbTimestamp a)
 {
-	_gda_fieldvalue->_u.v._u.dbtstamp = a;
+	_gda_value->_u.dbtstamp = a;
 }

 void
 Value::set (gdouble a)
 {
-	_gda_fieldvalue->_u.v._u.dp = a;
+	_gda_value->_u.dp = a;
 }

-void
-Value::set (glong a)
-{
-	_gda_fieldvalue->_u.v._u.i = a;
-}
+//void
+//Value::set (glong a)
+//{
+//	_gda_fieldvalue._u.v._u.i = a;
+//}

-void
-Value::set (GDA_VarBinString a)
-{
-	_gda_fieldvalue->_u.v._u.lvb = a;
-}
+//void
+//Value::set (GDA_VarBinString a)
+//{
+//	_gda_fieldvalue._u.v._u.lvb = a;
+//}

 // void Value::set(GDA_VarBinString a) {
-//      _gda_fieldvalue->_u.v._u.fb = a;
+// 	_gda_fieldvalue._u.v._u.fb = a;
 // }

 void
-Value::set (gchar * a)
+Value::set (const string& a)
 {
-	_gda_fieldvalue->_u.v._u.lvc = g_strdup (a);
+	_gda_value->_u.lvc = g_strdup (a.c_str ());
 }

 void
 Value::set (gfloat a)
 {
-	_gda_fieldvalue->_u.v._u.f = a;
+	_gda_value->_u.f = a;
 }

-// void Value::set(gint a) {
-//      _gda_fieldvalue->_u.v._u.ull = a;
+//void Value::set(gint a)
+//{
+//	_gda_fieldvalue._u.v._u.ull = a;
 // }

 void
 Value::set (gulong a)
 {
-	_gda_fieldvalue->_u.v._u.us = a;
+	_gda_value->_u.us = a;
 }

 void
 Value::set (guint a)
 {
-	_gda_fieldvalue->_u.v._u.c = a;
+	_gda_value->_u.c = a;
+}
+
+// based upon GDA-common.c GDA_Value__free ()
+//
+void
+Value::copyValue (const GDA_Value* src, GDA_Value* dst)
+{
+	if (NULL == src || NULL == dst) {
+		g_warning ("gda::Value::copyValue received NULL pointer");
+	}
+	else {
+		memset (dst, 0, sizeof (GDA_Value));
+		switch (src->_d)
+		{
+			case GDA_TypeTinyint:
+			case GDA_TypeBigint:
+			case GDA_TypeBoolean:
+			case GDA_TypeDate:
+			case GDA_TypeDbDate:
+			case GDA_TypeDbTime:
+			case GDA_TypeDbTimestamp:
+			case GDA_TypeDouble:
+			case GDA_TypeInteger:
+				memmove (dst, src, sizeof (GDA_Value));
+				break;
+
+			case GDA_TypeBinary:
+			case GDA_TypeVarbin:
+			case GDA_TypeVarwchar:
+			case GDA_TypeLongvarwchar:
+			case GDA_TypeLongvarbin:
+			case GDA_TypeUnknown:
+				//dst->_u.lvb = CORBA_sequence_CORBA_octet__alloc ();
+				dst->_u.lvb._length = src->_u.lvb._length;
+				dst->_u.lvb._buffer = CORBA_sequence_CORBA_octet_allocbuf (src->_u.lvb._length);
+				memmove (dst->_u.lvb._buffer, src->_u.lvb._buffer, dst->_u.lvb._length);
+				break;
+
+			case GDA_TypeFixbin:
+			case GDA_TypeFixwchar:
+			case GDA_TypeFixchar:
+				//dst->_u.fb = CORBA_sequence_CORBA_octet__alloc ();
+				dst->_u.fb._length = src->_u.fb._length;
+				dst->_u.fb._buffer = CORBA_sequence_CORBA_octet_allocbuf (src->_u.fb._length);
+				memmove (dst->_u.fb._buffer, src->_u.fb._buffer, dst->_u.fb._length);
+				break;
+
+			case GDA_TypeCurrency:
+			case GDA_TypeDecimal:
+			case GDA_TypeNumeric:
+			case GDA_TypeVarchar:
+			case GDA_TypeLongvarchar:
+				dst->_u.lvc = CORBA_string_dup (src->_u.lvc);
+				break;
+
+			case GDA_TypeSingle:
+			case GDA_TypeSmallint:
+			case GDA_TypeUBigint:
+			case GDA_TypeUSmallint:
+				memmove (dst, src, sizeof (GDA_Value));
+				break;
+
+			default:
+				g_error ("gda::Value::copyValue: Unknown GDA Value type.");
+				break;
 }
+
+		dst->_d = src->_d;
+	}
+}
+
diff -bBwNu c++/gdaValue.h c++.new/gdaValue.h
--- c++/gdaValue.h	Wed Jul 18 18:44:45 2001
+++ c++.new/gdaValue.h	Mon Nov  5 16:33:19 2001
@@ -19,34 +19,55 @@
 #ifndef __gda_bindings_cpp_gdaValueH
 #define __gda_bindings_cpp_gdaValueH

-#include "gdaIncludes.h"
+namespace gda {

-namespace gda
-{
+class VarBinString {
+
+	public:
+		VarBinString ();
+		VarBinString (const GDA_VarBinString& varBinString);
+		VarBinString (const VarBinString& varBinString);
+		~VarBinString ();
+
+		VarBinString& operator=(const GDA_VarBinString& varBinString);
+		VarBinString& operator=(const VarBinString& varBinString);
+
+		CORBA_octet& operator[](unsigned int index);
+
+		unsigned int length ();
+
+	private:
+
+		void freeBuffers ();
+		GDA_VarBinString* _GDA_VarBinString;
+}; // class VarBinString
+
+class Value {
+	friend class Command;
+	friend class Field;

-	class Value
-	{
 	      public:
 		Value ();
+		Value (const Value& value);
 		Value (GDA_FieldValue * fv);
+		Value (GDA_Value* v);
 		~Value ();

-		GDA_FieldValue *getCStruct ();
-		//      GDA_Value getCValue();
-		void setCStruct (GDA_FieldValue * fv);
+		Value& operator=(const Value& value);

-		gchar getTinyint ();
-		glong getBigint ();
+
+		gchar getTinyInt ();
+		glong getBigInt ();
 		bool getBoolean ();
 		GDA_Date getDate ();
-		GDA_DbDate getDBdate ();
-		GDA_DbTime getDBtime ();
-		GDA_DbTimestamp getDBtstamp ();
+		GDA_DbDate getDBDate ();
+		GDA_DbTime getDBTime();
+		GDA_DbTimestamp getDBTStamp ();
 		gdouble getDouble ();
 		glong getInteger ();
-		GDA_VarBinString getVarLenString ();
-		GDA_VarBinString getFixLenString ();
-		gchar *getLongVarChar ();
+		//GDA_VarBinString getVarLenString ();
+		//GDA_VarBinString getFixLenString ();
+		string getLongVarChar ();
 		gfloat getFloat ();
 		gint getSmallInt ();
 		gulong getULongLongInt ();
@@ -61,16 +82,18 @@
 		void set (GDA_DbTimestamp a);
 		void set (gdouble a);
 		// void set(glong a);  // CORBA_long
-		void set (GDA_VarBinString a);
+		//void set (GDA_VarBinString a);
 		// void set(GDA_VarBinString a);  // GDA_VarBinString fb;
-		void set (gchar * a);
+		void set (const string& a);
 		void set (gfloat a);
-		// void set(gint a); // CORBA_short
+		//void set (gint16 a); // CORBA_short
 		void set (gulong a);
 		void set (guint a);

 	      private:
-		  GDA_FieldValue * _gda_fieldvalue;
+		GDA_Value* _gda_value;
+
+		static void copyValue (const GDA_Value* src, GDA_Value* dst);
 	};

 };
----------------------------------------------------------------------

testing.diff
----------------------------------------------------------------------
diff -bBwNu testing/Makefile.am testing.new/Makefile.am
--- testing/Makefile.am	Fri Sep 28 18:31:21 2001
+++ testing.new/Makefile.am	Sat Oct 27 22:57:52 2001
@@ -3,21 +3,25 @@
 ## -------------------------------------------------------------------------

 INCLUDES = \
-	-I$(top_srcdir)/lib/gda-common \
+	-I$(top_srcdir)/lib/gda_common \
 	-I$(top_builddir)/lib/gda-common \
 	-I$(top_srcdir)/lib/gda-client \
 	-I$(top_builddir)/lib/gda-client \
+	-I$(top_builddir)/bindings/c++ \
 	$(GDA_CLIENT_CFLAGS)

 ## -------------------------------------------------------------------------

-bin_PROGRAMS = gda-test
+bin_PROGRAMS = gda-test gda-test-cpp

 noinst_PROGRAMS = gda-primebase-test gda-sybase-test gda-tds-test

 gda_test_SOURCES = \
 	gda-test.c

+gda_test_cpp_SOURCES = \
+	gda-test-cpp.cpp
+
 gda_primebase_test_SOURCES = \
 	gda-primebase-test.c

@@ -28,6 +32,12 @@
 	gda-tds-test.c

 gda_test_LDADD = \
+	$(top_builddir)/lib/gda-common/libgda-common.la \
+	$(top_builddir)/lib/gda-client/libgda-client.la \
+	$(GDA_CLIENT_LIBS)
+
+gda_test_cpp_LDADD = \
+	$(top_builddir)/bindings/c++/libgda-clientcpp.la \
 	$(top_builddir)/lib/gda-common/libgda-common.la \
 	$(top_builddir)/lib/gda-client/libgda-client.la \
 	$(GDA_CLIENT_LIBS)
diff -bBwNu testing/gda-test-cpp.cpp testing.new/gda-test-cpp.cpp
--- testing/gda-test-cpp.cpp	Wed Dec 31 19:00:00 1969
+++ testing.new/gda-test-cpp.cpp	Wed Nov  7 15:43:58 2001
@@ -0,0 +1,202 @@
+/***********************************************************************/
+/*                                                                     */
+/*  GNU Data Access                                                    */
+/*  Testing program                                                    */
+/*  (c) 2000 Free Software Foundation                                  */
+/*                                                                     */
+/***********************************************************************/
+/*                                                                     */
+/*  This program is free software; you can redistribute it and/or      */
+/*  modify it under the terms of the GNU General Public License as     */
+/*  published by the Free Software Foundation; either version 2 of     */
+/*  the License, or (at your option) any later version.                */
+/*                                                                     */
+/*  This program is distributed in the hope that it will be useful,    */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of     */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      */
+/*  GNU General Public License for more details.                       */
+/*                                                                     */
+/*  You should have received a copy of the GNU General Public License  */
+/*  along with this program; if not, write to the Free Software        */
+/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          */
+/*                                                                     */
+/***********************************************************************/
+
+extern "C" {
+#define export
+
+#include "config.h"
+#include <glib.h>
+#include <gda-common.h>
+#include <gda-client.h>
+#include <stdlib.h>
+}
+
+#include <gdaIncludes.h>
+
+/* ------------------------------------------------------------------------- */
+/* Print intro messages
+/* ------------------------------------------------------------------------- */
+void intro()
+{
+	cout << "GDA-Test version %s" << VERSION << endl;
+	cout << "Copyright (c) 2000 Free Software Foundation, Inc." << endl;
+	cout << "This program is part of GNU Data Access (GDA) version %s." << VERSION << cout;
+	cout << "GDA-Test comes with NO WARRANTY, ";
+	cout << "to the extent permitted by law." << endl;
+	cout << "You may redistribute copies of ";
+	cout << "GDA-Test under the terms of the GNU" << endl;
+	cout << "General Public License. ";
+	cout << "For more information see the file COPYING." << endl;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Print errors and exit program
+/* ------------------------------------------------------------------------- */
+int die(gda::Connection& cnc)
+{
+	gda::ErrorList errors = cnc.getErrors ();
+
+	for (int i = 0; i < errors.size (); i++) {
+		g_print ("%s\n", errors [i].description ());
+	}
+
+	exit(1);
+}
+
+/* ------------------------------------------------------------------------- */
+/* List all providers
+/* ------------------------------------------------------------------------- */
+string list_providers()
+{
+	GList *list;
+	GList *node;
+	GdaProvider *provider;
+	int i = 0;
+	string selected;
+	char *number = NULL;
+	gint dummy;
+	gint pno;		/* provider number converted with atoi */
+
+	list = gda_provider_list();
+	if (!list) {
+		cout << endl << "*** Error ***" << endl;
+		cout << "There are no GDA providers available" << endl;
+		cout << "If you installed libgda from a RPM, a DEB, or a Linux" << endl;
+		cout << "Distribution, you should install one of the providers," << endl;
+		cout << "which you can get from the same source as you got libgda." << endl;
+		cout << "If you built libgda yourself, you should run ./configure" << endl;
+		cout << "with one of the options that enable the providers (run" << endl;
+		cout << "./configure --help for details) and then make and install" << endl;
+		cout << "again." << endl;
+		cout << "If you already installed a provider, the .oafinfo file is" << endl;
+		cout << "maybe not installed in the right directory." << endl;
+		exit(1);
+	}
+
+	cout << endl << "The following " << g_list_length (list) << " GDA providers are available:" << endl;
+	for (node = g_list_first(list); node; node = g_list_next(node)) {
+		provider = (GdaProvider *) node->data;
+		cout << ++i << ":" << GDA_PROVIDER_NAME(provider) << endl;
+	}
+
+	if (i > 1) {
+		do {
+			string szNumber;	/* the number of provider entered */
+			cout << endl << "Choose one (enter the number):";
+			cin >> szNumber;
+			pno = atoi(szNumber.c_str ());
+		}
+		while (pno < 1 || pno > i);
+		node = g_list_nth(list, pno - 1);
+	}
+	else {
+		node = g_list_first(list);
+	}
+
+	provider = (GdaProvider *) node->data;
+	selected = g_strdup(GDA_PROVIDER_NAME(provider));
+
+	gda_provider_free_list(list);
+	return (selected);
+}
+
+/* ------------------------------------------------------------------------- */
+/* List all tables for a connection
+/* ------------------------------------------------------------------------- */
+void list_tables(gda::Connection cnc)
+{
+	gda::Recordset rs;
+	gda::Field field;
+	gint i;
+
+	cout << endl <<"opening table schema..." << endl;
+	rs = cnc.openSchema (GDA_Connection_GDCN_SCHEMA_TABLES, GDA_Connection_no_CONSTRAINT);
+
+	if (!rs.isValid ())
+		die(cnc);
+	cout << endl << "This database has following tables:" << endl;
+	for (rs.moveFirst (); !rs.eof (); rs.moveNext ()) {
+		for (i = 0; i < rs.rowsize (); i++) {
+			field = rs.field (i);
+
+			string name = field.name ();
+			string value = field.stringifyValue ();
+
+			cout << field.name () << "=" << field.stringifyValue () << "\t";
+
+		}
+		cout << endl;
+	}
+
+	return;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Main function
+/* ------------------------------------------------------------------------- */
+int main(int argc, char *argv[])
+{
+	string provider;
+	gchar *dsn = NULL;
+	string szDSN;
+	gchar *user = NULL;
+	string szUser;
+	gchar *password = NULL;
+	string szPasswd;
+	gint dummy;
+	gint length;
+	gint i;
+
+	intro();
+	cout << endl << "initializing..." << endl;
+	gda_init("gda-test", NULL, argc, argv);
+	gda::Connection cnc (gda_corba_get_orb ());
+
+//	cnc = gda_connection_new(gda_corba_get_orb());
+	provider = list_providers();
+	cout << endl << "choosing " << provider << "..."<< endl;
+	cnc.setProvider (provider);
+	//gda_connection_set_provider(cnc, const_cast<gchar*>(provider.c_str ()));
+	cout << endl << "Please enter dsn (like 'DATABASE=test'): ";
+	cin >> szDSN;
+	cout << "Please enter user name: ";
+	cin >> szUser;
+	cout << "Please enter password: ";
+	cin >> szPasswd;
+	cout << endl << "opening connection..." << endl;
+	!cnc.open (szDSN, szUser, szPasswd) || die (cnc);
+	/*
+	!gda_connection_open (
+		cnc, const_cast<gchar*>(szDSN.c_str ()),
+		const_cast<gchar*>(szUser.c_str ()),
+		const_cast<gchar*>(szPasswd.c_str ())) || die (cnc);
+	*/
+
+	for (i = 0; i < 10000; i++)
+		list_tables(cnc);
+	cout << endl << "closing connection..." << endl;
+	//gda_connection_free(cnc);
+
+	return (0);
+}
----------------------------------------------------------------------



-- 

Tego nie znajdziesz w zadnym sklepie!
[ http://oferty.onet.pl ]




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]