void _gda_oracle_value_free (GdaOracleValue *ora_value) { if (ora_value->g_type == GDA_TYPE_BLOB) OCIDescriptorFree ((dvoid *) ora_value->value, (ub4) gda_oracle_blob_type (ora_value->sql_type)); else g_free (ora_value->value); OCIDescriptorFree ((dvoid *) ora_value->pard, OCI_DTYPE_PARAM); g_free (ora_value); }
void _gda_oracle_set_value (GValue *value, GdaOracleValue *ora_value, GdaConnection *cnc) { GdaTime gtime; GdaTimestamp timestamp; sb2 year; ub1 month; ub1 day; ub1 hour; ub1 min; ub1 sec; if (ora_value->indicator == -1) { gda_value_set_null (value); return; } gda_value_reset_with_type (value, ora_value->g_type); switch (ora_value->s_type) { case GDA_STYPE_INT: g_value_set_int (value, *((gint *) ora_value->value)); break; case GDA_STYPE_STRING: { gchar *string_buffer, *tmp; string_buffer = (gchar *) ora_value->value; string_buffer [ora_value->rlen] = '\0'; g_strchomp (string_buffer); //tmp = g_locale_to_utf8 (string_buffer, -1, NULL, NULL, NULL); //g_value_take_string (value, tmp); g_value_set_string (value, string_buffer); if (ora_value->use_callback) { g_free (string_buffer); ora_value->value = NULL; } break; } case GDA_STYPE_BOOLEAN: g_value_set_boolean (value, (*((gint *) ora_value->value)) ? TRUE: FALSE); break; case GDA_STYPE_DATE: { GDate *date; OCIDateGetDate ((CONST OCIDate *) ora_value->value, (sb2 *) &year, (ub1 *) &month, (ub1 *) &day); date = g_date_new_dmy (day, month, year); g_value_take_boxed (value, date); break; } case GDA_STYPE_TIME: { OCIDateGetTime ((CONST OCIDate *) ora_value->value, (ub1 *) &hour, (ub1 *) &min, (ub1 *) &sec); gtime.hour = hour; gtime.minute = min; gtime.second = sec; gda_value_set_time (value, >ime); break; } case GDA_STYPE_TIMESTAMP: { OCIDateGetDate ((CONST OCIDate *) ora_value->value, (sb2 *) &year, (ub1 *) &month, (ub1 *) &day); OCIDateGetTime ((CONST OCIDate *) ora_value->value, (ub1 *) &hour, (ub1 *) &min, (ub1 *) &sec); timestamp.year = year; timestamp.month = month; timestamp.day = day; timestamp.hour = hour; timestamp.minute = min; timestamp.second = sec; timestamp.fraction = 0; timestamp.timezone = 0; gda_value_set_timestamp(value, ×tamp); break; } case GDA_STYPE_INT64: TO_IMPLEMENT; /* test that value fits in */ g_value_set_int64 (value, atoll (ora_value->value)); break; case GDA_STYPE_UINT64: TO_IMPLEMENT; /* test that value fits in */ g_value_set_uint64 (value, atoll (ora_value->value)); break; case GDA_STYPE_UINT: TO_IMPLEMENT; /* test that value fits in */ g_value_set_uint (value, *((guint*) ora_value->value)); break; case GDA_STYPE_FLOAT: g_value_set_float (value, *((gfloat*) ora_value->value)); break; case GDA_STYPE_DOUBLE: g_value_set_double (value, *((gdouble*) ora_value->value)); break; case GDA_STYPE_LONG: TO_IMPLEMENT; break; case GDA_STYPE_ULONG: TO_IMPLEMENT; break; case GDA_STYPE_NUMERIC: { GdaNumeric *numeric; gchar *tmp; g_assert (!ora_value->use_callback); tmp = g_malloc0 (ora_value->defined_size); memcpy (tmp, ora_value->value, ora_value->defined_size); tmp [ora_value->rlen] = '\0'; g_strchomp (tmp); numeric = gda_numeric_new (); gda_numeric_set_from_string (numeric, tmp); g_free (tmp); gda_numeric_set_precision (numeric, ora_value->precision); gda_numeric_set_width (numeric, ora_value->scale); g_value_take_boxed (value, numeric); break; } case GDA_STYPE_BINARY: { GdaBinary *bin; bin = g_new0 (GdaBinary, 1); if (ora_value->use_callback) { bin->data = ora_value->value; ora_value->value = NULL; } else { bin->data = g_new (guchar, ora_value->rlen); memcpy (bin->data, ora_value->value, ora_value->rlen); } bin->binary_length = ora_value->rlen; gda_value_take_binary (value, bin); break; } case GDA_STYPE_BLOB: { GdaBlob *blob; GdaBlobOp *op; OCILobLocator *lobloc; OracleConnectionData *cdata; gint result; /* REM: we need to make a "copy" of the lob locator to give to the GdaOracleblobOp object */ cdata = (OracleConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) { gda_connection_add_event_string (cnc, _("Invalid Oracle handle")); gda_value_set_null (value); return; } result = OCIDescriptorAlloc ((dvoid *) cdata->henv, (dvoid **) &lobloc, (ub4) gda_oracle_blob_type (ora_value->sql_type), (size_t) 0, (dvoid **) 0); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not allocate Lob locator"))) { gda_value_set_null (value); return; } result = OCILobAssign ((dvoid *) cdata->henv, (dvoid *) cdata->herr, ora_value->value, &lobloc); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not copy Lob locator"))) { gda_value_set_null (value); return; } blob = g_new0 (GdaBlob, 1); op = gda_oracle_blob_op_new (cnc, lobloc); gda_blob_set_op (blob, op); g_object_unref (op); gda_value_take_blob (value, blob); break; } case GDA_STYPE_CHAR: { TO_IMPLEMENT; /* test that value fits in */ g_value_set_schar (value, *((gint8*) ora_value->value)); break; } case GDA_STYPE_SHORT: { TO_IMPLEMENT; /* test that value fits in */ gda_value_set_short (value, *((gint*) ora_value->value)); break; } case GDA_STYPE_GTYPE: TO_IMPLEMENT; break; case GDA_STYPE_GEOMETRIC_POINT: TO_IMPLEMENT; break; case GDA_STYPE_NULL: gda_value_set_null (value); break; default: g_assert_not_reached (); } }
/* * the @ps struct is modified and transferred to the new data model created in * this function */ GdaDataModel * gda_oracle_recordset_new (GdaConnection *cnc, GdaOraclePStmt *ps, GdaSet *exec_params, GdaDataModelAccessFlags flags, GType *col_types) { GdaOracleRecordset *model; OracleConnectionData *cdata; gint i; GdaDataModelAccessFlags rflags; gint nb_rows = -1; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); g_return_val_if_fail (ps != NULL, NULL); cdata = (OracleConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) return NULL; /* make sure @ps reports the correct number of columns using the API */ if (_GDA_PSTMT (ps)->ncols < 0) { ub4 ncolumns; int result; /* get the number of columns in the result set */ result = OCIAttrGet ((dvoid *) ps->hstmt, (ub4) OCI_HTYPE_STMT, (dvoid *) &ncolumns, (ub4 *) 0, (ub4) OCI_ATTR_PARAM_COUNT, cdata->herr); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not get the number of columns in the result set"))) return NULL; _GDA_PSTMT (ps)->ncols = ncolumns; } /* completing @ps if not yet done */ if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) { /* create prepared statement's columns */ GSList *list; GList *ora_values = NULL; for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++) _GDA_PSTMT (ps)->tmpl_columns = g_slist_prepend (_GDA_PSTMT (ps)->tmpl_columns, gda_column_new ()); _GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns); /* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */ _GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols); for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++) _GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL; if (col_types) { for (i = 0; ; i++) { if (col_types [i] > 0) { if (col_types [i] == G_TYPE_NONE) break; if (i >= _GDA_PSTMT (ps)->ncols) { g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i, _GDA_PSTMT (ps)->ncols - 1); break; } else _GDA_PSTMT (ps)->types [i] = col_types [i]; } } } /* fill GdaColumn's data and define the GdaOracleValue structures */ for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; i < GDA_PSTMT (ps)->ncols; i++, list = list->next) { GdaColumn *column; int result; GdaOracleValue *ora_value; gboolean use_callback = FALSE; ora_value = g_new0 (GdaOracleValue, 1); ora_values = g_list_prepend (ora_values, ora_value); /* parameter to get attributes */ result = OCIParamGet (ps->hstmt, OCI_HTYPE_STMT, cdata->herr, (dvoid **) &(ora_value->pard), (ub4) i+1); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not get the Oracle parameter descripter in the result set"))) { g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL); return NULL; } /* data size */ result = OCIAttrGet ((dvoid *) (ora_value->pard), OCI_DTYPE_PARAM, &(ora_value->defined_size), 0, (ub4) OCI_ATTR_DATA_SIZE, cdata->herr); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not get the parameter defined size"))) { g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL); return NULL; } ora_value->defined_size++; /* data type */ result = OCIAttrGet ((dvoid *) (ora_value->pard), OCI_DTYPE_PARAM, &(ora_value->sql_type), 0, OCI_ATTR_DATA_TYPE, cdata->herr); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not get the parameter data type"))) { g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL); return NULL; } result = OCIAttrGet ((dvoid *) (ora_value->pard), OCI_DTYPE_PARAM, &(ora_value->precision), 0, OCI_ATTR_PRECISION, cdata->herr); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not get the type's precision"))) { g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL); return NULL; } result = OCIAttrGet ((dvoid *) (ora_value->pard), OCI_DTYPE_PARAM, &(ora_value->scale), 0, OCI_ATTR_SCALE, cdata->herr); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not get the type's scale"))) { g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL); return NULL; } /* column's name */ text *name; ub4 name_len; column = GDA_COLUMN (list->data); result = OCIAttrGet ((dvoid *) (ora_value->pard), (ub4) OCI_DTYPE_PARAM, (dvoid **) &name, (ub4 *) &name_len, (ub4) OCI_ATTR_NAME, (OCIError *) cdata->herr); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not get column name in the result set"))) { g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL); return NULL; } gchar *name_buffer; name_buffer = g_new (gchar, name_len + 1); memcpy (name_buffer, name, name_len); name_buffer [name_len] = '\0'; gda_column_set_name (column, name_buffer); gda_column_set_description (column, name_buffer); g_free (name_buffer); /* for data fetching */ if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL) ora_value->sql_type = _g_type_to_oracle_sqltype (_GDA_PSTMT (ps)->types [i]); switch (ora_value->sql_type) { case SQLT_CHR: /* for G_TYPE_STRING => request SQLT_CHR */ case SQLT_STR: case SQLT_VCS: case SQLT_RID: case SQLT_AVC: case SQLT_AFC: ora_value->sql_type = SQLT_CHR; if (ora_value->defined_size == 1) use_callback = TRUE; break; case SQLT_INT: ora_value->defined_size = sizeof (gint); break; case SQLT_FLT: case SQLT_BFLOAT: ora_value->defined_size = sizeof (gfloat); break; case SQLT_BDOUBLE: ora_value->defined_size = sizeof (gdouble); break; case SQLT_DAT: /* request OCIDate */ ora_value->sql_type = SQLT_ODT; break; case SQLT_NUM: /* for GDA_TYPE_NUMERIC => request SQLT_CHR */ case SQLT_VNU: ora_value->sql_type = SQLT_CHR; break; case SQLT_LBI: case SQLT_LVB: case SQLT_LVC: case SQLT_LNG: case SQLT_VBI: case SQLT_BIN: use_callback = TRUE; break; default: use_callback = TRUE; break; } if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL) ora_value->g_type = _GDA_PSTMT (ps)->types [i]; else ora_value->g_type = _oracle_sqltype_to_g_type (ora_value->sql_type, ora_value->precision, ora_value->scale); if (ora_value->g_type == GDA_TYPE_BLOB) { /* allocate a Lob locator */ OCILobLocator *lob; result = OCIDescriptorAlloc ((dvoid *) cdata->henv, (dvoid **) &lob, (ub4) gda_oracle_blob_type (ora_value->sql_type), (size_t) 0, (dvoid **) 0); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not allocate Lob locator"))) { g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL); return NULL; } ora_value->value = lob; ora_value->defined_size = 0; } else if (use_callback) { ora_value->value = NULL; ora_value->defined_size = 33554432; /* 32M */ } else ora_value->value = g_malloc0 (ora_value->defined_size); ora_value->s_type = gda_g_type_to_static_type (ora_value->g_type); if (_GDA_PSTMT (ps)->types [i] == GDA_TYPE_NULL) _GDA_PSTMT (ps)->types [i] = ora_value->g_type; gda_column_set_g_type (column, ora_value->g_type); #ifdef GDA_DEBUG_NO g_print ("**COL type is %d, GType is %s, ORA defined size is %d%s\n", ora_value->sql_type, g_type_name (ora_value->g_type), ora_value->defined_size - 1, use_callback ? " using callback": ""); #endif ora_value->hdef = (OCIDefine *) 0; ora_value->indicator = 0; result = OCIDefineByPos ((OCIStmt *) ps->hstmt, (OCIDefine **) &(ora_value->hdef), (OCIError *) cdata->herr, (ub4) i + 1, ora_value->value, ora_value->defined_size, ora_value->sql_type, (dvoid *) &(ora_value->indicator), &(ora_value->rlen), &(ora_value->rcode), (ub4) (use_callback ? OCI_DYNAMIC_FETCH : OCI_DEFAULT)); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not define by position"))) { OCIDescriptorFree ((dvoid *) ora_value->pard, OCI_DTYPE_PARAM); g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL); return NULL; } if (use_callback) { result = OCIDefineDynamic ((OCIDefine *) (ora_value->hdef), (OCIError *) (cdata->herr), (dvoid*) (ora_value), (OCICallbackDefine) ora_def_callback); if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not define by position"))) { OCIDescriptorFree ((dvoid *) ora_value->pard, OCI_DTYPE_PARAM); g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL); return NULL; } } ora_value->use_callback = use_callback; } ps->ora_values = g_list_reverse (ora_values); } /* determine access mode: RANDOM or CURSOR FORWARD are the only supported; if CURSOR BACKWARD * is requested, then we need RANDOM mode */ if (flags & GDA_DATA_MODEL_ACCESS_RANDOM) rflags = GDA_DATA_MODEL_ACCESS_RANDOM; else if (flags & GDA_DATA_MODEL_ACCESS_CURSOR_BACKWARD) rflags = GDA_DATA_MODEL_ACCESS_RANDOM; else rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD; ub4 prefetch; prefetch = (ub4) (100); OCIAttrSet (ps->hstmt, OCI_HTYPE_STMT, &prefetch, 0, OCI_ATTR_PREFETCH_ROWS, cdata->herr); /* create data model */ model = g_object_new (GDA_TYPE_ORACLE_RECORDSET, "connection", cnc, "prepared-stmt", ps, "model-usage", rflags, "exec-params", exec_params, NULL); GDA_DATA_SELECT (model)->advertized_nrows = nb_rows; return GDA_DATA_MODEL (model); }