1 /*
2 * Copyright (C) 2007 - 2013 Vivien Malerba <malerba@gnome-db.org>
3 * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com>
4 * Copyright (C) 2012 Daniel Espinosa <despinosa@src.gnome.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20 #include <stdlib.h>
21 #include <string.h>
22 #include "prov-test-common.h"
23 #include "prov-test-util.h"
24 #include <sql-parser/gda-sql-parser.h>
25 #include <sql-parser/gda-sql-statement.h>
26 #include "../test-cnc-utils.h"
27 #include "../test-errors.h"
28
29
30 #define CHECK_EXTRA_INFO
31 /*#undef CHECK_EXTRA_INFO*/
32
33 GdaProviderInfo *pinfo;
34 GdaConnection *cnc;
35 gboolean params_provided;
36 gboolean fork_tests = TRUE;
37
38 /*
39 *
40 * SETUP
41 *
42 */
43
44 int
prov_test_common_setup(void)45 prov_test_common_setup (void)
46 {
47 int number_failed = 0;
48 GError *error = NULL;
49
50 #ifdef CHECK_EXTRA_INFO
51 g_print ("\n============= %s() =============\n", __FUNCTION__);
52 #endif
53
54 cnc = test_cnc_setup_connection (pinfo->id, "testcheckdb", &error);
55 if (!cnc) {
56 if (error) {
57 if (error->domain != TEST_ERROR) {
58 gchar *str = g_strdup_printf ("Could not setup connection: %s",
59 error->message ? error->message : "No detail");
60 g_warning ("%s", str);
61 g_free (str);
62 number_failed++;
63 }
64 else
65 g_print ("==> %s\n", error->message ? error->message : "No detail");
66 g_error_free (error);
67 }
68 }
69 else {
70 gchar *file;
71 file = g_build_filename (CHECK_SQL_FILES, "tests", "providers", "prov_dbstruct.xml", NULL);
72 if (!test_cnc_setup_db_structure (cnc, file, &error)) {
73 gchar *str = g_strdup_printf ("Could not setup database structure: %s",
74 error && error->message ? error->message : "No detail");
75 g_warning ("%s", str);
76 g_free (str);
77 if (error)
78 g_error_free (error);
79 number_failed++;
80 }
81 g_free (file);
82 }
83 return number_failed;
84 }
85
86 GdaConnection *
prov_test_common_create_extra_connection(void)87 prov_test_common_create_extra_connection (void)
88 {
89 GdaConnection *cnc;
90 GError *lerror = NULL;
91 cnc = test_cnc_open_connection (pinfo->id, "testcheckdb", &lerror);
92 if (!cnc) {
93 g_print ("Error setting up connection: %s\n", lerror && lerror->message ? lerror->message : "No detail");
94 g_clear_error (&lerror);
95 }
96 return cnc;
97 }
98
99
100 /*
101 *
102 * CLEAN
103 *
104 */
105 int
prov_test_common_clean(void)106 prov_test_common_clean (void)
107 {
108 int number_failed = 0;
109
110 #ifdef CHECK_EXTRA_INFO
111 g_print ("\n============= %s() =============\n", __FUNCTION__);
112 #endif
113
114 if (!test_cnc_clean_connection (cnc, NULL))
115 number_failed++;
116
117 return number_failed;
118 }
119
120 /*
121 *
122 * CHECK_META
123 *
124 */
125
126 int
prov_test_common_check_meta(void)127 prov_test_common_check_meta (void)
128 {
129 int number_failed = 0;
130 GSList *tables = NULL, *list;
131 gboolean dump_ok = TRUE;
132 GdaMetaStore *store;
133 gchar **dump1 = NULL;
134 GError *gerror = NULL;
135 gint ntables, i;
136
137 #ifdef CHECK_EXTRA_INFO
138 g_print ("\n============= %s() =============\n", __FUNCTION__);
139 #endif
140
141 /* update meta store */
142 #ifdef CHECK_EXTRA_INFO
143 g_print ("Updating the complete meta store...\n");
144 #endif
145 if (! gda_connection_update_meta_store (cnc, NULL, &gerror)) {
146 #ifdef CHECK_EXTRA_INFO
147 g_warning ("Can't update meta store (1): %s\n",
148 gerror && gerror->message ? gerror->message : "???");
149 #endif
150 g_error_free (gerror);
151 number_failed++;
152 goto theend;
153 }
154
155 /* dump all tables */
156 store = gda_connection_get_meta_store (cnc);
157 tables = gda_meta_store_schema_get_all_tables (store);
158 ntables = g_slist_length (tables);
159 dump1 = g_new0 (gchar *, ntables + 1);
160
161 for (i = 0, list = tables; list; i++, list = list->next) {
162 GdaDataModel *model;
163 gchar *tmp;
164
165 tmp = g_strdup_printf ("SELECT * FROM %s", (gchar*) list->data);
166 model = gda_meta_store_extract (store, tmp, &gerror, NULL);
167 g_free (tmp);
168 if (!model) {
169 #ifdef CHECK_EXTRA_INFO
170 g_warning ("Can't execute SELECT statement: %s\n",
171 gerror && gerror->message ? gerror->message : "???");
172 #endif
173 g_error_free (gerror);
174 dump_ok = FALSE;
175 break;
176 }
177
178 dump1 [i] = gda_data_model_export_to_string (model, GDA_DATA_MODEL_IO_DATA_ARRAY_XML,
179 NULL, 0, NULL, 0, NULL);
180 g_object_unref (model);
181 if (!dump1 [i]) {
182 #ifdef CHECK_EXTRA_INFO
183 g_warning ("Can't export data model\n");
184 #endif
185 dump_ok = FALSE;
186 break;
187 }
188 }
189
190 if (!dump_ok) {
191 number_failed++;
192 goto theend;
193 }
194
195 /* update meta store */
196 #ifdef CHECK_EXTRA_INFO
197 g_print ("Updating the complete meta store...\n");
198 #endif
199 if (! gda_connection_update_meta_store (cnc, NULL, &gerror)) {
200 #ifdef CHECK_EXTRA_INFO
201 g_warning ("Can't update meta store (2): %s\n",
202 gerror && gerror->message ? gerror->message : "???");
203 #endif
204 g_error_free (gerror);
205 number_failed++;
206 goto theend;
207 }
208 /* Update meta store by context */
209 GdaMetaContext *ctx;
210 ctx = gda_meta_context_new ();
211 gchar *meta_tables[] = {"_tables", "_attributes", "_information_schema_catalog_name",
212 "_schemata", "_builtin_data_types", "_udt", "_udt_columns",
213 "_enums", "_element_types", "_domains", "_views", "_collations",
214 "_character_sets", "_routines", "_triggers", "_columns",
215 "_table_constraints", "_referential_constraints",
216 "_key_column_usage", "__declared_fk", "_check_column_usage",
217 "_view_column_usage", "_domain_constraints", "_parameters",
218 "_routine_columns", "_table_indexes", "_index_column_usage",
219 NULL};
220 for (i = 0; meta_tables[i]; i++) {
221 gda_meta_context_set_table (ctx, meta_tables[i]);
222 #ifdef CHECK_EXTRA_INFO
223 g_print ("Updating the meta store for table '%s'\n", meta_tables[i]);
224 #endif
225 if (! gda_connection_update_meta_store (cnc, ctx, &gerror)) {
226 #ifdef CHECK_EXTRA_INFO
227 g_warning ("Can't update meta store (on table %s): %s\n",
228 meta_tables[i], gerror && gerror->message ? gerror->message : "???");
229 #endif
230 g_error_free (gerror);
231 number_failed++;
232 goto theend;
233 }
234 }
235 gda_meta_context_free (ctx);
236
237 for (i = 0, list = tables; list; i++, list = list->next) {
238 GdaDataModel *model;
239 gchar *tmp;
240 GError *gerror = NULL;
241
242 tmp = g_strdup_printf ("SELECT * FROM %s", (gchar*) list->data);
243 model = gda_meta_store_extract (store, tmp, &gerror, NULL);
244 g_free (tmp);
245 if (!model) {
246 #ifdef CHECK_EXTRA_INFO
247 g_warning ("Can't execute SELECT statement: %s\n",
248 gerror && gerror->message ? gerror->message : "???");
249 #endif
250 g_error_free (gerror);
251 number_failed++;
252 continue;
253 }
254
255 tmp = gda_data_model_export_to_string (model, GDA_DATA_MODEL_IO_DATA_ARRAY_XML,
256 NULL, 0, NULL, 0, NULL);
257 g_object_unref (model);
258 if (!tmp) {
259 #ifdef CHECK_EXTRA_INFO
260 g_warning ("Can't export data model\n");
261 #endif
262 number_failed++;
263 continue;
264 }
265 if (strcmp (tmp, dump1[i])) {
266 #ifdef CHECK_EXTRA_INFO
267 g_warning ("Meta data has changed after update for table %s\n", (gchar*) list->data);
268 g_print ("===\n%s\n===\n%s\n===\n", tmp, dump1[i]);
269 #endif
270 number_failed++;
271 g_free (tmp);
272 continue;
273 }
274 #ifdef CHECK_EXTRA_INFO
275 else
276 g_print ("Meta for table '%s' Ok\n", (gchar*) list->data);
277 #endif
278 g_free (tmp);
279 }
280
281 theend:
282 /* remove tmp files */
283 if (dump1)
284 g_strfreev (dump1);
285 g_slist_free (tables);
286
287 return number_failed;
288 }
289
290 /*
291 *
292 * CHECK_META_IDENTIFIERS
293 *
294 */
295
296 int
prov_test_common_check_meta_identifiers(gboolean case_sensitive,gboolean update_all)297 prov_test_common_check_meta_identifiers (gboolean case_sensitive, gboolean update_all)
298 {
299 GdaMetaStore *store;
300 GError *error = NULL;
301 gchar *table_name = "CapitalTest";
302 gchar *field_name = "AName";
303 GdaServerProvider* provider = gda_connection_get_provider (cnc);
304 GdaServerOperation* operation;
305 GdaDataModel* data;
306 GValue *value, *value2;
307 const GValue *cvalue;
308 GdaMetaContext mcontext = {"_tables", 1, NULL, NULL};
309 GdaConnectionOptions options;
310
311 #ifdef CHECK_EXTRA_INFO
312 g_print ("\n============= %s(%s, %s) =============\n", __FUNCTION__,
313 case_sensitive ? "case sensitive" : "case NOT sensitive",
314 update_all ? "complete meta data update" : "partial meta data update");
315 #endif
316
317 g_object_get (G_OBJECT (cnc), "options", &options, NULL);
318 if (case_sensitive)
319 g_object_set (G_OBJECT (cnc), "options",
320 options | GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE, NULL);
321
322
323
324 /* DROP table */
325 operation = gda_server_provider_create_operation (provider, cnc,
326 GDA_SERVER_OPERATION_DROP_TABLE, NULL, &error);
327 g_assert (operation);
328 gda_server_operation_set_value_at_path (operation, table_name, "/TABLE_DESC_P/TABLE_NAME", NULL);
329 gda_server_provider_perform_operation (provider, cnc, operation, NULL);
330 g_object_unref (operation);
331
332 /* CREATE table */
333 operation = gda_server_provider_create_operation (provider, cnc,
334 GDA_SERVER_OPERATION_CREATE_TABLE, NULL, &error);
335 g_assert (operation);
336 gda_server_operation_set_value_at (operation, table_name, NULL, "/TABLE_DEF_P/TABLE_NAME");
337 gda_server_operation_set_value_at (operation, "id", NULL, "/FIELDS_A/@COLUMN_NAME/0");
338 gda_server_operation_set_value_at (operation, "int", NULL, "/FIELDS_A/@COLUMN_TYPE/0");
339 gda_server_operation_set_value_at (operation, "TRUE", NULL, "/FIELDS_A/@COLUMN_PKEY/0");
340 if (! gda_server_provider_perform_operation (provider, cnc, operation, &error)) {
341 #ifdef CHECK_EXTRA_INFO
342 g_warning ("perform_operation(CREATE_TABLE) failed: %s\n", error && error->message ?
343 error->message : "???");
344 #endif
345 g_clear_error (&error);
346 g_object_set (G_OBJECT (cnc), "options", options, NULL);
347 return 1;
348 }
349
350
351 /* update meta store */
352 #ifdef CHECK_EXTRA_INFO
353 g_print ("Updating the complete meta store...\n");
354 #endif
355 if (!update_all) {
356 g_value_take_string ((value = gda_value_new (G_TYPE_STRING)),
357 gda_meta_store_sql_identifier_quote (table_name, cnc));
358 mcontext.column_names = g_new (gchar *, 1);
359 mcontext.column_names [0] = "table_name";
360 mcontext.column_values = g_new (GValue *, 1);
361 mcontext.column_values [0] = value;
362 }
363 store = gda_meta_store_new (NULL); /* create an in memory meta store */
364 g_object_set (G_OBJECT (cnc), "meta-store", store, NULL);
365 g_object_unref (store);
366 if (! gda_connection_update_meta_store (cnc, update_all ? NULL : &mcontext, &error)) {
367 #ifdef CHECK_EXTRA_INFO
368 g_warning ("Can't FULL update meta store: %s\n",
369 error && error->message ? error->message : "???");
370 #endif
371 g_clear_error (&error);
372 g_object_set (G_OBJECT (cnc), "options", options, NULL);
373 return 1;
374 }
375
376 /* check table */
377 #ifdef CHECK_EXTRA_INFO
378 g_print ("Checking fetched meta data...\n");
379 #endif
380 g_value_take_string ((value = gda_value_new (G_TYPE_STRING)),
381 gda_meta_store_sql_identifier_quote (table_name, cnc));
382 data = gda_connection_get_meta_store_data (cnc, GDA_CONNECTION_META_TABLES, &error, 1,
383 "name", value);
384 g_assert (data);
385 if (gda_data_model_get_n_rows (data) != 1) {
386 #ifdef CHECK_EXTRA_INFO
387 g_warning ("gda_connection_get_meta_store_data(): wrong number of rows : %d\n",
388 gda_data_model_get_n_rows (data));
389 #endif
390 gda_value_free (value);
391 g_object_unref (data);
392 g_object_set (G_OBJECT (cnc), "options", options, NULL);
393 return 1;
394 }
395 cvalue = gda_data_model_get_value_at (data, 0, 0, &error);
396 g_assert (cvalue);
397 if (gda_value_compare (value, cvalue)) {
398 #ifdef CHECK_EXTRA_INFO
399 g_warning ("gda_connection_get_meta_store_data(): expected %s and got %s\n",
400 gda_value_stringify (cvalue), gda_value_stringify (value));
401 #endif
402 gda_value_free (value);
403 g_object_unref (data);
404 g_object_set (G_OBJECT (cnc), "options", options, NULL);
405 return 1;
406 }
407 g_object_unref (data);
408
409 /* check fields of table */
410 data = gda_connection_get_meta_store_data (cnc, GDA_CONNECTION_META_FIELDS, &error, 1,
411 "name", value);
412 g_assert (data);
413 if (gda_data_model_get_n_rows (data) != 1) {
414 #ifdef CHECK_EXTRA_INFO
415 g_warning ("gda_connection_get_meta_store_data(): wrong number of rows : %d\n",
416 gda_data_model_get_n_rows (data));
417 #endif
418 gda_value_free (value);
419 g_object_unref (data);
420 g_object_set (G_OBJECT (cnc), "options", options, NULL);
421 return 1;
422 }
423 cvalue = gda_data_model_get_value_at (data, 0, 0, &error);
424 g_assert (cvalue);
425 g_value_set_string ((value2 = gda_value_new (G_TYPE_STRING)), "id");
426 if (gda_value_compare (value2, cvalue)) {
427 #ifdef CHECK_EXTRA_INFO
428 g_warning ("gda_connection_get_meta_store_data(): expected %s and got %s\n",
429 gda_value_stringify (cvalue), gda_value_stringify (value));
430 #endif
431 gda_value_free (value);
432 g_object_unref (data);
433 g_object_set (G_OBJECT (cnc), "options", options, NULL);
434 return 1;
435 }
436 gda_value_free (value);
437 gda_value_free (value2);
438 g_object_unref (data);
439
440 /* ALTER table to add a column */
441 operation = gda_server_provider_create_operation (provider, cnc,
442 GDA_SERVER_OPERATION_ADD_COLUMN, NULL, &error);
443 g_assert (operation);
444 gda_server_operation_set_value_at_path (operation, table_name, "/COLUMN_DEF_P/TABLE_NAME", NULL);
445 gda_server_operation_set_value_at (operation, field_name, NULL, "/COLUMN_DEF_P/COLUMN_NAME", NULL);
446 gda_server_operation_set_value_at (operation, "int", NULL, "/COLUMN_DEF_P/COLUMN_TYPE", NULL);
447 if (! gda_server_provider_perform_operation (provider, cnc, operation, &error)) {
448 #ifdef CHECK_EXTRA_INFO
449 g_warning ("perform_operation(ADD_COLUMN) failed: %s\n", error && error->message ?
450 error->message : "???");
451 #endif
452 g_clear_error (&error);
453 g_object_set (G_OBJECT (cnc), "options", options, NULL);
454 return 1;
455 }
456
457 /* update meta store */
458 #ifdef CHECK_EXTRA_INFO
459 g_print ("Updating the complete meta store...\n");
460 #endif
461 if (! gda_connection_update_meta_store (cnc, update_all ? NULL : &mcontext, &error)) {
462 #ifdef CHECK_EXTRA_INFO
463 g_warning ("Can't FULL update meta store: %s\n",
464 error && error->message ? error->message : "???");
465 #endif
466 g_clear_error (&error);
467 g_object_set (G_OBJECT (cnc), "options", options, NULL);
468 return 1;
469 }
470
471 /* check table */
472 #ifdef CHECK_EXTRA_INFO
473 g_print ("Checking fetched meta data...\n");
474 #endif
475 g_value_take_string ((value = gda_value_new (G_TYPE_STRING)),
476 gda_meta_store_sql_identifier_quote (table_name, cnc));
477 data = gda_connection_get_meta_store_data (cnc, GDA_CONNECTION_META_TABLES, &error, 1,
478 "name", value);
479 g_assert (data);
480 if (gda_data_model_get_n_rows (data) != 1) {
481 #ifdef CHECK_EXTRA_INFO
482 g_warning ("gda_connection_get_meta_store_data(): wrong number of rows : %d\n",
483 gda_data_model_get_n_rows (data));
484 #endif
485 gda_value_free (value);
486 g_object_unref (data);
487 g_object_set (G_OBJECT (cnc), "options", options, NULL);
488 return 1;
489 }
490 cvalue = gda_data_model_get_value_at (data, 0, 0, &error);
491 g_assert (cvalue);
492 if (gda_value_compare (value, cvalue)) {
493 #ifdef CHECK_EXTRA_INFO
494 g_warning ("gda_connection_get_meta_store_data(): expected %s and got %s\n",
495 gda_value_stringify (cvalue), gda_value_stringify (value));
496 #endif
497 gda_value_free (value);
498 g_object_unref (data);
499 g_object_set (G_OBJECT (cnc), "options", options, NULL);
500 return 1;
501 }
502 g_object_unref (data);
503
504 /* check fields of table */
505 g_value_take_string ((value2 = gda_value_new (G_TYPE_STRING)),
506 gda_meta_store_sql_identifier_quote (field_name, cnc));
507 data = gda_connection_get_meta_store_data (cnc, GDA_CONNECTION_META_FIELDS, &error, 2,
508 "name", value, "field_name", value2);
509 g_assert (data);
510 if (gda_data_model_get_n_rows (data) != 1) {
511 #ifdef CHECK_EXTRA_INFO
512 g_warning ("gda_connection_get_meta_store_data(): wrong number of rows : %d\n",
513 gda_data_model_get_n_rows (data));
514 #endif
515 gda_value_free (value);
516 g_object_unref (data);
517 g_object_set (G_OBJECT (cnc), "options", options, NULL);
518 return 1;
519 }
520 cvalue = gda_data_model_get_value_at (data, 0, 0, &error);
521 g_assert (cvalue);
522 if (gda_value_compare (value2, cvalue)) {
523 #ifdef CHECK_EXTRA_INFO
524 g_warning ("gda_connection_get_meta_store_data(): expected %s and got %s\n",
525 gda_value_stringify (cvalue), gda_value_stringify (value));
526 #endif
527 gda_value_free (value);
528 g_object_unref (data);
529 g_object_set (G_OBJECT (cnc), "options", options, NULL);
530 return 1;
531 }
532 gda_value_free (value);
533 g_object_unref (data);
534
535 g_object_set (G_OBJECT (cnc), "options", options, NULL);
536 return 0;
537 }
538
539 /*
540 *
541 * LOAD_DATA
542 *
543 */
544 int
prov_test_common_load_data(void)545 prov_test_common_load_data (void)
546 {
547 int number_failed = 0;
548
549 #ifdef CHECK_EXTRA_INFO
550 g_print ("\n============= %s() =============\n", __FUNCTION__);
551 #endif
552
553 if (!prov_test_load_data (cnc, "actor"))
554 number_failed++;
555 if (!prov_test_load_data (cnc, "language"))
556 number_failed++;
557 if (!prov_test_load_data (cnc, "film"))
558 number_failed++;
559 if (!prov_test_load_data (cnc, "film_actor"))
560 number_failed++;
561
562 return number_failed;
563 }
564
565 /*
566 *
567 * CHECK_CURSOR_MODELS
568 *
569 */
570 int
prov_test_common_check_cursor_models(void)571 prov_test_common_check_cursor_models (void)
572 {
573 int number_failed = 0;
574
575 #ifdef CHECK_EXTRA_INFO
576 g_print ("\n============= %s() =============\n", __FUNCTION__);
577 #endif
578
579 if (!prov_test_check_table_cursor_model (cnc, "actor"))
580 number_failed++;
581 if (!prov_test_check_table_cursor_model (cnc, "language"))
582 number_failed++;
583 if (!prov_test_check_table_cursor_model (cnc, "film"))
584 number_failed++;
585 if (!prov_test_check_table_cursor_model (cnc, "film_actor"))
586 number_failed++;
587 if (!prov_test_check_types_schema (cnc))
588 number_failed++;
589
590 return number_failed;
591 }
592
593 /*
594 *
595 * Check for the GdaDataModel returned from a SELECT combined with the GDA_STATEMENT_MODEL_ALLOW_NOPARAM
596 * flag
597 *
598 */
599 int
prov_test_common_check_data_select(void)600 prov_test_common_check_data_select (void)
601 {
602 GdaSqlParser *parser = NULL;
603 GdaStatement *stmt = NULL;
604 GdaSet *params = NULL;
605 GError *error = NULL;
606 int number_failed = 0;
607 GdaDataModel *model = NULL;
608 const gchar *remain;
609 GSList *columns;
610 gint i, ncols;
611
612 #ifdef CHECK_EXTRA_INFO
613 g_print ("\n============= %s() =============\n", __FUNCTION__);
614 #endif
615
616 parser = gda_connection_create_parser (cnc);
617 if (!parser)
618 parser = gda_sql_parser_new ();
619
620 /* create statement */
621 stmt = gda_sql_parser_parse_string (parser, "SELECT * FROM actor WHERE actor_id <= ##theid::gint",
622 &remain, &error);
623 if (!stmt) {
624 number_failed ++;
625 goto out;
626 }
627 if (remain) {
628 g_set_error (&error, TEST_ERROR, TEST_ERROR_PARSING,
629 "Parsing error, remains: %s", remain);
630 number_failed ++;
631 goto out;
632 }
633
634 /* get model */
635 if (! (gda_statement_get_parameters (stmt, ¶ms, &error))) {
636 number_failed ++;
637 goto out;
638 }
639
640 model = gda_connection_statement_execute_select_full (cnc, stmt, params, GDA_STATEMENT_MODEL_ALLOW_NOPARAM,
641 NULL, &error);
642 if (!model) {
643 number_failed ++;
644 goto out;
645 }
646
647 if (gda_data_model_get_n_rows (model) != 0) {
648 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
649 "Data model reports %d rows when 0 expected", gda_data_model_get_n_rows (model));
650 number_failed ++;
651 goto out;
652 }
653
654 ncols = gda_data_model_get_n_columns (model);
655 for (columns = NULL, i = 0;
656 i < ncols; i++)
657 columns = g_slist_append (columns, gda_data_model_describe_column (model, i));
658
659 /* change param */
660 g_object_set (model, "auto-reset", TRUE, NULL);
661 if (! gda_set_set_holder_value (params, &error, "theid", 9)) {
662 number_failed++;
663 goto out;
664 }
665
666 if (gda_data_model_get_n_rows (model) != 9) {
667 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
668 "Data model reports %d rows when 9 expected", gda_data_model_get_n_rows (model));
669 number_failed ++;
670 goto out;
671 }
672
673 /* check the columns haven't changed */
674 ncols = gda_data_model_get_n_columns (model);
675 if (i != ncols) {
676 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
677 "Number of columns has changed from %d to %d\n", i, ncols);
678 number_failed ++;
679 goto out;
680 }
681
682 for (i = 0; i < ncols; i++) {
683 if (gda_data_model_describe_column (model, i) != g_slist_nth_data (columns, i)) {
684 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
685 "GdaColumn %d has changed from %p to %p\n", i,
686 g_slist_nth_data (columns, i),
687 gda_data_model_describe_column (model, i));
688 number_failed ++;
689 goto out;
690 }
691 }
692
693 out:
694 if (stmt)
695 g_object_unref (stmt);
696 if (params)
697 g_object_unref (params);
698 if (model)
699 g_object_unref (model);
700 g_object_unref (parser);
701
702 #ifdef CHECK_EXTRA_INFO
703 g_print ("GdaDataSelect test resulted in %d error(s)\n", number_failed);
704 if (number_failed != 0)
705 g_print ("error: %s\n", error && error->message ? error->message : "No detail");
706 if (error)
707 g_error_free (error);
708 #endif
709
710 return number_failed;
711 }
712
713
714 /*
715 * Check that timezones are handled correctly when storing and retreiving timestamps
716 */
717 static gboolean
timestamp_equal(const GValue * cv1,const GValue * cv2)718 timestamp_equal (const GValue *cv1, const GValue *cv2)
719 {
720 g_assert (G_VALUE_TYPE (cv1) == GDA_TYPE_TIMESTAMP);
721 g_assert (G_VALUE_TYPE (cv2) == GDA_TYPE_TIMESTAMP);
722 const GdaTimestamp *ts1, *ts2;
723 ts1 = gda_value_get_timestamp (cv1);
724 ts2 = gda_value_get_timestamp (cv2);
725 if (ts1->timezone == ts2->timezone)
726 return gda_value_differ (cv1, cv2) ? FALSE : TRUE;
727
728 GdaTimestamp *ts;
729 ts = gda_timestamp_copy ((GdaTimestamp*) ts1);
730 gda_timestamp_change_timezone (ts, ts2->timezone);
731 gboolean res;
732 res = memcmp (ts2, ts, sizeof (GdaTimestamp)) ? FALSE : TRUE;
733 gda_timestamp_free (ts);
734 return res;
735 }
736
737 int
prov_test_common_check_timestamp(void)738 prov_test_common_check_timestamp (void)
739 {
740 GdaSqlParser *parser = NULL;
741 GdaStatement *stmt = NULL;
742 GdaSet *params = NULL;
743 GError *error = NULL;
744 int number_failed = 0;
745 GdaDataModel *model = NULL;
746
747 #ifdef CHECK_EXTRA_INFO
748 g_print ("\n============= %s() =============\n", __FUNCTION__);
749 #endif
750
751 parser = gda_connection_create_parser (cnc);
752 if (!parser)
753 parser = gda_sql_parser_new ();
754
755 GValue *tso;
756 tso = gda_value_new_timestamp_from_timet (time (NULL));
757
758 /* insert timestamp */
759 stmt = gda_sql_parser_parse_string (parser, "INSERT INTO tstest (ts) VALUES (##ts::timestamp)", NULL, &error);
760 if (!stmt ||
761 ! gda_statement_get_parameters (stmt, ¶ms, &error) ||
762 ! gda_set_set_holder_value (params, &error, "ts", gda_value_get_timestamp (tso)) ||
763 (gda_connection_statement_execute_non_select (cnc, stmt, params, NULL, &error) == -1)) {
764 number_failed ++;
765 goto out;
766 }
767
768 g_print ("Inserted TS %s\n", gda_value_stringify (tso));
769
770 /* retreive timestamp */
771 stmt = gda_sql_parser_parse_string (parser, "SELECT ts FROM tstest", NULL, &error);
772 if (!stmt) {
773 number_failed ++;
774 goto out;
775 }
776
777 model = gda_connection_statement_execute_select (cnc, stmt, NULL, &error);
778 if (!model) {
779 number_failed ++;
780 goto out;
781 }
782 gda_data_model_dump (model, NULL);
783 if (gda_data_model_get_n_rows (model) != 1) {
784 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
785 "Data model should have exactly 1 row");
786 number_failed ++;
787 goto out;
788 }
789
790 const GValue *cvalue;
791 cvalue = gda_data_model_get_typed_value_at (model, 0, 0, GDA_TYPE_TIMESTAMP, FALSE, &error);
792 if (!cvalue) {
793 number_failed ++;
794 goto out;
795 }
796 if (! timestamp_equal (tso, cvalue)) {
797 gchar *tmpg, *tmpe;
798 tmpg = gda_value_stringify (cvalue);
799 tmpe = gda_value_stringify (tso);
800 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
801 "Retreived time stamp differs from expected: got '%s' and expected '%s'", tmpg, tmpe);
802 g_free (tmpg);
803 g_free (tmpe);
804 number_failed ++;
805 goto out;
806 }
807
808 /* check that data handler is correctly configured: compare the same timestamp rendered by a data handler for
809 * timestamps with the date rendered as a string by the server (by appending a string to the timestamp field) */
810 GdaDataHandler *dh;
811 dh = gda_server_provider_get_data_handler_g_type (gda_connection_get_provider (cnc), cnc, GDA_TYPE_TIMESTAMP);
812 gchar *str;
813 str = gda_data_handler_get_str_from_value (dh, cvalue);
814 g_object_unref (model);
815
816 stmt = gda_sql_parser_parse_string (parser, "SELECT ts || 'asstring' FROM tstest", NULL, &error); /* retreive timestamp as string */
817 if (!stmt) {
818 g_free (str);
819 number_failed ++;
820 goto out;
821 }
822
823 model = gda_connection_statement_execute_select (cnc, stmt, NULL, &error);
824 if (!model) {
825 g_free (str);
826 number_failed ++;
827 goto out;
828 }
829 gda_data_model_dump (model, NULL);
830 if (gda_data_model_get_n_rows (model) != 1) {
831 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
832 "Data model should have exactly 1 row");
833 g_free (str);
834 number_failed ++;
835 goto out;
836 }
837 cvalue = gda_data_model_get_typed_value_at (model, 0, 0, G_TYPE_STRING, FALSE, &error);
838 if (!cvalue) {
839 g_free (str);
840 number_failed ++;
841 goto out;
842 }
843 if (strncmp (str, g_value_get_string (cvalue), 10)) { /* only compare date parts */
844 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
845 "Returned GdaDataHandler returned wrong result: '%s' and expected '%s'", str, g_value_get_string (cvalue));
846 g_free (str);
847 number_failed ++;
848 goto out;
849 }
850
851 out:
852 if (stmt)
853 g_object_unref (stmt);
854 if (params)
855 g_object_unref (params);
856 if (model)
857 g_object_unref (model);
858 g_object_unref (parser);
859
860 #ifdef CHECK_EXTRA_INFO
861 g_print ("Timestamp test resulted in %d error(s)\n", number_failed);
862 if (number_failed != 0)
863 g_print ("error: %s\n", error && error->message ? error->message : "No detail");
864 if (error)
865 g_error_free (error);
866 #endif
867
868 return number_failed;
869 }
870
871 static GValue *
value_new_date_from_timet(time_t val)872 value_new_date_from_timet (time_t val)
873 {
874 GValue *value;
875 GDate *date;
876 date = g_date_new ();
877 g_date_set_time_t (date, val);
878
879 value = gda_value_new (G_TYPE_DATE);
880 g_value_set_boxed (value, date);
881 g_date_free (date);
882
883 return value;
884 }
885
886 static gboolean
date_equal(const GValue * cv1,const GValue * cv2)887 date_equal (const GValue *cv1, const GValue *cv2)
888 {
889 g_assert (G_VALUE_TYPE (cv1) == G_TYPE_DATE);
890 g_assert (G_VALUE_TYPE (cv2) == G_TYPE_DATE);
891 const GDate *ts1, *ts2;
892 ts1 = (GDate*) g_value_get_boxed (cv1);
893 ts2 = (GDate*) g_value_get_boxed (cv2);
894 return g_date_compare (ts1, ts2) ? FALSE : TRUE;
895 }
896
897 int
prov_test_common_check_date(void)898 prov_test_common_check_date (void)
899 {
900 GdaSqlParser *parser = NULL;
901 GdaStatement *stmt = NULL;
902 GdaSet *params = NULL;
903 GError *error = NULL;
904 int number_failed = 0;
905 GdaDataModel *model = NULL;
906
907 #ifdef CHECK_EXTRA_INFO
908 g_print ("\n============= %s() =============\n", __FUNCTION__);
909 #endif
910
911 parser = gda_connection_create_parser (cnc);
912 if (!parser)
913 parser = gda_sql_parser_new ();
914
915 GValue *tso;
916 tso = value_new_date_from_timet (time (NULL));
917
918 /* insert date */
919 stmt = gda_sql_parser_parse_string (parser, "INSERT INTO datetest (thedate) VALUES (##thedate::date)", NULL, &error);
920 if (!stmt ||
921 ! gda_statement_get_parameters (stmt, ¶ms, &error) ||
922 ! gda_set_set_holder_value (params, &error, "thedate", (GDate*) g_value_get_boxed (tso)) ||
923 (gda_connection_statement_execute_non_select (cnc, stmt, params, NULL, &error) == -1)) {
924 number_failed ++;
925 goto out;
926 }
927
928 g_print ("Inserted date %s\n", gda_value_stringify (tso));
929
930 /* retreive date */
931 stmt = gda_sql_parser_parse_string (parser, "SELECT thedate FROM datetest", NULL, &error);
932 if (!stmt) {
933 number_failed ++;
934 goto out;
935 }
936
937 model = gda_connection_statement_execute_select (cnc, stmt, NULL, &error);
938 if (!model) {
939 number_failed ++;
940 goto out;
941 }
942 gda_data_model_dump (model, NULL);
943 if (gda_data_model_get_n_rows (model) != 1) {
944 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
945 "Data model should have exactly 1 row");
946 number_failed ++;
947 goto out;
948 }
949
950 const GValue *cvalue;
951 cvalue = gda_data_model_get_typed_value_at (model, 0, 0, G_TYPE_DATE, FALSE, &error);
952 if (!cvalue) {
953 number_failed ++;
954 goto out;
955 }
956 if (! date_equal (tso, cvalue)) {
957 gchar *tmpg, *tmpe;
958 tmpg = gda_value_stringify (cvalue);
959 tmpe = gda_value_stringify (tso);
960 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
961 "Retreived date differs from expected: got '%s' and expected '%s'", tmpg, tmpe);
962 g_free (tmpg);
963 g_free (tmpe);
964 number_failed ++;
965 goto out;
966 }
967
968 /* check that data handler is correctly configured: compare the same timestamp rendered by a data handler for
969 * timestamps with the date rendered as a string by the server (by appending a string to the timestamp field) */
970 GdaDataHandler *dh;
971 dh = gda_server_provider_get_data_handler_g_type (gda_connection_get_provider (cnc), cnc, G_TYPE_DATE);
972 gchar *str;
973 str = gda_data_handler_get_str_from_value (dh, cvalue);
974 g_object_unref (model);
975
976 stmt = gda_sql_parser_parse_string (parser, "SELECT thedate || 'asstring' FROM datetest", NULL, &error); /* retreive date as string */
977 if (!stmt) {
978 g_free (str);
979 number_failed ++;
980 goto out;
981 }
982
983 model = gda_connection_statement_execute_select (cnc, stmt, NULL, &error);
984 if (!model) {
985 g_free (str);
986 number_failed ++;
987 goto out;
988 }
989 gda_data_model_dump (model, NULL);
990 if (gda_data_model_get_n_rows (model) != 1) {
991 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
992 "Data model should have exactly 1 row");
993 g_free (str);
994 number_failed ++;
995 goto out;
996 }
997 cvalue = gda_data_model_get_typed_value_at (model, 0, 0, G_TYPE_STRING, FALSE, &error);
998 if (!cvalue) {
999 g_free (str);
1000 number_failed ++;
1001 goto out;
1002 }
1003 if (strncmp (str, g_value_get_string (cvalue), 10)) { /* only compare date parts */
1004 g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
1005 "Returned GdaDataHandler returned wrong result: '%s' and expected '%s'", str, g_value_get_string (cvalue));
1006 g_free (str);
1007 number_failed ++;
1008 goto out;
1009 }
1010
1011 out:
1012 if (stmt)
1013 g_object_unref (stmt);
1014 if (params)
1015 g_object_unref (params);
1016 if (model)
1017 g_object_unref (model);
1018 g_object_unref (parser);
1019
1020 #ifdef CHECK_EXTRA_INFO
1021 g_print ("Date test resulted in %d error(s)\n", number_failed);
1022 if (number_failed != 0)
1023 g_print ("error: %s\n", error && error->message ? error->message : "No detail");
1024 if (error)
1025 g_error_free (error);
1026 #endif
1027
1028 return number_failed;
1029 }
1030