[libgda] gda-sqlite and virtual provider: improved destruction and tests
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] gda-sqlite and virtual provider: improved destruction and tests
- Date: Wed, 3 Oct 2018 22:53:07 +0000 (UTC)
commit 972d402ed58a6b7ede86103833b18ad18fe40252
Author: Daniel Espinosa <esodan gmail com>
Date: Wed Oct 3 17:51:02 2018 -0500
gda-sqlite and virtual provider: improved destruction and tests
libgda/sqlite/gda-sqlite-provider.c | 3 +-
libgda/sqlite/virtual/gda-vconnection-hub.c | 41 +++++--
libgda/sqlite/virtual/gda-virtual-connection.c | 17 ++-
tests/data-models/check_vcnc.c | 163 ++++++++++++++++++-------
4 files changed, 157 insertions(+), 67 deletions(-)
---
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index 770b9fe8c..d5c1cb05c 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -801,7 +801,8 @@ gda_sqlite_provider_dispose (GObject *object)
GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (object);
GdaSqliteProviderPrivate *priv = gda_sqlite_provider_get_instance_private (prov);
g_weak_ref_clear (priv->connection);
- g_free (priv->connection);
+ if (priv->connection)
+ g_free (priv->connection);
priv->connection = NULL;
}
diff --git a/libgda/sqlite/virtual/gda-vconnection-hub.c b/libgda/sqlite/virtual/gda-vconnection-hub.c
index dfe93dc43..615b82ba2 100644
--- a/libgda/sqlite/virtual/gda-vconnection-hub.c
+++ b/libgda/sqlite/virtual/gda-vconnection-hub.c
@@ -3,7 +3,7 @@
* Copyright (C) 2008 - 2011 Murray Cumming <murrayc murrayc com>
* Copyright (C) 2009 Bas Driessen <bas driessen xobas com>
* Copyright (C) 2010 David King <davidk openismus com>
- * Copyright (C) 2017 Daniel Espinosa <esodan gmail com>
+ * Copyright (C) 2017-2018 Daniel Espinosa <esodan gmail com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,15 +42,15 @@ static void hub_connection_free (HubConnection *hc);
static gboolean attach_hub_connection (GdaVconnectionHub *hub, HubConnection *hc, GError **error);
static void detach_hub_connection (GdaVconnectionHub *hub, HubConnection *hc);
-static GdaSqlParser *internal_parser;
-
struct _GdaVconnectionHubPrivate {
- GSList *hub_connections; /* list of HubConnection structures */
+ GSList *hub_connections; /* list of HubConnection structures */
+ GdaSqlParser *internal_parser;
};
static void gda_vconnection_hub_class_init (GdaVconnectionHubClass *klass);
static void gda_vconnection_hub_init (GdaVconnectionHub *cnc, GdaVconnectionHubClass *klass);
static void gda_vconnection_hub_dispose (GObject *object);
+static void gda_vconnection_hub_finalize (GObject *object);
static GObjectClass *parent_class = NULL;
static HubConnection *get_hub_cnc_by_ns (GdaVconnectionHub *hub, const gchar *ns);
@@ -67,9 +67,7 @@ gda_vconnection_hub_class_init (GdaVconnectionHubClass *klass)
parent_class = g_type_class_peek_parent (klass);
object_class->dispose = gda_vconnection_hub_dispose;
-
- /* static objects */
- internal_parser = gda_sql_parser_new ();
+ object_class->finalize = gda_vconnection_hub_finalize;
}
static void
@@ -77,6 +75,7 @@ gda_vconnection_hub_init (GdaVconnectionHub *cnc, G_GNUC_UNUSED GdaVconnectionHu
{
cnc->priv = g_new (GdaVconnectionHubPrivate, 1);
cnc->priv->hub_connections = NULL;
+ cnc->priv->internal_parser = gda_sql_parser_new ();;
}
static void
@@ -89,16 +88,34 @@ gda_vconnection_hub_dispose (GObject *object)
/* free memory */
if (cnc->priv) {
gda_connection_close ((GdaConnection *) cnc, NULL);
- g_assert (!cnc->priv->hub_connections);
+ if (cnc->priv->hub_connections) {
+ g_slist_free_full (cnc->priv->hub_connections, hub_connection_free);
+ cnc->priv->hub_connections = NULL;
+ }
+ if (cnc->priv->internal_parser)
+ g_object_unref (cnc->priv->internal_parser);
+ }
+
+ /* chain to parent class */
+ parent_class->dispose (object);
+}
+
+static void
+gda_vconnection_hub_finalize (GObject *object)
+{
+ GdaVconnectionHub *cnc = (GdaVconnectionHub *) object;
+
+ g_return_if_fail (GDA_IS_VCONNECTION_HUB (cnc));
+ /* free memory */
+ if (cnc->priv) {
g_free (cnc->priv);
cnc->priv = NULL;
}
/* chain to parent class */
- parent_class->dispose (object);
+ parent_class->finalize (object);
}
-
GType
gda_vconnection_hub_get_type (void)
{
@@ -826,7 +843,7 @@ attach_hub_connection (GdaVconnectionHub *hub, HubConnection *hc, GError **error
if (hc->ns) {
GdaStatement *stmt;
tmp = g_strdup_printf ("ATTACH ':memory:' AS %s", hc->ns);
- stmt = gda_sql_parser_parse_string (internal_parser, tmp, NULL, NULL);
+ stmt = gda_sql_parser_parse_string (hub->priv->internal_parser, tmp, NULL, NULL);
g_free (tmp);
g_assert (stmt);
if (gda_connection_statement_execute_non_select (GDA_CONNECTION (hub), stmt, NULL, NULL,
error) == -1) {
@@ -991,7 +1008,7 @@ detach_hub_connection (GdaVconnectionHub *hub, HubConnection *hc)
GdaStatement *stmt;
gchar *tmp;
tmp = g_strdup_printf ("DETACH %s", hc->ns);
- stmt = gda_sql_parser_parse_string (internal_parser, tmp, NULL, NULL);
+ stmt = gda_sql_parser_parse_string (hub->priv->internal_parser, tmp, NULL, NULL);
g_free (tmp);
g_assert (stmt);
gda_connection_statement_execute_non_select (GDA_CONNECTION (hub), stmt, NULL, NULL, NULL);
diff --git a/libgda/sqlite/virtual/gda-virtual-connection.c b/libgda/sqlite/virtual/gda-virtual-connection.c
index e1c4ea270..0221d0a6d 100644
--- a/libgda/sqlite/virtual/gda-virtual-connection.c
+++ b/libgda/sqlite/virtual/gda-virtual-connection.c
@@ -136,20 +136,19 @@ gda_virtual_connection_open (GdaVirtualProvider *virtual_provider, GdaConnection
{
g_return_val_if_fail (GDA_IS_VIRTUAL_PROVIDER (virtual_provider), NULL);
- GdaConnection *cnc;
+ GdaConnection *cnc = NULL;
cnc = _gda_server_provider_create_connection (GDA_SERVER_PROVIDER (virtual_provider), NULL, NULL,
NULL, options);
- if (cnc) {
- g_object_set (G_OBJECT (cnc), "provider", virtual_provider, NULL);
- if (!gda_connection_open (cnc, error)) {
- g_object_unref (cnc);
- cnc = NULL;
- }
- }
- else
+ if (!GDA_IS_CONNECTION (cnc)) {
g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_PROVIDER_ERROR, "%s",
_("Internal error: virtual provider does not implement the create_operation()
virtual method"));
+ return NULL;
+ }
+ if (!gda_connection_open (cnc, error)) {
+ g_object_unref (cnc);
+ cnc = NULL;
+ }
return cnc;
}
diff --git a/tests/data-models/check_vcnc.c b/tests/data-models/check_vcnc.c
index 0838b9910..627a36088 100644
--- a/tests/data-models/check_vcnc.c
+++ b/tests/data-models/check_vcnc.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 - 2014 Vivien Malerba <malerba gnome-db org>
- * Copyright (C) 2017 Daniel Espinosa <esodan gmail com>
+ * Copyright (C) 2017,2018 Daniel Espinosa <esodan gmail com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -21,6 +21,7 @@
#include <sql-parser/gda-sql-parser.h>
#include <string.h>
#include <unistd.h>
+#include <gio/gio.h>
#define NTHREADS 50
@@ -34,26 +35,58 @@ static GdaDataModel *run_sql_select (GdaConnection *cnc, const gchar *sql,
static gboolean run_sql_non_select (GdaConnection *cnc, const gchar *sql, GdaSet *params, GError **error);
static GdaDataModel *assert_run_sql_select (GdaConnection *cnc, const gchar *sql,
Action action, const gchar *compare_file);
-static void assert_run_sql_non_select (GdaConnection *cnc, const gchar *sql, GdaSet *params);
+static gboolean assert_run_sql_non_select (GdaConnection *cnc, const gchar *sql, GdaSet *params, GError
**error);
GdaDataModel *load_from_file (const gchar *filename);
static void assert_data_model_equal (GdaDataModel *model, GdaDataModel *ref);
-static GdaConnection *open_destination_connection (void);
+typedef struct {
+ gint fails;
+ GMainLoop *loop;
+ GFile *fdb;
+} Data;
+
+static GdaConnection *open_destination_connection (Data *data);
static void check_update_delete (GdaConnection *virtual);
static void check_simultanous_select_random (GdaConnection *virtual);
static void check_simultanous_select_forward (GdaConnection *virtual);
static void check_threads_select_random (GdaConnection *virtual);
static void check_date (GdaConnection *virtual);
+
+static gboolean test1 (Data *data);
+
int
main (int argc, char *argv[])
{
+ GMainLoop *loop;
+ gda_init ();
+ loop = g_main_loop_new (NULL, FALSE);
+ Data *data = g_new0(Data, 1);
+ data->fails = 0;
+ data->loop = loop;
+ g_idle_add ((GSourceFunc) test1, data);
+ g_main_loop_run (loop);
+ if (data->fails != 0)
+ g_print ("FAIL %d\n", data->fails);
+ else
+ g_print ("All Ok\n");
+ g_main_loop_unref (loop);
+ if (G_IS_OBJECT (data->fdb)) {
+ if (g_file_query_exists (data->fdb, NULL)) {
+ g_file_delete (data->fdb, NULL, NULL);
+ g_object_unref (data->fdb);
+ }
+ }
+ g_free (data);
+ return 0;
+}
+
+static gboolean
+test1 (Data *data) {
GError *error = NULL;
GdaConnection *virtual, *out_cnc;
GdaVirtualProvider *provider;
gchar *file;
-
- gda_init ();
provider = gda_vprovider_hub_new ();
virtual = gda_virtual_connection_open (provider, GDA_CONNECTION_OPTIONS_NONE, NULL);
@@ -66,16 +99,10 @@ main (int argc, char *argv[])
file = g_build_filename (CHECK_FILES, "tests", "data-models", "city.csv", NULL);
city_model = gda_data_model_import_new_file (file, TRUE, options);
g_free (file);
- g_print("Imported Data Model for CITIES:\n");
- g_assert (GDA_IS_DATA_MODEL (city_model));
- g_print ("%s", gda_data_model_dump_as_string (city_model));
file = g_build_filename (CHECK_FILES, "tests", "data-models", "country.csv", NULL);
country_model = gda_data_model_import_new_file (file, TRUE, options);
g_free (file);
g_object_unref (options);
- g_print("Imported Data Model for COUNTRIES:\n");
- g_assert (GDA_IS_DATA_MODEL (country_model));
- g_print ("%s", gda_data_model_dump_as_string (country_model));
/* Add data models to connection */
if (!gda_vconnection_data_model_add_model (GDA_VCONNECTION_DATA_MODEL (virtual), city_model, "city",
&error))
@@ -84,19 +111,23 @@ main (int argc, char *argv[])
g_error ("Add country model error: %s\n", error && error->message ? error->message : "no
detail");
/* SQLite connection for outputs */
- out_cnc = open_destination_connection ();
+ out_cnc = open_destination_connection (data);
+ if (out_cnc == NULL)
+ return FALSE;
/* adding connections to the virtual connection */
if (!gda_vconnection_hub_add (GDA_VCONNECTION_HUB (virtual), out_cnc, "out", &error)) {
g_print ("Could not add connection to virtual connection: %s\n",
error && error->message ? error->message : "No detail");
- exit (1);
+ data->fails += 1;
+ g_main_loop_quit (data->loop);
+ return G_SOURCE_REMOVE;
}
check_update_delete (virtual);
g_print ("*** Copying data into 'countries' virtual table...\n");
- assert_run_sql_non_select (virtual, "INSERT INTO out.countries SELECT * FROM country", NULL);
+ assert_run_sql_non_select (virtual, "INSERT INTO out.countries SELECT * FROM country", NULL, NULL);
check_simultanous_select_random (virtual);
check_simultanous_select_forward (virtual);
@@ -106,50 +137,98 @@ main (int argc, char *argv[])
if (! gda_connection_close (virtual, &error)) {
g_print ("gda_connection_close(virtual) error: %s\n",
error && error->message ? error->message : "No detail");
- exit (1);
+ data->fails += 1;
+ g_main_loop_quit (data->loop);
+ return G_SOURCE_REMOVE;
}
if (! gda_connection_close (out_cnc, &error)) {
g_print ("gda_connection_close(out_cnc) error: %s\n",
error && error->message ? error->message : "No detail");
- exit (1);
- }
+ data->fails += 1;
+ g_main_loop_quit (data->loop);
+ return G_SOURCE_REMOVE;
+ }
+ g_main_loop_quit (data->loop);
+ return G_SOURCE_REMOVE;
+}
- g_print ("All Ok\n");
- return 0;
+static gchar*
+create_connection_string () {
+ GFile *db;
+ GFile *d;
+ GRand *rand;
+ gint i;
+
+ rand = g_rand_new ();
+ gchar** envp = g_get_environ ();
+ const gchar* build_dir = g_environ_getenv (envp, "GDA_TOP_BUILD_DIR");
+ gchar *sd = g_strdup_printf ("file://%s/tests/data-models", build_dir);
+ g_strfreev (envp);
+ d = g_file_new_for_uri (sd);
+ g_assert (g_file_query_exists (d, NULL));
+ i = g_rand_int (rand);
+ gchar *sdb = g_strdup_printf ("%s/vcnc%d", sd, i);
+ db = g_file_new_for_uri (sdb);
+ while (g_file_query_exists (db, NULL)) {
+ g_object_unref (db);
+ i++;
+ g_free (sdb);
+ sdb = g_strdup_printf ("%s/vcnc%d", sd, i);
+ db = g_file_new_for_uri (sdb);
+ }
+ g_free (sd);
+
+ gchar* path = g_file_get_path (d);
+ gchar *cstr = g_strdup_printf ("DB_DIR=%s;DB_NAME=vcnc%d", path, i);
+ g_free (path);
+ g_print ("Connecting using: %s\n", cstr);
+ g_object_unref (d);
+ g_object_unref (db);
+ return cstr;
}
GdaConnection *
-open_destination_connection (void)
+open_destination_connection (Data *data)
{
/* create connection */
GdaConnection *cnc;
GError *error = NULL;
- cnc = gda_connection_new_from_string ("SQLite", "DB_DIR=.;DB_NAME=vcnc",
+
+ gchar *cstr = create_connection_string ();
+ cnc = gda_connection_new_from_string ("SQLite", cstr,
NULL,
GDA_CONNECTION_OPTIONS_NONE,
&error);
+ g_free (cstr);
if (!cnc) {
g_print ("Could not create connection to local SQLite database: %s\n",
error && error->message ? error->message : "No detail");
- exit (1);
+ data->fails++;
+ g_main_loop_quit (data->loop);
+ return NULL;
}
- if (! gda_connection_open (cnc, &error)) {
- g_print ("gda_connection_open() error: %s\n",
+ if (! gda_connection_open (cnc, &error)) {
+ g_print ("gda_connection_open() error: %s\n",
error && error->message ? error->message : "No detail");
- exit (1);
- }
+ data->fails++;
+ g_main_loop_quit (data->loop);
+ return NULL;
+ }
/* table "cities" */
- assert_run_sql_non_select (cnc, "DROP table IF EXISTS cities", NULL);
- assert_run_sql_non_select (cnc, "CREATE table cities (name string not NULL primary key, countrycode
string not null, population int)", NULL);
+ if (!assert_run_sql_non_select (cnc, "DROP table IF EXISTS cities", NULL, NULL)) {
+ g_object_unref (cnc);
+ cnc = open_destination_connection (data);
+ }
+ assert_run_sql_non_select (cnc, "CREATE table cities (name string not NULL primary key, countrycode
string not null, population int)", NULL, NULL);
/* table "countries" */
- assert_run_sql_non_select (cnc, "DROP table IF EXISTS countries", NULL);
- assert_run_sql_non_select (cnc, "CREATE table countries (code string not null primary key, name
string not null)", NULL);
+ assert_run_sql_non_select (cnc, "DROP table IF EXISTS countries", NULL, NULL);
+ assert_run_sql_non_select (cnc, "CREATE table countries (code string not null primary key, name
string not null)", NULL, NULL);
/* table "misc" */
- assert_run_sql_non_select (cnc, "DROP table IF EXISTS misc", NULL);
- assert_run_sql_non_select (cnc, "CREATE table misc (ts timestamp, adate date, atime time)", NULL);
+ assert_run_sql_non_select (cnc, "DROP table IF EXISTS misc", NULL, NULL);
+ assert_run_sql_non_select (cnc, "CREATE table misc (ts timestamp, adate date, atime time)", NULL,
NULL);
return cnc;
}
@@ -256,16 +335,10 @@ assert_run_sql_select (GdaConnection *cnc, const gchar *sql, Action action, cons
return model;
}
-static void
-assert_run_sql_non_select (GdaConnection *cnc, const gchar *sql, GdaSet *params)
+static gboolean
+assert_run_sql_non_select (GdaConnection *cnc, const gchar *sql, GdaSet *params, GError **error)
{
- GError *error = NULL;
- if (! run_sql_non_select (cnc, sql, params, &error)) {
- g_print ("Error executing [%s]: %s\n",
- sql,
- error && error->message ? error->message : "No detail");
- exit (1);
- }
+ return run_sql_non_select (cnc, sql, params, error);
}
GdaDataModel *
@@ -482,13 +555,13 @@ check_update_delete (GdaConnection *virtual)
{
/* Check DELETE and UPDATE */
g_print ("*** Copying data into virtual 'cities' table...\n");
- assert_run_sql_non_select (virtual, "INSERT INTO out.cities SELECT * FROM city WHERE population >=
500000", NULL);
+ assert_run_sql_non_select (virtual, "INSERT INTO out.cities SELECT * FROM city WHERE population >=
500000", NULL, NULL);
g_print ("*** Showing list of cities WHERE population >= 1000000\n");
assert_run_sql_select (virtual, "SELECT * FROM out.cities WHERE population >= 1000000 "
"ORDER BY name", ACTION_COMPARE, "cities1.xml");
g_print ("*** Deleting data where population < 2000000...\n");
- assert_run_sql_non_select (virtual, "DELETE FROM out.cities WHERE population < 2000000", NULL);
+ assert_run_sql_non_select (virtual, "DELETE FROM out.cities WHERE population < 2000000", NULL, NULL);
g_print ("*** Showing (shorter) list of cities WHERE population >= 1000000\n");
assert_run_sql_select (virtual, "SELECT * FROM out.cities WHERE population >= 1000000 "
@@ -496,7 +569,7 @@ check_update_delete (GdaConnection *virtual)
g_print ("*** Updating data where population > 3000000...\n");
assert_run_sql_non_select (virtual, "UPDATE out.cities SET population = 3000000 WHERE "
- "population >= 3000000", NULL);
+ "population >= 3000000", NULL, NULL);
g_print ("*** Showing list of cities WHERE population >= 2100000\n");
assert_run_sql_select (virtual, "SELECT * FROM out.cities WHERE population >= 2100000 "
@@ -605,7 +678,7 @@ check_date (GdaConnection *virtual)
g_date_free (adate);
assert_run_sql_non_select (virtual, "INSERT INTO out.misc VALUES (##ts::timestamp, "
- "##adate::date, ##atime::time)", set);
+ "##adate::date, ##atime::time)", set, NULL);
g_print ("*** Showing contents of 'misc'\n");
model = assert_run_sql_select (virtual, "SELECT * FROM out.misc",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]