[gnome-db] Oracle provider changes
- From: Tim Coleman <tim timcoleman com>
- To: rodrigo gnome-db org
- Cc: gnome-db-list gnome org
- Subject: [gnome-db] Oracle provider changes
- Date: Fri, 28 Jun 2002 00:43:12 -0400
Here's another installment of Oracle provider changes and improvements.
Here's the changelog entry:
2002-06-28 Tim Coleman <tim timcoleman com>
* providers/oracle/gda-oracle-provider.c:
- Added code to retrieve public/unique/foreign key information
for schema purposes.
- Free up more Oracle memory when bad things happen
- Added a function to retrieve list of Oracle tablespaces
for schema purposes.
* providers/oracle/gda-oracle-recordset.c:
- Free up more Oracle memory when bad things happen
- Clean up the get_n_rows code to work properly
* providers/oracle/utils.c:
- only allocate memory for the string buffer when I need
it.
Attached are the oracle provider diff and changelog diff to be applied.
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: Makefile.am
===================================================================
RCS file: /cvs/gnome/libgda/providers/oracle/Makefile.am,v
retrieving revision 1.5
diff -u -u -r1.5 Makefile.am
--- Makefile.am 21 Jun 2002 18:39:31 -0000 1.5
+++ Makefile.am 28 Jun 2002 04:36:07 -0000
@@ -2,8 +2,7 @@
provider_LTLIBRARIES = libgda-oracle.la
INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_builddir) \
+ -I. \
$(LIBGDA_CFLAGS) \
$(ORACLE_CFLAGS)
Index: gda-oracle-provider.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/oracle/gda-oracle-provider.c,v
retrieving revision 1.6
diff -u -u -r1.6 gda-oracle-provider.c
--- gda-oracle-provider.c 21 Jun 2002 18:39:31 -0000 1.6
+++ gda-oracle-provider.c 28 Jun 2002 04:36:08 -0000
@@ -81,6 +81,12 @@
GdaValueType data_type;
} GdaOracleColData;
+typedef struct {
+ gboolean primary_key;
+ gboolean unique;
+ gchar *references;
+} GdaOracleIndexData;
+
/*
* GdaOracleProvider class implementation
*/
@@ -217,8 +223,10 @@
(size_t) 0,
(dvoid **) 0);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ENV,
- _("Could not allocate the Oracle error handle")))
+ _("Could not allocate the Oracle error handle"))) {
+ OCIHandleFree ((dvoid *) priv_data->hservice, OCI_HTYPE_SVCCTX);
return FALSE;
+ }
/* we use the Multiple Sessions/Connections OCI paradigm for this server */
result = OCIHandleAlloc ((dvoid *) priv_data->henv,
@@ -227,8 +235,11 @@
(size_t) 0,
(dvoid **) 0);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ENV,
- _("Could not allocate the Oracle server handle")))
+ _("Could not allocate the Oracle server handle"))) {
+ OCIHandleFree ((dvoid *) priv_data->herr, OCI_HTYPE_ERROR);
+ OCIHandleFree ((dvoid *) priv_data->hservice, OCI_HTYPE_SVCCTX);
return FALSE;
+ }
/* create the session handle */
result = OCIHandleAlloc ((dvoid *) priv_data->henv,
@@ -237,8 +248,12 @@
(size_t) 0,
(dvoid **) 0);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ENV,
- _("Could not allocate the Oracle session handle")))
+ _("Could not allocate the Oracle session handle"))) {
+ OCIHandleFree ((dvoid *) priv_data->hserver, OCI_HTYPE_SERVER);
+ OCIHandleFree ((dvoid *) priv_data->herr, OCI_HTYPE_ERROR);
+ OCIHandleFree ((dvoid *) priv_data->hservice, OCI_HTYPE_SVCCTX);
return FALSE;
+ }
/* if the username isn't provided, try to find it in the DSN */
if (strlen(username) > 0)
@@ -263,8 +278,13 @@
(ub4) strlen (ora_tnsname),
OCI_DEFAULT);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not attach to the Oracle server")))
+ _("Could not attach to the Oracle server"))) {
+ OCIHandleFree ((dvoid *) priv_data->hsession, OCI_HTYPE_SESSION);
+ OCIHandleFree ((dvoid *) priv_data->hserver, OCI_HTYPE_SERVER);
+ OCIHandleFree ((dvoid *) priv_data->herr, OCI_HTYPE_ERROR);
+ OCIHandleFree ((dvoid *) priv_data->hservice, OCI_HTYPE_SVCCTX);
return FALSE;
+ }
/* set the server attribute in the service context */
result = OCIAttrSet ((dvoid *) priv_data->hservice,
@@ -274,8 +294,13 @@
(ub4) OCI_ATTR_SERVER,
priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not set the Oracle server attribute in the service context")))
+ _("Could not set the Oracle server attribute in the service context"))) {
+ OCIHandleFree ((dvoid *) priv_data->hsession, OCI_HTYPE_SESSION);
+ OCIHandleFree ((dvoid *) priv_data->hserver, OCI_HTYPE_SERVER);
+ OCIHandleFree ((dvoid *) priv_data->herr, OCI_HTYPE_ERROR);
+ OCIHandleFree ((dvoid *) priv_data->hservice, OCI_HTYPE_SVCCTX);
return FALSE;
+ }
/* set the username attribute */
result = OCIAttrSet ((dvoid *) priv_data->hsession,
@@ -285,8 +310,13 @@
(ub4) OCI_ATTR_USERNAME,
priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not set the Oracle username attribute")))
+ _("Could not set the Oracle username attribute"))) {
+ OCIHandleFree ((dvoid *) priv_data->hsession, OCI_HTYPE_SESSION);
+ OCIHandleFree ((dvoid *) priv_data->hserver, OCI_HTYPE_SERVER);
+ OCIHandleFree ((dvoid *) priv_data->herr, OCI_HTYPE_ERROR);
+ OCIHandleFree ((dvoid *) priv_data->hservice, OCI_HTYPE_SVCCTX);
return FALSE;
+ }
/* set the password attribute */
result = OCIAttrSet ((dvoid *) priv_data->hsession,
@@ -296,8 +326,13 @@
(ub4) OCI_ATTR_PASSWORD,
priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not set the Oracle password attribute")))
+ _("Could not set the Oracle password attribute"))) {
+ OCIHandleFree ((dvoid *) priv_data->hsession, OCI_HTYPE_SESSION);
+ OCIHandleFree ((dvoid *) priv_data->hserver, OCI_HTYPE_SERVER);
+ OCIHandleFree ((dvoid *) priv_data->herr, OCI_HTYPE_ERROR);
+ OCIHandleFree ((dvoid *) priv_data->hservice, OCI_HTYPE_SVCCTX);
return FALSE;
+ }
/* begin the session */
result = OCISessionBegin (priv_data->hservice,
@@ -309,6 +344,9 @@
_("Could not begin the Oracle session"))) {
OCIServerDetach (priv_data->hserver, priv_data->herr, OCI_DEFAULT);
OCIHandleFree ((dvoid *) priv_data->hsession, OCI_HTYPE_SESSION);
+ OCIHandleFree ((dvoid *) priv_data->hserver, OCI_HTYPE_SERVER);
+ OCIHandleFree ((dvoid *) priv_data->herr, OCI_HTYPE_ERROR);
+ OCIHandleFree ((dvoid *) priv_data->hservice, OCI_HTYPE_SVCCTX);
priv_data->hsession = NULL;
return FALSE;
}
@@ -321,8 +359,14 @@
(ub4) OCI_ATTR_SESSION,
priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not set the Oracle session attribute in the service context")))
+ _("Could not set the Oracle session attribute in the service context"))) {
+ OCIServerDetach (priv_data->hserver, priv_data->herr, OCI_DEFAULT);
+ OCIHandleFree ((dvoid *) priv_data->hsession, OCI_HTYPE_SESSION);
+ OCIHandleFree ((dvoid *) priv_data->hserver, OCI_HTYPE_SERVER);
+ OCIHandleFree ((dvoid *) priv_data->herr, OCI_HTYPE_ERROR);
+ OCIHandleFree ((dvoid *) priv_data->hservice, OCI_HTYPE_SVCCTX);
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);
@@ -419,8 +463,10 @@
(ub4) OCI_NTV_SYNTAX,
(ub4) OCI_DEFAULT);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not prepare the Oracle statement")))
+ _("Could not prepare the Oracle statement"))) {
+ OCIHandleFree ((dvoid *) stmthp, OCI_HTYPE_STMT);
return NULL;
+ }
/* Bind parameters */
if (params != NULL) {
@@ -449,8 +495,10 @@
(ub4 *) 0,
(ub4) OCI_DEFAULT);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not bind the Oracle statement parameter")))
+ _("Could not bind the Oracle statement parameter"))) {
+ OCIHandleFree ((dvoid *) stmthp, OCI_HTYPE_STMT);
return NULL;
+ }
}
}
return stmthp;
@@ -492,8 +540,10 @@
OCI_ATTR_STMT_TYPE,
priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the Oracle statement type")))
+ _("Could not get the Oracle statement type"))) {
+ OCIHandleFree ((dvoid *) stmthp, OCI_HTYPE_STMT);
return NULL;
+ }
result = OCIStmtExecute (priv_data->hservice,
@@ -508,8 +558,10 @@
continue;
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not execute the Oracle statement")))
+ _("Could not execute the Oracle statement"))) {
+ OCIHandleFree ((dvoid *) stmthp, OCI_HTYPE_STMT);
return NULL;
+ }
/* get the number of columns in the result set */
result = OCIAttrGet ((dvoid *) stmthp,
@@ -519,8 +571,10 @@
(ub4) OCI_ATTR_PARAM_COUNT,
priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the number of columns in the result set")))
+ _("Could not get the number of columns in the result set"))) {
+ OCIHandleFree ((dvoid *) stmthp, OCI_HTYPE_STMT);
return NULL;
+ }
for (i = 0; i < ncolumns; i += 1) {
text *pgchar_dummy = (text *) 0;
@@ -534,8 +588,10 @@
(dvoid **) &pard,
(ub4) i + 1);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the parameter descripter in the result set")))
+ _("Could not get the parameter descripter in the result set"))) {
+ OCIHandleFree ((dvoid *) stmthp, OCI_HTYPE_STMT);
return NULL;
+ }
result = OCIAttrGet ((dvoid *) pard,
(ub4) OCI_DTYPE_PARAM,
@@ -544,8 +600,10 @@
(ub4) OCI_ATTR_NAME,
(OCIError *) priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the column name in the result set")))
+ _("Could not get the column name in the result set"))) {
+ OCIHandleFree ((dvoid *) stmthp, OCI_HTYPE_STMT);
return NULL;
+ }
name_buffer = g_malloc0 (col_name_len + 1);
memcpy (name_buffer, pgchar_dummy, col_name_len);
@@ -750,8 +808,10 @@
OCI_ATTR_TRANS_NAME,
priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not set the Oracle transaction name")))
+ _("Could not set the Oracle transaction name"))) {
+ OCIHandleFree ((dvoid *) ora_xaction->txnhp, OCI_HTYPE_TRANS);
return FALSE;
+ }
/* attach the transaction to the service context */
@@ -762,8 +822,10 @@
OCI_ATTR_TRANS,
priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not attach the transaction to the service context")))
+ _("Could not attach the transaction to the service context"))) {
+ OCIHandleFree ((dvoid *) ora_xaction->txnhp, OCI_HTYPE_TRANS);
return FALSE;
+ }
/* start the transaction */
result = OCITransStart (priv_data->hservice,
@@ -771,8 +833,10 @@
60,
OCI_TRANS_NEW);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not start the Oracle transaction")))
- return FALSE;
+ _("Could not start the Oracle transaction"))) {
+ OCIHandleFree ((dvoid *) ora_xaction->txnhp, OCI_HTYPE_TRANS);
+ return FALSE;
+ }
g_object_set_data (G_OBJECT (xaction), OBJECT_DATA_ORACLE_HANDLE, ora_xaction);
return TRUE;
@@ -828,6 +892,7 @@
_("Could not commit the Oracle transaction")))
return FALSE;
+ OCIHandleFree ((dvoid *) ora_xaction->txnhp, OCI_HTYPE_TRANS);
return TRUE;
}
@@ -873,6 +938,7 @@
_("Could not rollback the Oracle transaction")))
return FALSE;
+ OCIHandleFree ((dvoid *) ora_xaction->txnhp, OCI_HTYPE_TRANS);
return TRUE;
}
@@ -1003,6 +1069,136 @@
return recset;
}
+static GString *
+g_string_right_trim (GString * input)
+{
+ gint i;
+
+ for (i = input->len - 1; i >= 0; i -= 1)
+ if (input->str[i] != ' ')
+ return g_string_truncate (input, i+1);
+
+ return g_string_truncate (input, 0);
+}
+
+static GHashTable *
+get_oracle_index_data (GdaConnection *cnc, const gchar *tblname)
+{
+ GList *reclist;
+ GdaDataModel *recset;
+ GdaOracleIndexData *index_data;
+ GdaParameterList *query_params = gda_parameter_list_new ();
+ GString *references;
+ gint nrows;
+ GString *colname;
+ GString *newcolname;
+ GHashTable *h_table = g_hash_table_new (g_str_hash, g_str_equal);
+ GdaValue *value;
+ gint i;
+
+
+ gchar *sql = g_strdup ("SELECT substr (c1.column_name,1,30) column_name, "
+ "con.constraint_type constraint_type, "
+ "'' uniqueness, "
+ "c2.table_name reference "
+ "FROM user_cons_columns c1, user_cons_columns c2, user_constraints con "
+ "WHERE con.constraint_name = c1.constraint_name "
+ "AND con.constraint_type = 'R' "
+ "AND con.constraint_type IS NOT NULL "
+ "AND c1.table_name = upper (:TBLNAME) "
+ "AND con.r_constraint_name = c2.constraint_name "
+ "UNION "
+ "SELECT substr (c.column_name,1,30) column_name, "
+ "t.constraint_type constraint_type, "
+ "substr (i.uniqueness, 1, 6) uniqueness, "
+ "'' reference "
+ "FROM user_indexes i, user_ind_columns c, user_constraints t "
+ "WHERE i.table_name = upper (:TBLNAME) "
+ "AND t.constraint_type != 'R' "
+ "AND i.index_name = c.index_name "
+ "AND i.index_name = t.constraint_name "
+ "ORDER BY 1" );
+
+ g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+
+ gda_parameter_list_add_parameter (query_params,
+ gda_parameter_new_string (":TBLNAME", tblname));
+
+ reclist = process_sql_commands (NULL, cnc, sql,
+ query_params, GDA_COMMAND_OPTION_STOP_ON_ERRORS);
+ if (!reclist)
+ return NULL;
+
+ recset = GDA_DATA_MODEL (reclist->data);
+ g_list_free (reclist);
+
+ nrows = gda_data_model_get_n_rows (recset);
+
+ if (nrows == 0)
+ return NULL;
+
+ index_data = g_new0 (GdaOracleIndexData, 1);
+ references = g_string_new ("");
+
+ value = gda_data_model_get_value_at (recset, 0, 0);
+ colname = g_string_right_trim (g_string_new (gda_value_get_string (value)));
+
+ for (i = 0; i < nrows; i += 1) {
+ gchar *constraint_type = "";
+
+ value = gda_data_model_get_value_at (recset, 1, i);
+ if (!value)
+ continue;
+ if (gda_value_is_null (value))
+ continue;
+
+ constraint_type = g_strdup (gda_value_get_string (value));
+
+ if (!strcmp (constraint_type, "P"))
+ index_data->primary_key = TRUE;
+
+ value = gda_data_model_get_value_at (recset, 2, i);
+ if (value)
+ if (!gda_value_is_null (value))
+ if (!strcmp (gda_value_get_string (value), "UNIQUE"))
+ index_data->unique = TRUE;
+
+ if (!strcmp (constraint_type, "R")) {
+ value = gda_data_model_get_value_at (recset, 3, i);
+ if (value)
+ if (!gda_value_is_null (value)) {
+ if (references->len > 0)
+ references = g_string_append (references, ", ");
+ references = g_string_right_trim (g_string_append (references, gda_value_get_string (value)));
+ }
+ }
+
+ if (i == nrows - 1) {
+ index_data->references = g_strdup (references->str);
+ g_hash_table_insert (h_table, colname->str, index_data);
+ break;
+ }
+
+ value = gda_data_model_get_value_at (recset, 0, i+1);
+ newcolname = g_string_right_trim (g_string_new (gda_value_get_string (value)));
+
+ if (strcmp (colname->str, newcolname->str)) {
+ index_data->references = g_strdup (references->str);
+ g_hash_table_insert (h_table, colname->str, index_data);
+
+ index_data = g_new0 (GdaOracleIndexData, 1);
+ index_data->unique = FALSE;
+ index_data->primary_key = FALSE;
+ index_data->references = g_strdup ("");
+ references = g_string_new ("");
+ colname = g_string_new (newcolname->str);
+ }
+ }
+ g_free (recset);
+ return h_table;
+}
+
+
static GList *
gda_oracle_fill_md_data (const gchar *tblname,
GdaDataModelArray *recset,
@@ -1017,6 +1213,7 @@
ub2 numcols;
GList *list = NULL;
gint result;
+ GHashTable *h_table_index;
priv_data = g_object_get_data (G_OBJECT (cnc), OBJECT_DATA_ORACLE_HANDLE);
@@ -1040,8 +1237,10 @@
OCI_PTYPE_TABLE,
(OCIDescribe *) dschp);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not describe the Oracle table")))
+ _("Could not describe the Oracle table"))) {
+ OCIHandleFree ((dvoid *) dschp, OCI_HTYPE_DESCRIBE);
return NULL;
+ }
/* Get the parameter handle */
result = OCIAttrGet ((dvoid *) dschp,
@@ -1051,8 +1250,10 @@
(ub4) OCI_ATTR_PARAM,
(OCIError *) priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the Oracle parameter handle")))
+ _("Could not get the Oracle parameter handle"))) {
+ OCIHandleFree ((dvoid *) dschp, OCI_HTYPE_DESCRIBE);
return NULL;
+ }
/* Get the number of columns */
result = OCIAttrGet ((dvoid *) parmh,
@@ -1062,8 +1263,10 @@
(ub4) OCI_ATTR_NUM_COLS,
(OCIError *) priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the number of columns in the table")))
+ _("Could not get the number of columns in the table"))) {
+ OCIHandleFree ((dvoid *) dschp, OCI_HTYPE_DESCRIBE);
return NULL;
+ }
result = OCIAttrGet ((dvoid *) parmh,
(ub4) OCI_DTYPE_PARAM,
@@ -1072,8 +1275,12 @@
(ub4) OCI_ATTR_LIST_COLUMNS,
(OCIError *) priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the column list")))
+ _("Could not get the column list"))) {
+ OCIHandleFree ((dvoid *) dschp, OCI_HTYPE_DESCRIBE);
return NULL;
+ }
+
+ h_table_index = get_oracle_index_data (cnc, tblname);
for (i = 1; i <= numcols; i += 1) {
text *strp;
@@ -1085,6 +1292,8 @@
ub2 defined_size;
ub2 scale;
+ GdaOracleIndexData *index_data;
+
GdaValue *value;
GList *rowlist = NULL;
@@ -1095,8 +1304,10 @@
(dvoid **) &colhd,
(ub2) i);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the Oracle column handle")))
+ _("Could not get the Oracle column handle"))) {
+ OCIHandleFree ((dvoid *) dschp, OCI_HTYPE_DESCRIBE);
return NULL;
+ }
/* Field name */
result = OCIAttrGet ((dvoid *) colhd,
@@ -1106,11 +1317,14 @@
(ub4) OCI_ATTR_NAME,
(OCIError *) priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the Oracle field name")))
+ _("Could not get the Oracle field name"))) {
+ OCIDescriptorFree ((dvoid *) colhd, OCI_DTYPE_PARAM);
+ OCIHandleFree ((dvoid *) dschp, OCI_HTYPE_DESCRIBE);
return NULL;
+ }
colname = g_malloc0 (sizep + 1);
- memcpy (colname, strp, (size_t) sizep);
+ memcpy (colname, strp, sizep);
colname[sizep] = '\0';
value = gda_value_new_string (colname);
rowlist = g_list_append (rowlist, value);
@@ -1124,8 +1338,11 @@
(ub4) OCI_ATTR_DATA_TYPE,
(OCIError *) priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the Oracle field data type")))
+ _("Could not get the Oracle field data type"))) {
+ OCIDescriptorFree ((dvoid *) colhd, OCI_DTYPE_PARAM);
+ OCIHandleFree ((dvoid *) dschp, OCI_HTYPE_DESCRIBE);
return NULL;
+ }
typename = oracle_sqltype_to_string (type);
value = gda_value_new_string (typename);
@@ -1139,8 +1356,11 @@
(ub4) OCI_ATTR_DATA_SIZE,
(OCIError *) priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the Oracle field defined size")))
+ _("Could not get the Oracle field defined size"))) {
+ OCIDescriptorFree ((dvoid *) colhd, OCI_DTYPE_PARAM);
+ OCIHandleFree ((dvoid *) dschp, OCI_HTYPE_DESCRIBE);
return NULL;
+ }
value = gda_value_new_integer (defined_size);
rowlist = g_list_append (rowlist, value);
@@ -1153,8 +1373,11 @@
(ub4) OCI_ATTR_SCALE,
(OCIError *) priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the Oracle field scale")))
+ _("Could not get the Oracle field scale"))) {
+ OCIDescriptorFree ((dvoid *) colhd, OCI_DTYPE_PARAM);
+ OCIHandleFree ((dvoid *) dschp, OCI_HTYPE_DESCRIBE);
return NULL;
+ }
value = gda_value_new_integer (scale);
rowlist = g_list_append (rowlist, value);
@@ -1167,28 +1390,52 @@
(ub4) OCI_ATTR_DATA_SIZE,
(OCIError *) priv_data->herr);
if (!gda_oracle_check_result (result, cnc, priv_data, OCI_HTYPE_ERROR,
- _("Could not get the Oracle field nullable attribute")))
+ _("Could not get the Oracle field nullable attribute"))) {
+ OCIDescriptorFree ((dvoid *) colhd, OCI_DTYPE_PARAM);
+ OCIHandleFree ((dvoid *) dschp, OCI_HTYPE_DESCRIBE);
return NULL;
+ }
value = gda_value_new_boolean (nullable > 0);
rowlist = g_list_append (rowlist, value);
+ if (!h_table_index) {
+ index_data = g_new0 (GdaOracleIndexData, 1);
+ index_data->primary_key = FALSE;
+ index_data->unique = FALSE;
+ index_data->references = g_strdup ("");
+ } else {
+ index_data = g_hash_table_lookup (h_table_index, colname);
+ }
+
+ if (!index_data) {
+ index_data = g_new0 (GdaOracleIndexData, 1);
+ index_data->primary_key = FALSE;
+ index_data->unique = FALSE;
+ index_data->references = g_strdup ("");
+ }
+
/* primary key? */
- value = gda_value_new_boolean (FALSE); // FIXME
+ value = gda_value_new_boolean (index_data->primary_key);
rowlist = g_list_append (rowlist, value);
/* unique? */
- value = gda_value_new_boolean (FALSE); // FIXME
+ value = gda_value_new_boolean (index_data->unique);
rowlist = g_list_append (rowlist, value);
/* references */
- value = gda_value_new_string (""); // FIXME
+ value = gda_value_new_string (index_data->references);
rowlist = g_list_append (rowlist, value);
+ g_free (index_data);
+
list = g_list_append (list, rowlist);
rowlist = NULL;
+
+ OCIDescriptorFree ((dvoid *) colhd, OCI_DTYPE_PARAM);
}
+ OCIHandleFree ((dvoid *) dschp, OCI_HTYPE_DESCRIBE);
return list;
}
@@ -1214,6 +1461,28 @@
return recset;
}
+static GdaDataModel *
+get_oracle_databases (GdaConnection *cnc, GdaParameterList *params)
+{
+ GList *reclist;
+ GdaDataModel *recset;
+ gchar *sql = g_strdup ("SELECT TABLESPACE_NAME FROM USER_TABLESPACES");
+
+ g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+
+ reclist = process_sql_commands (NULL, cnc, sql, NULL,
+ GDA_COMMAND_OPTION_STOP_ON_ERRORS);
+
+ g_free (sql);
+
+ if (!reclist)
+ return NULL;
+
+ recset = GDA_DATA_MODEL (reclist->data);
+ g_list_free (reclist);
+
+ return recset;
+}
/*
* get_oracle_objects
*
@@ -1233,7 +1502,7 @@
GList *reclist;
GdaDataModel *recset;
GdaParameterList *query_params = gda_parameter_list_new ();
- GString *sql = g_string_new ("SELECT OBJECT_NAME FROM USER_OBJECTS WHERE OBJECT_TYPE=:OBJ_TYPE");
+ gchar *sql = g_strdup ("SELECT OBJECT_NAME FROM USER_OBJECTS WHERE OBJECT_TYPE=:OBJ_TYPE");
g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
@@ -1267,11 +1536,11 @@
return NULL;
}
- reclist = process_sql_commands (NULL, cnc, sql->str, query_params,
+ reclist = process_sql_commands (NULL, cnc, sql, query_params,
GDA_COMMAND_OPTION_STOP_ON_ERRORS);
gda_parameter_list_free (query_params);
- g_string_free (sql, TRUE);
+ g_free (sql);
if (!reclist)
return NULL;
@@ -1343,7 +1612,6 @@
tblname = gda_value_get_string ((GdaValue *) gda_parameter_get_value (par));
g_return_val_if_fail (tblname != NULL, NULL);
-
recset = gda_oracle_init_md_recset (cnc);
list = gda_oracle_fill_md_data (tblname, recset, cnc);
g_list_foreach (list, add_g_list_row, recset);
@@ -1374,6 +1642,9 @@
break;
case GDA_CONNECTION_SCHEMA_USERS :
recset = get_oracle_users (cnc, params);
+ break;
+ case GDA_CONNECTION_SCHEMA_DATABASES :
+ recset = get_oracle_databases (cnc, params);
break;
case GDA_CONNECTION_SCHEMA_INDEXES :
recset = get_oracle_objects (cnc, params, schema);
Index: gda-oracle-recordset.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/oracle/gda-oracle-recordset.c,v
retrieving revision 1.3
diff -u -u -r1.3 gda-oracle-recordset.c
--- gda-oracle-recordset.c 20 Jun 2002 18:15:26 -0000 1.3
+++ gda-oracle-recordset.c 28 Jun 2002 04:36:08 -0000
@@ -80,8 +80,10 @@
OCI_ATTR_DATA_SIZE,
priv->cdata->herr);
if (!gda_oracle_check_result (result, priv->cnc, priv->cdata, OCI_HTYPE_ERROR,
- _("Could not get the parameter defined size")))
+ _("Could not get the parameter defined size"))) {
+ OCIDescriptorFree ((dvoid *) ora_value->pard, OCI_DTYPE_PARAM);
return NULL;
+ }
result = OCIAttrGet ((dvoid *) (ora_value->pard),
OCI_DTYPE_PARAM,
@@ -91,8 +93,10 @@
priv->cdata->herr);
if (!gda_oracle_check_result (result, priv->cnc, priv->cdata, OCI_HTYPE_ERROR,
- _("Could not get the parameter data type")))
+ _("Could not get the parameter data type"))) {
+ OCIDescriptorFree ((dvoid *) ora_value->pard, OCI_DTYPE_PARAM);
return NULL;
+ }
switch (ora_value->sql_type) {
case SQLT_NUM: // Numerics are coerced to string
@@ -120,8 +124,10 @@
(ub2 *) 0,
(ub4) OCI_DEFAULT);
if (!gda_oracle_check_result (result, priv->cnc, priv->cdata, OCI_HTYPE_ERROR,
- _("Could not define by position")))
+ _("Could not define by position"))) {
+ OCIDescriptorFree ((dvoid *) ora_value->pard, OCI_DTYPE_PARAM);
return NULL;
+ }
fields = g_list_append (fields, ora_value);
}
@@ -185,8 +191,10 @@
(ub4) OCI_ATTR_NAME,
(OCIError *) priv_data->cdata->herr);
if (!gda_oracle_check_result (result, priv_data->cnc, priv_data->cdata, OCI_HTYPE_ERROR,
- _("Could not get the Oracle column name")))
+ _("Could not get the Oracle column name"))) {
+ OCIDescriptorFree ((dvoid *) pard, OCI_DTYPE_PARAM);
return NULL;
+ }
memcpy (name_buffer, pgchar_dummy, col_name_len);
name_buffer[col_name_len] = '\0';
@@ -198,8 +206,10 @@
(ub4) OCI_ATTR_DATA_TYPE,
(OCIError *) priv_data->cdata->herr);
if (!gda_oracle_check_result (result, priv_data->cnc, priv_data->cdata, OCI_HTYPE_ERROR,
- _("Could not get the Oracle column data type")))
+ _("Could not get the Oracle column data type"))) {
+ OCIDescriptorFree ((dvoid *) pard, OCI_DTYPE_PARAM);
return NULL;
+ }
result = OCIAttrGet ((dvoid *) pard,
(ub4) OCI_DTYPE_PARAM,
@@ -208,8 +218,10 @@
(ub4) OCI_ATTR_SCALE,
(OCIError *) priv_data->cdata->herr);
if (!gda_oracle_check_result (result, priv_data->cnc, priv_data->cdata, OCI_HTYPE_ERROR,
- _("Could not get the Oracle column scale")))
+ _("Could not get the Oracle column scale"))) {
+ OCIDescriptorFree ((dvoid *) pard, OCI_DTYPE_PARAM);
return NULL;
+ }
result = OCIAttrGet ((dvoid *) pard,
(ub4) OCI_DTYPE_PARAM,
@@ -218,8 +230,10 @@
(ub4) OCI_ATTR_IS_NULL,
(OCIError *) priv_data->cdata->herr);
if (!gda_oracle_check_result (result, priv_data->cnc, priv_data->cdata, OCI_HTYPE_ERROR,
- _("Could not get the Oracle column nullable attribute")))
+ _("Could not get the Oracle column nullable attribute"))) {
+ OCIDescriptorFree ((dvoid *) pard, OCI_DTYPE_PARAM);
return NULL;
+ }
result = OCIAttrGet ((dvoid *) pard,
OCI_DTYPE_PARAM,
@@ -228,8 +242,10 @@
OCI_ATTR_DATA_SIZE,
priv_data->cdata->herr);
if (!gda_oracle_check_result (result, priv_data->cnc, priv_data->cdata, OCI_HTYPE_ERROR,
- _("Could not get the Oracle defined size")))
+ _("Could not get the Oracle defined size"))) {
+ OCIDescriptorFree ((dvoid *) pard, OCI_DTYPE_PARAM);
return NULL;
+ }
gda_field_attributes_set_name (field_attrs, name_buffer);
gda_field_attributes_set_scale (field_attrs, scale);
@@ -247,6 +263,8 @@
gda_field_attributes_set_allow_null (field_attrs, !(nullable == 0));
+ OCIDescriptorFree ((dvoid *) pard, OCI_DTYPE_PARAM);
+
return field_attrs;
}
@@ -255,40 +273,45 @@
{
GdaOracleRecordset *recset = (GdaOracleRecordset *) model;
GdaOracleRecordsetPrivate *priv_data;
- gint i = 0;
- gint fetch_status = OCI_SUCCESS;
+ gint result = OCI_SUCCESS;
+ gint nrows;
g_return_val_if_fail (GDA_IS_ORACLE_RECORDSET (model), 0);
g_return_val_if_fail (recset->priv != NULL, 0);
priv_data = recset->priv;
- if (priv_data->nrows > 0)
- return priv_data->nrows;
+ nrows = priv_data->nrows;
- while (fetch_status == OCI_SUCCESS) {
- i += 1;
- fetch_status = OCIStmtFetch (priv_data->hstmt,
- priv_data->cdata->herr,
- (ub4) 1,
- (ub2) OCI_FETCH_NEXT,
- (ub4) OCI_DEFAULT);
- }
+ if (nrows >= 0)
+ return nrows;
- priv_data->nrows = i-1;
+ while (result == OCI_SUCCESS) {
+ nrows += 1;
+ result = OCIStmtFetch (priv_data->hstmt,
+ priv_data->cdata->herr,
+ (ub4) 1,
+ (ub2) OCI_FETCH_NEXT,
+ (ub4) OCI_DEFAULT);
+ }
// reset the result set to the beginning
- OCIStmtExecute (priv_data->cdata->hservice,
- priv_data->hstmt,
- priv_data->cdata->herr,
- (ub4) ((OCI_STMT_SELECT == priv_data->cdata->stmt_type) ? 0 : 1),
- (ub4) 0,
- (CONST OCISnapshot *) NULL,
- (OCISnapshot *) NULL,
- OCI_DEFAULT);
+ result = OCIStmtExecute (priv_data->cdata->hservice,
+ priv_data->hstmt,
+ priv_data->cdata->herr,
+ (ub4) ((OCI_STMT_SELECT == priv_data->cdata->stmt_type) ? 0 : 1),
+ (ub4) 0,
+ (CONST OCISnapshot *) NULL,
+ (OCISnapshot *) NULL,
+ OCI_DEFAULT);
+ if (!gda_oracle_check_result (result, priv_data->cnc, priv_data->cdata,
+ OCI_HTYPE_ERROR, "Could not execute Oracle statement")) {
+ return 0;
+ }
+ priv_data->ora_values = define_columns (priv_data);
- return priv_data->nrows;
+ return nrows;
}
static gint
@@ -309,7 +332,7 @@
gchar *id;
GdaOracleRecordsetPrivate *priv;
GList *node;
- ub4 status;
+ gint result;
g_return_val_if_fail (GDA_IS_ORACLE_RECORDSET (recset), NULL);
g_return_val_if_fail (recset->priv != NULL, NULL);
@@ -318,21 +341,18 @@
row = gda_row_new (priv->ncolumns);
- status = OCIStmtFetch ((OCIStmt *) priv->hstmt,
+ result = OCIStmtFetch ((OCIStmt *) priv->hstmt,
(OCIError *) priv->cdata->herr,
(ub4) 1,
(ub2) OCI_FETCH_NEXT,
(ub4) OCI_DEFAULT);
- switch (status) {
- case OCI_SUCCESS:
- case OCI_SUCCESS_WITH_INFO:
- break;
- case OCI_NO_DATA:
+ if (result == OCI_NO_DATA)
return NULL;
- default:
- gda_connection_add_error_string (priv->cnc, _("An error occurred during fetch"));
+
+ if (!gda_oracle_check_result (result, priv->cnc, priv->cdata, OCI_HTYPE_ERROR,
+ _("Could not fetch a row")))
return NULL;
- }
+
i = 0;
for (node = g_list_first (priv->ora_values); node != NULL;
@@ -362,6 +382,7 @@
g_return_val_if_fail (recset->priv != NULL, 0);
priv_data = recset->priv;
+
if (!priv_data->cdata) {
gda_connection_add_error_string (priv_data->cnc,
_("Invalid Oracle handle"));
@@ -370,10 +391,10 @@
fetched_rows = priv_data->rows->len;
- if (row >= priv_data->nrows && priv_data->nrows > 0)
+ if (row >= priv_data->nrows && priv_data->nrows >= 0)
return NULL;
- if (row < fetched_rows)
+ if (row < fetched_rows)
return (const GdaRow *) g_ptr_array_index (priv_data->rows, row);
gda_data_model_freeze (GDA_DATA_MODEL (recset));
@@ -495,15 +516,6 @@
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);
@@ -530,11 +542,8 @@
gda_oracle_recordset_init (GdaOracleRecordset *recset, GdaOracleRecordsetClass *klass)
{
g_return_if_fail (GDA_IS_ORACLE_RECORDSET (recset));
-
recset->priv = g_new0 (GdaOracleRecordsetPrivate, 1);
- recset->priv->cnc = NULL;
- recset->priv->rows = g_ptr_array_new ();
- recset->priv->cdata = NULL;
+ recset->priv->rows = g_ptr_array_new ();
}
static void
@@ -557,25 +566,46 @@
model_class->update_row = gda_oracle_recordset_update_row;
}
+static void
+gda_oracle_free_values (GdaOracleValue *ora_value)
+{
+ g_free (ora_value->value);
+ OCIDescriptorFree ((dvoid *) ora_value->pard, OCI_DTYPE_PARAM);
+ g_free (ora_value);
+}
+
static void
gda_oracle_recordset_finalize (GObject *object)
{
GdaOracleRecordset *recset = (GdaOracleRecordset *) object;
+ GdaOracleRecordsetPrivate *priv_data;
+
+ g_return_if_fail (recset->priv != NULL);
+
+ priv_data = recset->priv;
+
+ if (!priv_data->cdata) {
+ gda_connection_add_error_string (priv_data->cnc,
+ _("Invalid Oracle handle"));
+ return NULL;
+ }
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);
+ while (priv_data->rows->len > 0) {
+ GdaRow *row = (GdaRow *) g_ptr_array_index (priv_data->rows, 0);
if (row != NULL)
gda_row_free (row);
- g_ptr_array_remove_index (recset->priv->rows, 0);
+ g_ptr_array_remove_index (priv_data->rows, 0);
}
- g_ptr_array_free (recset->priv->rows, TRUE);
+ g_ptr_array_free (priv_data->rows, TRUE);
recset->priv->rows = NULL;
- if (recset->priv->hstmt)
- OCIHandleFree ((dvoid *)recset->priv->hstmt, OCI_HTYPE_STMT);
+ g_list_foreach (priv_data->ora_values, (GFunc) gda_oracle_free_values, NULL);
+
+ if (priv_data->hstmt)
+ OCIHandleFree ((dvoid *) priv_data->hstmt, OCI_HTYPE_STMT);
parent_class->finalize (object);
}
@@ -623,12 +653,13 @@
cdata->herr);
recset = g_object_new (GDA_TYPE_ORACLE_RECORDSET, NULL);
+ recset->priv->nrows = -1;
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->ora_values = define_columns (recset->priv);
+ recset->priv->nrows = gda_oracle_recordset_get_n_rows (GDA_DATA_MODEL (recset));
return recset;
}
Index: utils.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/oracle/utils.c,v
retrieving revision 1.3
diff -u -u -r1.3 utils.c
--- utils.c 20 Jun 2002 18:15:26 -0000 1.3
+++ utils.c 28 Jun 2002 04:36:08 -0000
@@ -364,7 +364,7 @@
ub1 month;
ub1 day;
- gchar string_buffer[ora_value->defined_size+1];
+ gchar *string_buffer;
if (-1 == (ora_value->indicator)) {
gda_value_set_null (value);
@@ -376,6 +376,7 @@
gda_value_set_boolean (value, (atoi (ora_value->value)) ? TRUE: FALSE);
break;
case GDA_VALUE_TYPE_STRING:
+ string_buffer = g_malloc0 (ora_value->defined_size+1);
memcpy (string_buffer, ora_value->value, ora_value->defined_size);
string_buffer[ora_value->defined_size] = '\0';
gda_value_set_string (value, string_buffer);
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/libgda/ChangeLog,v
retrieving revision 1.308
diff -u -u -r1.308 ChangeLog
--- ChangeLog 21 Jun 2002 18:39:14 -0000 1.308
+++ ChangeLog 28 Jun 2002 04:40:58 -0000
@@ -1,3 +1,18 @@
+2002-06-28 Tim Coleman <tim timcoleman com>
+ * providers/oracle/gda-oracle-provider.c:
+ - Added code to retrieve public/unique/foreign key information
+ for schema purposes.
+ - Free up more Oracle memory when bad things happen
+ - Added a function to retrieve list of Oracle tablespaces
+ for schema purposes.
+ * providers/oracle/gda-oracle-recordset.c:
+ - Free up more Oracle memory when bad things happen
+ - Clean up the get_n_rows code to work properly
+ * providers/oracle/utils.c:
+ - only allocate memory for the string buffer when I need
+ it.
+
+
2002-06-21 Rodrigo Moya <rodrigo gnome-db org>
* libsql/Makefile.am: missing header files to SOURCES.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]