[libgda/LIBGDA_4.0] Improve Sqlite's make_last_inserted_set()



commit 215becf7e9b25191cc5b2d254f68372c5f36fc52
Author: Vivien Malerba <malerba gnome-db org>
Date:   Thu Aug 26 18:07:28 2010 +0200

    Improve Sqlite's make_last_inserted_set()
    
    reuse the same SELECT GdaStatement as long as the INSERT statement
    has not changed

 libgda/sqlite/gda-sqlite-provider.c |  156 +++++++++++++++++++----------------
 1 files changed, 85 insertions(+), 71 deletions(-)
---
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index 6cb3192..f747f02 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -1877,85 +1877,99 @@ real_prepare (GdaServerProvider *provider, GdaConnection *cnc, GdaStatement *stm
 	return NULL;
 }
 
+#define MAKE_LAST_INSERTED_SET_ID "__gda"
+static void
+lir_stmt_reset_cb (GdaStatement *stmt, gpointer data)
+{
+	/* get rid of the SELECT statement used in make_last_inserted_set() */
+	g_object_set_data ((GObject*) stmt, MAKE_LAST_INSERTED_SET_ID, NULL);
+}
+
 static GdaSet *
 make_last_inserted_set (GdaConnection *cnc, GdaStatement *stmt, sqlite3_int64 last_id)
 {
 	GError *lerror = NULL;
 
-	/* analyse @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;
-
-	/* build corresponding SELECT statement */
-	GdaSqlStatementSelect *select;
-        GdaSqlSelectTarget *target;
-        GdaSqlStatement *sql_statement = gda_sql_statement_new (GDA_SQL_STATEMENT_SELECT);
-
-	select = (GdaSqlStatementSelect*) sql_statement->contents;
-
-	/* 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_set_string ((value = gda_value_new (G_TYPE_STRING)), "rowid");
-	expr->value = value;
-	cond->operands = g_slist_append (NULL, expr);
-	gchar *str;
-	str = g_strdup_printf ("%lld", 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;
-        }
+	GdaStatement *statement;
+	statement = g_object_get_data ((GObject*) stmt, MAKE_LAST_INSERTED_SET_ID);
+	if (!statement) {
+		/* 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;
+		
+		/* build corresponding SELECT statement */
+		GdaSqlStatementSelect *select;
+		GdaSqlSelectTarget *target;
+		GdaSqlStatement *sql_statement = gda_sql_statement_new (GDA_SQL_STATEMENT_SELECT);
+		
+		select = (GdaSqlStatementSelect*) sql_statement->contents;
+		
+		/* 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_set_string ((value = gda_value_new (G_TYPE_STRING)), "rowid");
+		expr->value = value;
+		cond->operands = g_slist_append (NULL, expr);
+		gchar *str;
+		str = g_strdup_printf ("%lld", 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;
+		}
+		statement = g_object_new (GDA_TYPE_STATEMENT, "structure", sql_statement, NULL);
+		gda_sql_statement_free (sql_statement);
+		g_object_set_data_full ((GObject*) stmt, MAKE_LAST_INSERTED_SET_ID, statement, g_object_unref);
+		g_signal_connect (stmt, "reset",
+				  G_CALLBACK (lir_stmt_reset_cb), 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"));
@@ -1987,7 +2001,7 @@ make_last_inserted_set (GdaConnection *cnc, GdaStatement *stmt, sqlite3_int64 la
 			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, 
+			g_object_set (G_OBJECT (h), "id", id,
 				      "name", gda_column_get_name (col), NULL);
 			g_free (id);
 			cvalue = gda_data_model_get_value_at (model, i, 0, NULL);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]