1 /* 2 * Copyright (C) 2010 - 2012 Vivien Malerba <malerba@gnome-db.org> 3 * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com> 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 */ 19 #include <stdlib.h> 20 #include <string.h> 21 #include <glib.h> 22 #include <libgda/libgda.h> 23 #include <sql-parser/gda-sql-parser.h> 24 #include <sql-parser/gda-sql-statement.h> 25 #include <tests/gda-ddl-creator.h> 26 #include <glib/gstdio.h> 27 #include "../test-cnc-utils.h" 28 #include "../data-model-errors.h" 29 #include <virtual/libgda-virtual.h> 30 31 #define fail(x) g_warning (x) 32 #define fail_if(x,y) if (x) g_warning (y) 33 #define fail_unless(x,y) if (!(x)) g_warning (y) 34 35 #define CHECK_EXTRA_INFO 36 37 static void dump_data_model (GdaDataModel *model); 38 39 typedef gboolean (*TestFunc) (GdaConnection *); 40 static gint test1 (GdaConnection *cnc); 41 static gint test2 (GdaConnection *cnc); 42 43 TestFunc tests[] = { 44 test1, 45 test2 46 }; 47 48 int 49 main (int argc, char **argv) 50 { 51 guint i, ntests = 0, number_failed = 0; 52 53 gda_init (); 54 55 for (i = 0; i < sizeof (tests) / sizeof (TestFunc); i++) { 56 g_print ("---------- test %d ----------\n", i+1); 57 gint n = tests[i] (NULL); 58 number_failed += n; 59 if (n > 0) 60 g_print ("Test %d failed\n", i+1); 61 ntests ++; 62 } 63 64 g_print ("TESTS COUNT: %d\n", i); 65 g_print ("FAILURES: %d\n", number_failed); 66 67 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 68 } 69 70 /* Commented out because it is not used: 71 static GdaStatement * 72 stmt_from_string (const gchar *sql) 73 { 74 GdaStatement *stmt; 75 GError *error = NULL; 76 77 static GdaSqlParser *parser = NULL; 78 if (!parser) 79 parser = gda_sql_parser_new (); 80 81 stmt = gda_sql_parser_parse_string (parser, sql, NULL, &error); 82 if (!stmt) { 83 g_print ("Cound not parse SQL: %s\nSQL was: %s\n", 84 error && error->message ? error->message : "No detail", 85 sql); 86 exit (EXIT_FAILURE); 87 } 88 return stmt; 89 } 90 */ 91 92 static gboolean 93 check_iter_contents (GdaDataModel *model, GdaDataModelIter *iter) 94 { 95 gint i, row; 96 row = gda_data_model_iter_get_row (iter); 97 for (i = 0; i < gda_data_model_get_n_columns (model); i++) { 98 GdaHolder *holder; 99 const GValue *vi, *vm; 100 GError *lerror1 = NULL, *lerror2 = NULL; 101 102 holder = gda_set_get_nth_holder (GDA_SET (iter), i); 103 if (gda_holder_is_valid_e (holder, &lerror1)) 104 vi = gda_holder_get_value (holder); 105 else 106 vi = NULL; 107 vm = gda_data_model_get_value_at (model, i, row, &lerror2); 108 if (vi == vm) { 109 if (!vi) { 110 if (! lerror1 || !lerror1->message) { 111 #ifdef CHECK_EXTRA_INFO 112 g_print ("Iterator reported invalid value without any error set\n"); 113 #endif 114 return FALSE; 115 } 116 else if (! lerror2 || !lerror2->message) { 117 #ifdef CHECK_EXTRA_INFO 118 g_print ("Data model reported invalid value without any error set\n"); 119 #endif 120 return FALSE; 121 } 122 else if (lerror1->code != lerror2->code) { 123 #ifdef CHECK_EXTRA_INFO 124 g_print ("Error codes differ!\n"); 125 #endif 126 return FALSE; 127 } 128 else if (lerror1->domain != lerror2->domain) { 129 #ifdef CHECK_EXTRA_INFO 130 g_print ("Error domains differ!\n"); 131 #endif 132 return FALSE; 133 } 134 else if (strcmp (lerror1->message, lerror2->message)) { 135 #ifdef CHECK_EXTRA_INFO 136 g_print ("Error messages differ:\n\t%s\t%s", 137 lerror1->message, lerror2->message); 138 #endif 139 return FALSE; 140 } 141 } 142 else if (gda_value_differ (vi, vm)) { 143 #ifdef CHECK_EXTRA_INFO 144 g_print ("Iter's contents at (%d,%d) is wrong: expected [%s], got [%s]\n", 145 i, row, 146 vm ? gda_value_stringify (vm) : "ERROR", 147 vi ? gda_value_stringify (vi) : "ERROR"); 148 #endif 149 return FALSE; 150 } 151 } 152 else if (gda_value_differ (vi, vm)) { 153 #ifdef CHECK_EXTRA_INFO 154 g_print ("Iter's contents at (%d,%d) is wrong: expected [%s], got [%s]\n", 155 i, row, 156 vm ? gda_value_stringify (vm) : "ERROR", 157 vi ? gda_value_stringify (vi) : "ERROR"); 158 #endif 159 return FALSE; 160 } 161 } 162 return TRUE; 163 } 164 165 /* 166 * check modifications statements' setting 167 * 168 * Returns the number of failures 169 */ 170 static gint 171 test1 (GdaConnection *cnc) 172 { 173 GdaDataModel *model; 174 gint nfailed = 0; 175 176 model = data_model_errors_new (); 177 if (!model) { 178 nfailed++; 179 #ifdef CHECK_EXTRA_INFO 180 g_print ("Could not create DataModelErrors!\n"); 181 #endif 182 goto out; 183 } 184 dump_data_model (model); 185 186 /* iterate forward */ 187 GdaDataModelIter *iter; 188 gint i, row; 189 iter = gda_data_model_create_iter (model); 190 for (i = 0, gda_data_model_iter_move_next (iter); 191 gda_data_model_iter_is_valid (iter); 192 i++, gda_data_model_iter_move_next (iter)) { 193 row = gda_data_model_iter_get_row (iter); 194 if (i != row) { 195 nfailed++; 196 #ifdef CHECK_EXTRA_INFO 197 g_print ("Error iterating: expected to be at row %d and reported row is %d!\n", 198 i, row); 199 #endif 200 goto out; 201 } 202 g_print ("Now at row %d\n", i); 203 204 if (! check_iter_contents (model, iter)) { 205 nfailed++; 206 goto out; 207 } 208 } 209 g_print ("Now at row %d\n", gda_data_model_iter_get_row (iter)); 210 211 /* iterate backward */ 212 i--; 213 if (!gda_data_model_iter_move_to_row (iter, i)) { 214 nfailed++; 215 #ifdef CHECK_EXTRA_INFO 216 g_print ("Error iterating: move to last row (%d) failed\n", i); 217 #endif 218 goto out; 219 } 220 row = gda_data_model_iter_get_row (iter); 221 if (row != i) { 222 nfailed++; 223 #ifdef CHECK_EXTRA_INFO 224 g_print ("Error iterating: move to last row (%d) should have set row to %d and is set to %d\n", 225 i, i, row); 226 #endif 227 goto out; 228 } 229 for (; 230 gda_data_model_iter_is_valid (iter); 231 i--, gda_data_model_iter_move_prev (iter)) { 232 row = gda_data_model_iter_get_row (iter); 233 if (i != row) { 234 nfailed++; 235 #ifdef CHECK_EXTRA_INFO 236 g_print ("Error iterating: expected to be at row %d and reported row is %d!\n", 237 i, row); 238 #endif 239 goto out; 240 } 241 g_print ("Now at row %d\n", i); 242 243 if (! check_iter_contents (model, iter)) { 244 nfailed++; 245 goto out; 246 } 247 } 248 g_print ("Now at row %d\n", gda_data_model_iter_get_row (iter)); 249 250 out: 251 g_object_unref (model); 252 253 return nfailed; 254 } 255 256 static void 257 dump_data_model (GdaDataModel *model) 258 { 259 gint i, ncols; 260 g_print ("=== Data Model Dump ===\n"); 261 ncols = gda_data_model_get_n_columns (model); 262 for (i = 0; i < ncols; i++) { 263 GdaColumn *col; 264 col = gda_data_model_describe_column (model, i); 265 if (!col) 266 g_print ("Missing column %d\n", i); 267 g_print ("Column %d: ptr=>%p type=>%s\n", i, col, g_type_name (gda_column_get_g_type (col))); 268 } 269 gda_data_model_dump (model, stdout); 270 } 271 272 /* Commented out because it is not used. 273 static gboolean 274 compare_data_models (GdaDataModel *model1, GdaDataModel *model2, GError **error) 275 { 276 GdaDataComparator *cmp; 277 GError *lerror = NULL; 278 cmp = (GdaDataComparator*) gda_data_comparator_new (model1, model2); 279 if (! gda_data_comparator_compute_diff (cmp, &lerror)) { 280 #ifdef CHECK_EXTRA_INFO 281 g_print ("Could not compute the data model differences: %s\n", 282 lerror && lerror->message ? lerror->message : "No detail"); 283 g_print ("Model1 is:\n"); 284 gda_data_model_dump (model1, stdout); 285 g_print ("Model2 is:\n"); 286 gda_data_model_dump (model2, stdout); 287 #endif 288 goto onerror; 289 } 290 if (gda_data_comparator_get_n_diffs (cmp) != 0) { 291 #ifdef CHECK_EXTRA_INFO 292 g_print ("There are some differences when comparing data models...\n"); 293 g_print ("Model1 is:\n"); 294 gda_data_model_dump (model1, stdout); 295 g_print ("Model2 is:\n"); 296 gda_data_model_dump (model2, stdout); 297 #endif 298 g_set_error (&lerror, TEST_ERROR, TEST_ERROR_GENERIC, 299 "%s", "There are some differences when comparing data models..."); 300 goto onerror; 301 } 302 g_object_unref (cmp); 303 304 return TRUE; 305 306 onerror: 307 g_propagate_error (error, lerror); 308 return FALSE; 309 } 310 */ 311 312 /* 313 * check modifications statements' setting 314 * 315 * Returns the number of failures 316 */ 317 static gint 318 test2 (GdaConnection *cnc) 319 { 320 #define TABLE_NAME "data" 321 GdaDataModel *model; 322 gint nfailed = 0; 323 324 model = data_model_errors_new (); 325 if (!model) { 326 nfailed++; 327 #ifdef CHECK_EXTRA_INFO 328 g_print ("Could not create DataModelErrors!\n"); 329 #endif 330 goto out; 331 } 332 333 GdaVirtualProvider *virtual_provider; 334 GError *lerror = NULL; 335 GdaConnection *vcnc; 336 GdaDataModelIter *iter = NULL; 337 GdaStatement *stmt; 338 virtual_provider = gda_vprovider_data_model_new (); 339 vcnc = gda_virtual_connection_open (virtual_provider, &lerror); 340 if (!vcnc) { 341 #ifdef CHECK_EXTRA_INFO 342 g_print ("Virtual ERROR: %s\n", lerror && lerror->message ? lerror->message : "No detail"); 343 #endif 344 nfailed++; 345 g_clear_error (&lerror); 346 goto out; 347 } 348 349 if (!gda_vconnection_data_model_add_model (GDA_VCONNECTION_DATA_MODEL (vcnc), model, 350 TABLE_NAME, &lerror)) { 351 #ifdef CHECK_EXTRA_INFO 352 g_print ("Add model as table ERROR: %s\n", lerror && lerror->message ? lerror->message : "No detail"); 353 #endif 354 nfailed++; 355 g_clear_error (&lerror); 356 goto out; 357 } 358 g_object_unref (model); 359 360 /* Execute SELECT */ 361 stmt = gda_connection_parse_sql_string (vcnc, "SELECT * FROM " TABLE_NAME, NULL, NULL); 362 g_assert (stmt); 363 model = gda_connection_statement_execute_select (vcnc, stmt, NULL, &lerror); 364 g_object_unref (stmt); 365 if (!model) { 366 #ifdef CHECK_EXTRA_INFO 367 g_print ("SELECT ERROR: %s\n", lerror && lerror->message ? lerror->message : "No detail"); 368 #endif 369 nfailed++; 370 g_clear_error (&lerror); 371 goto out; 372 } 373 374 dump_data_model (model); 375 376 /* iterate forward */ 377 gint i, row; 378 iter = gda_data_model_create_iter (model); 379 for (i = 0, gda_data_model_iter_move_next (iter); 380 gda_data_model_iter_is_valid (iter); 381 i++, gda_data_model_iter_move_next (iter)) { 382 row = gda_data_model_iter_get_row (iter); 383 if (i != row) { 384 nfailed++; 385 #ifdef CHECK_EXTRA_INFO 386 g_print ("Error iterating: expected to be at row %d and reported row is %d!\n", 387 i, row); 388 #endif 389 goto out; 390 } 391 g_print ("Now at row %d\n", i); 392 393 if (! check_iter_contents (model, iter)) { 394 nfailed++; 395 goto out; 396 } 397 } 398 if (i != 4) { 399 #ifdef CHECK_EXTRA_INFO 400 g_print ("Error iterating: expected to have read %d rows, and read %d\n", 3, 401 i - 1); 402 nfailed++; 403 goto out; 404 #endif 405 } 406 if (gda_data_model_iter_get_row (iter) != -1) { 407 #ifdef CHECK_EXTRA_INFO 408 g_print ("Error iterating: expected to be at row -1 and reported row is %d!\n", 409 gda_data_model_iter_get_row (iter)); 410 #endif 411 nfailed++; 412 goto out; 413 } 414 415 /* bind as another table */ 416 if (!gda_vconnection_data_model_add_model (GDA_VCONNECTION_DATA_MODEL (vcnc), model, 417 TABLE_NAME "2", &lerror)) { 418 #ifdef CHECK_EXTRA_INFO 419 g_print ("Add model as table2 ERROR: %s\n", lerror && lerror->message ? lerror->message : "No detail"); 420 #endif 421 nfailed++; 422 g_clear_error (&lerror); 423 goto out; 424 } 425 g_object_unref (model); 426 427 stmt = gda_connection_parse_sql_string (vcnc, "SELECT * FROM " TABLE_NAME "2", NULL, NULL); 428 g_assert (stmt); 429 model = gda_connection_statement_execute_select (vcnc, stmt, NULL, &lerror); 430 g_object_unref (stmt); 431 if (!model) { 432 #ifdef CHECK_EXTRA_INFO 433 g_print ("SELECT ERROR: %s\n", lerror && lerror->message ? lerror->message : "No detail"); 434 #endif 435 nfailed++; 436 g_clear_error (&lerror); 437 goto out; 438 } 439 440 /* iterate forward */ 441 iter = gda_data_model_create_iter (model); 442 for (i = 0, gda_data_model_iter_move_next (iter); 443 gda_data_model_iter_is_valid (iter); 444 i++, gda_data_model_iter_move_next (iter)) { 445 row = gda_data_model_iter_get_row (iter); 446 if (i != row) { 447 nfailed++; 448 #ifdef CHECK_EXTRA_INFO 449 g_print ("Error iterating: expected to be at row %d and reported row is %d!\n", 450 i, row); 451 #endif 452 goto out; 453 } 454 g_print ("Now at row %d\n", i); 455 456 if (! check_iter_contents (model, iter)) { 457 nfailed++; 458 goto out; 459 } 460 } 461 if (i != 4) { 462 #ifdef CHECK_EXTRA_INFO 463 g_print ("Error iterating: expected to have read %d rows, and read %d\n", 3, 464 i - 1); 465 nfailed++; 466 goto out; 467 #endif 468 } 469 if (gda_data_model_iter_get_row (iter) != -1) { 470 #ifdef CHECK_EXTRA_INFO 471 g_print ("Error iterating: expected to be at row -1 and reported row is %d!\n", 472 gda_data_model_iter_get_row (iter)); 473 #endif 474 nfailed++; 475 goto out; 476 } 477 478 out: 479 if (iter) 480 g_object_unref (iter); 481 if (model) 482 g_object_unref (model); 483 g_object_unref (vcnc); 484 g_object_unref (virtual_provider); 485 486 return nfailed; 487 } 488