GdaConnectionEvent * _gda_firebird_make_error (GdaConnection *cnc, const gint statement_type) { FirebirdConnectionData *cdata; GdaConnectionEvent *error_ev; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) return NULL; error_ev = gda_connection_point_available_event (cnc, GDA_CONNECTION_EVENT_ERROR); gda_connection_event_set_code (error_ev, isc_sqlcode (cdata->status)); ISC_SCHAR *description; const ISC_STATUS *p = cdata->status; description = g_new0 (ISC_SCHAR, 512); fb_interpret (description, 511, &p); g_print ("MAKE_ERROR [%s]\n", description); gda_connection_event_set_source (error_ev, "[GDA Firebird]"); gda_connection_event_set_description (error_ev, description); gda_connection_add_event (cnc, error_ev); g_free (description); return error_ev; }
/* * Reopens a connection after the server has closed it (possibly because of a timeout) */ gboolean gda_ldap_rebind (GdaLdapConnection *cnc, GError **error) { g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), FALSE); gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */ LdapConnectionData *cdata; cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc)); if (!cdata) { gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ g_warning ("cdata != NULL failed"); return FALSE; } GdaServerProviderConnectionData *pcdata; pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL); GdaWorker *worker; worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata)); GMainContext *context; context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc); gpointer retval; gda_worker_do_job (worker, context, 0, &retval, NULL, (GdaWorkerFunc) worker_gda_ldap_rebind, (gpointer) cdata, NULL, NULL, error); if (context) g_main_context_unref (context); gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ gda_worker_unref (worker); return retval ? TRUE : FALSE; }
/* * Create a new filled #GdaRow object for the row at position @rownum, and put it into *prow. * * Each new #GdaRow created needs to be "given" to the #GdaDataSelect implementation using * gda_data_select_take_row() because backward iterating is not supported. */ static gboolean gda_oracle_recordset_fetch_random (GdaDataSelect *model, GdaRow **prow, gint rownum, GError **error) { GdaOracleRecordset *imodel; OracleConnectionData *cdata; GdaConnection *cnc; imodel = GDA_ORACLE_RECORDSET (model); cnc = gda_data_select_get_connection (model); cdata = (OracleConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error); if (!cdata) return TRUE; if (imodel->priv->next_row_num >= rownum) { g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_INTERNAL_ERROR, "%s", _("Requested row could not be found")); return TRUE; } for (*prow = fetch_next_oracle_row (imodel, TRUE, error); *prow && (imodel->priv->next_row_num < rownum); *prow = fetch_next_oracle_row (imodel, TRUE, error)); return TRUE; }
/* * Unbinds the connection if possible (i.e. if cdata->keep_bound_count is 0) * This allows to avoid keeping the connection to the LDAP server if unused */ void gda_ldap_may_unbind (GdaLdapConnection *cnc) { gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */ LdapConnectionData *cdata; cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc)); if (!cdata || (cdata->keep_bound_count > 0)) { gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ return; } GdaServerProviderConnectionData *pcdata; pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL); GdaWorker *worker; worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata)); GMainContext *context; context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc); gpointer retval; gda_worker_do_job (worker, context, 0, &retval, NULL, (GdaWorkerFunc) worker_gda_ldap_may_unbind, (gpointer) cdata, NULL, NULL, NULL); if (context) g_main_context_unref (context); gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ gda_worker_unref (worker); }
static void gda_web_pstmt_dispose (GObject *object) { GdaWebPStmt *pstmt = (GdaWebPStmt *) object; g_return_if_fail (GDA_IS_PSTMT (pstmt)); GdaWebPStmtPrivate *priv = gda_web_pstmt_get_instance_private (pstmt); if (priv->pstmt_hash) { GdaConnection *cnc = NULL; WebConnectionData *cdata; cnc = g_weak_ref_get (&priv->cnc); if (cnc != NULL) { cdata = (WebConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) goto next; /* send command to deallocate prepared statement */ xmlDocPtr doc; xmlNodePtr root, cmdnode; gchar *token; doc = xmlNewDoc (BAD_CAST "1.0"); root = xmlNewNode (NULL, BAD_CAST "request"); xmlDocSetRootElement (doc, root); token = _gda_web_compute_token (cdata); xmlNewChild (root, NULL, BAD_CAST "token", BAD_CAST token); g_free (token); cmdnode = xmlNewChild (root, NULL, BAD_CAST "cmd", BAD_CAST "UNPREPARE"); xmlNewChild (cmdnode, NULL, BAD_CAST "preparehash", BAD_CAST priv->pstmt_hash); xmlChar *cmde; xmlDocPtr replydoc; int size; gchar status; xmlDocDumpMemory (doc, &cmde, &size); xmlFreeDoc (doc); replydoc = _gda_web_send_message_to_frontend (cnc, cdata, MESSAGE_UNPREPARE, (gchar*) cmde, cdata->key, &status); xmlFree (cmde); if (replydoc) xmlFreeDoc (replydoc); } next: /* free memory */ g_free (priv->pstmt_hash); } /* chain to parent class */ G_OBJECT_CLASS (gda_web_pstmt_parent_class)->finalize (object); }
static GdaRow * fetch_next_oracle_row (GdaOracleRecordset *model, G_GNUC_UNUSED gboolean do_store, GError **error) { int result; GdaRow *prow = NULL; GdaOraclePStmt *ps = GDA_ORACLE_PSTMT (((GdaDataSelect*)model)->prep_stmt); OracleConnectionData *cdata; GdaConnection *cnc; cnc = gda_data_select_get_connection ((GdaDataSelect*) model); cdata = (OracleConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error); if (!cdata) return NULL; /* fetch row */ if (cdata->major_version > 9) result = OCIStmtFetch2 (ps->hstmt, cdata->herr, (ub4) 1, (ub2) OCI_FETCH_NEXT, (sb4) 1, (ub4) OCI_DEFAULT); else result = OCIStmtFetch (ps->hstmt, cdata->herr, (ub4) 1, (ub2) OCI_FETCH_NEXT, (ub4) OCI_DEFAULT); if (result == OCI_NO_DATA) { GDA_DATA_SELECT (model)->advertized_nrows = model->priv->next_row_num; return NULL; } else { GdaConnectionEvent *event; if ((event = gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR, _("Could not fetch next row")))) { /* set @error */ g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", gda_connection_event_get_description (event)); return NULL; } } prow = new_row ((GdaDataSelect*) model, cnc, ps); gda_data_select_take_row ((GdaDataSelect*) model, prow, model->priv->next_row_num); model->priv->next_row_num ++; return prow; }
/** * gdaprov_ldap_get_class_info: * @cnc: a #GdaLdapConnection (not %NULL) * @classname: the class name (not %NULL) * * Returns: the #GdaLdapClass for @classname, or %NULL */ GdaLdapClass * gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname) { g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL); g_return_val_if_fail (classname, NULL); gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */ LdapConnectionData *cdata; cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc)); if (!cdata) { gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ return NULL; } if (cdata->classes_hash) { gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ return g_hash_table_lookup (cdata->classes_hash, classname); } GdaServerProviderConnectionData *pcdata; pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL); GdaWorker *worker; worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata)); GMainContext *context; context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc); WorkerLdapClassInfoData data; data.cnc = cnc; data.cdata = cdata; data.classname = classname; gda_connection_increase_usage ((GdaConnection*) cnc); /* USAGE ++ */ gpointer retval; gda_worker_do_job (worker, context, 0, &retval, NULL, (GdaWorkerFunc) worker_gdaprov_ldap_get_class_info, (gpointer) &data, NULL, NULL, NULL); if (context) g_main_context_unref (context); gda_connection_decrease_usage ((GdaConnection*) cnc); /* USAGE -- */ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ gda_worker_unref (worker); return (GdaLdapClass*) retval; }
gchar * gda_postgres_render_DROP_USER (GdaServerProvider *provider, GdaConnection *cnc, GdaServerOperation *op, G_GNUC_UNUSED GError **error) { GString *string; const GValue *value; gchar *sql = NULL; gchar *tmp; gboolean use_role = TRUE; PostgresConnectionData *cdata = NULL; if (cnc) { g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE); g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE); cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error); } if (cdata && (cdata->reuseable->version_float < 8.1)) use_role = FALSE; if (use_role) string = g_string_new ("DROP ROLE "); else string = g_string_new ("DROP USER "); value = gda_server_operation_get_value_at (op, "/USER_DESC_P/USER_IFEXISTS"); if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) g_string_append (string, " IF EXISTS"); tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/USER_DESC_P/USER_NAME", error); if (!tmp) { g_string_free (string, TRUE); return NULL; } g_string_append_c (string, ' '); g_string_append (string, tmp); g_free (tmp); sql = string->str; g_string_free (string, FALSE); return sql; }
GdaLdapEntry * gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **error) { g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL); g_return_val_if_fail (!dn || (dn && *dn), NULL); gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */ LdapConnectionData *cdata; cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc)); if (!cdata) { gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ return NULL; } GdaServerProviderConnectionData *pcdata; pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL); GdaWorker *worker; worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata)); GMainContext *context; context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc); WorkerLdapDescrEntryData data; data.cnc = cnc; data.cdata = cdata; data.dn = dn; gda_connection_increase_usage ((GdaConnection*) cnc); /* USAGE ++ */ gpointer retval; gda_worker_do_job (worker, context, 0, &retval, NULL, (GdaWorkerFunc) worker_gdaprov_ldap_describe_entry, (gpointer) &data, NULL, NULL, error); if (context) g_main_context_unref (context); gda_connection_decrease_usage ((GdaConnection*) cnc); /* USAGE -- */ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ gda_worker_unref (worker); return (GdaLdapEntry*) retval; }
/** * gda_ldap_get_attr_info: * @cnc: a #GdaLdapConnection * @cdata: * @attribute: * * Returns: (transfer none): the #LdapAttribute for @attribute, or %NULL */ LdapAttribute * gda_ldap_get_attr_info (GdaLdapConnection *cnc, LdapConnectionData *cdata, const gchar *attribute) { g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); if (! attribute || !cdata) return NULL; gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */ GdaServerProviderConnectionData *pcdata; pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL); GdaWorker *worker; worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata)); GMainContext *context; context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc); WorkerLdapAttrInfoData data; data.cnc = cnc; data.cdata = cdata; data.attribute = attribute; gda_connection_increase_usage ((GdaConnection*) cnc); /* USAGE ++ */ gpointer retval; gda_worker_do_job (worker, context, 0, &retval, NULL, (GdaWorkerFunc) worker_gda_ldap_get_attr_info, (gpointer) &data, NULL, NULL, NULL); if (context) g_main_context_unref (context); gda_connection_decrease_usage ((GdaConnection*) cnc); /* USAGE -- */ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ gda_worker_unref (worker); return (LdapAttribute*) retval; }
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); }
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; }
/* * the @ps struct is modified and transferred to the new data model created in * this function */ GdaDataModel * _gda_sqlite_recordset_new (GdaConnection *cnc, GdaSqlitePStmt *ps, GdaSet *exec_params, GdaDataModelAccessFlags flags, GType *col_types, gboolean force_empty) { GdaSqliteRecordset *model; SqliteConnectionData *cdata; gint i; GdaDataModelAccessFlags rflags; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); g_return_val_if_fail (ps != NULL, NULL); cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) return NULL; if (!cdata->types_hash) _gda_sqlite_compute_types_hash (cdata); /* make sure @ps reports the correct number of columns */ if (_GDA_PSTMT (ps)->ncols < 0) _GDA_PSTMT (ps)->ncols = SQLITE3_CALL (sqlite3_column_count) (ps->sqlite_stmt) - ps->nb_rowid_columns; /* completing ps */ g_assert (! ps->stmt_used); ps->stmt_used = TRUE; if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) { /* create prepared statement's columns */ GSList *list; 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); else _GDA_PSTMT (ps)->types [i] = col_types [i]; } } } /* fill GdaColumn's data */ for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; i < GDA_PSTMT (ps)->ncols; i++, list = list->next) { GdaColumn *column; gint real_col = i + ps->nb_rowid_columns; column = GDA_COLUMN (list->data); gda_column_set_description (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col)); gda_column_set_name (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col)); gda_column_set_dbms_type (column, SQLITE3_CALL (sqlite3_column_decltype) (ps->sqlite_stmt, real_col)); if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL) gda_column_set_g_type (column, _GDA_PSTMT (ps)->types [i]); } } /* 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; /* create data model */ model = g_object_new (GDA_TYPE_SQLITE_RECORDSET, "connection", cnc, "prepared-stmt", ps, "model-usage", rflags, "exec-params", exec_params, "auto-reset", force_empty, NULL); gboolean is_virt; is_virt = GDA_IS_VCONNECTION_DATA_MODEL (cnc) ? TRUE : FALSE; if (is_virt) { /* steal the lock */ _gda_vconnection_change_working_obj ((GdaVconnectionDataModel*) cnc, (GObject*) model); _gda_vconnection_set_working_obj ((GdaVconnectionDataModel*) cnc, NULL); } /* fill the data model */ read_rows_to_init_col_types (model); return GDA_DATA_MODEL (model); }
gchar * gda_postgres_render_CREATE_USER (GdaServerProvider *provider, GdaConnection *cnc, GdaServerOperation *op, G_GNUC_UNUSED GError **error) { GString *string; const GValue *value; gchar *sql = NULL; gchar *tmp; gboolean with = FALSE, first, use_role = TRUE; gint nrows, i; PostgresConnectionData *cdata = NULL; if (cnc) { g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE); g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE); cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error); } if (cdata && (cdata->reuseable->version_float < 8.1)) use_role = FALSE; if (use_role) string = g_string_new ("CREATE ROLE "); else string = g_string_new ("CREATE USER "); tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/USER_DEF_P/USER_NAME", error); if (!tmp) { g_string_free (string, TRUE); return NULL; } g_string_append (string, tmp); g_free (tmp); value = gda_server_operation_get_value_at (op, "/USER_DEF_P/PASSWORD"); if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value) && (*g_value_get_string (value))) { GdaDataHandler *dh; const GValue *value2; g_string_append (string, " WITH"); with = TRUE; value2 = gda_server_operation_get_value_at (op, "/USER_DEF_P/PASSWORD_ENCRYPTED"); if (value2 && G_VALUE_HOLDS (value2, G_TYPE_BOOLEAN) && g_value_get_boolean (value2)) g_string_append (string, " ENCRYPTED"); g_string_append (string, " PASSWORD "); dh = gda_server_provider_get_data_handler_g_type (provider, cnc, G_TYPE_STRING); if (!dh) dh = gda_data_handler_get_default (G_TYPE_STRING); tmp = gda_data_handler_get_sql_from_value (dh, value); g_string_append (string, tmp); g_free (tmp); } value = gda_server_operation_get_value_at (op, "/USER_DEF_P/UID"); if (value && G_VALUE_HOLDS (value, G_TYPE_UINT)) { if (!with) { g_string_append (string, " WITH"); with = TRUE; } g_string_append_printf (string, "SYSID %u", g_value_get_uint (value)); } value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_SUPERUSER"); if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) { if (!with) { g_string_append (string, " WITH"); with = TRUE; } g_string_append (string, " SUPERUSER"); } value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_CREATEDB"); if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) { if (!with) { g_string_append (string, " WITH"); with = TRUE; } g_string_append (string, " CREATEDB"); } value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_CREATEROLE"); if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) { if (!with) { g_string_append (string, " WITH"); with = TRUE; } g_string_append (string, " CREATEROLE"); } value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_CREATEUSER"); if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) { if (!with) { g_string_append (string, " WITH"); with = TRUE; } g_string_append (string, " CREATEUSER"); } value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_INHERIT"); if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) { if (!with) { g_string_append (string, " WITH"); with = TRUE; } g_string_append (string, " INHERIT"); } else { if (!with) { g_string_append (string, " WITH"); with = TRUE; } g_string_append (string, " NOINHERIT"); } value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_LOGIN"); if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) { g_string_append (string, " LOGIN"); value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CNX_LIMIT"); if (value && G_VALUE_HOLDS (value, G_TYPE_INT)) g_string_append_printf (string, " CONNECTION LIMIT %d", g_value_get_int (value)); } nrows = gda_server_operation_get_sequence_size (op, "/GROUPS_S"); for (first = TRUE, i = 0; i < nrows; i++) { gchar *name; if (use_role) name = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/GROUPS_S/%d/ROLE", error, i); else name = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/GROUPS_S/%d/USER", error, i); if (name) { if (first) { first = FALSE; if (use_role) g_string_append (string, " IN ROLE "); else g_string_append (string, " IN GROUP "); } else g_string_append (string, ", "); g_string_append (string, name); g_free (name); } else { g_string_free (string, TRUE); return NULL; } } nrows = gda_server_operation_get_sequence_size (op, "/ROLES_S"); for (first = TRUE, i = 0; i < nrows; i++) { gchar *name; name = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/ROLES_S/%d/ROLE", error, i); if (name) { if (first) { first = FALSE; g_string_append (string, " ROLE "); } else g_string_append (string, ", "); g_string_append (string, name); g_free (name); } else { g_string_free (string, TRUE); return NULL; } } nrows = gda_server_operation_get_sequence_size (op, "/ADMINS_S"); for (first = TRUE, i = 0; i < nrows; i++) { gchar *name; name = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/ADMINS_S/%d/ROLE", error, i); if (name) { if (first) { first = FALSE; g_string_append (string, " ADMIN "); } else g_string_append (string, ", "); g_string_append (string, name); g_free (name); } else { g_string_free (string, TRUE); return NULL; } } value = gda_server_operation_get_value_at (op, "/USER_DEF_P/VALIDITY"); if (value && G_VALUE_HOLDS (value, GDA_TYPE_TIMESTAMP)) { if (value) { GdaDataHandler *dh; if (!with) { g_string_append (string, " WITH"); with = TRUE; } dh = gda_server_provider_get_data_handler_g_type (provider, cnc, GDA_TYPE_TIMESTAMP); if (!dh) dh = gda_data_handler_get_default (GDA_TYPE_TIMESTAMP); g_string_append (string, " VALID UNTIL "); tmp = gda_data_handler_get_sql_from_value (dh, value); g_string_append (string, tmp); g_free (tmp); } } sql = string->str; g_string_free (string, FALSE); return sql; }
GdaDataModel * gda_mysql_recordset_new_direct (GdaConnection *cnc, GdaDataModelAccessFlags flags, GType *col_types) { GdaMysqlRecordset *model; MysqlConnectionData *cdata; gint i; GdaDataModelAccessFlags rflags; GSList *columns = NULL; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); cdata = (MysqlConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) return NULL; /* determine access mode: RANDOM or CURSOR FORWARD are the only supported */ if (flags & GDA_DATA_MODEL_ACCESS_RANDOM) rflags = GDA_DATA_MODEL_ACCESS_RANDOM; else rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD; /* create data model */ model = g_object_new (GDA_TYPE_MYSQL_RECORDSET, "connection", cnc, "model-usage", rflags, NULL); model->priv->cnc = cnc; g_object_ref (G_OBJECT(cnc)); /* columns & types */ model->priv->ncols = mysql_field_count (cdata->mysql); model->priv->types = g_new0 (GType, model->priv->ncols); /* create columns */ for (i = 0; i < model->priv->ncols; i++) columns = g_slist_prepend (columns, gda_column_new ()); columns = g_slist_reverse (columns); if (col_types) { for (i = 0; ; i++) { if (col_types [i] > 0) { if (col_types [i] == G_TYPE_NONE) break; if (i >= model->priv->ncols) { g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i, model->priv->ncols - 1); break; } else model->priv->types [i] = col_types [i]; } } } /* fill bind result */ MYSQL_RES *mysql_res = mysql_store_result (cdata->mysql); MYSQL_FIELD *mysql_fields = mysql_fetch_fields (mysql_res); GSList *list; ((GdaDataSelect *) model)->advertized_nrows = mysql_affected_rows (cdata->mysql); for (i=0, list = columns; i < model->priv->ncols; i++, list = list->next) { GdaColumn *column = GDA_COLUMN (list->data); /* use C API to set columns' information using gda_column_set_*() */ MYSQL_FIELD *field = &mysql_fields[i]; GType gtype = model->priv->types [i]; if (gtype == GDA_TYPE_NULL) { gtype = _gda_mysql_type_to_gda (cdata, field->type, field->charsetnr); model->priv->types [i] = gtype; } gda_column_set_g_type (column, gtype); gda_column_set_name (column, field->name); gda_column_set_description (column, field->name); } gda_data_select_set_columns (GDA_DATA_SELECT (model), columns); /* load ALL data */ MYSQL_ROW mysql_row; gint rownum; GdaServerProvider *prov; prov = gda_connection_get_provider (cnc); for (mysql_row = mysql_fetch_row (mysql_res), rownum = 0; mysql_row; mysql_row = mysql_fetch_row (mysql_res), rownum++) { GdaRow *row = gda_row_new (model->priv->ncols); gint col; for (col = 0; col < model->priv->ncols; col++) { gint i = col; GValue *value = gda_row_get_value (row, i); GType type = model->priv->types[i]; char *data = mysql_row[i]; if (!data || (type == GDA_TYPE_NULL)) continue; gda_value_reset_with_type (value, type); if (type == G_TYPE_STRING) g_value_set_string (value, data); else { GdaDataHandler *dh; gboolean valueset = FALSE; dh = gda_server_provider_get_data_handler_g_type (prov, cnc, type); if (dh) { GValue *tmpvalue; tmpvalue = gda_data_handler_get_value_from_str (dh, data, type); if (tmpvalue) { *value = *tmpvalue; g_free (tmpvalue); valueset = TRUE; } } if (!valueset) gda_row_invalidate_value (row, value); } } gda_data_select_take_row ((GdaDataSelect*) model, row, rownum); } mysql_free_result (mysql_res); return GDA_DATA_MODEL (model); }
/* * the @ps struct is modified and transferred to the new data model created in * this function * * See MySQL's documentation "C API Prepared Statement Type Codes": * http://docs.oracle.com/cd/E17952_01/refman-5.5-en/c-api-prepared-statement-type-codes.html */ GdaDataModel * gda_mysql_recordset_new (GdaConnection *cnc, GdaMysqlPStmt *ps, GdaSet *exec_params, GdaDataModelAccessFlags flags, GType *col_types) { GdaMysqlRecordset *model; MysqlConnectionData *cdata; gint i; GdaDataModelAccessFlags rflags; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); g_return_val_if_fail (ps != NULL, NULL); cdata = (MysqlConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) return NULL; g_assert (ps->mysql_stmt); /* make sure @ps reports the correct number of columns using the API*/ if (_GDA_PSTMT (ps)->ncols < 0) _GDA_PSTMT(ps)->ncols = mysql_stmt_field_count (ps->mysql_stmt); /* completing @ps if not yet done */ g_assert (! ps->stmt_used); ps->stmt_used = TRUE; if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) { /* create prepared statement's columns */ 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]; } } } } /* get rid of old bound result if any */ if (ps->mysql_bind_result) { gint i; for (i = 0; i < ((GdaPStmt *) ps)->ncols; ++i) { g_free (ps->mysql_bind_result[i].buffer); g_free (ps->mysql_bind_result[i].is_null); g_free (ps->mysql_bind_result[i].length); } g_free (ps->mysql_bind_result); ps->mysql_bind_result = NULL; } /* fill bind result */ MYSQL_RES *mysql_res = mysql_stmt_result_metadata (ps->mysql_stmt); MYSQL_FIELD *mysql_fields = mysql_fetch_fields (mysql_res); MYSQL_BIND *mysql_bind_result = g_new0 (MYSQL_BIND, GDA_PSTMT (ps)->ncols); GSList *list; for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; i < GDA_PSTMT (ps)->ncols; i++, list = list->next) { GdaColumn *column = GDA_COLUMN (list->data); /* use C API to set columns' information using gda_column_set_*() */ MYSQL_FIELD *field = &mysql_fields[i]; GType gtype = _GDA_PSTMT(ps)->types[i]; if (gtype == GDA_TYPE_NULL) { gtype = _gda_mysql_type_to_gda (cdata, field->type, field->charsetnr); _GDA_PSTMT(ps)->types[i] = gtype; } gda_column_set_g_type (column, gtype); gda_column_set_name (column, field->name); gda_column_set_description (column, field->name); /* binding results with types */ mysql_bind_result[i].buffer_type = field->type; mysql_bind_result[i].is_unsigned = field->flags & UNSIGNED_FLAG ? TRUE : FALSE; mysql_bind_result[i].is_null = g_malloc0 (sizeof (my_bool)); switch (mysql_bind_result[i].buffer_type) { case MYSQL_TYPE_TINY: mysql_bind_result[i].buffer = g_malloc0 (sizeof (signed char)); break; case MYSQL_TYPE_SHORT: mysql_bind_result[i].buffer = g_malloc0 (sizeof (short int)); break; case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: case MYSQL_TYPE_YEAR: mysql_bind_result[i].buffer = g_malloc0 (sizeof (int)); break; case MYSQL_TYPE_LONGLONG: mysql_bind_result[i].buffer = g_malloc0 (sizeof (long long)); break; case MYSQL_TYPE_NULL: break; case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: mysql_bind_result[i].buffer = g_malloc0 (sizeof (MYSQL_TIME)); break; case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: mysql_bind_result[i].buffer = g_malloc0 (sizeof (double)); break; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_BIT: mysql_bind_result[i].buffer = g_malloc0 (field->max_length + 1); mysql_bind_result[i].buffer_length = field->max_length + 1; mysql_bind_result[i].length = g_malloc0 (sizeof (unsigned long)); break; default: g_warning (_("Invalid column bind data type. %d\n"), mysql_bind_result[i].buffer_type); } /*g_print ("%s(): NAME=%s, TYPE=%d, GTYPE=%s, unsigned: %d\n", __FUNCTION__, field->name, field->type, g_type_name (gtype), field->flags & UNSIGNED_FLAG);*/ } if (mysql_stmt_bind_result (ps->mysql_stmt, mysql_bind_result)) { g_warning ("mysql_stmt_bind_result failed: %s\n", mysql_stmt_error (ps->mysql_stmt)); } mysql_free_result (mysql_res); ps->mysql_bind_result = mysql_bind_result; /* determine access mode: RANDOM or CURSOR FORWARD are the only supported */ if (flags & GDA_DATA_MODEL_ACCESS_RANDOM) rflags = GDA_DATA_MODEL_ACCESS_RANDOM; else rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD; /* create data model */ model = g_object_new (GDA_TYPE_MYSQL_RECORDSET, "connection", cnc, "prepared-stmt", ps, "model-usage", rflags, "exec-params", exec_params, NULL); model->priv->cnc = cnc; g_object_ref (G_OBJECT(cnc)); model->priv->mysql_stmt = ps->mysql_stmt; ((GdaDataSelect *) model)->advertized_nrows = mysql_stmt_affected_rows (ps->mysql_stmt); return GDA_DATA_MODEL (model); }
GdaBlobOp * _gda_sqlite_blob_op_new (GdaConnection *cnc, const gchar *db_name, const gchar *table_name, const gchar *column_name, sqlite3_int64 rowid) { GdaSqliteBlobOp *bop = NULL; int rc; sqlite3_blob *sblob; gchar *db, *table; gboolean free_strings = TRUE; gboolean transaction_started = FALSE; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); g_return_val_if_fail (table_name, NULL); g_return_val_if_fail (column_name, NULL); g_return_val_if_fail (GDA_IS_SQLITE_PROVIDER (gda_connection_get_provider (cnc)), NULL); GdaSqliteBlobOpPrivate *priv = gda_sqlite_blob_op_get_instance_private (bop); if (db_name) { db = (gchar *) db_name; table = (gchar *) table_name; free_strings = FALSE; } else if (! _split_identifier_string (g_strdup (table_name), &db, &table)) return NULL; SqliteConnectionData *cdata; cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata || ! _gda_sqlite_check_transaction_started (cnc, &transaction_started, NULL)) return NULL; GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (cnc)); rc = SQLITE3_CALL (prov, sqlite3_blob_open) (cdata->connection, db ? db : "main", table, column_name, rowid, 1, /* Read & Write */ &(sblob)); if (rc != SQLITE_OK) { #ifdef GDA_DEBUG_NO g_print ("ERROR: %s\n", SQLITE3_CALL (prov, sqlite3_errmsg) (cdata->connection)); #endif if (transaction_started) gda_connection_rollback_transaction (cnc, NULL, NULL); goto out; } bop = g_object_new (GDA_TYPE_SQLITE_BLOB_OP, "connection", cnc, NULL); priv->sblob = sblob; g_weak_ref_set (&priv->provider, prov); #ifdef GDA_DEBUG_NO g_print ("OPENED blob %p\n", bop); #endif out: if (free_strings) { g_free (db); g_free (table); } return (GdaBlobOp*) bop; }