[gnome-db] libgda/providers/oracle diff



Here's a diff of about the last week and a half worth of libgda
oracle provider code I've been working on.  I can now do
lots more stuff with oracle than before, including:

1. Viewing data in gnome-db from an oracle database, including
    all tables, and most data types except for binary data.
2. Performing updates and such against the database.
3. The transactional logic is there, but has yet to be tested
   fully.
4. Parameters can be used, and in fact are used to get schema
  information from the oracle database.
5. Lots more small tweaks and changes here, there, and
  everywhere :)

If anyone wants screenshots, let me know :)

NOTE: The gda-oracle-connection.c and gda-oracle-connection.h
files that were in the CVS are not required anymore.

Rodrigo said that I should send this diff to cvsmaster gnome org
and CC to him.  I have also CC'ed the gnome-db list because I
thought that people might want to be "in the know".

If anyone is reading this, I would really like people to test this
code against their own oracle databases if they have them.
I've been testing against my own, but it's always good to have more
than one set of eyes looking at it.

Thanks,

-- 
Tim Coleman <tim timcoleman com>                       [43.28 N 80.31 W]
BMath, Honours Combinatorics and Optimization, University of Waterloo
 "They that can give up essential liberty to obtain a little temporary
  safety deserve neither liberty nor safety." -- Benjamin Franklin
Index: gda-oracle-provider.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/oracle/gda-oracle-provider.c,v
retrieving revision 1.3
diff -u -u -r1.3 gda-oracle-provider.c
--- gda-oracle-provider.c	2002/06/06 21:57:25	1.3
+++ gda-oracle-provider.c	2002/06/18 04:30:00
@@ -76,6 +76,11 @@
 
 static GObjectClass *parent_class = NULL;
 
+typedef struct {
+	gchar *col_name;
+	GdaValueType data_type;
+} GdaOracleColData;
+
 /*
  * GdaOracleProvider class implementation
  */
@@ -149,82 +154,6 @@
 	return GDA_SERVER_PROVIDER (provider);
 }
 
