Esempio n. 1
0
/**
 * 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;
}
Esempio n. 2
0
/**
 * 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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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, &params, 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;
}