/** * midgard_transaction_begin: * @self: #MidgardTransaction instance * * Begins new, underlying database provider's transaction. * In case of error, #MidgardConnection error is set to MGD_ERR_INTERNAL. * * Returns: %TRUE on success, %FALSE otherwise. * * Since: 9.09 */ gboolean midgard_transaction_begin (MidgardTransaction *self) { _ASSERT_T_MGD(self); gboolean rv = FALSE; GdaConnection *cnc = _T_CNC(self); MidgardConnection *mgd = self->priv->mgd; GError *error = NULL; g_debug("Begin named transaction '%s'", self->priv->name); rv = gda_connection_begin_transaction(cnc, self->priv->name, GDA_TRANSACTION_ISOLATION_UNKNOWN, &error); if (!error && rv) return TRUE; midgard_set_error(mgd, MGD_GENERIC_ERROR, MGD_ERR_INTERNAL, error && error->message ? error->message : " Unknown error."); if (error) g_error_free(error); return FALSE; }
/** * gda_xa_transaction_begin: * @xa_trans: a #GdaXaTransaction object * @error: (nullable): a place to store errors, or %NULL * * Begins a distributed transaction (managed by @xa_trans). Please note that this phase may fail * for some connections if a (normal) transaction is already started (this depends on the database * provider being used), so it's better to avoid starting any (normal) transaction on any of the * connections registered with @xa_trans. * * Returns: TRUE if no error occurred */ gboolean gda_xa_transaction_begin (GdaXaTransaction *xa_trans, GError **error) { GList *list; g_return_val_if_fail (GDA_IS_XA_TRANSACTION (xa_trans), FALSE); GdaXaTransactionPrivate *priv = gda_xa_transaction_get_instance_private (xa_trans); for (list = priv->cnc_list; list; list = list->next) { GdaConnection *cnc; GdaServerProvider *prov; cnc = GDA_CONNECTION (list->data); prov = gda_connection_get_provider (cnc); if (cnc != priv->non_xa_cnc) { GdaBinary *branch; branch = g_hash_table_lookup (priv->cnc_hash, cnc); memcpy (priv->xid.data + priv->xid.gtrid_length, /* Flawfinder: ignore */ gda_binary_get_data (branch), gda_binary_get_size (branch)); if (! _gda_server_provider_xa_start (prov, cnc, &(priv->xid), error)) break; } else { /* do a simple BEGIN */ if (! gda_connection_begin_transaction (cnc, NULL, GDA_TRANSACTION_ISOLATION_UNKNOWN, error)) break; } } if (list) { /* something went wrong */ for (; list; list = list->prev) { GdaConnection *cnc; GdaServerProvider *prov; cnc = GDA_CONNECTION (list->data); prov = gda_connection_get_provider (cnc); if (cnc != priv->non_xa_cnc) { GdaBinary *branch; branch = g_hash_table_lookup (priv->cnc_hash, cnc); memcpy (priv->xid.data + priv->xid.gtrid_length, /* Flawfinder: ignore */ gda_binary_get_data (branch), gda_binary_get_size (branch)); _gda_server_provider_xa_rollback (prov, cnc, &(priv->xid), NULL); } else { /* do a simple ROLLBACK */ gda_connection_rollback_transaction (cnc, NULL, NULL); } } return FALSE; } return TRUE; }
void midgard_cr_core_transaction_begin (MidgardCRCoreTransaction *self, GError **error) { _ASSERT_T_MGD (self); gboolean rv = FALSE; GdaConnection *cnc = _T_CNC (self); MidgardCRSQLStorageManager *manager = self->priv->manager; GError *err = NULL; rv = gda_connection_begin_transaction (cnc, self->priv->name, GDA_TRANSACTION_ISOLATION_UNKNOWN, &err); if (err) g_propagate_error (error, err); if (!rv && !err) g_warning ("Failed to begin underlying database transaction and no error has been set"); return; }
/** * gda_xa_transaction_begin: * @xa_trans: a #GdaXaTransaction object * @error: (allow-none): a place to store errors, or %NULL * * Begins a distributed transaction (managed by @xa_trans). Please note that this phase may fail * for some connections if a (normal) transaction is already started (this depends on the database * provider being used), so it's better to avoid starting any (normal) transaction on any of the * connections registered with @xa_trans. * * Returns: TRUE if no error occurred */ gboolean gda_xa_transaction_begin (GdaXaTransaction *xa_trans, GError **error) { GList *list; g_return_val_if_fail (GDA_IS_XA_TRANSACTION (xa_trans), FALSE); for (list = xa_trans->priv->cnc_list; list; list = list->next) { GdaConnection *cnc; GdaServerProvider *prov; cnc = GDA_CONNECTION (list->data); prov = gda_connection_get_provider (cnc); if (cnc != xa_trans->priv->non_xa_cnc) { if (!PROV_CLASS (prov)->xa_funcs->xa_start) { g_warning (_("Provider error: %s method not implemented for provider %s"), "xa_start()", gda_server_provider_get_name (prov)); break; } else { const GdaBinary *branch; branch = g_hash_table_lookup (xa_trans->priv->cnc_hash, cnc); memcpy (xa_trans->priv->xid.data + xa_trans->priv->xid.gtrid_length, /* Flawfinder: ignore */ branch->data, branch->binary_length); if (!PROV_CLASS (prov)->xa_funcs->xa_start (prov, cnc, &(xa_trans->priv->xid), error)) break; } } else { /* do a simple BEGIN */ if (! gda_connection_begin_transaction (cnc, NULL, GDA_TRANSACTION_ISOLATION_UNKNOWN, error)) break; } } if (list) { /* something went wrong */ for (; list; list = list->prev) { GdaConnection *cnc; GdaServerProvider *prov; cnc = GDA_CONNECTION (list->data); prov = gda_connection_get_provider (cnc); if (cnc != xa_trans->priv->non_xa_cnc) { if (!PROV_CLASS (prov)->xa_funcs->xa_rollback) g_warning (_("Provider error: %s method not implemented for provider %s"), "xa_rollback()", gda_server_provider_get_name (prov)); else { const GdaBinary *branch; branch = g_hash_table_lookup (xa_trans->priv->cnc_hash, cnc); memcpy (xa_trans->priv->xid.data + xa_trans->priv->xid.gtrid_length, /* Flawfinder: ignore */ branch->data, branch->binary_length); PROV_CLASS (prov)->xa_funcs->xa_rollback (prov, cnc, &(xa_trans->priv->xid), NULL); } } else { /* do a simple ROLLBACK */ gda_connection_rollback_transaction (cnc, NULL, NULL); } } return FALSE; } return TRUE; }
int main (int argc, char **argv) { GError *error = NULL; GOptionContext *context; GdaConnection *cnc; gchar *auth_string = NULL; gchar *blob_data; /* command line parsing */ context = g_option_context_new ("Tests opening a connection"); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_warning ("Can't parse arguments: %s", error->message); exit (1); } g_option_context_free (context); if (direct && dsn) { g_print ("DSN and connection string are exclusive\n"); exit (1); } if (!direct && !dsn) { g_print ("You must specify a connection to open either as a DSN or a connection string\n"); exit (1); } if (direct && !prov) { g_print ("You must specify a provider when using a connection string\n"); exit (1); } gda_init (); /* open connection */ if (user) { if (pass) auth_string = g_strdup_printf ("USERNAME=%s;PASSWORD=%s", user, pass); else auth_string = g_strdup_printf ("USERNAME=%s", user); } if (dsn) { GdaDsnInfo *info = NULL; info = gda_config_get_dsn_info (dsn); if (!info) g_error (_("DSN '%s' is not declared"), dsn); else { cnc = gda_connection_open_from_dsn (info->name, auth_string ? auth_string : info->auth_string, 0, &error); if (!cnc) { g_warning (_("Can't open connection to DSN %s: %s\n"), info->name, error && error->message ? error->message : "???"); exit (1); } prov = info->provider; } } else { cnc = gda_connection_open_from_string (prov, direct, auth_string, 0, &error); if (!cnc) { g_warning (_("Can't open specified connection: %s\n"), error && error->message ? error->message : "???"); exit (1); } } g_free (auth_string); g_print (_("Connection successfully opened!\n")); parser = gda_connection_create_parser (cnc); gda_connection_begin_transaction (cnc, NULL, GDA_TRANSACTION_ISOLATION_UNKNOWN, NULL); /* * clear all blobs */ if (!clear_blobs (cnc, &error)) g_error ("Blobs clear error: %s", error && error->message ? error->message : "No detail"); /* insert a blob */ blob_data = "Blob Data 1"; if (!insert_blob (cnc, 1, blob_data, strlen (blob_data), &error)) g_error ("Blob insert error: %s", error && error->message ? error->message : "No detail"); else if (error) { g_print ("Msg: %s\n", error->message); g_error_free (error); error = NULL; } /* insert a blob */ blob_data = "Blob Data 2"; if (!insert_blob (cnc, 2, blob_data, strlen (blob_data), &error)) g_error ("Blob insert error: %s", error && error->message ? error->message : "No detail"); else if (error) { g_print ("Msg: %s\n", error->message); g_error_free (error); error = NULL; } if (!display_blobs (cnc, &error)) g_error ("Blobs display error: %s", error && error->message ? error->message : "No detail"); /* update blob */ blob_data = "New blob 1 contents is now this one..."; if (!update_blob (cnc, 1, blob_data, strlen (blob_data), &error)) g_error ("Blob update error: %s", error && error->message ? error->message : "No detail"); else if (error) { g_print ("Msg: %s\n", error->message); g_error_free (error); error = NULL; } if (!display_blobs (cnc, &error)) g_error ("Blobs display error: %s", error && error->message ? error->message : "No detail"); /* update blob */ blob_data = "After several blobs updated"; if (!update_multiple_blobs (cnc, blob_data, strlen (blob_data), &error)) g_error ("Multiple blob update error: %s", error && error->message ? error->message : "No detail"); else if (error) { g_print ("Msg: %s\n", error->message); g_error_free (error); error = NULL; } if (!display_blobs (cnc, &error)) g_error ("Blobs display error: %s", error && error->message ? error->message : "No detail"); /* SQL Postgres: create table blobs (id serial not null primary key, name varchar (50), data oid); SQL Oracle: CREATE TABLE blobs (id number primary key, name varchar2 (50), data BLOB); */ gda_connection_commit_transaction (cnc, NULL, NULL); if (! gda_connection_close (cnc, &error)) g_error ("Can't close connection: %s", error && error->message ? error->message : "No detail"); return 0; }
int main (int argc, char *argv[]) { gda_init (); GdaConnection *cnc; GError *error = NULL; GdaStatement *stmt; GdaDataModel *model; gchar *str; GValue *name; /* open connection */ cnc = open_connection (); /* begin transaction */ if (! gda_connection_begin_transaction (cnc, NULL, GDA_TRANSACTION_ISOLATION_UNKNOWN, &error)) { g_print ("Could not begin transaction: %s\n", error && error->message ? error->message : "No detail"); exit (1); } /* execute SELECT */ stmt = gda_sql_parser_parse_string (parser, "SELECT id, name FROM customers ORDER BY id", NULL, NULL); g_assert (stmt); model = gda_connection_statement_execute_select (cnc, stmt, NULL, &error); g_object_unref (stmt); if (!model) { g_print ("Could not execute SELECT statement: %s\n", error && error->message ? error->message : "No detail"); exit (1); } g_print ("** Data model is:\n"); gda_data_model_dump (model, stdout); /* * make sure the mete data is up to date */ g_print ("Computing meta data, this may take a while; in real applications, this should be cached to avoid waiting\n"); if (! gda_connection_update_meta_store (cnc, NULL, &error)) { g_print ("Could not fetch meta data: %s\n", error && error->message ? error->message : "No detail"); exit (1); } /* * Make the data model compute the modification statements which * will actually be executed when the data model is modified */ if (! gda_data_select_compute_modification_statements (GDA_DATA_SELECT (model), &error)) { g_print ("Could not compute modification statements: %s\n", error && error->message ? error->message : "No detail"); exit (1); } g_object_get (G_OBJECT (model), "update-stmt", &stmt, NULL); str = gda_statement_to_sql (stmt, NULL, NULL); g_print ("Computed UPDATE: %s\n", str); g_free (str); g_object_unref (stmt); g_object_get (G_OBJECT (model), "delete-stmt", &stmt, NULL); str = gda_statement_to_sql (stmt, NULL, NULL); g_print ("Computed DELETE: %s\n", str); g_free (str); g_object_unref (stmt); g_object_get (G_OBJECT (model), "insert-stmt", &stmt, NULL); str = gda_statement_to_sql (stmt, NULL, NULL); g_print ("Computed INSERT: %s\n", str); g_free (str); g_object_unref (stmt); /* * remove row 0 (1st row) */ g_print ("\n\n** Removing row 0\n"); if (! gda_data_model_remove_row (model, 0, &error)) { g_print ("Could not remove row 0: %s\n", error && error->message ? error->message : "No detail"); exit (1); } g_print ("** Data model is now:\n"); gda_data_model_dump (model, stdout); g_print ("** Table's contents is now:\n"); display_customers (cnc); /* * add a row: the row's values is a list of GValue pointers * (or NULL pointers where the default value should be inserted */ GList *list; g_print ("\n\n** Adding a row\n"); list = g_list_append (NULL, NULL); g_value_set_string ((name = gda_value_new (G_TYPE_STRING)), "Hiro"); list = g_list_append (list, name); if (gda_data_model_append_values (model, list, &error) == -1) { g_print ("Could not add a row: %s\n", error && error->message ? error->message : "No detail"); exit (1); } gda_value_free (name); g_list_free (list); g_print ("** Data model is now:\n"); gda_data_model_dump (model, stdout); g_print ("** Table's contents is now:\n"); display_customers (cnc); /* * alter row 2 */ g_print ("\n\n** Modifying row 2\n"); g_value_set_string ((name = gda_value_new (G_TYPE_STRING)), "Tom"); if (! gda_data_model_set_value_at (model, 1, 2, name, &error)) { g_print ("Could not modify row 2: %s\n", error && error->message ? error->message : "No detail"); exit (1); } gda_value_free (name); g_print ("** Data model is now:\n"); gda_data_model_dump (model, stdout); g_print ("** Table's contents is now:\n"); display_customers (cnc); /* rollback transaction */ gda_connection_rollback_transaction (cnc, NULL, NULL); gda_connection_close (cnc); return 0; }
/* * Load data from file @file into table @table */ gboolean test_cnc_load_data_from_file (GdaConnection *cnc, const gchar *table, const gchar *full_file, GError **error) { GdaStatement *stmt = NULL; GdaSet *params = NULL; GdaDataModel *import; gint nrows, ncols, i; GdaMetaStruct *mstruct = NULL; GSList *list; gboolean retval = TRUE; /* loading XML file */ import = gda_data_model_import_new_file (full_file, TRUE, NULL); if (gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import))) { g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC, "Error loading '%s' file", full_file); return FALSE; } /* retrieving meta data info */ GdaMetaDbObject *table_dbo; GValue *name_value; g_value_set_string ((name_value = gda_value_new (G_TYPE_STRING)), table); mstruct = gda_meta_struct_new (gda_connection_get_meta_store (cnc), GDA_META_STRUCT_FEATURE_NONE); table_dbo = gda_meta_struct_complement (mstruct, GDA_META_DB_TABLE, NULL, NULL, name_value, error); gda_value_free (name_value); if (! table_dbo) { retval = FALSE; goto out; } /* creating INSERT statement */ GdaSqlStatement *st; GdaSqlStatementInsert *ist; GSList *insert_values_list = NULL; ist = g_new0 (GdaSqlStatementInsert, 1); GDA_SQL_ANY_PART (ist)->type = GDA_SQL_ANY_STMT_INSERT; ist->table = gda_sql_table_new (GDA_SQL_ANY_PART (ist)); ist->table->table_name = g_strdup (table); GdaMetaTable *mtable = GDA_META_TABLE (table_dbo); for (list = mtable->columns; list; list = list->next) { GdaMetaTableColumn *tcol = GDA_META_TABLE_COLUMN (list->data); GdaSqlField *field; /* field */ field = gda_sql_field_new (GDA_SQL_ANY_PART (ist)); field->field_name = g_strdup (tcol->column_name); ist->fields_list = g_slist_append (ist->fields_list, field); /* value */ GdaSqlParamSpec *pspec = g_new0 (GdaSqlParamSpec, 1); GdaSqlExpr *expr; pspec->name = g_strdup (tcol->column_name); pspec->g_type = tcol->gtype; pspec->nullok = tcol->nullok; expr = gda_sql_expr_new (GDA_SQL_ANY_PART (ist)); expr->param_spec = pspec; insert_values_list = g_slist_append (insert_values_list, expr); } ist->values_list = g_slist_append (NULL, insert_values_list); st = gda_sql_statement_new (GDA_SQL_STATEMENT_INSERT); st->contents = ist; stmt = g_object_new (GDA_TYPE_STATEMENT, "structure", st, NULL); gda_sql_statement_free (st); g_object_unref (mstruct); if (! gda_statement_get_parameters (stmt, ¶ms, error)) { retval = FALSE; goto out; } /* executing inserts */ nrows = gda_data_model_get_n_rows (import); ncols = gda_data_model_get_n_columns (import); if (!gda_connection_begin_transaction (cnc, NULL, GDA_TRANSACTION_ISOLATION_UNKNOWN, error)) { retval = FALSE; goto out; } for (i = 0; i < nrows; i++) { gint j; GSList *list; for (list = params->holders, j = 0; list && (j < ncols); list = list->next, j++) { const GValue *cvalue = gda_data_model_get_value_at (import, j, i, error); if (!cvalue) { gda_connection_rollback_transaction (cnc, NULL, NULL); retval = FALSE; goto out; } if (! gda_holder_set_value (GDA_HOLDER (list->data), cvalue, error)) { gda_connection_rollback_transaction (cnc, NULL, NULL); retval = FALSE; goto out; } } if (list || (j < ncols)) { g_set_error (error, TEST_ERROR, TEST_ERROR_GENERIC, "%s", "Incoherent number of columns in table and imported data"); gda_connection_rollback_transaction (cnc, NULL, NULL); retval = FALSE; goto out; } if (gda_connection_statement_execute_non_select (cnc, stmt, params, NULL, error) == -1) { gda_connection_rollback_transaction (cnc, NULL, NULL); retval = FALSE; goto out; } } if (! gda_connection_commit_transaction (cnc, NULL, error)) retval = FALSE; out: if (import) g_object_unref (import); if (stmt) g_object_unref (stmt); if (params) g_object_unref (params); return retval; }