1 /*
2  * Copyright (C) 2007 - 2012 Vivien Malerba <malerba@gnome-db.org>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 #include <libgda/libgda.h>
19 #include <virtual/libgda-virtual.h>
20 #include <sql-parser/gda-sql-parser.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 static GdaDataModel *run_sql_select (GdaConnection *cnc, const gchar *sql);
25 static gboolean run_sql_non_select (GdaConnection *cnc, const gchar *sql);
26 static gboolean test1 (void);
27 static gboolean test2 (void);
28 
29 int
main(int argc,char ** argv)30 main (int argc, char **argv)
31 {
32 	gint nfailed = 0;
33 	gda_init ();
34 
35 	if (! test1 ())
36 		nfailed++;
37 	if (! test2 ())
38 		nfailed++;
39 
40 	if (nfailed == 0) {
41 		g_print ("Ok, all tests passed\n");
42 		return EXIT_SUCCESS;
43 	}
44 	else {
45 		g_print ("%d failed\n", nfailed);
46 		return EXIT_FAILURE;
47 	}
48 }
49 
50 static gboolean
test1(void)51 test1 (void)
52 {
53 	GError *error = NULL;
54 	GdaConnection *cnc;
55 	GdaVirtualProvider *provider;
56 	GdaDataModel *rw_model;
57 	gchar *file;
58 	gboolean retval = FALSE;
59 
60 	g_print ("===== %s() =====\n", __FUNCTION__);
61 	provider = gda_vprovider_data_model_new ();
62 	cnc = gda_virtual_connection_open (provider, NULL);
63 	g_assert (cnc);
64 
65 	/* create RW data model to store results */
66 	rw_model = gda_data_model_array_new_with_g_types (2, G_TYPE_STRING, G_TYPE_INT);
67 	gda_data_model_set_column_name (rw_model, 0, "country");
68 	gda_data_model_set_column_name (rw_model, 1, "population");
69 
70 	/* load CSV data models */
71 	GdaDataModel *country_model, *city_model;
72 	GdaSet *options = gda_set_new_inline (1, "TITLE_AS_FIRST_LINE", G_TYPE_BOOLEAN, TRUE);
73 	file = g_build_filename (CHECK_FILES, "tests", "data-models", "city.csv", NULL);
74 	city_model = gda_data_model_import_new_file (file, TRUE, options);
75 	g_free (file);
76 	file = g_build_filename (CHECK_FILES, "tests", "data-models", "country.csv", NULL);
77 	country_model = gda_data_model_import_new_file (file, TRUE, options);
78 	g_free (file);
79 	file = NULL;
80 	g_object_unref (options);
81 
82 	/* Add data models to connection */
83 	if (!gda_vconnection_data_model_add_model (GDA_VCONNECTION_DATA_MODEL (cnc), rw_model, "results", &error))
84 		g_error ("Add RW model error: %s\n", error && error->message ? error->message : "no detail");
85 	if (!gda_vconnection_data_model_add_model (GDA_VCONNECTION_DATA_MODEL (cnc), city_model, "city", &error))
86 		g_error ("Add city model error: %s\n", error && error->message ? error->message : "no detail");
87 	if (!gda_vconnection_data_model_add_model (GDA_VCONNECTION_DATA_MODEL (cnc), country_model, "country", &error))
88 		g_error ("Add country model error: %s\n", error && error->message ? error->message : "no detail");
89 
90 	/* test */
91 	GdaDataModel *model;
92 	model = run_sql_select (cnc, "SELECT * FROM city");
93 	gda_data_model_dump (model, stdout);
94 	g_object_unref (model);
95 	model = run_sql_select (cnc, "SELECT __gda_row_nb, * FROM city");
96 	gda_data_model_dump (model, stdout);
97 	g_object_unref (model);
98 
99 
100 	/* compute list of countries where population >= 1M */
101 	if (! run_sql_non_select (cnc, "INSERT INTO results SELECT co.name, sum (ci.population) as pop FROM country co INNER JOIN city ci ON (co.code=ci.countrycode) GROUP BY co.name HAVING sum (ci.population) > 10000000 ORDER BY co.name DESC"))
102 		g_error ("Could not run computation query");
103 
104 	/* save resulting data model to CSV */
105 	gchar *export, *expected;
106 	export = gda_data_model_export_to_string (rw_model, GDA_DATA_MODEL_IO_TEXT_SEPARATED,
107 						  NULL, 0, NULL, 0, NULL);
108 	file = g_build_filename (CHECK_FILES, "tests", "data-models", "check_virtual.csv", NULL);
109 	if (!g_file_get_contents (file, &expected, NULL, NULL))
110 		goto out;
111 	if (strcmp (export, expected))
112 		goto out;
113 
114 	retval = TRUE;
115  out:
116 
117 	g_free (file);
118 	g_free (export);
119 	g_free (expected);
120 	g_object_unref (city_model);
121 	g_object_unref (country_model);
122 	g_object_unref (cnc);
123 	g_object_unref (provider);
124 
125 	g_print ("%s() is %s\n", __FUNCTION__, retval ? "Ok" : "NOT Ok");
126 	return retval;
127 }
128 
129 static gboolean
test2(void)130 test2 (void)
131 {
132 	GError *error = NULL;
133 	GdaConnection *cnc;
134 	GdaVirtualProvider *provider;
135 	gchar *file;
136 	gboolean retval = FALSE;
137 
138 	g_print ("===== %s () =====\n", __FUNCTION__);
139 	provider = gda_vprovider_data_model_new ();
140 	cnc = gda_virtual_connection_open (provider, NULL);
141 	g_assert (cnc);
142 
143 	/* load CSV data models */
144 	GdaDataModel *country_model, *city_model;
145 	GdaSet *options = gda_set_new_inline (1, "TITLE_AS_FIRST_LINE", G_TYPE_BOOLEAN, TRUE);
146 	file = g_build_filename (CHECK_FILES, "tests", "data-models", "city.csv", NULL);
147 	city_model = gda_data_model_import_new_file (file, TRUE, options);
148 	g_free (file);
149 	file = g_build_filename (CHECK_FILES, "tests", "data-models", "country.csv", NULL);
150 	country_model = gda_data_model_import_new_file (file, TRUE, options);
151 	g_free (file);
152 	g_object_unref (options);
153 
154 	/* Add data models to connection */
155 	if (!gda_vconnection_data_model_add_model (GDA_VCONNECTION_DATA_MODEL (cnc), city_model, "city", &error))
156 		g_error ("Add city model error: %s\n", error && error->message ? error->message : "no detail");
157 	if (!gda_vconnection_data_model_add_model (GDA_VCONNECTION_DATA_MODEL (cnc), country_model, "country", &error))
158 		g_error ("Add country model error: %s\n", error && error->message ? error->message : "no detail");
159 
160 	/* test */
161 	GdaDataModel *model;
162 	model = run_sql_select (cnc, "SELECT c.*, o.name FROM city c INNER JOIN country o ON (c.countrycode = o.code)");
163 	gda_data_model_dump (model, stdout);
164 	g_object_unref (model);
165 
166 	retval = TRUE;
167 
168 	g_object_unref (city_model);
169 	g_object_unref (country_model);
170 	g_object_unref (cnc);
171 	g_object_unref (provider);
172 
173 	g_print ("%s() is %s\n", __FUNCTION__, retval ? "Ok" : "NOT Ok");
174 	return retval;
175 }
176 
177 static GdaDataModel *
run_sql_select(GdaConnection * cnc,const gchar * sql)178 run_sql_select (GdaConnection *cnc, const gchar *sql)
179 {
180 	GdaStatement *stmt;
181 	GError *error = NULL;
182 	GdaDataModel *res;
183 	GdaSqlParser *parser;
184 
185 	parser = gda_connection_create_parser (cnc);
186 	stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
187 	g_object_unref (parser);
188 
189 	g_print ("EXECUTING [%s]\n", sql);
190         res = gda_connection_statement_execute_select (cnc, stmt, NULL, &error);
191         g_object_unref (stmt);
192 	if (!res)
193 		g_error ("Could not execute query: %s\n",
194 			 error && error->message ? error->message : "no detail");
195 	return res;
196 }
197 
198 
199 static gboolean
run_sql_non_select(GdaConnection * cnc,const gchar * sql)200 run_sql_non_select (GdaConnection *cnc, const gchar *sql)
201 {
202 	GdaStatement *stmt;
203         GError *error = NULL;
204         gint nrows;
205         GdaSqlParser *parser;
206 
207         parser = gda_connection_create_parser (cnc);
208         stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
209         g_object_unref (parser);
210 
211 	g_print ("EXECUTING [%s]\n", sql);
212         nrows = gda_connection_statement_execute_non_select (cnc, stmt, NULL, NULL, &error);
213         g_object_unref (stmt);
214         if (nrows == -1) {
215                 g_print ("NON SELECT error: %s\n", error && error->message ? error->message : "no detail");
216 		if (error)
217 			g_error_free (error);
218 		return FALSE;
219 	}
220 
221 	return TRUE;
222 }
223