-GdaValueType 
-oracle_sqltype_to_gda_type (const ub2 sqltype)
-{
-	/* an incomplete list of all the oracle types */
-	switch (sqltype) {
-	case OCI_TYPECODE_REF: 			/* SQLT_REF; -- SQL/OTS OBJECT REFERENCE */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_DATE: 		/* SQLT_DAT; -- SQL DATE  OTS DATE */
-		return GDA_VALUE_TYPE_DATE;
-	case OCI_TYPECODE_SIGNED8: 		/* 27; -- SQL SIGNED INTEGER(8)  OTS SINT8 */
-		return GDA_VALUE_TYPE_TINYINT;
-	case OCI_TYPECODE_SIGNED16: 		/* 28; -- SQL SIGNED INTEGER(16)  OTS SINT16 */
-		return GDA_VALUE_TYPE_SMALLINT;
-	case OCI_TYPECODE_SIGNED32: 		/* 29; -- SQL SIGNED INTEGER(32)  OTS SINT32 */
-		return GDA_VALUE_TYPE_INTEGER;
-	case OCI_TYPECODE_REAL: 		/* 21; -- SQL REAL  OTS SQL_REAL */
-		return GDA_VALUE_TYPE_SINGLE;
-	case OCI_TYPECODE_DOUBLE: 		/* 22; -- SQL DOUBLE PRECISION  OTS SQL_DOUBLE */
-		return GDA_VALUE_TYPE_DOUBLE;
-	case OCI_TYPECODE_FLOAT: 		/* SQLT_FLT; -- SQL FLOAT(P)  OTS FLOAT(P) */
-		return GDA_VALUE_TYPE_SINGLE;
-	case OCI_TYPECODE_NUMBER: 		/* SQLT_NUM; -- SQL NUMBER(P S)  OTS NUMBER(P S) */
-		return GDA_VALUE_TYPE_NUMERIC;
-	case OCI_TYPECODE_DECIMAL: 		/* SQLT_PDN; -- SQL DECIMAL(P S)  OTS DECIMAL(P S) */
-		return GDA_VALUE_TYPE_NUMERIC;
-	case OCI_TYPECODE_UNSIGNED8: 		/* SQLT_BIN; -- SQL UNSIGNED INTEGER(8)  OTS UINT8 */
-		return GDA_VALUE_TYPE_TINYINT;
-	case OCI_TYPECODE_UNSIGNED16: 		/* 25; -- SQL UNSIGNED INTEGER(16)  OTS UINT16 */
-		return GDA_VALUE_TYPE_SMALLINT;
-	case OCI_TYPECODE_UNSIGNED32: 		/* 26; -- SQL UNSIGNED INTEGER(32)  OTS UINT32 */
-		return GDA_VALUE_TYPE_INTEGER;
-	case OCI_TYPECODE_OCTET: 		/* 245; -- SQL ???  OTS OCTET */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_SMALLINT: 		/* 246; -- SQL SMALLINT  OTS SMALLINT */
-		return GDA_VALUE_TYPE_SMALLINT;
-	case OCI_TYPECODE_INTEGER: 		/* SQLT_INT; -- SQL INTEGER  OTS INTEGER */
-		return GDA_VALUE_TYPE_INTEGER;
-	case OCI_TYPECODE_RAW: 			/* SQLT_LVB; -- SQL RAW(N)  OTS RAW(N) */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_PTR: 			/* 32; -- SQL POINTER  OTS POINTER */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_VARCHAR2: 		/* SQLT_VCS; -- SQL VARCHAR2(N)  OTS SQL_VARCHAR2(N) */
-		return GDA_VALUE_TYPE_STRING;
-	case OCI_TYPECODE_CHAR: 		/* SQLT_AFC; -- SQL CHAR(N)  OTS SQL_CHAR(N) */
-		return GDA_VALUE_TYPE_STRING;
-	case OCI_TYPECODE_VARCHAR: 		/* SQLT_CHR; -- SQL VARCHAR(N)  OTS SQL_VARCHAR(N) */
-		return GDA_VALUE_TYPE_STRING;
-	case OCI_TYPECODE_MLSLABEL: 		/* SQLT_LAB; -- OTS MLSLABEL */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_VARRAY: 		/* 247; -- SQL VARRAY  OTS PAGED VARRAY */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_TABLE: 		/* 248; -- SQL TABLE  OTS MULTISET */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_OBJECT: 		/* SQLT_NTY; -- SQL/OTS NAMED OBJECT TYPE */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_OPAQUE: 		/* 58; --  SQL/OTS Opaque Types */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_NAMEDCOLLECTION: 	/* SQLT_NCO; -- SQL/OTS NAMED COLLECTION TYPE */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_BLOB: 		/* SQLT_BLOB; -- SQL/OTS BINARY LARGE OBJECT */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_BFILE: 		/* SQLT_BFILE; -- SQL/OTS BINARY FILE OBJECT */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_CLOB: 		/* SQLT_CLOB; -- SQL/OTS CHARACTER LARGE OBJECT */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_CFILE: 		/* SQLT_CFILE; -- SQL/OTS CHARACTER FILE OBJECT */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_OTMFIRST: 		/* 228; -- first Open Type Manager typecode */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	case OCI_TYPECODE_OTMLAST: 		/* 320; -- last OTM typecode */
-		return GDA_VALUE_TYPE_UNKNOWN;
-	}
-
-	return GDA_VALUE_TYPE_UNKNOWN;
-}
-
 /* open_connection handler for the GdaOracleProvider class */
 static gboolean
 gda_oracle_provider_open_connection (GdaServerProvider *provider,
@@ -245,7 +174,7 @@
 
 	priv_data = g_new0 (GdaOracleConnectionData, 1);
 
-        /* initialize Oracle environment */
+        /* initialize Oracle */
 	if (OCI_SUCCESS != 
 		OCIInitialize ((ub4) OCI_DEFAULT,
 				(dvoid *) 0,
@@ -257,6 +186,7 @@
 		return FALSE;
 	}
 
+	/* initialize the Oracle environment */
 	if (OCI_SUCCESS != 
 		OCIEnvInit ((OCIEnv **) & priv_data->henv, 
 				(ub4) OCI_DEFAULT, 
@@ -267,6 +197,7 @@
 		return FALSE;
 	}
 
+	/* create the service context */
 	if (OCI_SUCCESS !=
 		OCIHandleAlloc ((dvoid *) priv_data->henv,
 				(dvoid **) &priv_data->hservice,
@@ -277,15 +208,16 @@
 			cnc, _("Could not initialize Oracle service context"));
 		return FALSE;
 	}
-		
+
+	/* create the error handle */
 	if (OCI_SUCCESS != 
 		OCIHandleAlloc ((dvoid *) priv_data->henv, 
-				(dvoid **) &priv_data->herr, 
+				(dvoid **) &(priv_data->herr), 
 				(ub4) OCI_HTYPE_ERROR, 
 				(size_t) 0, 
 				(dvoid **) 0)) {
 		gda_connection_add_error_string (
-			cnc, _("Could not initialize Oracle error handler"));
+			cnc, _("Could not initialize Oracle error handle"));
 		return FALSE;
 	}
 			
@@ -327,7 +259,6 @@
 
 
 	ora_tnsname = gda_quark_list_find (params, "TNSNAME");
-
         g_assert (priv_data != NULL);
 
         /* attach to Oracle server */
@@ -342,6 +273,7 @@
 		return FALSE;
 	}
 
+	/* set the server attribute in the service context */
 	if (OCI_SUCCESS != 
 		OCIAttrSet ((dvoid *) priv_data->hservice, 
 				(ub4) OCI_HTYPE_SVCCTX,
@@ -353,7 +285,8 @@
 			cnc, _("Could not set the Oracle server attribute in the service context"));
 		return FALSE;
 	}
-		
+	
+	/* set the username attribute */
 	if (OCI_SUCCESS != 
 		OCIAttrSet ((dvoid *) priv_data->hsession, 
 				(ub4) OCI_HTYPE_SESSION, 
@@ -366,6 +299,7 @@
 		return FALSE;
 	}
 
+	/* set the password attribute */
 	if (OCI_SUCCESS != 
 		OCIAttrSet ((dvoid *) priv_data->hsession, 
 				(ub4) OCI_HTYPE_SESSION, 
@@ -378,8 +312,7 @@
 		return FALSE;
 	}
 
-	/* inititalize connection */
-	
+	/* begin the session */
 	if (OCI_SUCCESS != 
 		OCISessionBegin (priv_data->hservice,
 				priv_data->herr,
@@ -409,19 +342,7 @@
 	
 	}
 
-	/* Allocate an oracle statement handle */
-	if (OCI_SUCCESS !=
-		OCIHandleAlloc ((dvoid *) priv_data->henv,
-				(dvoid **) &priv_data->hstmt,
-				(ub4) OCI_HTYPE_STMT,
-				(size_t) 0,
-				(dvoid **) 0)) {
-		gda_connection_add_error_string (
-			cnc, _("Could not allocate the Oracle statement handle" ));
-		return FALSE;
-	}
-
-			
+	/* attach the oracle connection data to the gda connection object */
 	g_object_set_data (G_OBJECT (cnc), OBJECT_DATA_ORACLE_HANDLE, priv_data);
 
 	return TRUE;
@@ -441,6 +362,7 @@
 	if (!priv_data)
 		return FALSE;
 
+	/* end the session */
 	if (OCI_SUCCESS != 
 		OCISessionEnd (priv_data->hservice,
 				priv_data->herr,
@@ -451,8 +373,7 @@
 		return FALSE;
 	}
 
-        if (priv_data->hstmt)
-		OCIHandleFree ((dvoid *) priv_data->hstmt, OCI_HTYPE_STMT);
+	/* free all of the handles */
         if (priv_data->hsession)
 		OCIHandleFree ((dvoid *) priv_data->hsession, OCI_HTYPE_SESSION);
 	if (priv_data->hservice)
@@ -470,17 +391,108 @@
 	return TRUE;
 }
 
-static GList *
-process_sql_commands (GList *reclist, GdaConnection *cnc, const gchar *sql)
+/* prepare_oracle_statement prepares the Oracle statement handle for use */
+static OCIStmt *
+prepare_oracle_statement (GdaConnection *cnc, GdaParameterList *params, gchar *sql)
 {
 	GdaOracleConnectionData *priv_data;
+	OCIStmt *stmthp = (OCIStmt *) 0;
+	GList *l;
+	gint result;
+
+	/* Get the OracleConnectionData */
+	priv_data = g_object_get_data (G_OBJECT (cnc), OBJECT_DATA_ORACLE_HANDLE);
+	if (!priv_data) {
+		gda_connection_add_error_string (cnc, _("Invalid Oracle handle"));
+		return NULL;
+	}
+
+	/* Allocate an oracle statement handle */
+	if ((result =
+		OCIHandleAlloc ((dvoid *) priv_data->henv,
+				(dvoid **) &stmthp,
+				(ub4) OCI_HTYPE_STMT,
+				(size_t) 0,
+				(dvoid **) 0))) {
+		switch (result) {
+		case OCI_SUCCESS_WITH_INFO:
+			break;
+		default:
+			gda_connection_add_error (cnc, gda_oracle_make_error (priv_data));
+			return NULL;
+		}
+	}
+	
+	/* Prepare the statement */
+	if ((result = 
+		OCIStmtPrepare ((dvoid *) stmthp,
+				(dvoid *) priv_data->herr,
+				(text *) sql,
+				(ub4) strlen(sql),
+				(ub4) OCI_NTV_SYNTAX,
+				(ub4) OCI_DEFAULT))) {
+		switch (result) {
+		case OCI_SUCCESS_WITH_INFO:
+			break;
+		default:
+			gda_connection_add_error (cnc, gda_oracle_make_error (priv_data));
+			return NULL;
+		}
+	}
+
+	/* Bind parameters */
+	if (params != NULL) {
+		/* loop through parameters and bind by name */
+		GList *parm_list = gda_parameter_list_get_names (params);
+
+		for (l = g_list_first (parm_list); l != NULL; l = l->next) {
+			const gchar *parm_name = (gchar *) l->data;
+			GdaParameter *parm = gda_parameter_list_find (params, parm_name);
+			const GdaValue *gda_value = gda_parameter_get_value (parm);
+			GdaOracleValue *ora_value = gda_value_to_oracle_value (gda_value);
+			OCIBind *bindpp = (OCIBind *) 0;
+
+			if ((result =
+				OCIBindByName ((dvoid *) stmthp,
+						(OCIBind **) &bindpp,
+						(OCIError *) priv_data->herr,
+						(text *) parm_name,
+						(sb4) strlen (parm_name),
+						(dvoid *) ora_value->value,
+						(sb4) ora_value->defined_size,
+						(ub2) ora_value->sql_type,
+						(dvoid *) &ora_value->indicator,
+						(ub2 *) 0,
+						(ub2) 0,
+						(ub4) 0,
+						(ub4 *) 0,
+						(ub4) OCI_DEFAULT))) {
+				switch (result) {
+				case OCI_SUCCESS_WITH_INFO:
+					break;
+				default:
+					gda_connection_add_error (cnc, gda_oracle_make_error (priv_data));
+					return NULL;
+				}
+			}
+		}
+	}
+	return stmthp;
+}
 
+static GList *
+process_sql_commands (GList *reclist, GdaConnection *cnc, 
+			const gchar *sql, GdaParameterList *params, 
+			GdaCommandOptions options)
+{
+	GdaOracleConnectionData *priv_data;
 	gchar **arr;
+	gint result;
 
 	priv_data = g_object_get_data (G_OBJECT (cnc), OBJECT_DATA_ORACLE_HANDLE);
 	if (!priv_data) {
 		gda_connection_add_error_string (cnc, _("Invalid Oracle handle"));
-		return FALSE;
+		return NULL;
 	}
 
 	/* parse SQL string, which can contain several commands, separated by ';' */
@@ -490,21 +502,15 @@
 
 		while (arr[n]) {
 			GdaDataModel *recset;
+			GList *columns = NULL;
+			ub4 ncolumns;
+			ub4 i;
 
-			if (OCI_SUCCESS != 
-				OCIStmtPrepare (priv_data->hstmt,
-						priv_data->herr,
-						(text *) arr[n],
-						(ub4) strlen(arr[n]),
-						(ub4) OCI_NTV_SYNTAX,
-						(ub4) OCI_DEFAULT)) {
-				gda_connection_add_error_string (
-					cnc, _("Could not prepare the Oracle statement"));
-				return NULL;
-			}
+			/* prepare the statement for execution */
+			OCIStmt *stmthp = prepare_oracle_statement (cnc, params, arr[n]);
 
 			if (OCI_SUCCESS != 
-				OCIAttrGet (priv_data->hstmt,
+				OCIAttrGet (stmthp,
 						OCI_HTYPE_STMT,
 						(dvoid *) &priv_data->stmt_type,
 						NULL,
@@ -516,26 +522,83 @@
 			}
 				
 
-			if (OCI_SUCCESS != 
-				OCIStmtExecute (priv_data->hservice,
-						priv_data->hstmt,
+			if ((result = OCIStmtExecute (priv_data->hservice,
+						stmthp,
 						priv_data->herr,
 						(ub4) ((OCI_STMT_SELECT == priv_data->stmt_type) ? 0 : 1),
 						(ub4) 0,
 						(CONST OCISnapshot *) NULL,
 						(OCISnapshot *) NULL,
-						OCI_DEFAULT)) {
-				gda_connection_add_error_string (
-					cnc, _("Could not execute the Oracle command"));
-				return NULL;
+						OCI_DEFAULT))) {
+				switch (result) {
+				case OCI_NO_DATA:
+					continue;
+				default:
+					gda_connection_add_error_string (
+						cnc, _("Could not execute the Oracle command"));
+					return NULL;
+				}
 			}
+
+			/* get the number of columns in the result set */
+			OCIAttrGet ((dvoid *) stmthp,
+					(ub4) OCI_HTYPE_STMT,
+					(dvoid *) &ncolumns,
+					(ub4 *) 0,
+					(ub4) OCI_ATTR_PARAM_COUNT,
+					priv_data->herr);
+
+			for (i = 0; i < ncolumns; i += 1) {
+				text *pgchar_dummy = (text *) 0;
+				ub4 col_name_len;
+				OCIParam *pard = (OCIParam *) 0;
+				gchar *name_buffer;
+
+				if (OCI_SUCCESS != 
+					OCIParamGet ((dvoid *) stmthp,
+							OCI_HTYPE_STMT,
+							priv_data->herr,
+							(dvoid **) &pard,
+							(ub4) i + 1)) {
+					return NULL;
+				}
+				if (OCI_SUCCESS != 
+					OCIAttrGet ((dvoid *) pard,
+							(ub4) OCI_DTYPE_PARAM,
+							(dvoid **) &pgchar_dummy,
+							(ub4 *) &col_name_len,
+							(ub4) OCI_ATTR_NAME,
+							(OCIError *) priv_data->herr)) {
+					gda_connection_add_error_string (
+						cnc, _("Could not get the column name"));
+					return NULL;
+				}
+				name_buffer = g_malloc0 (col_name_len + 1);
+				memcpy (name_buffer, pgchar_dummy, col_name_len);
+				name_buffer[col_name_len] = '\0';
+				columns = g_list_append (columns, name_buffer);
+			}
+
+			recset = GDA_DATA_MODEL (gda_oracle_recordset_new (cnc, priv_data, stmthp));
+			stmthp = (OCIStmt *) 0;
 
-			recset = GDA_DATA_MODEL (gda_oracle_recordset_new (cnc, priv_data));
 			if (GDA_IS_ORACLE_RECORDSET (recset)) {
+				GList *l;
+
 				gda_data_model_set_command_text (recset, arr[n]);
 				gda_data_model_set_command_type (recset, GDA_COMMAND_TYPE_SQL);
+
+				i = 0;
+				for (l = g_list_first (columns); l != NULL; l = g_list_next (l)) {
+					gchar *col_name = (gchar *) l->data;
+
+					gda_data_model_set_column_title (recset, i, col_name);
+					i += 1;
+				}
+
 				reclist = g_list_append (reclist, recset);
 			}
+			g_list_free (columns);
 			n++;
 		}
 
@@ -620,12 +683,52 @@
 				    GdaParameterList *params)
 {
 	GList *reclist = NULL;
+	gchar *str;
 	GdaOracleProvider *ora_prv = (GdaOracleProvider *) provider;
+	GdaOracleConnectionData *priv_data;
 
+	GdaCommandOptions options;
+	GdaTransaction *xaction;
+
 	g_return_val_if_fail (GDA_IS_ORACLE_PROVIDER (ora_prv), NULL);
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
 	g_return_val_if_fail (cmd != NULL, NULL);
 
+	priv_data = g_object_get_data (G_OBJECT (cnc), OBJECT_DATA_ORACLE_HANDLE);
+	if (!priv_data) {
+		gda_connection_add_error_string (cnc, _("Invalid Oracle handle"));
+		return FALSE;
+	}
+
+	options = gda_command_get_options (cmd);
+	xaction = gda_command_get_transaction (cmd);
+
+	if (xaction != NULL) {
+		GdaOracleTransaction *ora_xaction = g_object_get_data (G_OBJECT (xaction), OBJECT_DATA_ORACLE_HANDLE);
+		/* attach a transaction */
+		if (OCI_SUCCESS !=
+			OCIAttrSet ((dvoid *) priv_data->hservice,
+					OCI_HTYPE_SVCCTX,
+					(dvoid *) ora_xaction->txnhp,
+					0,
+					OCI_ATTR_TRANS,
+					priv_data->herr)) {
+			gda_connection_add_error (cnc, gda_oracle_make_error (priv_data));
+			return FALSE;
+		}
+	}
+
+	switch (gda_command_get_command_type (cmd)) {
+	case GDA_COMMAND_TYPE_SQL:
+		reclist = process_sql_commands (reclist, cnc, gda_command_get_text (cmd), NULL, options);
+		break;
+	case GDA_COMMAND_TYPE_TABLE:
+		str = g_strdup_printf ("SELECT * FROM %s", gda_command_get_text (cmd));
+		reclist = process_sql_commands (reclist, cnc, str, NULL, options);
+		g_free (str);
+		break;
+	default:
+	}
 	/* don't know what to do here yet. */
 	return reclist;
 }
@@ -641,13 +744,11 @@
 	GdaOracleTransaction *ora_xaction;
 	gchar *xaction_name;
 
-
 	g_return_val_if_fail (GDA_IS_ORACLE_PROVIDER (ora_prv), FALSE);
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 	g_return_val_if_fail (xaction != NULL, FALSE);
 
 	priv_data = g_object_get_data (G_OBJECT (cnc), OBJECT_DATA_ORACLE_HANDLE);
-
 	ora_xaction = g_new0 (GdaOracleTransaction, 1);
 
 	if (!priv_data) {
@@ -728,18 +829,17 @@
 	}
 
 	/* attach the transaction to the service context */
-	/*
 	if (OCI_SUCCESS !=
 		OCIAttrSet ((dvoid *) priv_data->hservice,
 				OCI_HTYPE_SVCCTX,
-				(dvoid *) txnhp,
+				(dvoid *) ora_xaction->txnhp,
 				0,
 				OCI_ATTR_TRANS,
 				priv_data->herr)) {
 		gda_connection_add_error (cnc, gda_oracle_make_error (priv_data));
 		return FALSE;
 	}
-	*/
+	
 
 	/* prepare to commit.  This may return OCI_SUCCESS_WITH_INFO.?? */
 	if (OCI_SUCCESS != 
@@ -785,21 +885,17 @@
 		return FALSE;
 	}
 
-	/* get the transaction object */
-
 	/* attach the transaction to the service context */
-	/*
 	if (OCI_SUCCESS !=
 		OCIAttrSet ((dvoid *) priv_data->hservice,
 				OCI_HTYPE_SVCCTX,
-				(dvoid *) txnhp,
+				(dvoid *) ora_xaction->txnhp,
 				0,
 				OCI_ATTR_TRANS,
 				priv_data->herr)) {
 		gda_connection_add_error (cnc, gda_oracle_make_error (priv_data));
 		return FALSE;
 	}
-	*/
 
 	if (OCI_SUCCESS != 
 		OCITransRollback (priv_data->hservice, 
@@ -917,122 +1013,208 @@
 	return GDA_DATA_MODEL (recset);
 }
 
-static GdaDataModel *
-get_oracle_databases (GdaConnection *cnc, GdaParameterList *params)
+static GdaDataModelArray *
+gda_oracle_init_md_recset (GdaConnection *cnc)
 {
-	GList *reclist;
-	GdaOracleRecordset *recset;
-
-	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
-
-	reclist = process_sql_commands (NULL, cnc, "show databases");
-	if (!reclist)
-		return NULL;
-
-	recset = GDA_ORACLE_RECORDSET (reclist->data);
-	g_list_free (reclist);
-
-	return GDA_DATA_MODEL (recset);
-}
-
-static GdaDataModel *
-get_oracle_indexes (GdaConnection *cnc, GdaParameterList *params)
-{
-	GList *reclist;
-	GdaDataModel *recset;
-
-	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
-
-	reclist = process_sql_commands (NULL, cnc, "select object_name from user_objects where object_type='INDEX'");
-	if (!reclist)
-		return NULL;
-
-	recset = GDA_DATA_MODEL (reclist->data);
-	g_list_free (reclist);
-
-	gda_data_model_set_column_title (recset, 0, _("Indexes"));
+	GdaDataModelArray *recset;
+	gint i;
+	GdaOracleColData cols[8] = {
+		{ N_("Field name")	, GDA_VALUE_TYPE_STRING },
+		{ N_("Data type")	, GDA_VALUE_TYPE_STRING },
+		{ N_("Size")		, GDA_VALUE_TYPE_INTEGER },
+		{ N_("Scale")		, GDA_VALUE_TYPE_INTEGER },
+		{ N_("Not null?")	, GDA_VALUE_TYPE_BOOLEAN },
+		{ N_("Primary key?")	, GDA_VALUE_TYPE_BOOLEAN },
+		{ N_("Unique index?")	, GDA_VALUE_TYPE_BOOLEAN },
+		{ N_("References")	, GDA_VALUE_TYPE_STRING }
+	};
 
+	recset = GDA_DATA_MODEL_ARRAY (gda_data_model_array_new (sizeof cols / sizeof cols[0]));
+	for (i = 0; i < sizeof cols / sizeof cols[0]; i += 1)
+		gda_data_model_set_column_title (GDA_DATA_MODEL (recset), i, _(cols[i].col_name));
 	return recset;
 }
 
-static GdaDataModel *
-get_oracle_procedures (GdaConnection *cnc, GdaParameterList *params)
-{
-	GList *reclist;
-	GdaDataModel *recset;
-
-	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+static GList *
+gda_oracle_fill_md_data (const gchar *tblname, 
+			GdaDataModelArray *recset,
+			GdaOracleConnectionData *priv_data)
+{
+	OCIDescribe *dschp = (OCIDescribe *) 0;
+	OCIParam *parmh;    /* parameter handle */
+	OCIParam *collsthd; /* handle to list of columns */
+	OCIParam *colhd;    /* column handle */
+	gint i;
+	ub2 numcols;
+	GList *list = NULL;
 
-	reclist = process_sql_commands (NULL, cnc, "select object_name from user_objects where object_type='PROCEDURE'");
-	if (!reclist)
+	/* Allocate the Describe handle */
+	if (OCI_SUCCESS != 
+		OCIHandleAlloc ((dvoid *) priv_data->henv,
+				(dvoid **) &dschp,
+				(ub4) OCI_HTYPE_DESCRIBE,
+				(size_t) 0, 
+				(dvoid **) 0)) {
 		return NULL;
-
-	recset = GDA_DATA_MODEL (reclist->data);
-	g_list_free (reclist);
-
-	gda_data_model_set_column_title (recset, 0, _("Sequences"));
-
-	return recset;
-}
-
-static GdaDataModel *
-get_oracle_sequences (GdaConnection *cnc, GdaParameterList *params)
-{
-	GList *reclist;
-	GdaDataModel *recset;
-
-	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+	}
 
-	reclist = process_sql_commands (NULL, cnc, "select object_name from user_objects where object_type='SEQUENCE'");
-	if (!reclist)
+	/* Describe the table */
+	if (OCI_SUCCESS != 
+		OCIDescribeAny (priv_data->hservice,
+				priv_data->herr,
+				(text *) tblname,
+				strlen (tblname),
+				OCI_OTYPE_NAME,
+				0,
+				OCI_PTYPE_TABLE,
+				(OCIDescribe *) dschp)) {
 		return NULL;
-
-	recset = GDA_DATA_MODEL (reclist->data);
-	g_list_free (reclist);
-
-	gda_data_model_set_column_title (recset, 0, _("Sequences"));
-
-	return recset;
-}
+	}
 
-static GdaDataModel *
-get_oracle_tables (GdaConnection *cnc, GdaParameterList *params)
-{
-	GList *reclist;
-	GdaDataModel *recset;
+	/* Get the parameter handle */
+	if (OCI_SUCCESS != 
+		OCIAttrGet ((dvoid *) dschp,
+				(ub4) OCI_HTYPE_DESCRIBE, 
+				(dvoid **) &parmh,
+				(ub4 *) 0,
+				(ub4) OCI_ATTR_PARAM,
+				(OCIError *) priv_data->herr)) {
+		return NULL;
+	}
 
-	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+	/* Get the number of columns */
+	if (OCI_SUCCESS !=
+		OCIAttrGet ((dvoid *) parmh,
+				(ub4) OCI_DTYPE_PARAM,
+				(dvoid *) &numcols,
+				(ub4 *) 0,
+				(ub4) OCI_ATTR_NUM_COLS,
+				(OCIError *) priv_data->herr)) {
+		return NULL;
+	}
 
-	reclist = process_sql_commands (NULL, cnc, "select object_name from user_objects where object_type='TABLE'");
-	if (!reclist)
+	if (OCI_NO_DATA ==
+		OCIAttrGet ((dvoid *) parmh,
+				(ub4) OCI_DTYPE_PARAM,
+				(dvoid *) &collsthd,
+				(ub4 *) 0,
+				(ub4) OCI_ATTR_LIST_COLUMNS,
+				(OCIError *) priv_data->herr)) {
 		return NULL;
+	}
 
-	recset = GDA_DATA_MODEL (reclist->data);
-	g_list_free (reclist);
+	for (i = 1; i <= numcols; i += 1) {
+		text *strp;
+		ub4 sizep;
+		ub2 type;
+		gchar *colname;
+		gchar *typename;
+		ub2 nullable;
+		ub2 defined_size;
+		ub2 scale;
+
+		GdaValue *value;
+		GList *rowlist = NULL;
+
+		/* Get the column handle */
+		if (OCI_SUCCESS != 
+			OCIParamGet ((dvoid *) collsthd,
+					(ub4) OCI_DTYPE_PARAM,
+					(OCIError *) priv_data->herr,
+					(dvoid **) &colhd,
+					(ub2) i)) {
+			return NULL;
+		}
+		
+		/* Field name */
+		if (OCI_SUCCESS !=
+			OCIAttrGet ((dvoid *) colhd,
+					(ub4) OCI_DTYPE_PARAM,
+					(dvoid *) &strp,
+					(ub4 *) &sizep,
+					(ub4) OCI_ATTR_NAME,
+					(OCIError *) priv_data->herr)) {
+			return NULL;
+		}
 
-	gda_data_model_set_column_title (recset, 0, _("Tables"));
+		colname = g_malloc0 (sizep + 1);
+		memcpy (colname, strp, (size_t) sizep);
+		colname[sizep] = '\0';
+		value = gda_value_new_string (colname);
+		rowlist = g_list_append (rowlist, value);
+
+		/* Data type */
+		typename = g_malloc0 (31);
+		if (OCI_SUCCESS !=
+			OCIAttrGet ((dvoid *)colhd,
+					(ub4) OCI_DTYPE_PARAM,
+					(dvoid *) &type,
+					(ub4 *) 0,
+					(ub4) OCI_ATTR_DATA_TYPE,
+					(OCIError *) priv_data->herr)) {
+			return NULL;
+		}
 
-	return recset;
-}
+		typename = oracle_sqltype_to_string (type);
+		value = gda_value_new_string (typename);
+		rowlist = g_list_append (rowlist, value);
+
+		/* Defined Size */
+		if (OCI_SUCCESS !=
+			OCIAttrGet ((dvoid *)colhd,
+					(ub4) OCI_DTYPE_PARAM,
+					(dvoid *) &defined_size,
+					(ub4 *) 0,
+					(ub4) OCI_ATTR_DATA_SIZE,
+					(OCIError *) priv_data->herr)) {
+			return NULL;
+		}
+		value = gda_value_new_integer (defined_size);
+		rowlist = g_list_append (rowlist, value);
 
-static GdaDataModel *
-get_oracle_triggers (GdaConnection *cnc, GdaParameterList *params)
-{
-	GList *reclist;
-	GdaDataModel *recset;
+		/* Scale */
+		if (OCI_SUCCESS !=
+			OCIAttrGet ((dvoid *)colhd,
+					(ub4) OCI_DTYPE_PARAM,
+					(dvoid *) &scale,
+					(ub4 *) 0,
+					(ub4) OCI_ATTR_SCALE,
+					(OCIError *) priv_data->herr)) {
+			return NULL;
+		}
+		value = gda_value_new_integer (scale);
+		rowlist = g_list_append (rowlist, value);
 
-	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+		/* Not null? */
+		if (OCI_SUCCESS !=
+			OCIAttrGet ((dvoid *)colhd,
+					(ub4) OCI_DTYPE_PARAM,
+					(dvoid *) &nullable,
+					(ub4 *) 0,
+					(ub4) OCI_ATTR_DATA_SIZE,
+					(OCIError *) priv_data->herr)) {
+			return NULL;
+		}
+		value = gda_value_new_boolean (nullable > 0);
+		rowlist = g_list_append (rowlist, value);
 
-	reclist = process_sql_commands (NULL, cnc, "select object_name from user_objects where object_type='TRIGGER'");
-	if (!reclist)
-		return NULL;
+		/* primary key? */
+		value = gda_value_new_boolean (FALSE); // FIXME
+		rowlist = g_list_append (rowlist, value);
 
-	recset = GDA_DATA_MODEL (reclist->data);
-	g_list_free (reclist);
+		/* unique? */
+		value = gda_value_new_boolean (FALSE); // FIXME
+		rowlist = g_list_append (rowlist, value);
 
-	gda_data_model_set_column_title (recset, 0, _("Triggers"));
+		/* references */
+		value = gda_value_new_string ("");  // FIXME
+		rowlist = g_list_append (rowlist, value);
 
-	return recset;
+		list = g_list_append (list, rowlist);
+		rowlist = NULL;
+	}
+
+	return list;
 }
 
 static GdaDataModel *
@@ -1043,7 +1225,9 @@
 
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
 
-	reclist = process_sql_commands (NULL, cnc, "select username from user_users");
+	reclist = process_sql_commands (NULL, cnc, "SELECT USERNAME FROM USER_USERS",
+			NULL, GDA_COMMAND_OPTION_STOP_ON_ERRORS);
+
 	if (!reclist)
 		return NULL;
 
@@ -1056,22 +1240,55 @@
 }
 
 static GdaDataModel *
-get_oracle_views (GdaConnection *cnc, GdaParameterList *params)
+get_oracle_objects (GdaConnection *cnc, GdaParameterList *params, GdaConnectionSchema schema)
 {
 	GList *reclist;
 	GdaDataModel *recset;
-
+	gchar *sql = "SELECT OBJECT_NAME FROM USER_OBJECTS WHERE OBJECT_TYPE=:OBJ_TYPE";
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+
+	if (!params)
+		params = gda_parameter_list_new ();
+
+	/* add the object type parameter */
+	switch (schema) {
+	case GDA_CONNECTION_SCHEMA_INDEXES:
+		gda_parameter_list_add_parameter (params, 
+			gda_parameter_new_string (":OBJ_TYPE", "INDEX"));
+		break;
+	case GDA_CONNECTION_SCHEMA_PROCEDURES:
+		gda_parameter_list_add_parameter (params, 
+			gda_parameter_new_string (":OBJ_TYPE", "PROCEDURE"));
+		break;
+	case GDA_CONNECTION_SCHEMA_SEQUENCES:
+		gda_parameter_list_add_parameter (params, 
+			gda_parameter_new_string (":OBJ_TYPE", "SEQUENCE"));
+		break;
+	case GDA_CONNECTION_SCHEMA_TABLES:
+		gda_parameter_list_add_parameter (params, 
+			gda_parameter_new_string (":OBJ_TYPE", "TABLE"));
+		break;
+	case GDA_CONNECTION_SCHEMA_TRIGGERS:
+		gda_parameter_list_add_parameter (params, 
+			gda_parameter_new_string (":OBJ_TYPE", "TRIGGER"));
+		break;
+	case GDA_CONNECTION_SCHEMA_VIEWS:
+		gda_parameter_list_add_parameter (params, 
+			gda_parameter_new_string (":OBJ_TYPE", "VIEW"));
+		break;
+	default:
+		return NULL;
+	}
+
+	reclist = process_sql_commands (NULL, cnc, sql, params,
+			GDA_COMMAND_OPTION_STOP_ON_ERRORS);
 
-	reclist = process_sql_commands (NULL, cnc, "select object_name from user_objects where object_type='VIEW'");
 	if (!reclist)
 		return NULL;
 
 	recset = GDA_DATA_MODEL (reclist->data);
 	g_list_free (reclist);
 
-	gda_data_model_set_column_title (recset, 0, _("Views"));
-
 	return recset;
 }
 
@@ -1084,10 +1301,7 @@
 
 	/* create the recordset */
 	recset = (GdaDataModelArray *) gda_data_model_array_new (1);
-	//gda_server_recordset_model_set_field_defined_size (recset, 0, 32);
 	gda_data_model_set_column_title (GDA_DATA_MODEL (recset), 0, _("Type"));
-	//gda_server_recordset_model_set_field_scale (recset, 0, 0);
-	//gda_server_recordset_model_set_field_gdatype (recset, 0, GDA_TYPE_STRING);
 
 	/* fill the recordset */
 	add_string_row (recset, "blob");
@@ -1111,63 +1325,46 @@
 	return GDA_DATA_MODEL (recset);
 }
 
+static void 
+add_g_list_row (gpointer data, gpointer user_data)
+{
+	GList *rowlist = data;
+	GdaDataModelArray *recset = user_data;
+
+	gda_data_model_append_row (GDA_DATA_MODEL (recset), rowlist);
+	g_list_foreach (rowlist, (GFunc) gda_value_free, NULL);
+	g_list_free (rowlist);
+}
 
 static GdaDataModel *
-get_table_fields (GdaConnection *cnc, GdaParameterList *params)
+get_oracle_fields_metadata (GdaConnection *cnc, GdaParameterList *params)
 {
-	const gchar *table_name;
-	GdaParameter *par;
-	/*gchar *cmd_str;*/
-	/*GdaDataModelArray *recset;*/
-	/*gint rows, r;*/
+	GList *list;
 	GdaOracleConnectionData *priv_data;
-
-	/*
-	struct {
-		const gchar *name;
-		GdaValueType type;
-	} fields_desc[8] = {
-		{ N_("Field name")	, GDA_VALUE_TYPE_STRING  },
-		{ N_("Data type")	, GDA_VALUE_TYPE_STRING  },
-		{ N_("Size")		, GDA_VALUE_TYPE_INTEGER },
-		{ N_("Scale")		, GDA_VALUE_TYPE_INTEGER },
-		{ N_("Not null?")	, GDA_VALUE_TYPE_BOOLEAN },
-		{ N_("Primary key?")	, GDA_VALUE_TYPE_BOOLEAN },
-		{ N_("Unique index?")	, GDA_VALUE_TYPE_BOOLEAN },
-		{ N_("References")	, GDA_VALUE_TYPE_STRING  }
-	};
-	*/
+	GdaDataModelArray *recset;
+	GdaParameter *par;
+	const gchar *tblname;
 
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
 	g_return_val_if_fail (params != NULL, NULL);
 
-	priv_data = g_object_get_data (G_OBJECT (cnc), OBJECT_DATA_ORACLE_HANDLE);
-	if (!priv_data) {
-		gda_connection_add_error_string (cnc, _("Invalid Oracle handle"));
-		return NULL;
-	}
-
-	/* get parameters sent by client */
 	par = gda_parameter_list_find (params, "name");
-	if (!par) {
-		gda_connection_add_error_string (
-			cnc,
-			_("You need to specify the name of the table"));
-		return NULL;
-	}
+	g_return_val_if_fail (par != NULL, NULL);
+	
+	tblname = gda_value_get_string ((GdaValue *) gda_parameter_get_value (par));
+	g_return_val_if_fail (tblname != NULL, NULL);
 
-	table_name = gda_value_get_string ((GdaValue *) gda_parameter_get_value (par));
-	if (!table_name) {
-		gda_connection_add_error_string (
-			cnc,
-			_("You need to specify the name of the table"));
-		return NULL;
-	}
+	priv_data = g_object_get_data (G_OBJECT (cnc), OBJECT_DATA_ORACLE_HANDLE);
 
-	/*return GDA_DATA_MODEL (recset);*/
-	return NULL;
+	recset = gda_oracle_init_md_recset (cnc);
+	list = gda_oracle_fill_md_data (tblname, recset, priv_data);
+	g_list_foreach (list, add_g_list_row, recset);
+	g_list_free (list);
+
+	return GDA_DATA_MODEL (recset);
 }
 
+
 /* get_schema handler for the GdaOracleProvider class */
 static GdaDataModel *
 gda_oracle_provider_get_schema (GdaServerProvider *provider,
@@ -1175,32 +1372,43 @@
 			       GdaConnectionSchema schema,
 			       GdaParameterList *params)
 {
-	g_return_val_if_fail (GDA_IS_SERVER_PROVIDER (provider), NULL);
-	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+	GdaDataModel *recset;
 
 	switch (schema) {
 	case GDA_CONNECTION_SCHEMA_AGGREGATES :
 		return get_oracle_aggregates (cnc, params);
-	case GDA_CONNECTION_SCHEMA_DATABASES :
-		return get_oracle_databases (cnc, params);
 	case GDA_CONNECTION_SCHEMA_FIELDS :
-		return get_table_fields (cnc, params);
+		return get_oracle_fields_metadata (cnc, params);
+	case GDA_CONNECTION_SCHEMA_TYPES :
+		return get_oracle_types (cnc, params);
+	case GDA_CONNECTION_SCHEMA_USERS :
+		return get_oracle_users (cnc, params);
+	case GDA_CONNECTION_SCHEMA_DATABASES :
+		return NULL;
 	case GDA_CONNECTION_SCHEMA_INDEXES :
-		return get_oracle_indexes (cnc, params);
+		recset = get_oracle_objects (cnc, params, schema);
+		gda_data_model_set_column_title (recset, 0, _("Indexes"));
+		return recset;
 	case GDA_CONNECTION_SCHEMA_PROCEDURES :
-		return get_oracle_procedures (cnc, params);
+		recset = get_oracle_objects (cnc, params, schema);
+		gda_data_model_set_column_title (recset, 0, _("Procedures"));
+		return recset;
 	case GDA_CONNECTION_SCHEMA_SEQUENCES :
-		return get_oracle_sequences (cnc, params);
+		recset = get_oracle_objects (cnc, params, schema);
+		gda_data_model_set_column_title (recset, 0, _("Sequences"));
+		return recset;
 	case GDA_CONNECTION_SCHEMA_TABLES :
-		return get_oracle_tables (cnc, params);
+		recset = get_oracle_objects (cnc, params, schema);
+		gda_data_model_set_column_title (recset, 0, _("Tables"));
+		return recset;
 	case GDA_CONNECTION_SCHEMA_TRIGGERS :
-		return get_oracle_triggers (cnc, params);
-	case GDA_CONNECTION_SCHEMA_TYPES :
-		return get_oracle_types (cnc, params);
-	case GDA_CONNECTION_SCHEMA_USERS :
-		return get_oracle_users (cnc, params);
+		recset = get_oracle_objects (cnc, params, schema);
+		gda_data_model_set_column_title (recset, 0, _("Triggers"));
+		return recset;
 	case GDA_CONNECTION_SCHEMA_VIEWS :
-		return get_oracle_views (cnc, params);
+		recset = get_oracle_objects (cnc, params, schema);
+		gda_data_model_set_column_title (recset, 0, _("Views"));
+		return recset;
 	default :
 	}
 
Index: gda-oracle-provider.h
===================================================================
RCS file: /cvs/gnome/libgda/providers/oracle/gda-oracle-provider.h,v
retrieving revision 1.3
diff -u -u -r1.3 gda-oracle-provider.h
--- gda-oracle-provider.h	2002/06/06 21:57:25	1.3
+++ gda-oracle-provider.h	2002/06/18 04:30:00
@@ -49,7 +49,6 @@
 	OCIServer *hserver;
 	OCISvcCtx *hservice;
 	OCISession *hsession;
-	OCIStmt *hstmt;
 	sword stmt_type;
 } GdaOracleConnectionData;
 
@@ -61,7 +60,6 @@
 
 GType                gda_oracle_provider_get_type (void);
 GdaServerProvider   *gda_oracle_provider_new (void);
-GdaValueType  oracle_sqltype_to_gda_type (const ub2 sqltype);
 
 
 G_END_DECLS
Index: gda-oracle-recordset.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/oracle/gda-oracle-recordset.c,v
retrieving revision 1.1
diff -u -u -r1.1 gda-oracle-recordset.c
--- gda-oracle-recordset.c	2002/06/06 21:57:25	1.1
+++ gda-oracle-recordset.c	2002/06/18 04:30:00
@@ -33,23 +33,15 @@
 struct _GdaOracleRecordsetPrivate {
 	GdaConnection *cnc;
 	GdaOracleConnectionData *cdata;
-	GdaValueType *column_types;
 
-	GdaOracleValue *ora_values;
+	GList *ora_values;
 	GPtrArray *rows;
+	OCIStmt *hstmt;
 
 	gint ncolumns;
 	gint nrows;
 };
 
-struct _GdaOracleValue {
-	OCIDefine *hdef;
-	OCIParam *pard;
-	sb2 indicator;
-	ub2 sql_type;
-	ub2 defined_size;
-	gpointer value;
-};
 
 static void gda_oracle_recordset_class_init (GdaOracleRecordsetClass *klass);
 static void gda_oracle_recordset_init       (GdaOracleRecordset *recset,
@@ -61,71 +53,71 @@
 /*
  * Private functions
  */
-
-static GdaValueType *
-get_column_types (GdaOracleRecordsetPrivate *priv)
-{	
-	GdaValueType *types;
-	gint i;
-
-	types = g_new (GdaValueType, priv->ncolumns);
-	for (i = 0; i < priv->ncolumns; i += 1) {
-		types[i] = oracle_sqltype_to_gda_type (priv->ora_values[i].sql_type);
-	}
-	return types;
-}
 
-static GdaOracleValue *
+static GList *
 define_columns (GdaOracleRecordsetPrivate *priv)
 {
-	GdaOracleValue *fields;
+	GList *fields = NULL;
+	GdaOracleValue *ora_value;
 	gint i;
 
-	fields = g_new (GdaOracleValue, priv->ncolumns);
-
 	for (i = 0; i < priv->ncolumns; i += 1) {
-
+		ora_value = g_new0 (GdaOracleValue, 1);
                 if (OCI_SUCCESS != 
-			OCIParamGet (priv->cdata->hstmt,
+			OCIParamGet (priv->hstmt,
 					OCI_HTYPE_STMT,
 					priv->cdata->herr,
-					(dvoid **) &(fields[i].pard),
+					(dvoid **) &(ora_value->pard),
 					(ub4) i+1)) {
+			gda_connection_add_error_string (priv->cnc, 
+				_("Could not get the Oracle parameter"));
 			break;
 		}
 
-		OCIAttrGet ((dvoid *) (fields[i].pard),
+		OCIAttrGet ((dvoid *) (ora_value->pard),
 				OCI_DTYPE_PARAM,
-				&(fields[i].defined_size),
+				&(ora_value->defined_size),
 				0,
 				OCI_ATTR_DATA_SIZE,
 				priv->cdata->herr);
 
-		OCIAttrGet ((dvoid *) (fields[i].pard),
+		OCIAttrGet ((dvoid *) (ora_value->pard),
 				OCI_DTYPE_PARAM,
-				&(fields[i].sql_type),
+				&(ora_value->sql_type),
 				0,
 				OCI_ATTR_DATA_TYPE,
 				priv->cdata->herr);
+
+		switch (ora_value->sql_type) {
+		case SQLT_NUM: // Numerics are coerced to string
+			ora_value->sql_type = SQLT_CHR;
+			break;
+		case SQLT_DAT: // Convert SQLT_DAT to OCIDate
+			ora_value->sql_type = SQLT_ODT;
+			break;
+		}
 
-		fields[i].value = g_malloc0 (fields[i].defined_size);
-		fields[i].hdef = NULL;
-		fields[i].indicator = 0;
+		ora_value->value = g_malloc0 (ora_value->defined_size);
+		ora_value->hdef = (OCIDefine *) 0;
+		ora_value->indicator = 0;
+		ora_value->gda_type = oracle_sqltype_to_gda_type (ora_value->sql_type);
 
 		if (OCI_SUCCESS !=
-			OCIDefineByPos ((OCIStmt *) priv->cdata->hstmt,
-					(OCIDefine **) &(fields[i].hdef),
+			OCIDefineByPos ((OCIStmt *) priv->hstmt,
+					(OCIDefine **) &(ora_value->hdef),
 					(OCIError *) priv->cdata->herr,
 					(ub4) i + 1,
-					(dvoid *)fields[i].value,
-					fields[i].defined_size,
-					(ub2) fields[i].sql_type,
-					(dvoid *) &(fields[i].indicator),
-					(ub2) 0,
-					(ub2) 0, 
+					ora_value->value,
+					ora_value->defined_size,
+					(ub2) ora_value->sql_type,
+					(dvoid *) &(ora_value->indicator),
+					(ub2 *) 0,
+					(ub2 *) 0, 
 					(ub4) OCI_DEFAULT)) {
-			break;
+			gda_connection_add_error_string (priv->cnc, _("Could not define by position"));
+			return NULL;
 		}
+		fields = g_list_append (fields, ora_value);
 	}
 	return fields;
 }
@@ -141,23 +133,22 @@
 	GdaOracleRecordset *recset = (GdaOracleRecordset *) model;
 	GdaOracleRecordsetPrivate *priv_data;
 	GdaFieldAttributes *field_attrs;
-	OCIStmt *stmthp;
 	OCIParam *pard;
 	gchar *pgchar_dummy;
 	glong col_name_len;
 
 	gchar name_buffer[ORA_NAME_BUFFER_SIZE + 1];
 	ub2 sql_type;
-	ub2 scale;
-	ub2 nullable;
+	sb1 scale;
+	ub1 nullable;
+	ub2 defined_size;
 
 	g_return_val_if_fail (GDA_IS_ORACLE_RECORDSET (recset), NULL);
 	g_return_val_if_fail (recset->priv != NULL, NULL);
 
 	priv_data = recset->priv;
-	stmthp = priv_data->cdata->hstmt;
 
-	if (!stmthp) {
+	if (!priv_data->cdata) {
 		gda_connection_add_error_string (priv_data->cnc, 
 						_("Invalid Oracle handle"));
 		return NULL;
@@ -172,47 +163,60 @@
 	field_attrs = gda_field_attributes_new ();
 
 	if (OCI_SUCCESS !=
-		OCIParamGet (stmthp,
-				OCI_HTYPE_STMT,
-				priv_data->cdata->herr,
+		OCIParamGet ((dvoid *) priv_data->hstmt,
+				(ub4) OCI_HTYPE_STMT,
+				(OCIError *) priv_data->cdata->herr,
 				(dvoid **) &pard,
-				(ub4) col)) {
+				(ub4) col + 1)) {
 		gda_connection_add_error_string (priv_data->cnc, 
 						_("Could not retrieve the parameter information from Oracle"));
+		return NULL;
 	}
+
 	OCIAttrGet ((dvoid *) pard,
-			OCI_DTYPE_PARAM,
-			&pgchar_dummy,
+			(ub4) OCI_DTYPE_PARAM,
+			(dvoid **) &pgchar_dummy,
 			(ub4 *) & col_name_len,
-			OCI_ATTR_NAME,
-			priv_data->cdata->herr);
+			(ub4) OCI_ATTR_NAME,
+			(OCIError *) priv_data->cdata->herr);
 
 	memcpy (name_buffer, pgchar_dummy, col_name_len);
 	name_buffer[col_name_len] = '\0';
 
 	OCIAttrGet ((dvoid *) pard,
-			OCI_DTYPE_PARAM,
-			&sql_type,
-			0,
-			OCI_ATTR_DATA_TYPE,
-			priv_data->cdata->herr);
+			(ub4) OCI_DTYPE_PARAM,
+			(dvoid *) &sql_type,
+			(ub4 *) 0,
+			(ub4) OCI_ATTR_DATA_TYPE,
+			(OCIError *) priv_data->cdata->herr);
+
 	OCIAttrGet ((dvoid *) pard,
-			OCI_DTYPE_PARAM,
-			&scale,
-			0,
-			OCI_ATTR_SCALE,
-			priv_data->cdata->herr);
+			(ub4) OCI_DTYPE_PARAM,
+			(sb1 *) &scale,
+			(ub4 *) 0,
+			(ub4) OCI_ATTR_SCALE,
+			(OCIError *) priv_data->cdata->herr);
+
+	OCIAttrGet ((dvoid *) pard,
+			(ub4) OCI_DTYPE_PARAM,
+			(ub1 *) &nullable,
+			(ub4 *) 0,
+			(ub4) OCI_ATTR_IS_NULL,
+			(OCIError *) priv_data->cdata->herr);
+
 	OCIAttrGet ((dvoid *) pard,
 			OCI_DTYPE_PARAM,
-			&nullable,
+			&defined_size,
 			0,
-			OCI_ATTR_IS_NULL,
+			OCI_ATTR_DATA_SIZE,
 			priv_data->cdata->herr);
 
 	gda_field_attributes_set_name (field_attrs, name_buffer);
 	gda_field_attributes_set_scale (field_attrs, scale);
 	gda_field_attributes_set_gdatype (field_attrs, oracle_sqltype_to_gda_type (sql_type));
-	gda_field_attributes_set_defined_size (field_attrs, priv_data->ora_values[col].defined_size);
+	gda_field_attributes_set_defined_size (field_attrs, defined_size);
+
+	/* FIXME */
 	gda_field_attributes_set_references (field_attrs, "");
 
 	/* FIXME */
@@ -221,7 +225,7 @@
 	/* FIXME */
 	gda_field_attributes_set_unique_key (field_attrs, FALSE);
 
-	gda_field_attributes_set_allow_null (field_attrs, nullable);
+	gda_field_attributes_set_allow_null (field_attrs, !(nullable == 0));
 	
 	return field_attrs;
 }
@@ -244,7 +248,7 @@
 
 	while (fetch_status == OCI_SUCCESS) {
 		i += 1;
-		fetch_status = OCIStmtFetch (priv_data->cdata->hstmt,
+		fetch_status = OCIStmtFetch (priv_data->hstmt,
 				priv_data->cdata->herr,
 				(ub4) 1,
 				(ub2) OCI_FETCH_NEXT,
@@ -255,7 +259,7 @@
 
 	// reset the result set to the beginning
 	OCIStmtExecute (priv_data->cdata->hservice,
-			priv_data->cdata->hstmt,
+			priv_data->hstmt,
 			priv_data->cdata->herr,
 			(ub4) ((OCI_STMT_SELECT == priv_data->cdata->stmt_type) ? 0 : 1),
 			(ub4) 0,
@@ -280,15 +284,12 @@
 static GdaRow *
 fetch_row (GdaOracleRecordset *recset, gint rownum)
 {
-	gpointer thevalue;
-	GdaValueType ftype;
-	gboolean isNull;
-	GdaValue *value;
 	GdaRow *row;
 	gint i;
 	gchar *id;
-	gint defined_size;
 	GdaOracleRecordsetPrivate *priv;
+	GList *node;
+	ub4 status;
 
 	g_return_val_if_fail (GDA_IS_ORACLE_RECORDSET (recset), NULL);
 	g_return_val_if_fail (recset->priv != NULL, NULL);
@@ -297,22 +298,29 @@
 
 	row = gda_row_new (priv->ncolumns);
 
-	if (OCI_SUCCESS !=
-		OCIStmtFetch (priv->cdata->hstmt,
-				priv->cdata->herr,
-				(ub4) rownum + 1,
+	status = OCIStmtFetch ((OCIStmt *) priv->hstmt,
+				(OCIError *) priv->cdata->herr,
+				(ub4) 1,
 				(ub2) OCI_FETCH_NEXT,
-				(ub4) OCI_DEFAULT)) {
+				(ub4) OCI_DEFAULT); 
+	switch (status) {
+	case OCI_SUCCESS:
+	case OCI_SUCCESS_WITH_INFO:
+		break;
+	case OCI_NO_DATA:
+		return NULL;
+	default:
+		gda_connection_add_error_string (priv->cnc, _("An error occurred during fetch"));
 		return NULL;
 	}
 
-	for (i = 0; i < priv->ncolumns; i += 1) {
-		thevalue = priv->ora_values[i].value;
-		ftype = priv->column_types[i];
-		defined_size = priv->ora_values[i].defined_size;
-		isNull = FALSE; // FIXME
-		value = gda_row_get_value (row, i);
-		gda_oracle_set_value (value, ftype, thevalue, isNull, defined_size);
+	i = 0;
+	for (node = g_list_first (priv->ora_values); node != NULL; 
+	     node = g_list_next (node)) {
+		GdaOracleValue *ora_value = (GdaOracleValue *) node->data;
+		GdaValue *value = gda_row_get_value (row, i);
+		gda_oracle_set_value (value, ora_value, priv->cnc);
+		i += 1;
 	}
 
 	id = g_strdup_printf ("%d", rownum);
@@ -341,7 +349,8 @@
 	}
 
 	fetched_rows = priv_data->rows->len;
-	if (row >= priv_data->nrows)
+
+	if (row >= priv_data->nrows && priv_data->nrows > 0)
 		return NULL;
 
 	if (row < fetched_rows)
@@ -350,8 +359,8 @@
 	gda_data_model_freeze (GDA_DATA_MODEL (recset));
 
 	for (i = fetched_rows; i <= row; i += 1) {
-		fields = fetch_row (recset, 0);
-		if (!fields)
+		fields = fetch_row (recset, i);
+		if (!fields) 
 			return NULL;
 		g_ptr_array_add (priv_data->rows, fields);
 	}
@@ -383,13 +392,103 @@
 static gboolean
 gda_oracle_recordset_is_editable (GdaDataModel *model)
 {
-	return FALSE;
+	GdaCommandType cmd_type;
+	GdaOracleRecordset *recset = (GdaOracleRecordset *) model;
+
+	g_return_val_if_fail (GDA_IS_ORACLE_RECORDSET (recset), FALSE);
+
+	cmd_type = gda_data_model_get_command_type (model);
+
+	return cmd_type == GDA_COMMAND_TYPE_TABLE ? TRUE : FALSE;
 }
 
 static const GdaRow *
 gda_oracle_recordset_append_row (GdaDataModel *model, const GList *values)
 {
-	return NULL;
+	GString *sql;
+	GdaRow *row;
+	gint i;
+	gint rc;
+	GList *l;
+	GdaOracleRecordset *recset = (GdaOracleRecordset *) model;
+	GdaOracleRecordsetPrivate *priv_data;
+
+	g_return_val_if_fail (GDA_IS_ORACLE_RECORDSET (recset), NULL);
+	g_return_val_if_fail (values != NULL, NULL);
+	g_return_val_if_fail (gda_data_model_is_editable (model), NULL);
+	g_return_val_if_fail (gda_data_model_is_editing (model), NULL);
+	g_return_val_if_fail (recset->priv != NULL, 0);
+
+	priv_data = recset->priv;
+
+	if (priv_data->ncolumns != g_list_length ((GList *) values)) {
+		gda_connection_add_error_string (
+			recset->priv->cnc,
+			_("Attempt to insert a row with an invalid number of columns"));
+		return NULL;
+	}
+
+	sql = g_string_new ("INSERT INTO ");
+	sql = g_string_append (sql, gda_data_model_get_command_text (model));
+	sql = g_string_append (sql, "(");
+
+	for (i = 0; i < priv_data->ncolumns; i += 1) {
+		GdaFieldAttributes *fa;
+
+		fa = gda_data_model_describe_column (model, i);
+		if (!fa) {
+			gda_connection_add_error_string (
+				recset->priv->cnc,
+				_("Could not retrieve column's information"));
+			g_string_free (sql, TRUE);
+			return NULL;
+		}
+
+		if (i != 0) 
+			sql = g_string_append (sql, ", ");
+		sql = g_string_append (sql, gda_field_attributes_get_name (fa));
+	}
+	sql = g_string_append (sql, ") VALUES (");
+
+	for (l = (GList *) values, i = 0; i < priv_data->ncolumns; i += 1, l = l->next) {
+		gchar *val_str;
+		const GdaValue *val = (const GdaValue *) l->data;
+
+		if (!val) { 
+			gda_connection_add_error_string (
+				recset->priv->cnc,
+				_("Could not retrieve column's value"));
+			g_string_free (sql, TRUE);
+			return NULL;
+		}
+
+		if (i != 0) 
+			sql = g_string_append (sql, ", ");
+		val_str = gda_oracle_value_to_sql_string (val);
+		sql = g_string_append (sql, val_str);
+
+		g_free (val_str);
+	}
+	sql = g_string_append (sql, ")");
+
+	/* execute the UPDATE command */
+	/* not sure what to do here yet. */
+
+	g_string_free (sql, TRUE);
+
+	/*
+	if (rc != 0) {
+		gda_connection_add_error (
+			recset->priv->cnc, gda_oracle_make_error 
+			
+		return NULL;
+	}
+	*/
+
+	row = gda_row_new_from_list (values);
+	g_ptr_array_add (recset->priv->rows, row);
+
+	return (const GdaRow *) row;
 }
 
 static gboolean
@@ -445,9 +544,19 @@
 	GdaOracleRecordset *recset = (GdaOracleRecordset *) object;
 
 	g_return_if_fail (GDA_IS_ORACLE_RECORDSET (recset));
+
+	while (recset->priv->rows->len > 0) {
+		GdaRow *row = (GdaRow *) g_ptr_array_index (recset->priv->rows, 0);
+
+		if (row != NULL) 
+			gda_row_free (row);
+		g_ptr_array_remove_index (recset->priv->rows, 0);
+	}
+	g_ptr_array_free (recset->priv->rows, TRUE);
+	recset->priv->rows = NULL;
 
-	if (recset->priv->cdata->hstmt)
-		OCIHandleFree ((dvoid *)recset->priv->cdata->hstmt, OCI_HTYPE_STMT);
+	if (recset->priv->hstmt)
+		OCIHandleFree ((dvoid *)recset->priv->hstmt, OCI_HTYPE_STMT);
 
 	parent_class->finalize (object);
 }
@@ -477,7 +586,9 @@
 }
 
 GdaOracleRecordset *
-gda_oracle_recordset_new (GdaConnection *cnc, GdaOracleConnectionData *cdata)
+gda_oracle_recordset_new (GdaConnection *cnc, 
+				GdaOracleConnectionData *cdata,
+				OCIStmt *stmthp)
 {
 	GdaOracleRecordset *recset;
 	ub4 parcount;
@@ -485,7 +596,7 @@
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
 	g_return_val_if_fail (cdata != NULL, NULL);
 
-	OCIAttrGet ((dvoid *) cdata->hstmt,
+	OCIAttrGet ((dvoid *) stmthp,
 			(ub4) OCI_HTYPE_STMT,
 			(dvoid *) &parcount, 
 			0,
@@ -495,10 +606,10 @@
 	recset = g_object_new (GDA_TYPE_ORACLE_RECORDSET, NULL);
 	recset->priv->cnc = cnc;
 	recset->priv->cdata = cdata;
+	recset->priv->hstmt = stmthp;
 	recset->priv->ncolumns = parcount;
-	recset->priv->nrows = gda_oracle_recordset_get_n_rows (GDA_DATA_MODEL(recset));
+	recset->priv->nrows = gda_oracle_recordset_get_n_rows (GDA_DATA_MODEL (recset));
 	recset->priv->ora_values = define_columns (recset->priv);
-	recset->priv->column_types = get_column_types (recset->priv);
 
 	return recset;
 }
Index: gda-oracle-recordset.h
===================================================================
RCS file: /cvs/gnome/libgda/providers/oracle/gda-oracle-recordset.h,v
retrieving revision 1.1
diff -u -u -r1.1 gda-oracle-recordset.h
--- gda-oracle-recordset.h	2002/06/06 21:57:25	1.1
+++ gda-oracle-recordset.h	2002/06/18 04:30:00
@@ -30,6 +30,7 @@
 
 #include <libgda/gda-data-model-hash.h>
 #include <libgda/gda-value.h>
+#include <oci.h>
 
 G_BEGIN_DECLS
 
@@ -55,9 +56,19 @@
 	GdaDataModelClass parent_class;
 };
 
+struct _GdaOracleValue {
+	OCIDefine *hdef;
+	OCIParam *pard;
+	sb2 indicator;
+	ub2 sql_type;
+	ub2 defined_size;
+	gpointer value;
+	GdaValueType gda_type;
+};
+
 
 GType               gda_oracle_recordset_get_type (void);
-GdaOracleRecordset *gda_oracle_recordset_new (GdaConnection *cnc, GdaOracleConnectionData *cdata);
+GdaOracleRecordset *gda_oracle_recordset_new (GdaConnection *cnc, GdaOracleConnectionData *cdata, OCIStmt *stmthp);
 
 G_END_DECLS
 
Index: gda-oracle.h
===================================================================
RCS file: /cvs/gnome/libgda/providers/oracle/gda-oracle.h,v
retrieving revision 1.3
diff -u -u -r1.3 gda-oracle.h
--- gda-oracle.h	2002/06/06 21:57:25	1.3
+++ gda-oracle.h	2002/06/18 04:30:00
@@ -38,6 +38,7 @@
 #include <libgda/gda-intl.h>
 #include <libgda/gda-value.h>
 #include "gda-oracle-provider.h"
+#include "gda-oracle-recordset.h"
 #include <oci.h>
 
 #define GDA_ORACLE_PROVIDER_ID          "GDA Oracle provider"
@@ -51,11 +52,13 @@
 
 GdaError *gda_oracle_make_error (GdaOracleConnectionData *handle);
 void gda_oracle_set_value (GdaValue *value, 
-				GdaValueType type, 
-				gconstpointer thevalue, 
-				gboolean isNull,
-				gint defined_size);
+				GdaOracleValue *thevalue,
+				GdaConnection *cnc);
 gchar *gda_oracle_value_to_sql_string (GdaValue *value);
+GdaValueType  oracle_sqltype_to_gda_type (const ub2 sqltype);
+gchar *oracle_sqltype_to_string (const ub2 sqltype);
+GdaOracleValue *gda_value_to_oracle_value (GdaValue *value);
+
 
 G_END_DECLS
 
Index: utils.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/oracle/utils.c,v
retrieving revision 1.1
diff -u -u -r1.1 utils.c
--- utils.c	2002/06/06 21:57:25	1.1
+++ utils.c	2002/06/18 04:30:00
@@ -34,7 +34,190 @@
 GdaError *
 gda_oracle_make_error (GdaOracleConnectionData *handle)
 {
-	return NULL;
+	GdaError *error;
+	gchar errbuf[512];
+	ub4 buflen;
+	ub4 errcode;
+
+	error = gda_error_new ();
+
+	if (handle != NULL) {
+		OCIErrorGet ((dvoid *) handle->herr, 
+				(ub4) 1, 
+				(text *) NULL, 
+				&errcode, 
+				errbuf, 
+				(ub4) sizeof (errbuf), 
+				(ub4) OCI_HTYPE_ERROR);
+	
+		gda_error_set_description (error, errbuf);	
+	} else {
+		gda_error_set_description (error, _("NO DESCRIPTION"));
+	}
+		
+	gda_error_set_number (error, errcode);
+	gda_error_set_source (error, "gda-oracle");
+	gda_error_set_sqlstate (error, _("Not available"));
+	
+	return error;
+}
+
+GdaValueType 
+oracle_sqltype_to_gda_type (const ub2 sqltype)
+{
+	/* an incomplete list of all the oracle types */
+	switch (sqltype) {
+	case SQLT_CHR:
+	case SQLT_STR:
+	case SQLT_VCS:
+	case SQLT_RID:
+	case SQLT_LNG:
+	case SQLT_LVC:
+	case SQLT_AFC:
+	case SQLT_AVC:
+	case SQLT_LAB:
+	case SQLT_VST:
+	case SQLT_CLOB:
+	case SQLT_CFILEE:
+		return GDA_VALUE_TYPE_STRING;
+	case SQLT_NUM:
+		return GDA_VALUE_TYPE_NUMERIC;
+	case SQLT_INT:
+		return GDA_VALUE_TYPE_INTEGER;
+	case SQLT_FLT:
+		return GDA_VALUE_TYPE_SINGLE;
+	case SQLT_VBI:
+	case SQLT_BIN:
+	case SQLT_LBI:
+	case SQLT_LVB:
+	case SQLT_BLOB:
+	case SQLT_BFILEE:
+		return GDA_VALUE_TYPE_BINARY;
+	case SQLT_UIN:
+		return GDA_VALUE_TYPE_INTEGER;
+	case SQLT_DAT:
+	case SQLT_ODT:
+	case SQLT_DATE:
+		return GDA_VALUE_TYPE_DATE;
+	case SQLT_TIME:
+	case SQLT_TIME_TZ:
+		return GDA_VALUE_TYPE_TIME;
+	case SQLT_TIMESTAMP:
+	case SQLT_TIMESTAMP_TZ:
+	case SQLT_TIMESTAMP_LTZ:
+		return GDA_VALUE_TYPE_TIMESTAMP;
+	case SQLT_SLS:
+	case SQLT_CUR:
+	case SQLT_RDD:
+	case SQLT_OSL:
+	case SQLT_NTY:
+	case SQLT_REF:
+	case SQLT_RSET:
+	case SQLT_NCO:
+	case SQLT_INTERVAL_YM:
+	case SQLT_INTERVAL_DS:
+	case SQLT_VNU:
+	case SQLT_PDN:
+	case SQLT_NON:
+	default:
+		return GDA_VALUE_TYPE_UNKNOWN;
+	}
+}
+
+gchar * 
+oracle_sqltype_to_string (const ub2 sqltype)
+{
+	/* an incomplete list of all the oracle types */
+	switch (sqltype) {
+	case SQLT_CHR:
+		return "VARCHAR2";
+	case SQLT_NUM:
+		return "NUMERIC";
+	case SQLT_INT:
+		return "INTEGER";
+	case SQLT_FLT:
+		return "FLOAT";
+	case SQLT_STR:
+		return "STRING";
+	case SQLT_VNU:
+		return "VARNUM";
+	case SQLT_PDN:
+		return "";
+	case SQLT_LNG:
+		return "LONG";
+	case SQLT_VCS:
+		return "VARCHAR";
+	case SQLT_NON:
+		return "";
+	case SQLT_RID:
+		return "ROWID";
+	case SQLT_DAT:
+		return "DATE";
+	case SQLT_VBI:
+		return "VARRAW";
+	case SQLT_BIN:
+		return "RAW";
+	case SQLT_LBI:
+		return "LONG RAW";
+	case SQLT_UIN:
+		return "UNSIGNED INT";
+	case SQLT_SLS:
+		return "";
+	case SQLT_LVC:
+		return "LONG VARCHAR";
+	case SQLT_LVB:
+		return "LONG VARRAW";
+	case SQLT_AFC:
+		return "CHAR";
+	case SQLT_AVC:
+		return "CHARZ";
+	case SQLT_CUR:
+		return "CURSOR";
+	case SQLT_RDD:
+		return "ROWID";
+	case SQLT_LAB:
+		return "LABEL";
+	case SQLT_OSL:
+		return "OSLABEL";
+	case SQLT_NTY:
+		return "";
+	case SQLT_REF:
+		return "";
+	case SQLT_CLOB:
+		return "CLOB";
+	case SQLT_BLOB:
+		return "BLOB";
+	case SQLT_BFILEE:
+		return "BFILE";
+	case SQLT_CFILEE:
+		return "CFILE";
+	case SQLT_RSET:
+		return "RESULT SET";
+	case SQLT_NCO:
+		return "";
+	case SQLT_VST:
+		return "";
+	case SQLT_ODT:
+		return "OCI DATE";
+	case SQLT_DATE:
+		return "ANSI DATE";
+	case SQLT_TIME:
+		return "TIME";
+	case SQLT_TIME_TZ:
+		return "TIME WITH TIME ZONE";
+	case SQLT_TIMESTAMP:
+		return "TIMESTAMP";
+	case SQLT_TIMESTAMP_TZ:
+		return "TIMESTAMP WITH TIME ZONE";
+	case SQLT_INTERVAL_YM:
+		return "INTERVAL YEAR TO MONTH";
+	case SQLT_INTERVAL_DS:
+		return "INTERVAL DAY TO SECOND";
+	case SQLT_TIMESTAMP_LTZ:
+		return "TIMESTAMP WITH LOCAL TIME ZONE";
+	default:
+		return "UNKNOWN";
+	}
 }
 
 gchar *
@@ -68,56 +251,114 @@
 	return ret;
 }
 
+GdaOracleValue *
+gda_value_to_oracle_value (GdaValue *value)
+{
+	GdaOracleValue *ora_value;
+	gchar *val_str;
+	OCIDate *oci_date;
+	GdaDate *gda_date;
+
+	val_str = gda_value_stringify (value);
+	if (!val_str)
+		return NULL;
+
+	ora_value = g_new0 (GdaOracleValue, 1);
+
+	ora_value->gda_type = value->type;
+	ora_value->indicator = 0;
+	ora_value->hdef = (OCIDefine *) 0;
+	ora_value->pard = (OCIParam *) 0;
+
+	switch (ora_value->gda_type) {
+	case GDA_VALUE_TYPE_NULL:
+		ora_value->indicator = -1;
+		break;
+	case GDA_VALUE_TYPE_BIGINT :
+	case GDA_VALUE_TYPE_DOUBLE :
+	case GDA_VALUE_TYPE_INTEGER :
+	case GDA_VALUE_TYPE_NUMERIC :
+	case GDA_VALUE_TYPE_SINGLE :
+	case GDA_VALUE_TYPE_SMALLINT :
+	case GDA_VALUE_TYPE_TINYINT :
+		ora_value->sql_type = SQLT_NUM;
+		ora_value->value = (void *) val_str;
+		ora_value->defined_size = strlen (val_str);
+		break;
+	case GDA_VALUE_TYPE_DATE :
+		ora_value->sql_type = SQLT_ODT;
+		oci_date = (OCIDate *) 0;
+		gda_date = gda_value_get_date (value);
+		ora_value->defined_size = 7;
+		OCIDateSetDate (oci_date, gda_date->year, gda_date->month, gda_date->day);
+		break;
+	default :
+		ora_value->sql_type = SQLT_CHR;
+		ora_value->value = g_malloc0 (strlen (val_str));
+		ora_value->value = val_str;
+		ora_value->defined_size = strlen (val_str);
+	}
+
+	/*g_free (val_str);*/
+	return ora_value;
+}
+
 void
 gda_oracle_set_value (GdaValue *value, 
-			GdaValueType type, 
-			gconstpointer thevalue, 
-			gboolean isNull,
-			gint defined_size)
+			GdaOracleValue *ora_value,
+			GdaConnection *cnc)
 {
 	GDate *gdate;
 	GdaDate date;
-	GdaTime timegda;
-	GdaTimestamp timestamp;
-	GdaGeometricPoint point;
 	GdaNumeric numeric;
-	gchar string_buffer[defined_size+1];
 
-	if (isNull) {
+	gchar string_buffer[ora_value->defined_size+1];
+
+	if (-1 == (ora_value->indicator)) {
 		gda_value_set_null (value);
 		return;
 	}
 
-	switch (type) {
+	switch (ora_value->gda_type) {
 	case GDA_VALUE_TYPE_BOOLEAN:
-		gda_value_set_boolean (value, (atoi (thevalue)) ? TRUE: FALSE);
+		gda_value_set_boolean (value, (atoi (ora_value->value)) ? TRUE: FALSE);
 		break;
 	case GDA_VALUE_TYPE_STRING:
-		memcpy (string_buffer, thevalue, defined_size);
-		string_buffer[defined_size] = '\0';
+		memcpy (string_buffer, ora_value->value, ora_value->defined_size);
+		string_buffer[ora_value->defined_size] = '\0';
 		gda_value_set_string (value, string_buffer);
 		break;
 	case GDA_VALUE_TYPE_BIGINT:
-		gda_value_set_bigint (value, atoll (thevalue));
+		gda_value_set_bigint (value, atoll (ora_value->value));
 		break;
 	case GDA_VALUE_TYPE_INTEGER:
-		gda_value_set_integer (value, atol (thevalue));
+		gda_value_set_integer (value, atol (ora_value->value));
 		break;
 	case GDA_VALUE_TYPE_SMALLINT:
-		gda_value_set_smallint (value, atoi (thevalue));
+		gda_value_set_smallint (value, atoi (ora_value->value));
 		break;
 	case GDA_VALUE_TYPE_SINGLE:
-		gda_value_set_single (value, atof (thevalue));
+		gda_value_set_single (value, atof (ora_value->value));
 		break;
 	case GDA_VALUE_TYPE_DOUBLE:
-		gda_value_set_double (value, atof (thevalue));
+		gda_value_set_double (value, atof (ora_value->value));
 		break;
 	case GDA_VALUE_TYPE_NUMERIC:
-		numeric.number = thevalue;
-		numeric.precision = 0; // FIXME
-		numeric.width = 0; // FIXME
+		numeric.number = ora_value->value;
+		numeric.precision = 5; // FIXME
+		numeric.width = 5; // FIXME
 		gda_value_set_numeric (value, &numeric);
 		break;
+	case GDA_VALUE_TYPE_DATE:
+		gdate = g_date_new ();
+		g_date_clear (gdate, 1);
+		OCIDateGetDate ((CONST OCIDate *) ora_value->value,
+				(sb2 *) &date.year,
+				(ub1 *) &date.month,
+				(ub1 *) &date.day);
+		gda_value_set_date (value, &date);
+		g_date_free (gdate);
+		break;
 	case GDA_VALUE_TYPE_GEOMETRIC_POINT:
 		break;
 	case GDA_VALUE_TYPE_NULL:
@@ -131,6 +372,6 @@
 		// FIXME
 		break;
 	default:
-		gda_value_set_string (value, thevalue);
+		gda_value_set_string (value, ora_value->value);
 	}
 }


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