Hi Vivien,

I see a strange behaviour with gda_connection_statement_execute_select
() and the unreffing of the returned GdaDataModel.
I slightly modified the samples/SimpleExample/example.c test file to let
you see the memory leak. Just launch gnome-system-monitor and see how
the process takes more and more memory.

In my Anjuta's population process this leak grows till 200+ Mb.

I hope I'm doing the right calls, but seeing your examples it seems it's
all ok.

thanks and regards,
Massimo

#include <libgda/libgda.h>
#include <sql-parser/gda-sql-parser.h>
#include <glib.h>

GdaConnection *open_connection (void);
void display_products_contents (GdaConnection *cnc);
void create_table (GdaConnection *cnc);
void run_sql_non_select (GdaConnection *cnc, const gchar *sql);
GdaConnection *cnc;
GdaSqlParser *sql_parser;

static void
execute_statement ()
{
        GdaStatement *stmt;
        GdaSet *plist;
        GdaHolder *param;
        gint i;
        gchar* sql = "SELECT * from products where ref =  ## /* name:'foopar' 
type:gchararray */ ";
        
        sql_parser = gda_connection_create_parser (cnc);
        
        stmt = gda_sql_parser_parse_string (sql_parser, sql, NULL, NULL);       
        
        gda_statement_get_parameters (stmt,  &plist, NULL);

                
        for (i=0; i < 100000; i++) {
                gchar *curr_val;
                
                // even with GdaDataModelArray the leak is present.
                GdaDataModel *res;              
                
                GValue* value = gda_value_new (G_TYPE_STRING);
                curr_val = g_strdup_printf ("hey%d", i);
                g_value_set_string (value, curr_val);
                
                
                if ((param = gda_set_get_holder (plist, "foopar")) == NULL)
                {
                        printf ("error");
                        return ;
                }
                gda_holder_set_value(param, value);
                g_free (curr_val);
                gda_value_free (value);
                
                res = gda_connection_statement_execute_select (cnc, 
(GdaStatement*)stmt, 
                                                                                
                                  (GdaSet*)plist, NULL);
                
                // unreffing res!
                g_object_unref (res);           
        }
}

int
main (int argc, char *argv[])
{
        gda_init ();



        /* open connections */
        cnc = open_connection ();
        create_table (cnc);
//      display_products_contents (cnc);
//        gda_connection_close (cnc);

        execute_statement ();
        sleep (10000);
        return 0;
}

/*
 * Open a connection to the example.db file
 */
GdaConnection *
open_connection ()
{
        GdaConnection *cnc;
        GError *error = NULL;
        GdaSqlParser *parser;

        /* open connection */
        cnc = gda_connection_open_from_string ("SQLite", 
"DB_DIR=.;DB_NAME=example_db", NULL,
                                               GDA_CONNECTION_OPTIONS_NONE,
                                               &error);
        if (!cnc) {
                g_print ("Could not open connection to SQLite database in 
example_db.db file: %s\n",
                         error && error->message ? error->message : "No 
detail");
                exit (1);
        }

        /* create an SQL parser */
        parser = gda_connection_create_parser (cnc);
        if (!parser) /* @cnc doe snot provide its own parser => use default one 
*/
                parser = gda_sql_parser_new ();
        /* attach the parser object to the connection */
        g_object_set_data_full (G_OBJECT (cnc), "parser", parser, 
g_object_unref);

        return cnc;
}

/*
 * Create a "products" table
 */
void
create_table (GdaConnection *cnc)
{
        run_sql_non_select (cnc, "DROP table IF EXISTS products");
        run_sql_non_select (cnc, "CREATE table products (ref string not null 
primary key, "
                            "name string not null, price real)");
        run_sql_non_select (cnc, "INSERT INTO products VALUES ('p1', 'chair', 
2.0)");
        run_sql_non_select (cnc, "INSERT INTO products VALUES ('p2', 'table', 
5.0)");

        run_sql_non_select (cnc, "INSERT INTO products VALUES ('p3', 'glass', 
1.1)");
        
        
}


/* 
 * display the contents of the 'products' table 
 */
void
display_products_contents (GdaConnection *cnc)
{
        GdaDataModel *data_model;
        GdaSqlParser *parser;
        GdaStatement *stmt;
        gchar *sql = "SELECT ref, name, price FROM products";
        GError *error = NULL;

        parser = g_object_get_data (G_OBJECT (cnc), "parser");
        stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
        data_model = gda_connection_statement_execute_select (cnc, stmt, NULL, 
&error);
        g_object_unref (stmt);
        if (!data_model) 
                g_error ("Could not get the contents of the 'products' table: 
%s\n",
                         error && error->message ? error->message : "No 
detail");
        gda_data_model_dump (data_model, stdout);
        g_object_unref (data_model);
}

/*
 * run a non SELECT command and stops if an error occurs
 */
void
run_sql_non_select (GdaConnection *cnc, const gchar *sql)
{
        GdaStatement *stmt;
        GError *error = NULL;
        gint nrows;
        const gchar *remain;
        GdaSqlParser *parser;

        parser = g_object_get_data (G_OBJECT (cnc), "parser");
        stmt = gda_sql_parser_parse_string (parser, sql, &remain, &error);
        if (remain) 
                g_print ("REMAINS: %s\n", remain);

        nrows = gda_connection_statement_execute_non_select (cnc, stmt, NULL, 
NULL, &error);
        if (nrows == -1)
                g_error ("NON SELECT error: %s\n", error && error->message ? 
error->message : "no detail");
        g_object_unref (stmt);
}
_______________________________________________
gnome-db-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gnome-db-list

Reply via email to