1 /* 2 * Copyright (C) 2010 Claude Paroz <claude@2xlibre.net> 3 * Copyright (C) 2010 David King <davidk@openismus.com> 4 * Copyright (C) 2010 Murray Cumming <murrayc@murrayc.com> 5 * Copyright (C) 2010 - 2012 Vivien Malerba <malerba@gnome-db.org> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 */ 21 22 #include <string.h> 23 #include <glib/gi18n-lib.h> 24 #include "browser-connection.h" 25 #include <libgda/thread-wrapper/gda-thread-wrapper.h> 26 #include "support.h" 27 #include "marshal.h" 28 #include <sql-parser/gda-sql-parser.h> 29 #include <libgda/gda-data-model-extra.h> 30 #include <libgda/gda-sql-builder.h> 31 #include "../common/ui-formgrid.h" 32 #include "../../tool-utils.h" main(int,char **)33 34 #include "data-source.h" 35 #define DEFAULT_DATA_SOURCE_NAME "DataSource" 36 #define DEPENDENCY_SEPARATOR "<|>" 37 38 /* signals */ 39 enum { 40 CHANGED, 41 EXEC_STARTED, 42 EXEC_FINISHED, 43 LAST_SIGNAL 44 }; 45 46 gint data_source_signals [LAST_SIGNAL] = {0, 0, 0}; 47 48 /* 49 * Main static functions 50 */ 51 static void data_source_class_init (DataSourceClass *klass); 52 static void data_source_init (DataSource *source); 53 static void data_source_dispose (GObject *object); 54 55 56 static void update_export_information (DataSource *source); 57 static void compute_stmt_and_params (DataSource *source); 58 static void compute_import_params (DataSource *source); 59 60 61 /* get a pointer to the parents to be able to call their destructor */ 62 static GObjectClass *parent_class = NULL; 63 64 typedef struct { 65 gchar *dep_id; 66 gchar *dep_table; 67 gchar *dep_columns; /* column names, separated by a |, sorted */ 68 } Dependency; 69 70 static void 71 dependency_free (Dependency *dep) 72 { 73 g_free (dep->dep_id); 74 g_free (dep->dep_table); 75 g_free (dep->dep_columns); 76 g_free (dep); 77 } 78 79 /* 80 * converts an array of column names into a single string in the format: 81 * <colname>[SEP<colname>...] where SEP is DEPENDENCY_SEPARATOR 82 * 83 * Returns: a new string, never %NULL 84 */ 85 static gchar * 86 column_names_to_string (gint size, const gchar **colnames) 87 { 88 if (!colnames) 89 return g_strdup (""); 90 91 GString *string = NULL; 92 GArray *colsarray; 93 gint i; 94 colsarray = g_array_new (FALSE, FALSE, sizeof (gchar*)); 95 for (i = 0; i < size; i++) 96 g_array_append_val (colsarray, colnames[i]); 97 g_array_sort (colsarray, (GCompareFunc) g_strcmp0); 98 for (i = 0; i < size; i++) { 99 gchar *tmp; 100 tmp = g_array_index (colsarray, gchar *, i); 101 if (!string) 102 string = g_string_new (tmp); 103 else { 104 g_string_append (string, DEPENDENCY_SEPARATOR); 105 g_string_append (string, tmp); 106 } 107 } 108 g_array_free (colsarray, TRUE); 109 return g_string_free (string, FALSE); 110 } 111 112 static Dependency * 113 dependency_find (GSList *dep_list, const gchar *id, const gchar *table, gint size, const gchar **colnames) 114 { 115 GSList *list; 116 gchar *colsstring = NULL; 117 for (list = dep_list; list; list = list->next) { 118 Dependency *dep = (Dependency*) list->data; 119 if (strcmp (dep->dep_id, id) || strcmp (dep->dep_table, table)) 120 continue; 121 122 if (!colsstring) 123 colsstring = column_names_to_string (size, colnames); 124 if (!strcmp (colsstring, dep->dep_columns)) { 125 g_free (colsstring); 126 return dep; 127 } 128 } 129 g_free (colsstring); 130 return NULL; 131 } 132 133 struct _DataSourcePrivate { 134 BrowserConnection *bcnc; 135 gchar *title; 136 gchar *impl_title; 137 gchar *id; 138 DataSourceType source_type; 139 140 GError *init_error; 141 GArray *export_names; /* array of strings, memory allocated in export_columns */ 142 GHashTable *export_columns; /* key = export name, value = column number */ 143 144 guint exec_id; 145 gboolean executing; 146 gboolean exec_again; 147 148 gchar *tablename; 149 GdaSqlBuilder *builder; 150 GSList *dependencies; /* list of Dependency pointers */ 151 152 GdaStatement *stmt; 153 GdaSet *ext_params; /* "free" parameters */ 154 GdaSet *params; /* all the params used when executing @stmt */ 155 gboolean need_rerun; /* set to %TRUE if @params has changed since the last exec */ 156 157 GError *exec_error; 158 159 GdaDataModel *model; 160 }; 161 162 GType 163 data_source_get_type (void) 164 { 165 static GType type = 0; 166 167 if (G_UNLIKELY (type == 0)) { 168 static GMutex registering; 169 static const GTypeInfo info = { 170 sizeof (DataSourceClass), 171 (GBaseInitFunc) NULL, 172 (GBaseFinalizeFunc) NULL, 173 (GClassInitFunc) data_source_class_init, 174 NULL, 175 NULL, 176 sizeof (DataSource), 177 0, 178 (GInstanceInitFunc) data_source_init, 179 0 180 }; 181 182 183 g_mutex_lock (®istering); 184 if (type == 0) 185 type = g_type_register_static (G_TYPE_OBJECT, "DataSource", &info, 0); 186 g_mutex_unlock (®istering); 187 } 188 return type; 189 } 190 191 static void 192 data_source_class_init (DataSourceClass *klass) 193 { 194 GObjectClass *object_class = G_OBJECT_CLASS (klass); 195 parent_class = g_type_class_peek_parent (klass); 196 197 /* signals */ 198 data_source_signals [CHANGED] = 199 g_signal_new ("changed", 200 G_TYPE_FROM_CLASS (object_class), 201 G_SIGNAL_RUN_FIRST, 202 G_STRUCT_OFFSET (DataSourceClass, changed), 203 NULL, NULL, 204 _dm_marshal_VOID__VOID, G_TYPE_NONE, 0); 205 data_source_signals [EXEC_STARTED] = 206 g_signal_new ("execution-started", 207 G_TYPE_FROM_CLASS (object_class), 208 G_SIGNAL_RUN_FIRST, 209 G_STRUCT_OFFSET (DataSourceClass, execution_started), 210 NULL, NULL, 211 _dm_marshal_VOID__VOID, G_TYPE_NONE, 0); 212 data_source_signals [EXEC_FINISHED] = 213 g_signal_new ("execution-finished", 214 G_TYPE_FROM_CLASS (object_class), 215 G_SIGNAL_RUN_FIRST, 216 G_STRUCT_OFFSET (DataSourceClass, execution_finished), 217 NULL, NULL, 218 _dm_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); 219 klass->changed = NULL; 220 klass->execution_started = NULL; 221 klass->execution_finished = NULL; 222 223 object_class->dispose = data_source_dispose; 224 } 225 226 static void 227 data_source_init (DataSource *source) 228 { 229 source->priv = g_new0 (DataSourcePrivate, 1); 230 source->priv->id = g_strdup (DEFAULT_DATA_SOURCE_NAME); 231 source->priv->bcnc = NULL; 232 source->priv->source_type = DATA_SOURCE_UNKNOWN; 233 source->priv->need_rerun = FALSE; 234 source->priv->exec_id = 0; 235 source->priv->executing = FALSE; 236 source->priv->exec_again = FALSE; 237 } 238 239 static void 240 params_changed_cb (G_GNUC_UNUSED GdaSet *params, G_GNUC_UNUSED GdaHolder *holder, DataSource *source) 241 { 242 source->priv->need_rerun = TRUE; 243 } 244 245 static void 246 ext_params_changed_cb (G_GNUC_UNUSED GdaSet *params, G_GNUC_UNUSED GdaHolder *holder, DataSource *source) 247 { 248 #ifdef DEBUG_SOURCE 249 g_print (" => data source [%s] should rerun\n", 250 data_source_get_title (source)); 251 #endif 252 source->priv->need_rerun = TRUE; 253 } 254 255 static void 256 data_source_reset (DataSource *source) 257 { 258 source->priv->source_type = DATA_SOURCE_UNKNOWN; 259 g_clear_error (& source->priv->init_error); 260 261 if (source->priv->builder) { 262 g_object_unref (source->priv->builder); 263 source->priv->builder = NULL; 264 } 265 if (source->priv->stmt) { 266 g_object_unref (source->priv->stmt); 267 source->priv->stmt = NULL; 268 } 269 if (source->priv->params) { 270 g_signal_handlers_disconnect_by_func (source->priv->params, 271 G_CALLBACK (params_changed_cb), source); 272 g_object_unref (source->priv->params); 273 source->priv->params = NULL; 274 } 275 if (source->priv->ext_params) { 276 g_signal_handlers_disconnect_by_func (source->priv->ext_params, 277 G_CALLBACK (ext_params_changed_cb), 278 source); 279 g_object_unref (source->priv->ext_params); 280 source->priv->ext_params = NULL; 281 } 282 283 if (source->priv->tablename) { 284 g_free (source->priv->tablename); 285 source->priv->tablename = NULL; 286 } 287 288 if (source->priv->dependencies) { 289 g_slist_foreach (source->priv->dependencies, (GFunc) dependency_free, NULL); 290 g_slist_free (source->priv->dependencies); 291 source->priv->dependencies = NULL; 292 } 293 294 if (source->priv->model) { 295 g_object_unref (source->priv->model); 296 source->priv->model = NULL; 297 } 298 299 if (source->priv->export_names) { 300 g_array_free (source->priv->export_names, TRUE); 301 source->priv->export_names = NULL; 302 } 303 304 if (source->priv->export_columns) { 305 g_hash_table_destroy (source->priv->export_columns); 306 source->priv->export_columns = NULL; 307 } 308 } 309 310 static void 311 data_source_dispose (GObject *object) 312 { 313 DataSource *source; 314 315 g_return_if_fail (object != NULL); 316 g_return_if_fail (IS_DATA_SOURCE (object)); 317 318 source = DATA_SOURCE (object); 319 if (source->priv) { 320 if (source->priv->bcnc) 321 g_object_unref (source->priv->bcnc); 322 data_source_reset (source); 323 g_free (source->priv->id); 324 g_free (source->priv->title); 325 g_free (source->priv->impl_title); 326 327 g_free (source->priv); 328 source->priv = NULL; 329 } 330 331 /* parent class */ 332 parent_class->dispose (object); 333 } 334 335 static void init_from_query (DataSource *source, xmlNodePtr node); 336 static gboolean init_from_table_node (DataSource *source, xmlNodePtr node, GError **error); 337 338 /** 339 * data_source_new 340 * @bcnc: a #BrowserConnection 341 * @type: the new data source's requested type 342 * 343 * Returns: a new #DataSource object 344 */ 345 DataSource * 346 data_source_new (BrowserConnection *bcnc, DataSourceType type) 347 { 348 DataSource *source; 349 350 g_return_val_if_fail (BROWSER_IS_CONNECTION (bcnc), NULL); 351 352 source = DATA_SOURCE (g_object_new (DATA_SOURCE_TYPE, NULL)); 353 source->priv->bcnc = g_object_ref (bcnc); 354 source->priv->source_type = type; 355 356 return source; 357 } 358 359 /** 360 * data_source_new_from_xml_node 361 * @bcnc: a #BrowserConnection 362 * @node: 363 * @error: 364 * 365 * Creates a new #DataSource object 366 * 367 * Returns: a new object 368 */ 369 DataSource* 370 data_source_new_from_xml_node (BrowserConnection *bcnc, xmlNodePtr node, GError **error) 371 { 372 DataSource *source; 373 374 g_return_val_if_fail (BROWSER_IS_CONNECTION (bcnc), NULL); 375 g_return_val_if_fail (node, NULL); 376 377 source = DATA_SOURCE (g_object_new (DATA_SOURCE_TYPE, NULL)); 378 source->priv->bcnc = g_object_ref (bcnc); 379 xmlChar *prop; 380 prop = xmlGetProp (node, BAD_CAST "title"); 381 if (prop) { 382 g_free (source->priv->title); 383 source->priv->title = g_strdup ((gchar*) prop); 384 xmlFree (prop); 385 } 386 prop = xmlGetProp (node, BAD_CAST "id"); 387 if (prop) { 388 g_free (source->priv->id); 389 source->priv->id = g_strdup ((gchar*) prop); 390 xmlFree (prop); 391 } 392 393 if (!strcmp ((gchar*)node->name, "table")) { 394 if (! init_from_table_node (source, node, error)) { 395 g_object_unref (source); 396 source = NULL; 397 } 398 } 399 else if (!strcmp ((gchar*)node->name, "query")) { 400 init_from_query (source, node); 401 } 402 else { 403 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_COMMAND_ARGUMENTS_ERROR, 404 /* Translators: Do not translate "table" nor "query" */ 405 _("Node must be \"table\" or \"query\", and is \"%s\""), (gchar*)node->name); 406 g_object_unref (source); 407 source = NULL; 408 } 409 410 return source; 411 } 412 413 static void 414 init_from_query (DataSource *source, xmlNodePtr node) 415 { 416 xmlChar *contents; 417 418 #ifdef DEBUG_SOURCE 419 g_print ("%s(%s [%s])\n", __FUNCTION__, source->priv->id, source->priv->title); 420 #endif 421 contents = xmlNodeGetContent (node); 422 g_clear_error (& source->priv->init_error); 423 data_source_set_query (source, (gchar*) contents, &source->priv->init_error); 424 } 425 426 static GdaMetaTable * 427 get_meta_table (DataSource *source, const gchar *table_name, GError **error) 428 { 429 GdaMetaStruct *mstruct; 430 GdaMetaDbObject *dbo; 431 GValue *vname[3] = {NULL, NULL, NULL}; 432 gchar **split; 433 gint len; 434 435 mstruct = browser_connection_get_meta_struct (source->priv->bcnc); 436 if (! mstruct) { 437 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_STORED_DATA_ERROR, 438 "%s", _("Not ready")); 439 return NULL; 440 } 441 442 split = gda_sql_identifier_split (table_name); 443 if (! split) { 444 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_COMMAND_ARGUMENTS_ERROR, 445 _("Malformed table name \"%s\""), table_name); 446 return NULL; 447 } 448 len = g_strv_length (split); 449 g_value_set_string ((vname[2] = gda_value_new (G_TYPE_STRING)), split[len - 1]); 450 if (len > 1) 451 g_value_set_string ((vname[1] = gda_value_new (G_TYPE_STRING)), split[len -2]); 452 if (len > 2) 453 g_value_set_string ((vname[0] = gda_value_new (G_TYPE_STRING)), split[len - 3]); 454 455 dbo = gda_meta_struct_get_db_object (mstruct, vname[0], vname[1], vname[2]); 456 if (vname[0]) gda_value_free (vname[0]); 457 if (vname[1]) gda_value_free (vname[1]); 458 if (vname[2]) gda_value_free (vname[2]); 459 460 if (! dbo) { 461 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_INTERNAL_COMMAND_ERROR, 462 _("Could not find the \"%s\" table"), table_name); 463 return NULL; 464 } 465 if ((dbo->obj_type != GDA_META_DB_TABLE) && (dbo->obj_type != GDA_META_DB_VIEW)) { 466 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_INTERNAL_COMMAND_ERROR, 467 _("The \"%s\" object is not a table"), table_name); 468 return NULL; 469 } 470 return GDA_META_TABLE (dbo); 471 } 472 473 static gboolean 474 init_from_table_node (DataSource *source, xmlNodePtr node, GError **error) 475 { 476 xmlChar *tname; 477 gboolean retval; 478 479 #ifdef DEBUG_SOURCE 480 g_print ("%s(%s [%s])\n", __FUNCTION__, source->priv->id, source->priv->title); 481 #endif 482 tname = xmlGetProp (node, BAD_CAST "name"); 483 if (!tname) { 484 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_COMMAND_ARGUMENTS_ERROR, 485 /* Translators: Do not translate "name" */ 486 "%s", _("Missing attribute \"name\" for table")); 487 return FALSE; 488 } 489 490 retval = data_source_set_table (source, (gchar*) tname, error); 491 xmlFree (tname); 492 493 /* linking */ 494 xmlNodePtr subnode; 495 for (subnode = node->children; subnode; subnode = subnode->next) { 496 if (!strcmp ((gchar*)subnode->name, "depend")) { 497 xmlChar *fk_table, *id; 498 GArray *cols_array = NULL; 499 xmlNodePtr chnode; 500 501 fk_table = xmlGetProp (subnode, BAD_CAST "foreign_key_table"); 502 id = xmlGetProp (subnode, BAD_CAST "id"); 503 for (chnode = subnode->children; chnode; chnode = chnode->next) { 504 xmlChar *colname; 505 if (strcmp ((gchar*)chnode->name, "column")) 506 continue; 507 colname = xmlNodeGetContent (chnode); 508 if (colname) { 509 if (! cols_array) 510 cols_array = g_array_new (FALSE, FALSE, sizeof (gchar*)); 511 g_array_append_val (cols_array, colname); 512 } 513 } 514 515 if (fk_table && 516 ! data_source_add_dependency (source, (gchar *) fk_table, (gchar*) id, 517 cols_array ? cols_array->len : 0, 518 (const gchar **) (cols_array ? cols_array->data : NULL), 519 error)) 520 retval = FALSE; 521 if (fk_table) 522 xmlFree (fk_table); 523 if (id) 524 xmlFree (id); 525 if (cols_array) { 526 gsize i; 527 for (i = 0; i < cols_array->len; i++) { 528 xmlChar *colname; 529 colname = g_array_index (cols_array, xmlChar*, i); 530 xmlFree (colname); 531 } 532 g_array_free (cols_array, TRUE); 533 } 534 break; 535 } 536 } 537 538 return retval; 539 } 540 541 /** 542 * data_source_add_dependency 543 * @source: a #DataSource 544 * @table: the name of the referenced table 545 * @id: (allow-none): the ID of the referenced data source, or %NULL if its ID is the same as the table name 546 * @col_name_size: the size of @col_names 547 * @col_names: (allow-none): names of the FK columns involved in the foreign key, or %NULL 548 * @error: a place to store errors, or %NULL 549 * 550 * Adds a dependency on the @table table, only for DATA_SOURCE_TABLE sources 551 */ 552 gboolean 553 data_source_add_dependency (DataSource *source, const gchar *table, 554 const char *id, gint col_name_size, const gchar **col_names, 555 GError **error) 556 { 557 g_return_val_if_fail (IS_DATA_SOURCE (source), FALSE); 558 g_return_val_if_fail (table && *table, FALSE); 559 g_return_val_if_fail (source->priv->source_type == DATA_SOURCE_TABLE, FALSE); 560 g_return_val_if_fail (source->priv->builder, FALSE); 561 562 if (dependency_find (source->priv->dependencies, id ? id : table, table, col_name_size, col_names)) 563 return TRUE; 564 565 GdaMetaTable *mtable, *mlinked; 566 mtable = get_meta_table (source, source->priv->tablename, error); 567 if (!mtable) 568 return FALSE; 569 570 mlinked = get_meta_table (source, table, error); 571 if (!mlinked) 572 return FALSE; 573 574 /* find foreign key to linked table */ 575 GdaMetaTableForeignKey *fk = NULL; 576 GSList *list; 577 gboolean reverse = FALSE; 578 for (list = mtable->fk_list; list; list = list->next) { 579 if (GDA_META_TABLE_FOREIGN_KEY (list->data)->depend_on == GDA_META_DB_OBJECT (mlinked)) { 580 fk = GDA_META_TABLE_FOREIGN_KEY (list->data); 581 if (col_names && (col_name_size == fk->cols_nb)) { 582 gint i; 583 for (i = 0; i < col_name_size; i++) { 584 gint j; 585 for (j = 0; j < col_name_size; j++) { 586 if (!strcmp (col_names [i], fk->fk_names_array [j])) 587 break; 588 } 589 if (j == col_name_size) { 590 fk = NULL; /* not this FK */ 591 break; 592 } 593 } 594 } 595 if (fk) 596 break; 597 } 598 } 599 if (!fk) { 600 for (list = mlinked->fk_list; list; list = list->next) { 601 if (GDA_META_TABLE_FOREIGN_KEY (list->data)->depend_on == GDA_META_DB_OBJECT (mtable)) { 602 fk = GDA_META_TABLE_FOREIGN_KEY (list->data); 603 reverse = TRUE; 604 if (col_names && (col_name_size == fk->cols_nb)) { 605 gint i; 606 for (i = 0; i < col_name_size; i++) { 607 gint j; 608 for (j = 0; j < col_name_size; j++) { 609 if (!strcmp (col_names [i], 610 fk->fk_names_array [j])) 611 break; 612 } 613 if (j == col_name_size) { 614 fk = NULL; /* not this FK */ 615 break; 616 } 617 } 618 } 619 if (fk) 620 break; 621 } 622 } 623 } 624 if (!fk) { 625 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_INTERNAL_COMMAND_ERROR, 626 _("Could not find any foreign key to \"%s\""), table); 627 return FALSE; 628 } 629 else if (fk->cols_nb <= 0) { 630 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_INTERNAL_COMMAND_ERROR, 631 _("The fields involved in the foreign key to \"%s\" are not known"), 632 table); 633 return FALSE; 634 } 635 else if (fk->cols_nb == 1) { 636 gchar *tmp; 637 GdaMetaTableColumn *col; 638 GdaSqlBuilderId id1, id2, id_cond; 639 if (reverse) { 640 id1 = gda_sql_builder_add_id (source->priv->builder, fk->ref_pk_names_array [0]); 641 tmp = g_strdup_printf ("%s@%s", id ? id : table, fk->fk_names_array [0]); 642 643 col = GDA_META_TABLE_COLUMN (g_slist_nth_data (mlinked->columns, 644 fk->fk_cols_array [0] - 1)); 645 g_assert (col); 646 id2 = gda_sql_builder_add_param (source->priv->builder, tmp, col->gtype, FALSE); 647 g_free (tmp); 648 } 649 else { 650 id1 = gda_sql_builder_add_id (source->priv->builder, fk->fk_names_array [0]); 651 tmp = g_strdup_printf ("%s@%s", id ? id : table, fk->ref_pk_names_array [0]); 652 653 col = GDA_META_TABLE_COLUMN (g_slist_nth_data (mlinked->columns, 654 fk->ref_pk_cols_array [0] - 1)); 655 g_assert (col); 656 id2 = gda_sql_builder_add_param (source->priv->builder, tmp, col->gtype, FALSE); 657 g_free (tmp); 658 id_cond = gda_sql_builder_add_cond (source->priv->builder, 659 GDA_SQL_OPERATOR_TYPE_EQ, 660 id1, id2, 0); 661 } 662 id_cond = gda_sql_builder_add_cond (source->priv->builder, 663 GDA_SQL_OPERATOR_TYPE_EQ, 664 id1, id2, 0); 665 gda_sql_builder_set_where (source->priv->builder, id_cond); 666 } 667 else { 668 gchar *tmp; 669 gint i; 670 GdaMetaTableColumn *col; 671 GdaSqlBuilderId andid; 672 GdaSqlBuilderId *op_ids; 673 GdaSqlBuilderId id1, id2; 674 op_ids = g_new (GdaSqlBuilderId, fk->cols_nb); 675 676 for (i = 0; i < fk->cols_nb; i++) { 677 if (reverse) { 678 id1 = gda_sql_builder_add_id (source->priv->builder, fk->ref_pk_names_array [i]); 679 tmp = g_strdup_printf ("%s@%s", id ? id : table, fk->fk_names_array [i]); 680 681 col = GDA_META_TABLE_COLUMN (g_slist_nth_data (mlinked->columns, 682 fk->fk_cols_array [i] - 1)); 683 g_assert (col); 684 id2 = gda_sql_builder_add_param (source->priv->builder, tmp, col->gtype, FALSE); 685 g_free (tmp); 686 } 687 else { 688 id1 = gda_sql_builder_add_id (source->priv->builder, fk->fk_names_array [i]); 689 tmp = g_strdup_printf ("%s@%s", id ? id : table, fk->ref_pk_names_array [i]); 690 691 col = GDA_META_TABLE_COLUMN (g_slist_nth_data (mlinked->columns, 692 fk->ref_pk_cols_array [i] - 1)); 693 g_assert (col); 694 id2 = gda_sql_builder_add_param (source->priv->builder, tmp, col->gtype, FALSE); 695 g_free (tmp); 696 } 697 op_ids [i] = gda_sql_builder_add_cond (source->priv->builder, 698 GDA_SQL_OPERATOR_TYPE_EQ, 699 id1, id2, 0); 700 } 701 andid = gda_sql_builder_add_cond_v (source->priv->builder, GDA_SQL_OPERATOR_TYPE_AND, 702 op_ids, fk->cols_nb); 703 g_free (op_ids); 704 gda_sql_builder_set_where (source->priv->builder, andid); 705 } 706 707 Dependency *dep = g_new0 (Dependency, 1); 708 dep->dep_id = g_strdup (id ? id : table); 709 dep->dep_table = g_strdup (table); 710 dep->dep_columns = column_names_to_string (col_name_size, col_names); 711 source->priv->dependencies = g_slist_append (source->priv->dependencies, dep); 712 713 compute_stmt_and_params (source); 714 return TRUE; 715 } 716 717 718 /** 719 * data_source_to_xml_node 720 */ 721 xmlNodePtr 722 data_source_to_xml_node (DataSource *source) 723 { 724 xmlNodePtr node = NULL; 725 g_return_val_if_fail (IS_DATA_SOURCE (source), NULL); 726 switch (source->priv->source_type) { 727 case DATA_SOURCE_TABLE: 728 node = xmlNewNode (NULL, BAD_CAST "table"); 729 if (g_strcmp0 (source->priv->id, source->priv->tablename)) 730 xmlSetProp (node, BAD_CAST "id", BAD_CAST source->priv->id); 731 if (source->priv->title && g_strcmp0 (source->priv->title, source->priv->tablename)) 732 xmlSetProp (node, BAD_CAST "title", BAD_CAST source->priv->title); 733 xmlSetProp (node, BAD_CAST "name", 734 BAD_CAST (source->priv->tablename ? source->priv->tablename : "")); 735 736 if (source->priv->dependencies) { 737 GSList *list; 738 for (list = source->priv->dependencies; list; list = list->next) { 739 Dependency *dep = (Dependency*) list->data; 740 xmlNodePtr depnode; 741 depnode = xmlNewChild (node, NULL, BAD_CAST "depend", NULL); 742 xmlSetProp (depnode, BAD_CAST "foreign_key_table", 743 BAD_CAST (dep->dep_table)); 744 xmlSetProp (depnode, BAD_CAST "id", 745 BAD_CAST (dep->dep_id)); 746 747 gchar **array; 748 gint i; 749 array = g_strsplit (dep->dep_columns, DEPENDENCY_SEPARATOR, 0); 750 for (i = 0; array[i]; i++) 751 xmlNewChild (depnode, NULL, BAD_CAST "column", BAD_CAST (array[i])); 752 g_strfreev (array); 753 } 754 } 755 break; 756 case DATA_SOURCE_SELECT: { 757 node = xmlNewNode (NULL, BAD_CAST "query"); 758 xmlSetProp (node, BAD_CAST "id", BAD_CAST source->priv->id); 759 if (source->priv->title) 760 xmlSetProp (node, BAD_CAST "title", BAD_CAST source->priv->title); 761 762 if (source->priv->stmt) { 763 gchar *sql; 764 sql = gda_statement_to_sql_extended (source->priv->stmt, NULL, NULL, 765 GDA_STATEMENT_SQL_PRETTY | 766 GDA_STATEMENT_SQL_PARAMS_SHORT, NULL, NULL); 767 if (sql) { 768 xmlNodeSetContent (node, BAD_CAST sql); 769 g_free (sql); 770 } 771 } 772 break; 773 } 774 default: 775 break; 776 } 777 778 if (node) { 779 } 780 return node; 781 } 782 783 static gboolean 784 exec_end_timeout_cb (DataSource *source) 785 { 786 GObject *obj; 787 788 g_return_val_if_fail (source->priv->exec_id > 0, FALSE); 789 790 g_clear_error (&source->priv->exec_error); 791 obj = browser_connection_execution_get_result (source->priv->bcnc, 792 source->priv->exec_id, 793 NULL, 794 &source->priv->exec_error); 795 if (obj) { 796 if (GDA_IS_DATA_MODEL (obj)) { 797 if (source->priv->model != GDA_DATA_MODEL (obj)) { 798 if (source->priv->model) 799 g_object_unref (source->priv->model); 800 source->priv->model = GDA_DATA_MODEL (obj); 801 g_object_set (source->priv->model, "auto-reset", FALSE, NULL); 802 } 803 else { 804 gda_data_model_thaw (source->priv->model); 805 gda_data_model_reset (source->priv->model); 806 } 807 /*gda_data_model_dump (source->priv->model, NULL);*/ 808 } 809 else { 810 g_object_unref (obj); 811 g_set_error (&source->priv->exec_error, GDA_TOOLS_ERROR, GDA_TOOLS_COMMAND_ARGUMENTS_ERROR, 812 "%s", _("Statement to execute is not a selection statement")); 813 } 814 815 source->priv->exec_id = 0; 816 g_signal_emit (source, data_source_signals [EXEC_FINISHED], 0, source->priv->exec_error); 817 if (source->priv->exec_again) { 818 source->priv->exec_again = FALSE; 819 data_source_execute (source, NULL); 820 } 821 return FALSE; 822 } 823 else if (source->priv->exec_error) { 824 source->priv->exec_id = 0; 825 g_signal_emit (source, data_source_signals [EXEC_FINISHED], 0, source->priv->exec_error); 826 if (source->priv->exec_again) { 827 source->priv->exec_again = FALSE; 828 data_source_execute (source, NULL); 829 } 830 return FALSE; 831 } 832 else 833 return TRUE; /* keep timer */ 834 } 835 836 /** 837 *data_source_get_statement 838 */ 839 GdaStatement * 840 data_source_get_statement (DataSource *source) 841 { 842 g_return_val_if_fail (IS_DATA_SOURCE (source), NULL); 843 return source->priv->stmt; 844 } 845 846 /** 847 * data_source_execution_going_on 848 */ 849 gboolean 850 data_source_execution_going_on (DataSource *source) 851 { 852 g_return_val_if_fail (IS_DATA_SOURCE (source), FALSE); 853 return source->priv->executing || (source->priv->exec_id > 0); 854 } 855 856 /** 857 * data_source_get_import 858 * 859 * Returns: a pointer to a read-only #GdaSet, or %NULL (must not be modified) 860 */ 861 GdaSet * 862 data_source_get_import (DataSource *source) 863 { 864 g_return_val_if_fail (IS_DATA_SOURCE (source), NULL); 865 return source->priv->params; 866 } 867 868 /** 869 * data_source_set_params 870 */ 871 void 872 data_source_set_params (DataSource *source, GdaSet *params) 873 { 874 gboolean bound = FALSE; 875 g_return_if_fail (IS_DATA_SOURCE (source)); 876 g_return_if_fail (!params || GDA_IS_SET (params)); 877 878 if (source->priv->ext_params) { 879 g_signal_handlers_disconnect_by_func (source->priv->ext_params, 880 G_CALLBACK (ext_params_changed_cb), source); 881 g_object_unref (source->priv->ext_params); 882 source->priv->ext_params = NULL; 883 } 884 885 if (source->priv->params) { 886 GSList *list; 887 for (list = source->priv->params->holders; list; list = list->next) { 888 GdaHolder *holder = GDA_HOLDER (list->data); 889 GdaHolder *bind = NULL; 890 if (params) 891 bind = gda_set_get_holder (params, gda_holder_get_id (holder)); 892 if ((holder != bind) && gda_holder_set_bind (holder, bind, NULL)) 893 bound = TRUE; 894 } 895 } 896 897 if (params && bound) { 898 source->priv->ext_params = g_object_ref (params); 899 g_signal_connect (params, "holder-changed", 900 G_CALLBACK (ext_params_changed_cb), source); 901 } 902 } 903 904 /** 905 * data_source_get_export_names 906 * 907 * Returns: an array of strings (don't modify) or %NULL 908 */ 909 GArray * 910 data_source_get_export_names (DataSource *source) 911 { 912 g_return_val_if_fail (IS_DATA_SOURCE (source), NULL); 913 return source->priv->export_names; 914 } 915 916 /** 917 * data_source_get_export_columns 918 * 919 * Returns: a #GHashTable where key is an export name and value is its column number (use GPOINTER_TO_INT) 920 */ 921 GHashTable * 922 data_source_get_export_columns (DataSource *source) 923 { 924 g_return_val_if_fail (IS_DATA_SOURCE (source), NULL); 925 return source->priv->export_columns; 926 } 927 928 /** 929 * data_source_execute 930 */ 931 void 932 data_source_execute (DataSource *source, GError **error) 933 { 934 GError *lerror = NULL; 935 gboolean has_exec = TRUE; 936 guint exec_id = 0; 937 g_return_if_fail (IS_DATA_SOURCE (source)); 938 939 if (source->priv->exec_again) 940 return; 941 if (source->priv->executing || (source->priv->exec_id > 0)) { 942 source->priv->exec_again = TRUE; 943 return; 944 } 945 946 source->priv->executing = TRUE; 947 if (! source->priv->stmt) { 948 if (source->priv->init_error) 949 g_propagate_error (error, source->priv->init_error); 950 else 951 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_COMMAND_ARGUMENTS_ERROR, 952 "%s", _("No SELECT statement to execute")); 953 } 954 955 if (source->priv->model) { 956 if (source->priv->need_rerun) { 957 /* freeze source->priv->model to avoid that it emits signals while being in the 958 * wrong thread */ 959 source->priv->need_rerun = FALSE; 960 gda_data_model_freeze (source->priv->model); 961 exec_id = browser_connection_rerun_select (source->priv->bcnc, 962 source->priv->model, &lerror); 963 } 964 else 965 has_exec = FALSE; 966 } 967 else 968 exec_id = browser_connection_execute_statement (source->priv->bcnc, 969 source->priv->stmt, 970 source->priv->params, 971 GDA_STATEMENT_MODEL_RANDOM_ACCESS | 972 GDA_STATEMENT_MODEL_ALLOW_NOPARAM, 973 FALSE, &lerror); 974 975 if (has_exec) { 976 g_signal_emit (source, data_source_signals [EXEC_STARTED], 0); 977 if (! exec_id) { 978 gda_data_model_thaw (source->priv->model); 979 gda_data_model_reset (source->priv->model); 980 g_signal_emit (source, data_source_signals [EXEC_FINISHED], 0, lerror); 981 g_propagate_error (error, lerror); 982 } 983 else { 984 /* monitor the end of execution */ 985 source->priv->exec_id = exec_id; 986 g_timeout_add (50, (GSourceFunc) exec_end_timeout_cb, source); 987 } 988 } 989 source->priv->executing = FALSE; 990 } 991 992 static void 993 action_refresh_cb (GtkAction *action, DataSource *source) 994 { 995 source->priv->need_rerun = TRUE; 996 data_source_execute (source, NULL); 997 } 998 999 /** 1000 * data_source_create_grid 1001 * 1002 * Returns: a new #GdauiRawGrid, or %NULL if an error occurred 1003 */ 1004 GtkWidget * 1005 data_source_create_grid (DataSource *source) 1006 { 1007 g_return_val_if_fail (IS_DATA_SOURCE (source), NULL); 1008 1009 if (! source->priv->model) 1010 return NULL; 1011 1012 GtkWidget *fg; 1013 fg = ui_formgrid_new (source->priv->model, FALSE, GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS); 1014 1015 /* add a refresh action */ 1016 GtkUIManager *uimanager; 1017 GtkActionGroup *agroup; 1018 GtkAction *action; 1019 guint mid; 1020 1021 agroup = gtk_action_group_new ("DSGroup"); 1022 gtk_action_group_set_translation_domain (agroup, GETTEXT_PACKAGE); 1023 action = gtk_action_new ("Refresh", "Refresh", 1024 _("Refresh data"), GTK_STOCK_EXECUTE); 1025 gtk_action_group_add_action (agroup, action); 1026 g_signal_connect (G_OBJECT (action), "activate", 1027 G_CALLBACK (action_refresh_cb), source); 1028 g_object_unref (action); 1029 uimanager = ui_formgrid_get_ui_manager (UI_FORMGRID (fg)); 1030 gtk_ui_manager_insert_action_group (uimanager, agroup, 0); 1031 g_object_unref (agroup); 1032 1033 mid = gtk_ui_manager_new_merge_id (uimanager); 1034 gtk_ui_manager_add_ui (uimanager, mid, "/ToolBar/RowModifExtension", "Refresh", "Refresh", 1035 GTK_UI_MANAGER_AUTO, TRUE); 1036 gtk_ui_manager_ensure_update (uimanager); 1037 1038 return fg; 1039 } 1040 1041 /** 1042 * data_source_set_id 1043 * @source: a #DataSource 1044 * @id: the new source's ID, not %NULL 1045 * 1046 * @source MUST NOT be executed when calling this method. 1047 */ 1048 void 1049 data_source_set_id (DataSource *source, const gchar * id) 1050 { 1051 g_return_if_fail (IS_DATA_SOURCE (source)); 1052 g_return_if_fail (! data_source_execution_going_on (source)); 1053 g_return_if_fail (id && *id); 1054 1055 g_free (source->priv->id); 1056 source->priv->id = g_strdup (id); 1057 update_export_information (source); 1058 g_signal_emit (source, data_source_signals [CHANGED], 0); 1059 } 1060 1061 1062 /** 1063 * data_source_get_id 1064 * @source: a #DataSource 1065 * 1066 * Returns: the ID, or %NULL if no ID has been defined 1067 */ 1068 const gchar * 1069 data_source_get_id (DataSource *source) 1070 { 1071 g_return_val_if_fail (IS_DATA_SOURCE (source), NULL); 1072 1073 return source->priv->id; 1074 } 1075 1076 /** 1077 * data_source_set_title 1078 * @source: a #DataSource 1079 * @title: the new source's TITLE 1080 * 1081 * @source MUST NOT be executed when calling this method. 1082 */ 1083 void 1084 data_source_set_title (DataSource *source, const gchar * title) 1085 { 1086 g_return_if_fail (IS_DATA_SOURCE (source)); 1087 g_return_if_fail (! data_source_execution_going_on (source)); 1088 1089 g_free (source->priv->title); 1090 if (title) 1091 source->priv->title = g_strdup (title); 1092 else 1093 source->priv->title = NULL; 1094 g_signal_emit (source, data_source_signals [CHANGED], 0); 1095 } 1096 1097 /** 1098 * data_source_get_title 1099 * @source: a #DataSource 1100 */ 1101 const gchar * 1102 data_source_get_title (DataSource *source) 1103 { 1104 g_return_val_if_fail (IS_DATA_SOURCE (source), NULL); 1105 1106 if (source->priv->title) 1107 return source->priv->title; 1108 else if (source->priv->impl_title) 1109 return source->priv->impl_title; 1110 else 1111 return source->priv->id; 1112 } 1113 1114 static void 1115 update_export_information (DataSource *source) 1116 { 1117 g_assert (source->priv->id); 1118 1119 /* clear previous information */ 1120 if (source->priv->export_names) { 1121 g_array_free (source->priv->export_names, TRUE); 1122 source->priv->export_names = NULL; 1123 } 1124 if (source->priv->export_columns) { 1125 g_hash_table_destroy (source->priv->export_columns); 1126 source->priv->export_columns = NULL; 1127 } 1128 1129 if (! source->priv->stmt) 1130 return; 1131 1132 /* Get GdaSqlStatement */ 1133 GdaSqlStatement *sqlst; 1134 g_object_get ((GObject*) source->priv->stmt, "structure", &sqlst, NULL); 1135 if (browser_connection_check_sql_statement_validify (source->priv->bcnc, sqlst, NULL)) 1136 g_object_set ((GObject*) source->priv->stmt, "structure", sqlst, NULL); 1137 if (! sqlst) 1138 return; 1139 1140 /* compute exported data */ 1141 if (sqlst->stmt_type == GDA_SQL_STATEMENT_SELECT) { 1142 GdaSqlStatementSelect *selst; 1143 selst = (GdaSqlStatementSelect*) sqlst->contents; 1144 GSList *list; 1145 gint i; 1146 for (i = 0, list = selst->expr_list; list; i++, list = list->next) { 1147 gchar *tmp; 1148 if (! source->priv->export_names) 1149 source->priv->export_names = g_array_new (FALSE, FALSE, 1150 sizeof (gchar*)); 1151 if (! source->priv->export_columns) 1152 source->priv->export_columns = 1153 g_hash_table_new_full (g_str_hash, g_str_equal, 1154 g_free, NULL); 1155 1156 tmp = g_strdup_printf ("%s@%d", source->priv->id, i+1); 1157 g_array_append_val (source->priv->export_names, tmp); 1158 g_hash_table_insert (source->priv->export_columns, tmp, 1159 GINT_TO_POINTER (i + 1)); 1160 #ifdef DEBUG_SOURCE 1161 g_print ("\tEXPORT [%s]\n", tmp); 1162 #endif 1163 1164 GdaSqlSelectField *sf = (GdaSqlSelectField *) list->data; 1165 if (sf->validity_meta_table_column) { 1166 tmp = g_strdup_printf ("%s@%s", source->priv->id, 1167 sf->validity_meta_table_column->column_name); 1168 g_array_append_val (source->priv->export_names, tmp); 1169 g_hash_table_insert (source->priv->export_columns, tmp, 1170 GINT_TO_POINTER (i + 1)); 1171 #ifdef DEBUG_SOURCE 1172 g_print ("\tEXPORT [%s]\n", tmp); 1173 #endif 1174 } 1175 } 1176 } 1177 1178 gda_sql_statement_free (sqlst); 1179 } 1180 1181 /** 1182 * data_source_set_table 1183 * 1184 * @source MUST NOT be executed when calling this method. 1185 */ 1186 gboolean 1187 data_source_set_table (DataSource *source, const gchar *table, GError **error) 1188 { 1189 g_return_val_if_fail (IS_DATA_SOURCE (source), FALSE); 1190 g_return_val_if_fail (! data_source_execution_going_on (source), FALSE); 1191 1192 data_source_reset (source); 1193 if (!table) 1194 return FALSE; 1195 1196 /* locate table */ 1197 GdaMetaTable *mtable; 1198 mtable = get_meta_table (source, table, error); 1199 if (!mtable) 1200 return FALSE; 1201 1202 source->priv->source_type = DATA_SOURCE_TABLE; 1203 source->priv->tablename = g_strdup (table); 1204 1205 if (! strcmp (source->priv->id, DEFAULT_DATA_SOURCE_NAME)) { 1206 g_free (source->priv->id); 1207 source->priv->id = g_strdup (table); 1208 } 1209 1210 g_free (source->priv->impl_title); 1211 source->priv->impl_title = g_strdup_printf (_("Contents of '%s'"), table); 1212 1213 /* build statement */ 1214 GdaSqlBuilder *b; 1215 gint i; 1216 GSList *list; 1217 1218 b = gda_sql_builder_new (GDA_SQL_STATEMENT_SELECT); 1219 source->priv->builder = b; 1220 if (! gda_sql_builder_select_add_target (b, table, NULL)) { 1221 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_INTERNAL_COMMAND_ERROR, 1222 "%s", _("Could not build SELECT statement")); 1223 return FALSE; 1224 } 1225 gda_sql_builder_select_set_limit (b, 1226 gda_sql_builder_add_expr (b, NULL, 1227 G_TYPE_INT, DEFAULT_DATA_SELECT_LIMIT), 1228 0); 1229 for (i = 0, list = mtable->columns; list; i++, list = list->next) { 1230 GdaMetaTableColumn *mcol; 1231 mcol = GDA_META_TABLE_COLUMN (list->data); 1232 gda_sql_builder_select_add_field (b, mcol->column_name, NULL, NULL); 1233 1234 if (mcol->pkey) { 1235 /* ORDER BY */ 1236 gda_sql_builder_select_order_by (b, 1237 gda_sql_builder_add_id (b, 1238 mcol->column_name), 1239 FALSE, NULL); 1240 } 1241 } 1242 1243 /* compute statement & parameters */ 1244 compute_stmt_and_params (source); 1245 /*g_print ("SQL [%s]\n", gda_statement_to_sql (source->priv->stmt, NULL, NULL));*/ 1246 1247 update_export_information (source); 1248 1249 #ifdef DEBUG_SOURCE 1250 g_print ("\n"); 1251 #endif 1252 1253 g_signal_emit (source, data_source_signals [CHANGED], 0); 1254 return source->priv->stmt ? TRUE : FALSE; 1255 } 1256 1257 /** 1258 * data_source_set_query 1259 * 1260 * @source MUST NOT be executed when calling this method. 1261 */ 1262 void 1263 data_source_set_query (DataSource *source, const gchar *sql, GError **warning) 1264 { 1265 g_return_if_fail (IS_DATA_SOURCE (source)); 1266 g_return_if_fail (! data_source_execution_going_on (source)); 1267 1268 data_source_reset (source); 1269 1270 source->priv->source_type = DATA_SOURCE_SELECT; 1271 if (!sql) { 1272 g_signal_emit (source, data_source_signals [CHANGED], 0); 1273 return; 1274 } 1275 1276 GdaSqlParser *parser; 1277 const gchar *remain; 1278 parser = browser_connection_create_parser (source->priv->bcnc); 1279 source->priv->stmt = gda_sql_parser_parse_string (parser, sql, 1280 &remain, warning); 1281 g_object_unref (parser); 1282 if (!source->priv->stmt) { 1283 g_signal_emit (source, data_source_signals [CHANGED], 0); 1284 return; 1285 } 1286 1287 if (remain) 1288 g_set_error (warning, GDA_TOOLS_ERROR, GDA_TOOLS_COMMAND_ARGUMENTS_ERROR, 1289 "%s", _("Multiple statements detected, only the first will be used")); 1290 1291 /* try to normalize the statement */ 1292 GdaSqlStatement *sqlst; 1293 g_object_get ((GObject*) source->priv->stmt, "structure", &sqlst, NULL); 1294 if (browser_connection_normalize_sql_statement (source->priv->bcnc, sqlst, NULL)) 1295 g_object_set ((GObject*) source->priv->stmt, "structure", sqlst, NULL); 1296 gda_sql_statement_free (sqlst); 1297 1298 update_export_information (source); 1299 1300 /* compute parameters */ 1301 source->priv->need_rerun = FALSE; 1302 compute_import_params (source); 1303 1304 #ifdef DEBUG_SOURCE 1305 g_print ("\n"); 1306 #endif 1307 1308 g_signal_emit (source, data_source_signals [CHANGED], 0); 1309 } 1310 1311 static void 1312 compute_stmt_and_params (DataSource *source) 1313 { 1314 g_assert (source->priv->builder); 1315 if (source->priv->stmt) 1316 g_object_unref (source->priv->stmt); 1317 source->priv->stmt = gda_sql_builder_get_statement (source->priv->builder, NULL); 1318 compute_import_params (source); 1319 1320 #ifdef DEBUG_SOURCE 1321 gchar *sql; 1322 sql = gda_statement_to_sql (source->priv->stmt, NULL, NULL); 1323 g_print ("[%s]\n", sql); 1324 g_free (sql); 1325 #endif 1326 } 1327 1328 static void 1329 compute_import_params (DataSource *source) 1330 { 1331 if (source->priv->params) { 1332 g_signal_handlers_disconnect_by_func (source->priv->params, 1333 G_CALLBACK (params_changed_cb), source); 1334 g_object_unref (source->priv->params); 1335 source->priv->params = NULL; 1336 } 1337 g_clear_error (& source->priv->init_error); 1338 1339 gda_statement_get_parameters (source->priv->stmt, &source->priv->params, 1340 &source->priv->init_error); 1341 if (source->priv->params) { 1342 GSList *list; 1343 for (list = source->priv->params->holders; list; list = list->next) { 1344 gda_holder_set_not_null (GDA_HOLDER (list->data), FALSE); 1345 #ifdef DEBUG_SOURCE 1346 g_print ("\tIMPORT [%s]\n", gda_holder_get_id (GDA_HOLDER (list->data))); 1347 #endif 1348 } 1349 1350 browser_connection_define_ui_plugins_for_stmt (source->priv->bcnc, source->priv->stmt, 1351 source->priv->params); 1352 1353 g_signal_connect (source->priv->params, "holder-changed", 1354 G_CALLBACK (params_changed_cb), source); 1355 } 1356 } 1357 1358 /** 1359 * data_source_get_table 1360 * @source: a #DataSource 1361 * 1362 * Returns: the name of the table used by @source, if its type is %DATA_SOURCE_TABLE 1363 */ 1364 const gchar * 1365 data_source_get_table (DataSource *source) 1366 { 1367 g_return_val_if_fail (IS_DATA_SOURCE (source), NULL); 1368 return source->priv->tablename; 1369 } 1370 1371 /** 1372 * data_source_get_source_type 1373 */ 1374 DataSourceType 1375 data_source_get_source_type (DataSource *source) 1376 { 1377 g_return_val_if_fail (IS_DATA_SOURCE (source), DATA_SOURCE_UNKNOWN); 1378 return source->priv->source_type; 1379 } 1380 1381 /** 1382 * data_source_should_rerun 1383 * 1384 * The SELECT statement will be re-executed the next time 1385 * data_source_execute() is called 1386 */ 1387 void 1388 data_source_should_rerun (DataSource *source) 1389 { 1390 g_return_if_fail (IS_DATA_SOURCE (source)); 1391 source->priv->need_rerun = TRUE; 1392 } 1393