Beispiel #1
0
/**
 * gda_tree_mgr_select_new:
 * @cnc: a #GdaConnection object
 * @stmt: a #GdaStatement object representing a SELECT statement
 * @params: a #GdaSet object representing fixed parameters which are to be used when executing @stmt
 *
 * Creates a new #GdaTreeMgrSelect object which will add one tree node for each row in
 * the #GdaDataModel resulting from the execution of @stmt.
 *
 * Returns: (transfer full): a new #GdaTreeManager object
 *
 * Since: 4.2
 */
GdaTreeManager*
gda_tree_mgr_select_new (GdaConnection *cnc, GdaStatement *stmt, GdaSet *params)
{
	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
	g_return_val_if_fail (GDA_IS_STATEMENT (stmt), NULL);
	g_return_val_if_fail (gda_statement_get_statement_type (stmt) == GDA_SQL_STATEMENT_SELECT, NULL);
	g_return_val_if_fail (!params || GDA_IS_SET (params), NULL);

	return (GdaTreeManager*) g_object_new (GDA_TYPE_TREE_MGR_SELECT,
					       "connection", cnc, 
					       "statement", stmt,
					       "params", params, NULL);
}
/**
 * gda_select_alter_select_for_empty:
 * @stmt: a SELECT #GdaStatement
 * @error: (allow-none): a place to store errors, or %NULL
 *
 * Creates a new #GdaStatement, selecting the same data as @stmt, but which always returns an
 * empty (no row) data model. This is use dy database providers' implementations.
 *
 * Returns: (transfer full): a new #GdaStatement
 */
GdaStatement *
gda_select_alter_select_for_empty (GdaStatement *stmt, G_GNUC_UNUSED GError **error)
{
	GdaStatement *estmt;
	GdaSqlStatement *sqlst;
	GdaSqlStatementSelect *stsel;

	g_assert (gda_statement_get_statement_type (stmt) == GDA_SQL_STATEMENT_SELECT);
	g_object_get (G_OBJECT (stmt), "structure", &sqlst, NULL);
	g_assert (sqlst);

	if (sqlst->sql) {
		g_free (sqlst->sql);
		sqlst->sql = NULL;
	}
	stsel = (GdaSqlStatementSelect*) sqlst->contents;

	/* set the WHERE condition to "1 = 0" */
	GdaSqlExpr *expr, *cond = stsel->where_cond;
	GdaSqlOperation *op;
	if (cond)
		gda_sql_expr_free (cond);
	cond = gda_sql_expr_new (GDA_SQL_ANY_PART (stsel));
	stsel->where_cond = cond;
	op = gda_sql_operation_new (GDA_SQL_ANY_PART (cond));
	cond->cond = op;
	op->operator_type = GDA_SQL_OPERATOR_TYPE_EQ;
	expr = gda_sql_expr_new (GDA_SQL_ANY_PART (op));
	op->operands = g_slist_prepend (NULL, expr);
	g_value_set_int ((expr->value = gda_value_new (G_TYPE_INT)), 1);
	expr = gda_sql_expr_new (GDA_SQL_ANY_PART (op));
	op->operands = g_slist_prepend (op->operands, expr);
	g_value_set_int ((expr->value = gda_value_new (G_TYPE_INT)), 0);

	/* replace any selected field which has a parameter with NULL */
	gda_sql_any_part_foreach (GDA_SQL_ANY_PART (stsel), (GdaSqlForeachFunc) param_to_null_foreach,
				  NULL, NULL);

	/* create new statement */
	estmt = g_object_new (GDA_TYPE_STATEMENT, "structure", sqlst, NULL);
	gda_sql_statement_free (sqlst);
	return estmt;
}
Beispiel #3
0
/*
 * @prov may be NULL
 */
