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 (); } }
static GdaRow * fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **error) { int rc; SqliteConnectionData *cdata; GdaSqlitePStmt *ps; GdaRow *prow = NULL; GdaConnection *cnc; glong length; cnc = gda_data_select_get_connection ((GdaDataSelect*) model); cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error); if (!cdata) return NULL; ps = GDA_SQLITE_PSTMT (GDA_DATA_SELECT (model)->prep_stmt); virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) model), model); if (model->priv->empty_forced) rc = SQLITE_DONE; else rc = SQLITE3_CALL (sqlite3_step) (ps->sqlite_stmt); switch (rc) { case SQLITE_ROW: { gint col, real_col; prow = gda_row_new (_GDA_PSTMT (ps)->ncols); for (col = 0; col < _GDA_PSTMT (ps)->ncols; col++) { GValue *value; GType type = _GDA_PSTMT (ps)->types [col]; real_col = col + ps->nb_rowid_columns; if (type == GDA_TYPE_NULL) { type = fuzzy_get_gtype (cdata, ps, col); if (type == GDA_TYPE_BLOB) { /* extra check: make sure we have a rowid for this blob, or fallback to binary */ if (ps->rowid_hash) { gint oidcol = 0; const char *ctable; ctable = SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col); if (ctable) oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, ctable)); if (oidcol == 0) { ctable = SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt, real_col); if (ctable) oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, ctable)); } if (oidcol == 0) type = GDA_TYPE_BINARY; } else type = GDA_TYPE_BINARY; } if (type != GDA_TYPE_NULL) { GdaColumn *column; _GDA_PSTMT (ps)->types [col] = type; column = gda_data_model_describe_column (GDA_DATA_MODEL (model), col); gda_column_set_g_type (column, type); column = (GdaColumn *) g_slist_nth_data (_GDA_PSTMT (ps)->tmpl_columns, col); gda_column_set_g_type (column, type); } } /* fill GValue */ value = gda_row_get_value (prow, col); GError *may_error; may_error = (GError*) SQLITE3_CALL (sqlite3_column_blob) (ps->sqlite_stmt, real_col); if (may_error && g_hash_table_lookup (error_blobs_hash, may_error)) { /*g_print ("Row invalidated: [%s]\n", may_error->message);*/ gda_row_invalidate_value_e (prow, value, may_error); g_hash_table_remove (error_blobs_hash, may_error); } else if (SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col) == NULL) { /* we have a NULL value */ gda_value_set_null (value); } else { gda_value_reset_with_type (value, type); if (type == GDA_TYPE_NULL) ; else if (type == G_TYPE_INT) { gint64 i; i = SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if ((i > G_MAXINT) || (i < G_MININT)) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else g_value_set_int (value, (gint) i); } else if (type == G_TYPE_UINT) { guint64 i; i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if (i > G_MAXUINT) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else g_value_set_uint (value, (gint) i); } else if (type == G_TYPE_INT64) g_value_set_int64 (value, SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col)); else if (type == G_TYPE_UINT64) g_value_set_uint64 (value, (guint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col)); else if (type == G_TYPE_DOUBLE) g_value_set_double (value, SQLITE3_CALL (sqlite3_column_double) (ps->sqlite_stmt, real_col)); else if (type == G_TYPE_STRING) g_value_set_string (value, (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col)); else if (type == GDA_TYPE_BINARY) { GdaBinary *bin; bin = gda_binary_new (); length = SQLITE3_CALL (sqlite3_column_bytes) (ps->sqlite_stmt, real_col); if (length > 0) { gda_binary_set_data (bin, SQLITE3_CALL (sqlite3_column_blob) (ps->sqlite_stmt, /* Flawfinder: ignore */ real_col), length); } gda_value_take_binary (value, bin); } else if (type == GDA_TYPE_BLOB) { GdaBlobOp *bop = NULL; gint oidcol = 0; if (ps->rowid_hash) { const char *ctable; ctable = SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col); if (ctable) oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, ctable)); if (oidcol == 0) { ctable = SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt, real_col); if (ctable) oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, ctable)); } } if (oidcol != 0) { gint64 rowid; rowid = SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, oidcol - 1); /* remove 1 because it was added in the first place */ bop = _gda_sqlite_blob_op_new (cnc, SQLITE3_CALL (sqlite3_column_database_name) (ps->sqlite_stmt, real_col), SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt, real_col), SQLITE3_CALL (sqlite3_column_origin_name) (ps->sqlite_stmt, real_col), rowid); } if (!bop) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Unable to open BLOB")); gda_row_invalidate_value_e (prow, value, lerror); } else { GdaBlob *blob; blob = gda_blob_new (); gda_blob_set_op (blob, bop); g_object_unref (bop); gda_value_take_blob (value, blob); } } else if (type == G_TYPE_BOOLEAN) g_value_set_boolean (value, SQLITE3_CALL (sqlite3_column_int) (ps->sqlite_stmt, real_col) == 0 ? FALSE : TRUE); else if (type == G_TYPE_DATE) { GDate date; if (!gda_parse_iso8601_date (&date, (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col))) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Invalid date '%s' (date format should be YYYY-MM-DD)"), (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col)); gda_row_invalidate_value_e (prow, value, lerror); } else g_value_set_boxed (value, &date); } else if (type == GDA_TYPE_TIME) { GdaTime timegda; if (!gda_parse_iso8601_time (&timegda, (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col))) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Invalid time '%s' (time format should be HH:MM:SS[.ms])"), (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col)); gda_row_invalidate_value_e (prow, value, lerror); } else { if (timegda.timezone == GDA_TIMEZONE_INVALID) timegda.timezone = 0; /* set to GMT */ gda_value_set_time (value, &timegda); } } else if (type == GDA_TYPE_TIMESTAMP) { GdaTimestamp timestamp; if (!gda_parse_iso8601_timestamp (×tamp, (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col))) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Invalid timestamp '%s' (format should be YYYY-MM-DD HH:MM:SS[.ms])"), (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col)); gda_row_invalidate_value_e (prow, value, lerror); } else { if (timestamp.timezone == GDA_TIMEZONE_INVALID) timestamp.timezone = 0; /* set to GMT */ gda_value_set_timestamp (value, ×tamp); } } else if (type == G_TYPE_CHAR) { gint64 i; i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if ((i > G_MAXINT8) || (i < G_MININT8)) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else g_value_set_schar (value, (gchar) i); } else if (type == G_TYPE_UCHAR) { gint64 i; i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if ((i > G_MAXUINT8) || (i < 0)) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else g_value_set_uchar (value, (guchar) i); } else if (type == GDA_TYPE_SHORT) { gint64 i; i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if ((i > G_MAXSHORT) || (i < G_MINSHORT)) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else gda_value_set_short (value, (guchar) i); } else if (type == GDA_TYPE_USHORT) { gint64 i; i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if ((i > G_MAXUSHORT) || (i < 0)) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else gda_value_set_ushort (value, (guchar) i); } else { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "Unhandled type '%s' in SQLite recordset", gda_g_type_to_string (_GDA_PSTMT (ps)->types [col])); gda_row_invalidate_value_e (prow, value, lerror); } } } if (do_store) { /* insert row */ gda_data_select_take_row (GDA_DATA_SELECT (model), prow, model->priv->next_row_num); } model->priv->next_row_num ++; break; } case SQLITE_BUSY: /* nothing to do */ break; case SQLITE_DONE: GDA_DATA_SELECT (model)->advertized_nrows = model->priv->next_row_num; SQLITE3_CALL (sqlite3_reset) (ps->sqlite_stmt); break; case SQLITE_READONLY: case SQLITE_MISUSE: g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_INTERNAL_ERROR, "%s", _("SQLite provider fatal internal error")); break; case SQLITE_ERROR: default: { GError *lerror = NULL; SQLITE3_CALL (sqlite3_reset) (ps->sqlite_stmt); if (rc == SQLITE_IOERR_TRUNCATE) g_set_error (&lerror, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_TRUNCATED_ERROR, "%s", _("Truncated data")); else g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_INTERNAL_ERROR, "%s", SQLITE3_CALL (sqlite3_errmsg) (cdata->connection)); gda_data_select_add_exception (GDA_DATA_SELECT (model), lerror); if (rc == SQLITE_ERROR) g_propagate_error (error, g_error_copy (lerror)); GDA_DATA_SELECT (model)->advertized_nrows = model->priv->next_row_num; break; } } virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) model), NULL); return prow; }