[libgda/LIBGDA_4.0] Honor the request for the last inserted row in the MySQL provider
- From: Vivien Malerba <vivien src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [libgda/LIBGDA_4.0] Honor the request for the last inserted row in the MySQL provider
- Date: Fri, 29 Jan 2010 20:53:28 +0000 (UTC)
commit d082b37e0a2bec7b6fbd10cf0c6013d8fd8e2fc9
Author: Vivien Malerba <malerba gnome-db org>
Date: Fri Jan 29 20:57:41 2010 +0100
Honor the request for the last inserted row in the MySQL provider
providers/mysql/gda-mysql-provider.c | 182 ++++++++++++++++++++++++++++++++++
1 files changed, 182 insertions(+), 0 deletions(-)
---
diff --git a/providers/mysql/gda-mysql-provider.c b/providers/mysql/gda-mysql-provider.c
index 7308019..668dd3b 100644
--- a/providers/mysql/gda-mysql-provider.c
+++ b/providers/mysql/gda-mysql-provider.c
@@ -1612,6 +1612,180 @@ prepare_stmt_simple (MysqlConnectionData *cdata,
return ps;
}
+static GdaSet *
+make_last_inserted_set (GdaConnection *cnc, GdaStatement *stmt, my_ulonglong last_id)
+{
+ GError *lerror = NULL;
+
+ /* analyze @stmt */
+ GdaSqlStatement *sql_insert;
+ GdaSqlStatementInsert *insert;
+ if (gda_statement_get_statement_type (stmt) != GDA_SQL_STATEMENT_INSERT)
+ /* unable to compute anything */
+ return NULL;
+
+ g_object_get (G_OBJECT (stmt), "structure", &sql_insert, NULL);
+ g_assert (sql_insert);
+ insert = (GdaSqlStatementInsert *) sql_insert->contents;
+
+ /* find the name of the 1st column which has the AUTO_INCREMENT */
+ gchar *autoinc_colname = NULL;
+ gint rc;
+ gchar *sql;
+ MysqlConnectionData *cdata;
+ cdata = (MysqlConnectionData*) gda_connection_internal_get_provider_data (cnc);
+ if (!cdata)
+ return NULL;
+ sql = g_strdup_printf ("DESCRIBE %s", insert->table->table_name);
+ rc = gda_mysql_real_query_wrap (cnc, cdata->mysql, sql, strlen (sql));
+ g_free (sql);
+ if (!rc) {
+ MYSQL_RES *result;
+ result = mysql_store_result (cdata->mysql);
+ if (result) {
+ MYSQL_ROW row;
+ unsigned int nfields;
+ nfields = mysql_num_fields (result);
+ while ((row = mysql_fetch_row(result))) {
+ if (row [nfields-1] &&
+ !g_ascii_strcasecmp (row [nfields-1], "auto_increment")) {
+ autoinc_colname = g_strdup (row [0]);
+ break;
+ }
+ }
+ mysql_free_result (result);
+ }
+ }
+ if (! autoinc_colname) {
+ gda_sql_statement_free (sql_insert);
+ return NULL;
+ }
+
+ /* build corresponding SELECT statement */
+ GdaSqlStatementSelect *select;
+ GdaSqlSelectTarget *target;
+ GdaSqlStatement *sql_statement = gda_sql_statement_new (GDA_SQL_STATEMENT_SELECT);
+
+ select = g_new0 (GdaSqlStatementSelect, 1);
+ GDA_SQL_ANY_PART (select)->type = GDA_SQL_ANY_STMT_SELECT;
+ sql_statement->contents = select;
+
+ /* FROM */
+ select->from = gda_sql_select_from_new (GDA_SQL_ANY_PART (select));
+ target = gda_sql_select_target_new (GDA_SQL_ANY_PART (select->from));
+ gda_sql_select_from_take_new_target (select->from, target);
+
+ /* Filling in the target */
+ GValue *value;
+ g_value_set_string ((value = gda_value_new (G_TYPE_STRING)), insert->table->table_name);
+ gda_sql_select_target_take_table_name (target, value);
+ gda_sql_statement_free (sql_insert);
+
+ /* selected fields */
+ GdaSqlSelectField *field;
+ GSList *fields_list = NULL;
+
+ field = gda_sql_select_field_new (GDA_SQL_ANY_PART (select));
+ g_value_set_string ((value = gda_value_new (G_TYPE_STRING)), "*");
+ gda_sql_select_field_take_star_value (field, value);
+ fields_list = g_slist_append (fields_list, field);
+
+ gda_sql_statement_select_take_expr_list (sql_statement, fields_list);
+
+ /* WHERE */
+ GdaSqlExpr *where, *expr;
+ GdaSqlOperation *cond;
+ where = gda_sql_expr_new (GDA_SQL_ANY_PART (select));
+ cond = gda_sql_operation_new (GDA_SQL_ANY_PART (where));
+ where->cond = cond;
+ cond->operator_type = GDA_SQL_OPERATOR_TYPE_EQ;
+ expr = gda_sql_expr_new (GDA_SQL_ANY_PART (cond));
+ g_value_take_string ((value = gda_value_new (G_TYPE_STRING)), autoinc_colname);
+ expr->value = value;
+ cond->operands = g_slist_append (NULL, expr);
+ gchar *str;
+ str = g_strdup_printf ("%llu", last_id);
+ expr = gda_sql_expr_new (GDA_SQL_ANY_PART (cond));
+ g_value_take_string ((value = gda_value_new (G_TYPE_STRING)), str);
+ expr->value = value;
+ cond->operands = g_slist_append (cond->operands, expr);
+
+ gda_sql_statement_select_take_where_cond (sql_statement, where);
+
+ if (gda_sql_statement_check_structure (sql_statement, &lerror) == FALSE) {
+ g_warning (_("Can't build SELECT statement to get last inserted row: %s)"),
+ lerror && lerror->message ? lerror->message : _("No detail"));
+ if (lerror)
+ g_error_free (lerror);
+ gda_sql_statement_free (sql_statement);
+ return NULL;
+ }
+
+ /* execute SELECT statement */
+ GdaDataModel *model;
+ GdaStatement *statement = g_object_new (GDA_TYPE_STATEMENT, "structure", sql_statement, NULL);
+ gda_sql_statement_free (sql_statement);
+ model = gda_connection_statement_execute_select (cnc, statement, NULL, &lerror);
+ g_object_unref (statement);
+ if (!model) {
+ g_warning (_("Can't execute SELECT statement to get last inserted row: %s"),
+ lerror && lerror->message ? lerror->message : _("No detail"));
+ if (lerror)
+ g_error_free (lerror);
+ return NULL;
+ }
+ else {
+ GdaSet *set = NULL;
+ GSList *holders = NULL;
+ gint nrows, ncols, i;
+
+ nrows = gda_data_model_get_n_rows (model);
+ if (nrows <= 0) {
+ g_warning (_("SELECT statement to get last inserted row did not return any row"));
+ return NULL;
+ }
+ else if (nrows > 1) {
+ g_warning (_("SELECT statement to get last inserted row returned too many (%d) rows"),
+ nrows);
+ return NULL;
+ }
+ ncols = gda_data_model_get_n_columns (model);
+ for (i = 0; i < ncols; i++) {
+ GdaHolder *h;
+ GdaColumn *col;
+ gchar *id;
+ const GValue *cvalue;
+
+ col = gda_data_model_describe_column (model, i);
+ h = gda_holder_new (gda_column_get_g_type (col));
+ id = g_strdup_printf ("+%d", i);
+ g_object_set (G_OBJECT (h), "id", id, "not-null", FALSE,
+ "name", gda_column_get_name (col), NULL);
+ g_free (id);
+ cvalue = gda_data_model_get_value_at (model, i, 0, NULL);
+ if (!cvalue || !gda_holder_set_value (h, cvalue, NULL)) {
+ if (holders) {
+ g_slist_foreach (holders, (GFunc) g_object_unref, NULL);
+ g_slist_free (holders);
+ holders = NULL;
+ }
+ break;
+ }
+ holders = g_slist_prepend (holders, h);
+ }
+ g_object_unref (model);
+
+ if (holders) {
+ holders = g_slist_reverse (holders);
+ set = gda_set_new (holders);
+ g_slist_foreach (holders, (GFunc) g_object_unref, NULL);
+ g_slist_free (holders);
+ }
+
+ return set;
+ }
+}
+
static void
free_bind_param_data (GSList *mem_to_free)
{
@@ -2079,6 +2253,14 @@ gda_mysql_provider_statement_execute (GdaServerProvider *provider,
else {
return_value = (GObject *) gda_data_model_array_new (0);
}
+
+ if (last_inserted_row) {
+ my_ulonglong last_row;
+ last_row = mysql_insert_id (cdata->mysql);
+ if (last_row)
+ *last_inserted_row = make_last_inserted_set (cnc, stmt, last_row);
+ }
+
}
}
g_object_unref (ps);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]