static guint
do_a_test (GdaServerProvider *prov, GdaSqlParser *parser)
{
	guint nfailed = 0;
	GdaStatement *stmt;
	GdaSet *params;
	gchar *sql;
	GError *error = NULL;

	/* SQL parsed as an INSERT statement */
	sql = "INSERT INTO tstest VALUES (##ts::timestamp, ##time::time)";
	stmt = gda_sql_parser_parse_string (parser, sql, NULL, &error);
	if (!stmt) {
		g_print ("Failed to parse [%s]: %s\n", sql, error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		nfailed ++;
		goto endtest;
	}

	g_assert (gda_statement_get_statement_type (stmt) == GDA_SQL_STATEMENT_INSERT);
	if (! gda_statement_get_parameters (stmt, &params, &error)) {
		g_print ("Failed to obtain parameters: %s\n", error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		g_object_unref (stmt);
		nfailed ++;
		goto endtest;
	}

	if (! gda_set_set_holder_value (params, &error, "ts", &ts)) {
		g_print ("Failed to bind 'ts' parameter: %s\n", error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		g_object_unref (stmt);
		g_object_unref (params);
		nfailed ++;
		goto endtest;
	}

	if (! gda_set_set_holder_value (params, &error, "time", &gt)) {
		g_print ("Failed to bind 'time' parameter: %s\n", error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		g_object_unref (stmt);
		g_object_unref (params);
		nfailed ++;
		goto endtest;
	}

	GdaConnection *cnc = NULL;
	if (prov) {
		cnc = gda_connection_new_from_string (gda_server_provider_get_name (prov), "DB_NAME=dummy;HOST=dummy", NULL,
						      GDA_CONNECTION_OPTIONS_NONE, &error);
		if (!cnc) {
			g_print ("Failed to create GdaConnection object: %s\n",
				 error && error->message ? error->message : "No detail");
			g_clear_error (&error);
			g_object_unref (stmt);
			g_object_unref (params);
			nfailed ++;
			goto endtest;
		}
	}
	gchar *expected;
	expected = "('@@@@@@@@@@ 17:10:23+2', '16:09:22-3')";
	if (cnc)
		sql = gda_connection_statement_to_sql (cnc, stmt, params, 0, NULL, &error);
	else
		sql = gda_statement_to_sql_extended (stmt, NULL, params, 0, NULL, &error);
	if (!sql) {
		g_print ("Failed to render as SQL: %s\n", error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		g_object_unref (stmt);
		g_object_unref (params);
		nfailed ++;
		goto endtest;
	}
	if (!string_equal_to_template (sql, expected)) {
		g_print ("Wrong rendered SQL: [%s] instead of [%s]\n", sql, expected);
		g_object_unref (stmt);
		g_object_unref (params);
		g_free (sql);
		nfailed ++;
		goto endtest;
	}
	g_free (sql);

	expected = "('@@@@@@@@@@ 15:10:23', '19:09:22')";
	if (cnc)
		sql = gda_connection_statement_to_sql (cnc, stmt, params, GDA_STATEMENT_SQL_TIMEZONE_TO_GMT, NULL, &error);
	else
		sql = gda_statement_to_sql_extended (stmt, NULL, params, GDA_STATEMENT_SQL_TIMEZONE_TO_GMT, NULL, &error);
	if (!sql) {
		g_print ("Failed to render as SQL: %s\n", error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		g_object_unref (stmt);
		g_object_unref (params);
		nfailed ++;
		goto endtest;
	}
	if (!string_equal_to_template (sql, expected)) {
		g_print ("Wrong rendered SQL for GMT timezone: [%s] instead of [%s]\n", sql, expected);
		g_object_unref (stmt);
		g_object_unref (params);
		g_free (sql);
		nfailed ++;
		goto endtest;
	}
	g_free (sql);

	/* SQL not parsed as a valid statement */
	sql = "AAAA (##ts::timestamp, ##time::time)";
	stmt = gda_sql_parser_parse_string (parser, sql, NULL, &error);
	if (!stmt) {
		g_print ("Failed to parse [%s]: %s\n", sql, error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		nfailed ++;
		goto endtest;
	}

	g_assert (gda_statement_get_statement_type (stmt) == GDA_SQL_STATEMENT_UNKNOWN);
	if (! gda_statement_get_parameters (stmt, &params, &error)) {
		g_print ("Failed to obtain parameters: %s\n", error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		g_object_unref (stmt);
		nfailed ++;
		goto endtest;
	}

	if (! gda_set_set_holder_value (params, &error, "ts", &ts)) {
		g_print ("Failed to bind 'ts' parameter: %s\n", error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		g_object_unref (stmt);
		g_object_unref (params);
		nfailed ++;
		goto endtest;
	}

	if (! gda_set_set_holder_value (params, &error, "time", &gt)) {
		g_print ("Failed to bind 'time' parameter: %s\n", error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		g_object_unref (stmt);
		g_object_unref (params);
		nfailed ++;
		goto endtest;
	}

	expected = "('@@@@@@@@@@ 17:10:23+2', '16:09:22-3')";
	if (cnc)
		sql = gda_connection_statement_to_sql (cnc, stmt, params, 0, NULL, &error);
	else
		sql = gda_statement_to_sql_extended (stmt, NULL, params, 0, NULL, &error);
	if (!sql) {
		g_print ("Failed to render as SQL: %s\n", error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		g_object_unref (stmt);
		g_object_unref (params);
		nfailed ++;
		goto endtest;
	}
	if (!string_equal_to_template (sql, expected)) {
		g_print ("Wrong rendered SQL: [%s] instead of [%s]\n", sql, expected);
		g_object_unref (stmt);
		g_object_unref (params);
		g_free (sql);
		nfailed ++;
		goto endtest;
	}
	g_free (sql);

	expected = "('@@@@@@@@@@ 15:10:23', '19:09:22')";
	if (cnc)
		sql = gda_connection_statement_to_sql (cnc, stmt, params, GDA_STATEMENT_SQL_TIMEZONE_TO_GMT, NULL, &error);
	else
		sql = gda_statement_to_sql_extended (stmt, NULL, params, GDA_STATEMENT_SQL_TIMEZONE_TO_GMT, NULL, &error);
	if (!sql) {
		g_print ("Failed to render as SQL: %s\n", error && error->message ? error->message : "No detail");
		g_clear_error (&error);
		g_object_unref (stmt);
		g_object_unref (params);
		nfailed ++;
		goto endtest;
	}
	if (!string_equal_to_template (sql, expected)) {
		g_print ("Wrong rendered SQL for GMT timezone: [%s] instead of [%s]\n", sql, expected);
		g_object_unref (stmt);
		g_object_unref (params);
		g_free (sql);
		nfailed ++;
		goto endtest;
	}
	g_free (sql);

 endtest:
	return nfailed;
}
Beispiel #4
0
static void
actually_execute (QueryConsolePage *tconsole, const gchar *sql, GdaSet *params,
		  gboolean add_editor_history)
{
	GdaBatch *batch;
	GError *error = NULL;
	const gchar *remain;

	/* if a query is being executed, then show an error */
	if (tconsole->priv->currently_executing) {
		ui_show_error (GTK_WINDOW (gtk_widget_get_toplevel ((GtkWidget*) tconsole)),
			       _("A query is already being executed, "
				 "to execute another query, open a new connection."));
		return;
	}
	tconsole->priv->currently_executing = TRUE;

	if (!tconsole->priv->parser)
		tconsole->priv->parser = t_connection_create_parser (tconsole->priv->tcnc);

	batch = gda_sql_parser_parse_string_as_batch (tconsole->priv->parser, sql, &remain, &error);
	if (!batch) {
		ui_show_error (GTK_WINDOW (gtk_widget_get_toplevel ((GtkWidget*) tconsole)),
			       _("Error while parsing code: %s"),
			       error && error->message ? error->message : _("No detail"));
		g_clear_error (&error);
		return;
	}

	if (add_editor_history) {
		/* mark the current SQL to be kept by the editor as an internal history */
		query_editor_keep_current_state (tconsole->priv->editor);
	}

	/* actual Execution */
	const GSList *stmt_list, *list;
	GTimeVal start_time;
	g_get_current_time (&start_time);

	QueryEditorHistoryBatch *hist_batch;
	hist_batch = query_editor_history_batch_new (start_time, params);
	query_editor_start_history_batch (tconsole->priv->history, hist_batch);
	query_editor_history_batch_unref (hist_batch);

	gboolean within_transaction;
	stmt_list = gda_batch_get_statements (batch);
	for (list = stmt_list; list; list = list->next) {
		GdaStatement *stmt;
		GObject *result;
		GError *lerror = NULL;
		within_transaction = t_connection_get_transaction_status (tconsole->priv->tcnc) ? TRUE : FALSE;
		stmt = GDA_STATEMENT (list->data);
		result = t_connection_execute_statement (tconsole->priv->tcnc, stmt, params,
							 GDA_STATEMENT_MODEL_RANDOM_ACCESS,
							 NULL, &lerror);
		if (result) {
			QueryEditorHistoryItem *history;
			GdaSqlStatement *sqlst;
			g_object_get (G_OBJECT (stmt), "structure", &sqlst, NULL);
			if (!sqlst->sql) {
				gchar *sql;
				sql = gda_statement_to_sql (stmt, NULL, NULL);
				history = query_editor_history_item_new (sql, result, lerror);
				g_free (sql);
			}
			else
				history = query_editor_history_item_new (sqlst->sql, result, lerror);
			g_object_unref (result);
			gda_sql_statement_free (sqlst);
			
			history->within_transaction = within_transaction;

			/* display a message if a transaction has been started */
			if (! history->within_transaction &&
			    t_connection_get_transaction_status (tconsole->priv->tcnc) &&
			    gda_statement_get_statement_type (stmt) != GDA_SQL_STATEMENT_BEGIN) {
				browser_window_show_notice_printf (BROWSER_WINDOW (gtk_widget_get_toplevel ((GtkWidget*) tconsole)),
								   GTK_MESSAGE_INFO,
								   "QueryExecTransactionStarted",
								   "%s", _("A transaction has automatically been started\n"
									   "during this statement's execution, this usually\n"
									   "happens when blobs are selected (and the transaction\n"
									   "will have to remain opened while the blobs are still\n"
									   "accessible, clear the corresponding history item before\n"
									   "closing the transaction)."));
			}

			query_editor_add_history_item (tconsole->priv->history, history);
			query_editor_history_item_unref (history);

			browser_window_push_status (BROWSER_WINDOW (gtk_widget_get_toplevel ((GtkWidget*) tconsole)),
						    "QueryConsolePage", _("Statement executed"), TRUE);			
		}
		else {
			ui_show_error (GTK_WINDOW (gtk_widget_get_toplevel ((GtkWidget*) tconsole)),
				       _("Error executing query:\n%s"),
				       lerror && lerror->message ? lerror->message : _("No detail"));
			g_clear_error (&lerror);
			break;
		}
	}
	g_object_unref (batch);
	tconsole->priv->currently_executing = FALSE;
}