1 /* 2 * Copyright (C) 2008 Massimo Cora <maxcvs@email.it> 3 * Copyright (C) 2008 - 2011 Murray Cumming <murrayc@murrayc.com> 4 * Copyright (C) 2008 - 2013 Vivien Malerba <malerba@gnome-db.org> 5 * Copyright (C) 2009 Bas Driessen <bas.driessen@xobas.com> 6 * Copyright (C) 2010 David King <davidk@openismus.com> 7 * Copyright (C) 2010 Jonh Wendell <jwendell@gnome.org> 8 * Copyright (C) 2011 Daniel Espinosa <despinosa@src.gnome.org> 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the 22 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 23 * Boston, MA 02110-1301, USA. 24 */ 25 26 #include <glib/gi18n-lib.h> 27 #include <stdarg.h> 28 #include <string.h> 29 #include "gda-holder.h" 30 #include "gda-statement.h" 31 #include "gda-data-model.h" 32 #include "gda-data-handler.h" 33 #include "gda-marshal.h" 34 #include "gda-util.h" 35 #include <libgda.h> 36 #include <libgda/gda-attributes-manager.h> 37 #include <libgda/gda-custom-marshal.h> 38 #include <libgda/gda-types.h> 39 40 /* 41 * Main static functions 42 */ 43 static void gda_holder_class_init (GdaHolderClass * class); 44 static void gda_holder_init (GdaHolder *holder); 45 static void gda_holder_dispose (GObject *object); 46 static void gda_holder_finalize (GObject *object); 47 48 static void gda_holder_set_property (GObject *object, 49 guint param_id, 50 const GValue *value, 51 GParamSpec *pspec); 52 static void gda_holder_get_property (GObject *object, 53 guint param_id, 54 GValue *value, 55 GParamSpec *pspec); 56 57 /* GdaLockable interface */ 58 static void gda_holder_lockable_init (GdaLockableIface *iface); 59 static void gda_holder_lock (GdaLockable *lockable); 60 static gboolean gda_holder_trylock (GdaLockable *lockable); 61 static void gda_holder_unlock (GdaLockable *lockable); 62 63 64 static void bound_holder_changed_cb (GdaHolder *alias_of, GdaHolder *holder); 65 static void full_bound_holder_changed_cb (GdaHolder *alias_of, GdaHolder *holder); 66 static void gda_holder_set_full_bind (GdaHolder *holder, GdaHolder *alias_of); 67 68 /* get a pointer to the parents to be able to call their destructor */ 69 static GObjectClass *parent_class = NULL; 70 GdaAttributesManager *gda_holder_attributes_manager; 71 72 /* signals */ 73 enum 74 { 75 CHANGED, 76 SOURCE_CHANGED, 77 VALIDATE_CHANGE, 78 ATT_CHANGED, 79 LAST_SIGNAL 80 }; 81 82 static gint gda_holder_signals[LAST_SIGNAL] = { 0, 0, 0, 0 }; 83 84 85 /* properties */ 86 enum 87 { 88 PROP_0, 89 PROP_ID, 90 PROP_NAME, 91 PROP_DESCR, 92 PROP_SIMPLE_BIND, 93 PROP_FULL_BIND, 94 PROP_SOURCE_MODEL, 95 PROP_SOURCE_COLUMN, 96 PROP_GDA_TYPE, 97 PROP_NOT_NULL, 98 PROP_VALIDATE_CHANGES 99 }; 100 101 102 struct _GdaHolderPrivate 103 { 104 gchar *id; 105 106 GType g_type; 107 GdaHolder *full_bind; /* FULL bind to holder */ 108 GdaHolder *simple_bind; /* SIMPLE bind to holder */ 109 gulong simple_bind_type_changed_id; 110 111 gboolean invalid_forced; 112 GError *invalid_error; 113 gboolean valid; 114 gboolean is_freeable; 115 116 GValue *value; 117 GValue *default_value; /* CAN be either NULL or of any type */ 118 gboolean default_forced; 119 gboolean not_null; /* TRUE if 'value' must not be NULL when passed to destination fields */ 120 121 GdaDataModel *source_model; 122 gint source_col; 123 124 GdaMutex *mutex; 125 126 gboolean validate_changes; 127 }; 128 129 /* module error */ 130 GQuark gda_holder_error_quark (void) 131 { 132 static GQuark quark; 133 if (!quark) 134 quark = g_quark_from_static_string ("gda_holder_error"); 135 return quark; 136 } 137 138 GType 139 gda_holder_get_type (void) 140 { 141 static GType type = 0; 142 143 if (G_UNLIKELY (type == 0)) { 144 static GMutex registering; 145 static const GTypeInfo info = { 146 sizeof (GdaHolderClass), 147 (GBaseInitFunc) NULL, 148 (GBaseFinalizeFunc) NULL, 149 (GClassInitFunc) gda_holder_class_init, 150 NULL, 151 NULL, 152 sizeof (GdaHolder), 153 0, 154 (GInstanceInitFunc) gda_holder_init, 155 0 156 }; 157 158 static GInterfaceInfo lockable_info = { 159 (GInterfaceInitFunc) gda_holder_lockable_init, 160 NULL, 161 NULL 162 }; 163 164 g_mutex_lock (®istering); 165 if (type == 0) { 166 type = g_type_register_static (G_TYPE_OBJECT, "GdaHolder", &info, 0); 167 g_type_add_interface_static (type, GDA_TYPE_LOCKABLE, &lockable_info); 168 } 169 g_mutex_unlock (®istering); 170 } 171 172 return type; 173 } 174 175 static gboolean 176 validate_change_accumulator (G_GNUC_UNUSED GSignalInvocationHint *ihint, 177 GValue *return_accu, 178 const GValue *handler_return, 179 G_GNUC_UNUSED gpointer data) 180 { 181 GError *error; 182 183 error = g_value_get_boxed (handler_return); 184 g_value_set_boxed (return_accu, error); 185 186 return error ? FALSE : TRUE; /* stop signal if error has been set */ 187 } 188 189 static GError * 190 m_validate_change (G_GNUC_UNUSED GdaHolder *holder, G_GNUC_UNUSED const GValue *new_value) 191 { 192 return NULL; 193 } 194 195 static void 196 holder_attribute_set_cb (GObject *obj, const gchar *att_name, const GValue *value, 197 G_GNUC_UNUSED gpointer data) 198 { 199 g_signal_emit (obj, gda_holder_signals[ATT_CHANGED], 0, att_name, value); 200 } 201 202 static void 203 gda_holder_class_init (GdaHolderClass *class) 204 { 205 GObjectClass *object_class = G_OBJECT_CLASS (class); 206 207 parent_class = g_type_class_peek_parent (class); 208 209 /** 210 * GdaHolder::source-changed: 211 * @holder: the #GdaHolder 212 * 213 * Gets emitted when the data model in which @holder's values should be has changed 214 */ 215 gda_holder_signals[SOURCE_CHANGED] = 216 g_signal_new ("source-changed", 217 G_TYPE_FROM_CLASS (object_class), 218 G_SIGNAL_RUN_FIRST, 219 G_STRUCT_OFFSET (GdaHolderClass, source_changed), 220 NULL, NULL, 221 _gda_marshal_VOID__VOID, G_TYPE_NONE, 0); 222 /** 223 * GdaHolder::changed: 224 * @holder: the #GdaHolder 225 * 226 * Gets emitted when @holder's value has changed 227 */ 228 gda_holder_signals[CHANGED] = 229 g_signal_new ("changed", 230 G_TYPE_FROM_CLASS (object_class), 231 G_SIGNAL_RUN_FIRST, 232 G_STRUCT_OFFSET (GdaHolderClass, changed), 233 NULL, NULL, 234 _gda_marshal_VOID__VOID, G_TYPE_NONE, 0); 235 /** 236 * GdaHolder::attribute-changed: 237 * @holder: the #GdaHolder 238 * @att_name: attribute's name 239 * @att_value: attribute's value 240 * 241 * Gets emitted when any @holder's attribute has changed 242 */ 243 gda_holder_signals[ATT_CHANGED] = 244 g_signal_new ("attribute-changed", 245 G_TYPE_FROM_CLASS (object_class), 246 G_SIGNAL_RUN_FIRST, 247 G_STRUCT_OFFSET (GdaHolderClass, att_changed), 248 NULL, NULL, 249 _gda_marshal_VOID__STRING_VALUE, G_TYPE_NONE, 2, 250 G_TYPE_STRING, G_TYPE_VALUE); 251 252 /** 253 * GdaHolder::validate-change: 254 * @holder: the object which received the signal 255 * @new_value: the proposed new value for @holder 256 * 257 * Gets emitted when @holder is going to change its value. One can connect to 258 * this signal to control which values @holder can have (for example to implement some business rules) 259 * 260 * Returns: NULL if @holder is allowed to change its value to @new_value, or a #GError 261 * otherwise. 262 */ 263 gda_holder_signals[VALIDATE_CHANGE] = 264 g_signal_new ("validate-change", 265 G_TYPE_FROM_CLASS (object_class), 266 G_SIGNAL_RUN_LAST, 267 G_STRUCT_OFFSET (GdaHolderClass, validate_change), 268 validate_change_accumulator, NULL, 269 _gda_marshal_ERROR__VALUE, G_TYPE_ERROR, 1, G_TYPE_VALUE); 270 271 class->changed = NULL; 272 class->source_changed = NULL; 273 class->validate_change = m_validate_change; 274 class->att_changed = NULL; 275 276 /* virtual functions */ 277 object_class->dispose = gda_holder_dispose; 278 object_class->finalize = gda_holder_finalize; 279 280 /* Properties */ 281 object_class->set_property = gda_holder_set_property; 282 object_class->get_property = gda_holder_get_property; 283 g_object_class_install_property (object_class, PROP_ID, 284 g_param_spec_string ("id", NULL, "Holder's ID", NULL, 285 (G_PARAM_READABLE | G_PARAM_WRITABLE))); 286 g_object_class_install_property (object_class, PROP_NAME, 287 g_param_spec_string ("name", NULL, "Holder's name", NULL, 288 (G_PARAM_READABLE | G_PARAM_WRITABLE))); 289 g_object_class_install_property (object_class, PROP_DESCR, 290 g_param_spec_string ("description", NULL, "Holder's description", NULL, 291 (G_PARAM_READABLE | G_PARAM_WRITABLE))); 292 g_object_class_install_property (object_class, PROP_GDA_TYPE, 293 g_param_spec_gtype ("g-type", NULL, "Holder's GType", G_TYPE_NONE, 294 (G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT))); 295 g_object_class_install_property (object_class, PROP_NOT_NULL, 296 g_param_spec_boolean ("not-null", NULL, "Can the value holder be NULL?", FALSE, 297 (G_PARAM_READABLE | G_PARAM_WRITABLE))); 298 g_object_class_install_property (object_class, PROP_SIMPLE_BIND, 299 g_param_spec_object ("simple-bind", NULL, 300 "Make value holder follow other GdaHolder's changes", 301 GDA_TYPE_HOLDER, 302 (G_PARAM_READABLE | G_PARAM_WRITABLE))); 303 g_object_class_install_property (object_class, PROP_FULL_BIND, 304 g_param_spec_object ("full-bind", NULL, 305 "Make value holder follow other GdaHolder's changes " 306 "and the other way around", 307 GDA_TYPE_HOLDER, 308 (G_PARAM_READABLE | G_PARAM_WRITABLE))); 309 g_object_class_install_property (object_class, PROP_SOURCE_MODEL, 310 g_param_spec_object ("source-model", NULL, "Data model among which the holder's " 311 "value should be", 312 GDA_TYPE_DATA_MODEL, 313 (G_PARAM_READABLE | G_PARAM_WRITABLE))); 314 g_object_class_install_property (object_class, PROP_SOURCE_COLUMN, 315 g_param_spec_int ("source-column", NULL, "Column number to use in coordination " 316 "with the source-model property", 317 0, G_MAXINT, 0, 318 (G_PARAM_READABLE | G_PARAM_WRITABLE))); 319 320 /** 321 * GdaHolder:validate-changes: 322 * 323 * Defines if the "validate-change" signal gets emitted when 324 * the holder's value changes. 325 * 326 * Since: 5.2.0 327 */ 328 g_object_class_install_property (object_class, PROP_VALIDATE_CHANGES, 329 g_param_spec_boolean ("validate-changes", NULL, "Defines if the validate-change signal is emitted on value change", TRUE, 330 (G_PARAM_READABLE | G_PARAM_WRITABLE))); 331 332 /* extra */ 333 gda_holder_attributes_manager = gda_attributes_manager_new (TRUE, holder_attribute_set_cb, NULL); 334 } 335 336 static void 337 gda_holder_lockable_init (GdaLockableIface *iface) 338 { 339 iface->i_lock = gda_holder_lock; 340 iface->i_trylock = gda_holder_trylock; 341 iface->i_unlock = gda_holder_unlock; 342 } 343 344 static void 345 gda_holder_init (GdaHolder *holder) 346 { 347 holder->priv = g_new0 (GdaHolderPrivate, 1); 348 349 holder->priv->id = NULL; 350 351 holder->priv->g_type = GDA_TYPE_NULL; 352 holder->priv->full_bind = NULL; 353 holder->priv->simple_bind = NULL; 354 holder->priv->simple_bind_type_changed_id = 0; 355 356 holder->priv->invalid_forced = FALSE; 357 holder->priv->invalid_error = NULL; 358 holder->priv->valid = TRUE; 359 holder->priv->default_forced = FALSE; 360 holder->priv->is_freeable = TRUE; 361 holder->priv->value = NULL; 362 holder->priv->default_value = NULL; 363 364 holder->priv->not_null = FALSE; 365 holder->priv->source_model = NULL; 366 holder->priv->source_col = 0; 367 368 holder->priv->mutex = gda_mutex_new (); 369 370 holder->priv->validate_changes = TRUE; 371 } 372 373 /** 374 * gda_holder_new: 375 * @type: the #GType requested 376 * 377 * Creates a new holder of type @type 378 * 379 * Returns: a new #GdaHolder object 380 */ 381 GdaHolder * 382 gda_holder_new (GType type) 383 { 384 return (GdaHolder*) g_object_new (GDA_TYPE_HOLDER, "g-type", type, NULL); 385 } 386 387 /** 388 * gda_holder_copy: 389 * @orig: a #GdaHolder object to copy 390 * 391 * Copy constructor. 392 * 393 * Note1: if @orig is set with a static value (see gda_holder_take_static_value()) 394 * its copy will have a fresh new allocated GValue, so that user should free it when done. 395 * 396 * Returns: (transfer full): a new #GdaHolder object 397 */ 398 GdaHolder * 399 gda_holder_copy (GdaHolder *orig) 400 { 401 GObject *obj; 402 GdaHolder *holder; 403 gboolean allok = TRUE; 404 405 g_return_val_if_fail (orig && GDA_IS_HOLDER (orig), NULL); 406 g_return_val_if_fail (orig->priv, NULL); 407 408 gda_holder_lock ((GdaLockable*) orig); 409 obj = g_object_new (GDA_TYPE_HOLDER, "g-type", orig->priv->g_type, NULL); 410 holder = GDA_HOLDER (obj); 411 412 if (orig->priv->id) 413 holder->priv->id = g_strdup (orig->priv->id); 414 415 if (orig->priv->full_bind) 416 gda_holder_set_full_bind (holder, orig->priv->full_bind); 417 if (orig->priv->simple_bind) 418 allok = gda_holder_set_bind (holder, orig->priv->simple_bind, NULL); 419 420 if (allok && orig->priv->source_model) { 421 /*g_print ("Source holder %p\n", holder);*/ 422 allok = gda_holder_set_source_model (holder, orig->priv->source_model, orig->priv->source_col, 423 NULL); 424 } 425 426 if (allok) { 427 /* direct settings */ 428 holder->priv->invalid_forced = orig->priv->invalid_forced; 429 if (orig->priv->invalid_error) 430 holder->priv->invalid_error = g_error_copy (orig->priv->invalid_error); 431 holder->priv->valid = orig->priv->valid; 432 holder->priv->is_freeable = TRUE; 433 holder->priv->default_forced = orig->priv->default_forced; 434 if (orig->priv->value) 435 holder->priv->value = gda_value_copy (orig->priv->value); 436 if (orig->priv->default_value) 437 holder->priv->default_value = gda_value_copy (orig->priv->default_value); 438 holder->priv->not_null = orig->priv->not_null; 439 gda_attributes_manager_copy (gda_holder_attributes_manager, (gpointer) orig, gda_holder_attributes_manager, (gpointer) holder); 440 441 GValue *att_value; 442 g_value_set_boolean ((att_value = gda_value_new (G_TYPE_BOOLEAN)), holder->priv->default_forced); 443 gda_holder_set_attribute_static (holder, GDA_ATTRIBUTE_IS_DEFAULT, att_value); 444 gda_value_free (att_value); 445 446 447 gda_holder_unlock ((GdaLockable*) orig); 448 return holder; 449 } 450 else { 451 g_warning ("Internal error: could not copy GdaHolder (please report a bug)."); 452 g_object_unref (holder); 453 gda_holder_unlock ((GdaLockable*) orig); 454 return NULL; 455 } 456 } 457 458 /** 459 * gda_holder_new_inline: 460 * @type: a valid GLib type 461 * @id: (allow-none): the id of the holder to create, or %NULL 462 * @...: value to set 463 * 464 * Creates a new #GdaHolder object with an ID set to @id, of type @type, 465 * and containing the value passed as the last argument. 466 * 467 * Note that this function is a utility function and that only a limited set of types are supported. Trying 468 * to use an unsupported type will result in a warning, and the returned value holder holding a safe default 469 * value. 470 * 471 * Returns: a new #GdaHolder object 472 */ 473 GdaHolder * 474 gda_holder_new_inline (GType type, const gchar *id, ...) 475 { 476 GdaHolder *holder; 477 478 static GMutex serial_mutex; 479 static guint serial = 0; 480 481 holder = gda_holder_new (type); 482 if (holder) { 483 GValue *value; 484 va_list ap; 485 GError *lerror = NULL; 486 487 if (id) 488 holder->priv->id = g_strdup (id); 489 else { 490 g_mutex_lock (&serial_mutex); 491 holder->priv->id = g_strdup_printf ("%d", serial++); 492 g_mutex_unlock (&serial_mutex); 493 } 494 495 va_start (ap, id); 496 value = gda_value_new (type); 497 if (type == G_TYPE_BOOLEAN) 498 g_value_set_boolean (value, va_arg (ap, int)); 499 else if (type == G_TYPE_STRING) 500 g_value_set_string (value, va_arg (ap, gchar *)); 501 else if (type == G_TYPE_OBJECT) 502 g_value_set_object (value, va_arg (ap, gpointer)); 503 else if (type == G_TYPE_INT) 504 g_value_set_int (value, va_arg (ap, gint)); 505 else if (type == G_TYPE_UINT) 506 g_value_set_uint (value, va_arg (ap, guint)); 507 else if (type == GDA_TYPE_BINARY) 508 gda_value_set_binary (value, va_arg (ap, GdaBinary *)); 509 else if (type == G_TYPE_INT64) 510 g_value_set_int64 (value, va_arg (ap, gint64)); 511 else if (type == G_TYPE_UINT64) 512 g_value_set_uint64 (value, va_arg (ap, guint64)); 513 else if (type == GDA_TYPE_SHORT) 514 gda_value_set_short (value, va_arg (ap, int)); 515 else if (type == GDA_TYPE_USHORT) 516 gda_value_set_ushort (value, va_arg (ap, guint)); 517 else if (type == G_TYPE_CHAR) 518 g_value_set_schar (value, va_arg (ap, int)); 519 else if (type == G_TYPE_UCHAR) 520 g_value_set_uchar (value, va_arg (ap, guint)); 521 else if (type == G_TYPE_FLOAT) 522 g_value_set_float (value, va_arg (ap, double)); 523 else if (type == G_TYPE_DOUBLE) 524 g_value_set_double (value, va_arg (ap, gdouble)); 525 else if (type == G_TYPE_GTYPE) 526 g_value_set_gtype (value, va_arg (ap, GType)); 527 else if (type == G_TYPE_LONG) 528 g_value_set_long (value, va_arg (ap, glong)); 529 else if (type == G_TYPE_ULONG) 530 g_value_set_ulong (value, va_arg (ap, gulong)); 531 else if (type == GDA_TYPE_NUMERIC) 532 gda_value_set_numeric (value, va_arg (ap, GdaNumeric *)); 533 else if (type == G_TYPE_DATE) 534 g_value_set_boxed (value, va_arg (ap, GDate *)); 535 else { 536 g_warning ("%s() does not handle values of type %s, value will not be assigned.", 537 __FUNCTION__, g_type_name (type)); 538 g_object_unref (holder); 539 holder = NULL; 540 } 541 va_end (ap); 542 543 if (holder && !gda_holder_set_value (holder, value, &lerror)) { 544 g_warning (_("Unable to set holder's value: %s"), 545 lerror && lerror->message ? lerror->message : _("No detail")); 546 if (lerror) 547 g_error_free (lerror); 548 g_object_unref (holder); 549 holder = NULL; 550 } 551 gda_value_free (value); 552 } 553 554 return holder; 555 } 556 557 static void 558 gda_holder_dispose (GObject *object) 559 { 560 GdaHolder *holder; 561 562 holder = GDA_HOLDER (object); 563 if (holder->priv) { 564 gda_holder_set_bind (holder, NULL, NULL); 565 gda_holder_set_full_bind (holder, NULL); 566 567 if (holder->priv->source_model) { 568 g_object_unref (holder->priv->source_model); 569 holder->priv->source_model = NULL; 570 } 571 572 holder->priv->g_type = G_TYPE_INVALID; 573 574 if (holder->priv->value) { 575 if (holder->priv->is_freeable) 576 gda_value_free (holder->priv->value); 577 holder->priv->value = NULL; 578 } 579 580 if (holder->priv->default_value) { 581 gda_value_free (holder->priv->default_value); 582 holder->priv->default_value = NULL; 583 } 584 585 if (holder->priv->invalid_error) { 586 g_error_free (holder->priv->invalid_error); 587 holder->priv->invalid_error = NULL; 588 } 589 } 590 591 /* parent class */ 592 parent_class->dispose (object); 593 } 594 595 static void 596 gda_holder_finalize (GObject * object) 597 { 598 GdaHolder *holder; 599 600 g_return_if_fail (object != NULL); 601 g_return_if_fail (GDA_IS_HOLDER (object)); 602 603 holder = GDA_HOLDER (object); 604 if (holder->priv) { 605 g_free (holder->priv->id); 606 607 gda_mutex_free (holder->priv->mutex); 608 609 g_free (holder->priv); 610 holder->priv = NULL; 611 } 612 613 /* parent class */ 614 parent_class->finalize (object); 615 } 616 617 618 static void 619 gda_holder_set_property (GObject *object, 620 guint param_id, 621 const GValue *value, 622 GParamSpec *pspec) 623 { 624 GdaHolder *holder; 625 626 holder = GDA_HOLDER (object); 627 if (holder->priv) { 628 switch (param_id) { 629 case PROP_ID: 630 g_free (holder->priv->id); 631 holder->priv->id = g_value_dup_string (value); 632 break; 633 case PROP_NAME: 634 gda_holder_set_attribute_static (holder, GDA_ATTRIBUTE_NAME, value); 635 break; 636 case PROP_DESCR: 637 gda_holder_set_attribute_static (holder, GDA_ATTRIBUTE_DESCRIPTION, value); 638 break; 639 case PROP_GDA_TYPE: 640 if (holder->priv->g_type == GDA_TYPE_NULL) { 641 holder->priv->g_type = g_value_get_gtype (value); 642 g_object_notify ((GObject*) holder, "g-type"); 643 } 644 else 645 g_warning (_("The 'g-type' property cannot be changed")); 646 break; 647 case PROP_NOT_NULL: { 648 gboolean not_null = g_value_get_boolean (value); 649 if (not_null != holder->priv->not_null) { 650 holder->priv->not_null = not_null; 651 652 /* updating the holder's validity regarding the NULL value */ 653 if (!not_null && 654 (!holder->priv->value || GDA_VALUE_HOLDS_NULL (holder->priv->value))) 655 holder->priv->valid = TRUE; 656 657 if (not_null && 658 (!holder->priv->value || GDA_VALUE_HOLDS_NULL (holder->priv->value))) 659 holder->priv->valid = FALSE; 660 661 g_signal_emit (holder, gda_holder_signals[CHANGED], 0); 662 } 663 break; 664 } 665 case PROP_SIMPLE_BIND: 666 if (!gda_holder_set_bind (holder, (GdaHolder*) g_value_get_object (value), NULL)) 667 g_warning ("Could not set the 'simple-bind' property"); 668 break; 669 case PROP_FULL_BIND: 670 gda_holder_set_full_bind (holder, (GdaHolder*) g_value_get_object (value)); 671 break; 672 case PROP_SOURCE_MODEL: { 673 GdaDataModel* ptr = g_value_get_object (value); 674 g_return_if_fail (gda_holder_set_source_model (holder, 675 (GdaDataModel *)ptr, -1, NULL)); 676 break; 677 } 678 case PROP_SOURCE_COLUMN: 679 holder->priv->source_col = g_value_get_int (value); 680 break; 681 case PROP_VALIDATE_CHANGES: 682 holder->priv->validate_changes = g_value_get_boolean (value); 683 break; 684 default: 685 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); 686 break; 687 } 688 } 689 } 690 691 static void 692 gda_holder_get_property (GObject *object, 693 guint param_id, 694 GValue *value, 695 GParamSpec *pspec) 696 { 697 GdaHolder *holder; 698 const GValue *cvalue; 699 700 holder = GDA_HOLDER (object); 701 if (holder->priv) { 702 switch (param_id) { 703 case PROP_ID: 704 g_value_set_string (value, holder->priv->id); 705 break; 706 case PROP_NAME: 707 cvalue = gda_holder_get_attribute (holder, GDA_ATTRIBUTE_NAME); 708 if (cvalue) 709 g_value_set_string (value, g_value_get_string (cvalue)); 710 else 711 g_value_set_string (value, holder->priv->id); 712 break; 713 case PROP_DESCR: 714 cvalue = gda_holder_get_attribute (holder, GDA_ATTRIBUTE_DESCRIPTION); 715 if (cvalue) 716 g_value_set_string (value, g_value_get_string (cvalue)); 717 else 718 g_value_set_string (value, NULL); 719 break; 720 case PROP_GDA_TYPE: 721 g_value_set_gtype (value, holder->priv->g_type); 722 break; 723 case PROP_NOT_NULL: 724 g_value_set_boolean (value, gda_holder_get_not_null (holder)); 725 break; 726 case PROP_SIMPLE_BIND: 727 g_value_set_object (value, (GObject*) holder->priv->simple_bind); 728 break; 729 case PROP_FULL_BIND: 730 g_value_set_object (value, (GObject*) holder->priv->full_bind); 731 break; 732 case PROP_SOURCE_MODEL: 733 g_value_set_object (value, (GObject*) holder->priv->source_model); 734 break; 735 case PROP_SOURCE_COLUMN: 736 g_value_set_int (value, holder->priv->source_col); 737 break; 738 case PROP_VALIDATE_CHANGES: 739 g_value_set_boolean (value, holder->priv->validate_changes); 740 break; 741 default: 742 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); 743 break; 744 } 745 } 746 } 747 748 GType 749 gda_holder_get_g_type (GdaHolder *holder) 750 { 751 g_return_val_if_fail (GDA_IS_HOLDER (holder), G_TYPE_INVALID); 752 g_return_val_if_fail (holder->priv, G_TYPE_INVALID); 753 754 return holder->priv->g_type; 755 } 756 757 /** 758 * gda_holder_get_id: 759 * @holder: a #GdaHolder object 760 * 761 * Get the ID of @holder. The ID can be set using @holder's "id" property 762 * 763 * Returns: the ID (don't modify the string). 764 */ 765 const gchar * 766 gda_holder_get_id (GdaHolder *holder) 767 { 768 g_return_val_if_fail (GDA_IS_HOLDER (holder), NULL); 769 g_return_val_if_fail (holder->priv, NULL); 770 771 return holder->priv->id; 772 } 773 774 775 /** 776 * gda_holder_get_value: 777 * @holder: a #GdaHolder object 778 * 779 * Get the value held into the holder. If @holder is set to use its default value 780 * and that default value is not of the same type as @holder, then %NULL is returned. 781 * 782 * If @holder is set to NULL, then the returned value is a #GDA_TYPE_NULL GValue. 783 * 784 * If @holder is invalid, then the returned value is %NULL. 785 * 786 * Returns: (allow-none) (transfer none): the value, or %NULL 787 */ 788 const GValue * 789 gda_holder_get_value (GdaHolder *holder) 790 { 791 g_return_val_if_fail (GDA_IS_HOLDER (holder), NULL); 792 g_return_val_if_fail (holder->priv, NULL); 793 794 if (holder->priv->full_bind) 795 return gda_holder_get_value (holder->priv->full_bind); 796 else { 797 if (holder->priv->valid) { 798 /* return default value if possible */ 799 if (holder->priv->default_forced) { 800 g_assert (holder->priv->default_value); 801 if (G_VALUE_TYPE (holder->priv->default_value) == holder->priv->g_type) 802 return holder->priv->default_value; 803 else 804 return NULL; 805 } 806 807 if (!holder->priv->value) 808 holder->priv->value = gda_value_new_null (); 809 return holder->priv->value; 810 } 811 else 812 return NULL; 813 } 814 } 815 816 /** 817 * gda_holder_get_value_str: 818 * @holder: a #GdaHolder object 819 * @dh: (allow-none): a #GdaDataHandler to use, or %NULL 820 * 821 * Same functionality as gda_holder_get_value() except that it returns the value as a string 822 * (the conversion is done using @dh if not %NULL, or the default data handler otherwise). 823 * 824 * Returns: (transfer full): the value, or %NULL 825 */ 826 gchar * 827 gda_holder_get_value_str (GdaHolder *holder, GdaDataHandler *dh) 828 { 829 const GValue *current_val; 830 831 g_return_val_if_fail (GDA_IS_HOLDER (holder), NULL); 832 g_return_val_if_fail (holder->priv, NULL); 833 834 gda_holder_lock ((GdaLockable*) holder); 835 current_val = gda_holder_get_value (holder); 836 if (!current_val || GDA_VALUE_HOLDS_NULL (current_val)) { 837 gda_holder_unlock ((GdaLockable*) holder); 838 return NULL; 839 } 840 else { 841 gchar *retval = NULL; 842 if (!dh) 843 dh = gda_data_handler_get_default (holder->priv->g_type); 844 if (dh) 845 retval = gda_data_handler_get_str_from_value (dh, current_val); 846 gda_holder_unlock ((GdaLockable*) holder); 847 return retval; 848 } 849 } 850 851 static gboolean real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, GError **error); 852 853 /** 854 * gda_holder_set_value: 855 * @holder: a #GdaHolder object 856 * @value: (allow-none): a value to set the holder to, or %NULL 857 * @error: a place to store errors, or %NULL 858 * 859 * Sets the value within the holder. If @holder is an alias for another 860 * holder, then the value is also set for that other holder. 861 * 862 * On success, the action of any call to gda_holder_force_invalid() is cancelled 863 * as soon as this method is called (even if @holder's value does not actually change) 864 * 865 * If the value is not different from the one already contained within @holder, 866 * then @holder is not changed and no signal is emitted. 867 * 868 * Note1: the @value argument is treated the same way if it is %NULL or if it is a #GDA_TYPE_NULL value 869 * 870 * Note2: if @holder can't accept the @value value, then this method returns FALSE, and @holder will be left 871 * in an invalid state. 872 * 873 * Note3: before the change is accepted by @holder, the "validate-change" signal will be emitted (the value 874 * of which can prevent the change from happening) which can be connected to to have a greater control 875 * of which values @holder can have, or implement some business rules. 876 * 877 * Returns: TRUE if value has been set 878 */ 879 gboolean 880 gda_holder_set_value (GdaHolder *holder, const GValue *value, GError **error) 881 { 882 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 883 g_return_val_if_fail (holder->priv, FALSE); 884 885 return real_gda_holder_set_value (holder, (GValue*) value, TRUE, error); 886 } 887 888 /** 889 * gda_holder_set_value_str: 890 * @holder: a #GdaHolder object 891 * @dh: a #GdaDataHandler to use, or %NULL 892 * @value: a value to set the holder to, as a string 893 * @error: a place to store errors, or %NULL 894 * 895 * Same functionality as gda_holder_set_value() except that it uses a string representation 896 * of the value to set, which will be converted into a GValue first (using default data handler if 897 * @dh is %NULL). 898 * 899 * Note1: if @value is %NULL or is the "NULL" string, then @holder's value is set to %NULL. 900 * Note2: if @holder can't accept the @value value, then this method returns FALSE, and @holder will be left 901 * in an invalid state. 902 * 903 * Returns: TRUE if value has been set 904 */ 905 gboolean 906 gda_holder_set_value_str (GdaHolder *holder, GdaDataHandler *dh, const gchar *value, GError **error) 907 { 908 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 909 g_return_val_if_fail (holder->priv, FALSE); 910 g_return_val_if_fail (!dh || GDA_IS_DATA_HANDLER (dh), FALSE); 911 912 if (!value || !g_ascii_strcasecmp (value, "NULL")) 913 return gda_holder_set_value (holder, NULL, error); 914 else { 915 GValue *gdaval = NULL; 916 gboolean retval = FALSE; 917 918 gda_holder_lock ((GdaLockable*) holder); 919 if (!dh) 920 dh = gda_data_handler_get_default (holder->priv->g_type); 921 if (dh) 922 gdaval = gda_data_handler_get_value_from_str (dh, value, holder->priv->g_type); 923 924 if (gdaval) 925 retval = real_gda_holder_set_value (holder, gdaval, FALSE, error); 926 else 927 g_set_error (error, GDA_HOLDER_ERROR, GDA_HOLDER_STRING_CONVERSION_ERROR, 928 _("Unable to convert string to '%s' type"), 929 gda_g_type_to_string (holder->priv->g_type)); 930 gda_holder_unlock ((GdaLockable*) holder); 931 return retval; 932 } 933 } 934 935 /** 936 * gda_holder_take_value: 937 * @holder: a #GdaHolder object 938 * @value: (transfer full): a value to set the holder to 939 * @error: a place to store errors, or %NULL 940 * 941 * Sets the value within the holder. If @holder is an alias for another 942 * holder, then the value is also set for that other holder. 943 * 944 * On success, the action of any call to gda_holder_force_invalid() is cancelled 945 * as soon as this method is called (even if @holder's value does not actually change). 946 * 947 * If the value is not different from the one already contained within @holder, 948 * then @holder is not changed and no signal is emitted. 949 * 950 * Note1: if @holder can't accept the @value value, then this method returns FALSE, and @holder will be left 951 * in an invalid state. 952 * 953 * Note2: before the change is accepted by @holder, the "validate-change" signal will be emitted (the value 954 * of which can prevent the change from happening) which can be connected to to have a greater control 955 * of which values @holder can have, or implement some business rules. 956 * 957 * Note3: if user previously set this holder with gda_holder_take_static_value () the GValue 958 * stored internally will be forgiven and replaced by the @value. User should then 959 * take care of the 'old' static GValue. 960 * 961 * Returns: TRUE if value has been set 962 */ 963 gboolean 964 gda_holder_take_value (GdaHolder *holder, GValue *value, GError **error) 965 { 966 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 967 g_return_val_if_fail (holder->priv, FALSE); 968 969 return real_gda_holder_set_value (holder, (GValue*) value, FALSE, error); 970 } 971 972 static gboolean 973 real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, GError **error) 974 { 975 gboolean changed = TRUE; 976 gboolean newvalid; 977 const GValue *current_val; 978 gboolean newnull; 979 gboolean was_valid; 980 #define DEBUG_HOLDER 981 #undef DEBUG_HOLDER 982 983 gda_holder_lock ((GdaLockable*) holder); 984 was_valid = gda_holder_is_valid (holder); 985 986 /* if the value has been set with gda_holder_take_static_value () you'll be able 987 * to change the value only with another call to real_gda_holder_set_value 988 */ 989 if (!holder->priv->is_freeable) { 990 gda_holder_unlock ((GdaLockable*) holder); 991 g_warning (_("Can't use this method to set value because there is already a static value")); 992 return FALSE; 993 } 994 995 /* holder will be changed? */ 996 newnull = !value || GDA_VALUE_HOLDS_NULL (value); 997 current_val = gda_holder_get_value (holder); 998 if (current_val == value) 999 changed = FALSE; 1000 else if ((!current_val || GDA_VALUE_HOLDS_NULL ((GValue *)current_val)) && newnull) 1001 changed = FALSE; 1002 else if (value && current_val && 1003 (G_VALUE_TYPE (value) == G_VALUE_TYPE ((GValue *)current_val))) 1004 changed = gda_value_differ (value, (GValue *)current_val); 1005 1006 /* holder's validity */ 1007 newvalid = TRUE; 1008 if (newnull && holder->priv->not_null) { 1009 g_set_error (error, GDA_HOLDER_ERROR, GDA_HOLDER_VALUE_NULL_ERROR, 1010 _("(%s): Holder does not allow NULL values"), 1011 holder->priv->id); 1012 newvalid = FALSE; 1013 changed = TRUE; 1014 } 1015 else if (!newnull && (G_VALUE_TYPE (value) != holder->priv->g_type)) { 1016 g_set_error (error, GDA_HOLDER_ERROR, GDA_HOLDER_VALUE_TYPE_ERROR, 1017 _("(%s): Wrong Holder value type, expected type '%s' when value's type is '%s'"), 1018 holder->priv->id, 1019 gda_g_type_to_string (holder->priv->g_type), 1020 gda_g_type_to_string (G_VALUE_TYPE (value))); 1021 newvalid = FALSE; 1022 changed = TRUE; 1023 } 1024 1025 if (was_valid != newvalid) 1026 changed = TRUE; 1027 1028 #ifdef DEBUG_HOLDER 1029 g_print ("Holder to change %p (%s): value %s --> %s \t(type %d -> %d) VALID: %d->%d CHANGED: %d\n", 1030 holder, holder->priv->id, 1031 gda_value_stringify ((GValue *)current_val), 1032 gda_value_stringify ((value)), 1033 current_val ? G_VALUE_TYPE ((GValue *)current_val) : 0, 1034 value ? G_VALUE_TYPE (value) : 0, 1035 was_valid, newvalid, changed); 1036 #endif 1037 1038 /* end of procedure if the value has not been changed, after calculating the holder's validity */ 1039 if (!changed) { 1040 if (!do_copy && value) 1041 gda_value_free (value); 1042 holder->priv->invalid_forced = FALSE; 1043 if (holder->priv->invalid_error) { 1044 g_error_free (holder->priv->invalid_error); 1045 holder->priv->invalid_error = NULL; 1046 } 1047 holder->priv->valid = newvalid; 1048 gda_holder_unlock ((GdaLockable*) holder); 1049 return TRUE; 1050 } 1051 1052 /* check if we are allowed to change value */ 1053 if (holder->priv->validate_changes) { 1054 GError *lerror = NULL; 1055 g_signal_emit (holder, gda_holder_signals[VALIDATE_CHANGE], 0, value, &lerror); 1056 if (lerror) { 1057 /* change refused by signal callback */ 1058 #ifdef DEBUG_HOLDER 1059 g_print ("Holder change refused %p (ERROR %s)\n", holder, 1060 lerror->message); 1061 #endif 1062 g_propagate_error (error, lerror); 1063 if (!do_copy) 1064 gda_value_free (value); 1065 gda_holder_unlock ((GdaLockable*) holder); 1066 return FALSE; 1067 } 1068 } 1069 1070 /* new valid status */ 1071 holder->priv->invalid_forced = FALSE; 1072 if (holder->priv->invalid_error) { 1073 g_error_free (holder->priv->invalid_error); 1074 holder->priv->invalid_error = NULL; 1075 } 1076 holder->priv->valid = newvalid; 1077 /* we're setting a non-static value, so be sure to flag is as freeable */ 1078 holder->priv->is_freeable = TRUE; 1079 1080 /* check is the new value is the default one */ 1081 holder->priv->default_forced = FALSE; 1082 if (holder->priv->default_value) { 1083 if ((G_VALUE_TYPE (holder->priv->default_value) == GDA_TYPE_NULL) && newnull) 1084 holder->priv->default_forced = TRUE; 1085 else if ((G_VALUE_TYPE (holder->priv->default_value) == holder->priv->g_type) && 1086 value && (G_VALUE_TYPE (value) == holder->priv->g_type)) 1087 holder->priv->default_forced = !gda_value_compare (holder->priv->default_value, value); 1088 } 1089 GValue att_value = {0}; 1090 g_value_init (&att_value, G_TYPE_BOOLEAN); 1091 g_value_set_boolean (&att_value, holder->priv->default_forced); 1092 gda_holder_set_attribute_static (holder, GDA_ATTRIBUTE_IS_DEFAULT, &att_value); 1093 1094 /* real setting of the value */ 1095 if (holder->priv->full_bind) { 1096 #ifdef DEBUG_HOLDER 1097 g_print ("Holder %p is alias of holder %p => propagating changes to holder %p\n", 1098 holder, holder->priv->full_bind, holder->priv->full_bind); 1099 #endif 1100 gda_holder_unlock ((GdaLockable*) holder); 1101 return real_gda_holder_set_value (holder->priv->full_bind, value, do_copy, error); 1102 } 1103 else { 1104 if (holder->priv->value) { 1105 gda_value_free (holder->priv->value); 1106 holder->priv->value = NULL; 1107 } 1108 1109 if (value) { 1110 if (newvalid) { 1111 if (do_copy) 1112 holder->priv->value = gda_value_copy (value); 1113 else 1114 holder->priv->value = value; 1115 } 1116 else if (!do_copy) 1117 gda_value_free (value); 1118 } 1119 1120 g_signal_emit (holder, gda_holder_signals[CHANGED], 0); 1121 } 1122 1123 gda_holder_unlock ((GdaLockable*) holder); 1124 return newvalid; 1125 } 1126 1127 static GValue * 1128 real_gda_holder_set_const_value (GdaHolder *holder, const GValue *value, 1129 gboolean *value_changed, GError **error) 1130 { 1131 gboolean changed = TRUE; 1132 gboolean newvalid; 1133 const GValue *current_val; 1134 GValue *value_to_return = NULL; 1135 gboolean newnull; 1136 #define DEBUG_HOLDER 1137 #undef DEBUG_HOLDER 1138 1139 #ifdef DEBUG_HOLDER 1140 gboolean was_valid = gda_holder_is_valid (holder); 1141 #endif 1142 1143 /* holder will be changed? */ 1144 newnull = !value || GDA_VALUE_HOLDS_NULL (value); 1145 current_val = gda_holder_get_value (holder); 1146 if (current_val == value) 1147 changed = FALSE; 1148 else if ((!current_val || GDA_VALUE_HOLDS_NULL (current_val)) && newnull) 1149 changed = FALSE; 1150 else if (value && current_val && 1151 (G_VALUE_TYPE (value) == G_VALUE_TYPE (current_val))) 1152 changed = gda_value_differ (value, current_val); 1153 1154 /* holder's validity */ 1155 newvalid = TRUE; 1156 if (newnull && holder->priv->not_null) { 1157 g_set_error (error, GDA_HOLDER_ERROR, GDA_HOLDER_VALUE_NULL_ERROR, 1158 _("(%s): Holder does not allow NULL values"), 1159 holder->priv->id); 1160 newvalid = FALSE; 1161 changed = TRUE; 1162 } 1163 else if (!newnull && (G_VALUE_TYPE (value) != holder->priv->g_type)) { 1164 g_set_error (error, GDA_HOLDER_ERROR, GDA_HOLDER_VALUE_TYPE_ERROR, 1165 _("(%s): Wrong value type: expected type '%s' when value's type is '%s'"), 1166 holder->priv->id, 1167 gda_g_type_to_string (holder->priv->g_type), 1168 gda_g_type_to_string (G_VALUE_TYPE (value))); 1169 newvalid = FALSE; 1170 changed = TRUE; 1171 } 1172 1173 #ifdef DEBUG_HOLDER 1174 g_print ("Changed holder %p (%s): value %s --> %s \t(type %d -> %d) VALID: %d->%d CHANGED: %d\n", 1175 holder, holder->priv->id, 1176 current_val ? gda_value_stringify ((GValue *)current_val) : "_NULL_", 1177 value ? gda_value_stringify ((value)) : "_NULL_", 1178 current_val ? G_VALUE_TYPE ((GValue *)current_val) : 0, 1179 value ? G_VALUE_TYPE (value) : 0, 1180 was_valid, newvalid, changed); 1181 #endif 1182 1183 1184 /* end of procedure if the value has not been changed, after calculating the holder's validity */ 1185 if (!changed) { 1186 holder->priv->invalid_forced = FALSE; 1187 if (holder->priv->invalid_error) { 1188 g_error_free (holder->priv->invalid_error); 1189 holder->priv->invalid_error = NULL; 1190 } 1191 holder->priv->valid = newvalid; 1192 #ifdef DEBUG_HOLDER 1193 g_print ("Holder is not changed"); 1194 #endif 1195 /* set the changed status */ 1196 *value_changed = FALSE; 1197 } 1198 else { 1199 *value_changed = TRUE; 1200 } 1201 1202 /* check if we are allowed to change value */ 1203 if (holder->priv->validate_changes) { 1204 GError *lerror = NULL; 1205 g_signal_emit (holder, gda_holder_signals[VALIDATE_CHANGE], 0, value, &lerror); 1206 if (lerror) { 1207 /* change refused by signal callback */ 1208 g_propagate_error (error, lerror); 1209 return NULL; 1210 } 1211 } 1212 1213 /* new valid status */ 1214 holder->priv->invalid_forced = FALSE; 1215 if (holder->priv->invalid_error) { 1216 g_error_free (holder->priv->invalid_error); 1217 holder->priv->invalid_error = NULL; 1218 } 1219 holder->priv->valid = newvalid; 1220 /* we're setting a static value, so be sure to flag is as unfreeable */ 1221 holder->priv->is_freeable = FALSE; 1222 1223 /* check is the new value is the default one */ 1224 holder->priv->default_forced = FALSE; 1225 if (holder->priv->default_value) { 1226 if ((G_VALUE_TYPE (holder->priv->default_value) == GDA_TYPE_NULL) && newnull) 1227 holder->priv->default_forced = TRUE; 1228 else if ((G_VALUE_TYPE (holder->priv->default_value) == holder->priv->g_type) && 1229 value && (G_VALUE_TYPE (value) == holder->priv->g_type)) 1230 holder->priv->default_forced = !gda_value_compare (holder->priv->default_value, value); 1231 } 1232 GValue *att_value; 1233 g_value_set_boolean ((att_value = gda_value_new (G_TYPE_BOOLEAN)), holder->priv->default_forced); 1234 gda_holder_set_attribute_static (holder, GDA_ATTRIBUTE_IS_DEFAULT, att_value); 1235 gda_value_free (att_value); 1236 1237 /* real setting of the value */ 1238 if (holder->priv->full_bind) { 1239 #ifdef DEBUG_HOLDER 1240 g_print ("Holder %p is alias of holder %p => propagating changes to holder %p\n", 1241 holder, holder->priv->full_bind, holder->priv->full_bind); 1242 #endif 1243 return real_gda_holder_set_const_value (holder->priv->full_bind, value, 1244 value_changed, error); 1245 } 1246 else { 1247 if (holder->priv->value) { 1248 if (G_IS_VALUE (holder->priv->value)) 1249 value_to_return = holder->priv->value; 1250 else 1251 value_to_return = NULL; 1252 holder->priv->value = NULL; 1253 } 1254 1255 if (value) { 1256 if (newvalid) { 1257 holder->priv->value = (GValue*)value; 1258 } 1259 } 1260 1261 g_signal_emit (holder, gda_holder_signals[CHANGED], 0); 1262 } 1263 1264 #ifdef DEBUG_HOLDER 1265 g_print ("returning %p, wannabe was %p\n", value_to_return, 1266 value); 1267 #endif 1268 1269 return value_to_return; 1270 } 1271 1272 /** 1273 * gda_holder_take_static_value: 1274 * @holder: a #GdaHolder object 1275 * @value: a const value to set the holder to 1276 * @value_changed: a boolean set with TRUE if the value changes, FALSE elsewhere. 1277 * @error: a place to store errors, or %NULL 1278 * 1279 * Sets the const value within the holder. If @holder is an alias for another 1280 * holder, then the value is also set for that other holder. 1281 * 1282 * The value will not be freed, and user should take care of it, either for its 1283 * freeing or for its correct value at the moment of query. 1284 * 1285 * If the value is not different from the one already contained within @holder, 1286 * then @holder is not changed and no signal is emitted. 1287 * 1288 * Note1: if @holder can't accept the @value value, then this method returns NULL, and @holder will be left 1289 * in an invalid state. 1290 * 1291 * Note2: before the change is accepted by @holder, the "validate-change" signal will be emitted (the value 1292 * of which can prevent the change from happening) which can be connected to to have a greater control 1293 * of which values @holder can have, or implement some business rules. 1294 * 1295 * Returns: NULL if an error occurred or if the previous GValue was NULL itself. It returns 1296 * the static GValue user set previously, so that he can free it. 1297 */ 1298 GValue * 1299 gda_holder_take_static_value (GdaHolder *holder, const GValue *value, gboolean *value_changed, 1300 GError **error) 1301 { 1302 GValue *retvalue; 1303 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 1304 g_return_val_if_fail (holder->priv, FALSE); 1305 1306 gda_holder_lock ((GdaLockable*) holder); 1307 retvalue = real_gda_holder_set_const_value (holder, value, value_changed, error); 1308 gda_holder_unlock ((GdaLockable*) holder); 1309 1310 return retvalue; 1311 } 1312 1313 /** 1314 * gda_holder_force_invalid: 1315 * @holder: a #GdaHolder object 1316 * 1317 * Forces a holder to be invalid; to set it valid again, a new value must be assigned 1318 * to it using gda_holder_set_value() or gda_holder_take_value(). 1319 * 1320 * @holder's value is set to %NULL. 1321 */ 1322 void 1323 gda_holder_force_invalid (GdaHolder *holder) 1324 { 1325 g_return_if_fail (GDA_IS_HOLDER (holder)); 1326 gda_holder_force_invalid_e (holder, NULL); 1327 } 1328 1329 /** 1330 * gda_holder_force_invalid_e: 1331 * @holder: a #GdaHolder object 1332 * @error: (allow-none) (transfer full): a #GError explaining why @holder is declared invalid, or %NULL 1333 * 1334 * Forces a holder to be invalid; to set it valid again, a new value must be assigned 1335 * to it using gda_holder_set_value() or gda_holder_take_value(). 1336 * 1337 * @holder's value is set to %NULL. 1338 * 1339 * Since: 4.2.10 1340 */ 1341 void 1342 gda_holder_force_invalid_e (GdaHolder *holder, GError *error) 1343 { 1344 g_return_if_fail (GDA_IS_HOLDER (holder)); 1345 g_return_if_fail (holder->priv); 1346 1347 #ifdef GDA_DEBUG_NO 1348 g_print ("Holder %p (%s): declare invalid\n", holder, holder->priv->id); 1349 #endif 1350 1351 gda_holder_lock ((GdaLockable*) holder); 1352 if (holder->priv->invalid_error) 1353 g_error_free (holder->priv->invalid_error); 1354 holder->priv->invalid_error = error; 1355 1356 if (holder->priv->invalid_forced) { 1357 gda_holder_unlock ((GdaLockable*) holder); 1358 return; 1359 } 1360 1361 holder->priv->invalid_forced = TRUE; 1362 holder->priv->valid = FALSE; 1363 if (holder->priv->value) { 1364 if (holder->priv->is_freeable) 1365 gda_value_free (holder->priv->value); 1366 holder->priv->value = NULL; 1367 } 1368 1369 /* if we are an alias, then we forward the value setting to the master */ 1370 if (holder->priv->full_bind) 1371 gda_holder_force_invalid (holder->priv->full_bind); 1372 else 1373 g_signal_emit (holder, gda_holder_signals[CHANGED], 0); 1374 gda_holder_unlock ((GdaLockable*) holder); 1375 } 1376 1377 /** 1378 * gda_holder_is_valid: 1379 * @holder: a #GdaHolder object 1380 * 1381 * Get the validity of @holder (that is, of the value held by @holder) 1382 * 1383 * Returns: TRUE if @holder's value can safely be used 1384 */ 1385 gboolean 1386 gda_holder_is_valid (GdaHolder *holder) 1387 { 1388 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 1389 return gda_holder_is_valid_e (holder, NULL); 1390 } 1391 1392 /** 1393 * gda_holder_is_valid_e: 1394 * @holder: a #GdaHolder object 1395 * @error: (allow-none): a place to store invalid error, or %NULL 1396 * 1397 * Get the validity of @holder (that is, of the value held by @holder) 1398 * 1399 * Returns: TRUE if @holder's value can safely be used 1400 * 1401 * Since: 4.2.10 1402 */ 1403 gboolean 1404 gda_holder_is_valid_e (GdaHolder *holder, GError **error) 1405 { 1406 gboolean retval; 1407 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 1408 g_return_val_if_fail (holder->priv, FALSE); 1409 1410 gda_holder_lock ((GdaLockable*) holder); 1411 if (holder->priv->full_bind) 1412 retval = gda_holder_is_valid_e (holder->priv->full_bind, error); 1413 else { 1414 if (holder->priv->invalid_forced) 1415 retval = FALSE; 1416 else { 1417 if (holder->priv->default_forced) 1418 retval = holder->priv->default_value ? TRUE : FALSE; 1419 else 1420 retval = holder->priv->valid; 1421 } 1422 if (!retval && holder->priv->invalid_error) 1423 g_propagate_error (error, g_error_copy (holder->priv->invalid_error)); 1424 } 1425 gda_holder_unlock ((GdaLockable*) holder); 1426 return retval; 1427 } 1428 1429 /** 1430 * gda_holder_set_value_to_default: 1431 * @holder: a #GdaHolder object 1432 * 1433 * Set @holder's value to its default value. 1434 * 1435 * Returns: TRUE if @holder has got a default value 1436 */ 1437 gboolean 1438 gda_holder_set_value_to_default (GdaHolder *holder) 1439 { 1440 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 1441 g_return_val_if_fail (holder->priv, FALSE); 1442 1443 gda_holder_lock ((GdaLockable*) holder); 1444 if (holder->priv->default_forced) { 1445 gda_holder_unlock ((GdaLockable*) holder); 1446 return TRUE; 1447 } 1448 1449 if (!holder->priv->default_value) { 1450 gda_holder_unlock ((GdaLockable*) holder); 1451 return FALSE; 1452 } 1453 else { 1454 holder->priv->default_forced = TRUE; 1455 holder->priv->invalid_forced = FALSE; 1456 if (holder->priv->invalid_error) { 1457 g_error_free (holder->priv->invalid_error); 1458 holder->priv->invalid_error = NULL; 1459 } 1460 1461 if (holder->priv->value) { 1462 if (holder->priv->is_freeable) 1463 gda_value_free (holder->priv->value); 1464 holder->priv->value = NULL; 1465 } 1466 } 1467 1468 GValue *att_value; 1469 g_value_set_boolean ((att_value = gda_value_new (G_TYPE_BOOLEAN)), TRUE); 1470 gda_holder_set_attribute_static (holder, GDA_ATTRIBUTE_IS_DEFAULT, att_value); 1471 gda_value_free (att_value); 1472 g_signal_emit (holder, gda_holder_signals[CHANGED], 0); 1473 1474 gda_holder_unlock ((GdaLockable*) holder); 1475 return TRUE; 1476 } 1477 1478 /** 1479 * gda_holder_value_is_default: 1480 * @holder: a #GdaHolder object 1481 * 1482 * Tells if @holder's current value is the default one. 1483 * 1484 * Returns: TRUE if @holder @holder's current value is the default one 1485 */ 1486 gboolean 1487 gda_holder_value_is_default (GdaHolder *holder) 1488 { 1489 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 1490 g_return_val_if_fail (holder->priv, FALSE); 1491 1492 return holder->priv->default_forced; 1493 } 1494 1495 1496 /** 1497 * gda_holder_get_default_value: 1498 * @holder: a #GdaHolder object 1499 * 1500 * Get the default value held into the holder. WARNING: the default value does not need to be of 1501 * the same type as the one required by @holder. 1502 * 1503 * Returns: the default value 1504 */ 1505 const GValue * 1506 gda_holder_get_default_value (GdaHolder *holder) 1507 { 1508 g_return_val_if_fail (GDA_IS_HOLDER (holder), NULL); 1509 g_return_val_if_fail (holder->priv, NULL); 1510 1511 return holder->priv->default_value; 1512 } 1513 1514 1515 /** 1516 * gda_holder_set_default_value: 1517 * @holder: a #GdaHolder object 1518 * @value: a value to set the holder's default value, or %NULL 1519 * 1520 * Sets the default value within the holder. If @value is %NULL then @holder won't have a 1521 * default value anymore. To set a default value to %NULL, then pass a #GValue created using 1522 * gda_value_new_null(). 1523 * 1524 * NOTE: the default value does not need to be of the same type as the one required by @holder. 1525 */ 1526 void 1527 gda_holder_set_default_value (GdaHolder *holder, const GValue *value) 1528 { 1529 g_return_if_fail (GDA_IS_HOLDER (holder)); 1530 g_return_if_fail (holder->priv); 1531 1532 gda_holder_lock ((GdaLockable*) holder); 1533 if (holder->priv->default_value) { 1534 if (holder->priv->default_forced) { 1535 gda_holder_take_value (holder, holder->priv->default_value, NULL); 1536 holder->priv->default_forced = FALSE; 1537 holder->priv->default_value = NULL; 1538 } 1539 else { 1540 gda_value_free (holder->priv->default_value); 1541 holder->priv->default_value = NULL; 1542 } 1543 } 1544 1545 holder->priv->default_forced = FALSE; 1546 if (value) { 1547 const GValue *current = gda_holder_get_value (holder); 1548 1549 /* check if default is equal to current value */ 1550 if (GDA_VALUE_HOLDS_NULL (value) && 1551 (!current || GDA_VALUE_HOLDS_NULL (current))) 1552 holder->priv->default_forced = TRUE; 1553 else if ((G_VALUE_TYPE (value) == holder->priv->g_type) && 1554 current && !gda_value_compare (value, current)) 1555 holder->priv->default_forced = TRUE; 1556 1557 holder->priv->default_value = gda_value_copy ((GValue *)value); 1558 } 1559 1560 GValue *att_value; 1561 g_value_set_boolean ((att_value = gda_value_new (G_TYPE_BOOLEAN)), holder->priv->default_forced); 1562 gda_holder_set_attribute_static (holder, GDA_ATTRIBUTE_IS_DEFAULT, att_value); 1563 gda_value_free (att_value); 1564 1565 /* don't emit the "changed" signal */ 1566 gda_holder_unlock ((GdaLockable*) holder); 1567 } 1568 1569 /** 1570 * gda_holder_set_not_null: 1571 * @holder: a #GdaHolder object 1572 * @not_null: TRUE if @holder should not accept %NULL values 1573 * 1574 * Sets if the holder can have a NULL value. If @not_null is TRUE, then that won't be allowed 1575 */ 1576 void 1577 gda_holder_set_not_null (GdaHolder *holder, gboolean not_null) 1578 { 1579 g_return_if_fail (GDA_IS_HOLDER (holder)); 1580 g_return_if_fail (holder->priv); 1581 1582 g_object_set (G_OBJECT (holder), "not-null", not_null, NULL); 1583 } 1584 1585 /** 1586 * gda_holder_get_not_null: 1587 * @holder: a #GdaHolder object 1588 * 1589 * Get wether the holder can be NULL or not 1590 * 1591 * Returns: TRUE if the holder cannot be NULL 1592 */ 1593 gboolean 1594 gda_holder_get_not_null (GdaHolder *holder) 1595 { 1596 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 1597 g_return_val_if_fail (holder->priv, FALSE); 1598 1599 return holder->priv->not_null; 1600 } 1601 1602 /** 1603 * gda_holder_set_source_model: 1604 * @holder: a #GdaHolder object 1605 * @model: a #GdaDataModel object or %NULL 1606 * @col: the reference column in @model 1607 * @error: location to store error, or %NULL 1608 * 1609 * Sets an hint that @holder's values should be restricted among the values 1610 * contained in the @col column of the @model data model. Note that this is just a hint, 1611 * meaning this policy is not enforced by @holder's implementation. 1612 * 1613 * If @model is %NULL, then the effect is to cancel ant previous call to gda_holder_set_source_model() 1614 * where @model was not %NULL. 1615 * 1616 * Returns: TRUE if no error occurred 1617 */ 1618 gboolean 1619 gda_holder_set_source_model (GdaHolder *holder, GdaDataModel *model, 1620 gint col, GError **error) 1621 { 1622 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 1623 g_return_val_if_fail (holder->priv, FALSE); 1624 if (model) 1625 g_return_val_if_fail (GDA_IS_DATA_MODEL (model), FALSE); 1626 1627 /* No check is done on the validity of @col or even its existance */ 1628 /* Note: for internal implementation if @col<0, then it's ignored */ 1629 1630 gda_holder_lock ((GdaLockable*) holder); 1631 if (model && (col >= 0)) { 1632 GType htype, ctype; 1633 GdaColumn *gcol; 1634 htype = gda_holder_get_g_type (holder); 1635 gcol = gda_data_model_describe_column (model, col); 1636 if (gcol) { 1637 ctype = gda_column_get_g_type (gcol); 1638 if ((htype != GDA_TYPE_NULL) && (ctype != GDA_TYPE_NULL) && 1639 (htype != ctype)) { 1640 g_set_error (error, GDA_HOLDER_ERROR, GDA_HOLDER_VALUE_TYPE_ERROR, 1641 _("GdaHolder has a gda type (%s) incompatible with " 1642 "source column %d type (%s)"), 1643 gda_g_type_to_string (htype), 1644 col, gda_g_type_to_string (ctype)); 1645 gda_holder_unlock ((GdaLockable*) holder); 1646 return FALSE; 1647 } 1648 } 1649 } 1650 1651 if (col >= 0) 1652 holder->priv->source_col = col; 1653 1654 if (holder->priv->source_model != model) { 1655 if (holder->priv->source_model) { 1656 g_object_unref (holder->priv->source_model); 1657 holder->priv->source_model = NULL; 1658 } 1659 1660 holder->priv->source_model = model; 1661 if (model) 1662 g_object_ref (model); 1663 else 1664 holder->priv->source_col = 0; 1665 } 1666 1667 #ifdef GDA_DEBUG_signal 1668 g_print (">> 'SOURCE_CHANGED' from %p\n", holder); 1669 #endif 1670 g_signal_emit (holder, gda_holder_signals[SOURCE_CHANGED], 0); 1671 #ifdef GDA_DEBUG_signal 1672 g_print ("<< 'SOURCE_CHANGED' from %p\n", holder); 1673 #endif 1674 1675 gda_holder_unlock ((GdaLockable*) holder); 1676 return TRUE; 1677 } 1678 1679 1680 /** 1681 * gda_holder_get_source_model: 1682 * @holder: a #GdaHolder 1683 * @col: a place to store the column in the model sourcing the holder, or %NULL 1684 * 1685 * If gda_holder_set_source_model() has been used to provide a hint that @holder's value 1686 * should be among the values contained in a column of a data model, then this method 1687 * returns which data model, and if @col is not %NULL, then it is set to the restricting column 1688 * as well. 1689 * 1690 * Otherwise, this method returns %NULL, and if @col is not %NULL, then it is set to 0. 1691 * 1692 * Returns: (transfer none): a pointer to a #GdaDataModel, or %NULL 1693 */ 1694 GdaDataModel * 1695 gda_holder_get_source_model (GdaHolder *holder, gint *col) 1696 { 1697 GdaDataModel *model; 1698 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 1699 g_return_val_if_fail (holder->priv, FALSE); 1700 1701 gda_holder_lock ((GdaLockable*) holder); 1702 if (col) 1703 *col = holder->priv->source_col; 1704 model = holder->priv->source_model; 1705 gda_holder_unlock ((GdaLockable*) holder); 1706 return model; 1707 } 1708 1709 /* 1710 * This callback is called when @holder->priv->simple_bind's GType was GDA_TYPE_NULL at the time 1711 * gda_holder_set_bind() was called, and it makes sure @holder's GType is the same as @holder->priv->simple_bind's 1712 */ 1713 static void 1714 bind_to_notify_cb (GdaHolder *bind_to, G_GNUC_UNUSED GParamSpec *pspec, GdaHolder *holder) 1715 { 1716 gda_holder_lock ((GdaLockable*) holder); 1717 gda_holder_lock ((GdaLockable*) bind_to); 1718 1719 g_signal_handler_disconnect (holder->priv->simple_bind, 1720 holder->priv->simple_bind_type_changed_id); 1721 holder->priv->simple_bind_type_changed_id = 0; 1722 if (holder->priv->g_type == GDA_TYPE_NULL) { 1723 holder->priv->g_type = bind_to->priv->g_type; 1724 g_object_notify ((GObject*) holder, "g-type"); 1725 } 1726 else if (holder->priv->g_type != bind_to->priv->g_type) { 1727 /* break holder's binding because type differ */ 1728 g_warning (_("Cannot bind holders if their type is not the same, " 1729 "breaking existing bind where '%s' was bound to '%s'"), 1730 gda_holder_get_id (holder), gda_holder_get_id (bind_to)); 1731 gda_holder_set_bind (holder, NULL, NULL); 1732 } 1733 1734 gda_holder_unlock ((GdaLockable*) holder); 1735 gda_holder_unlock ((GdaLockable*) bind_to); 1736 } 1737 1738 /** 1739 * gda_holder_set_bind: 1740 * @holder: a #GdaHolder 1741 * @bind_to: a #GdaHolder or %NULL 1742 * @error: a place to store errors, or %NULL 1743 * 1744 * Sets @holder to change when @bind_to changes (and does not make @bind_to change when @holder changes). 1745 * For the operation to succeed, the GType of @holder and @bind_to must be the same, with the exception that 1746 * any of them can have a %GDA_TYPE_NULL type (in this situation, the GType of the two #GdaHolder objects 1747 * involved is set to match the other when any of them sets its type to something different than GDA_TYPE_NULL). 1748 * 1749 * If @bind_to is %NULL, then @holder will not be bound anymore. 1750 * 1751 * Returns: TRUE if no error occurred 1752 */ 1753 gboolean 1754 gda_holder_set_bind (GdaHolder *holder, GdaHolder *bind_to, GError **error) 1755 { 1756 const GValue *cvalue; 1757 GValue *value1 = NULL; 1758 const GValue *value2 = NULL; 1759 1760 g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE); 1761 g_return_val_if_fail (holder->priv, FALSE); 1762 g_return_val_if_fail (holder != bind_to, FALSE); 1763 1764 gda_holder_lock ((GdaLockable*) holder); 1765 if (holder->priv->simple_bind == bind_to) { 1766 gda_holder_unlock ((GdaLockable*) holder); 1767 return TRUE; 1768 } 1769 1770 /* get a copy of the current values of @holder and @bind_to */ 1771 if (bind_to) { 1772 g_return_val_if_fail (GDA_IS_HOLDER (bind_to), FALSE); 1773 g_return_val_if_fail (bind_to->priv, FALSE); 1774 1775 if ((holder->priv->g_type != GDA_TYPE_NULL) && 1776 (bind_to->priv->g_type != GDA_TYPE_NULL) && 1777 (holder->priv->g_type != bind_to->priv->g_type)) { 1778 g_set_error (error, GDA_HOLDER_ERROR, GDA_HOLDER_VALUE_TYPE_ERROR, 1779 "%s", _("Cannot bind holders if their type is not the same")); 1780 gda_holder_unlock ((GdaLockable*) holder); 1781 return FALSE; 1782 } 1783 value2 = gda_holder_get_value (bind_to); 1784 } 1785 1786 cvalue = gda_holder_get_value (holder); 1787 if (cvalue) 1788 value1 = gda_value_copy ((GValue*)cvalue); 1789 1790 /* get rid of the old alias */ 1791 if (holder->priv->simple_bind) { 1792 g_signal_handlers_disconnect_by_func (holder->priv->simple_bind, 1793 G_CALLBACK (bound_holder_changed_cb), holder); 1794 1795 if (holder->priv->simple_bind_type_changed_id) { 1796 g_signal_handler_disconnect (holder->priv->simple_bind, 1797 holder->priv->simple_bind_type_changed_id); 1798 holder->priv->simple_bind_type_changed_id = 0; 1799 } 1800 g_object_unref (holder->priv->simple_bind); 1801 holder->priv->simple_bind = NULL; 1802 } 1803 1804 /* setting the new alias or reseting the value if there is no new alias */ 1805 gboolean retval; 1806 if (bind_to) { 1807 holder->priv->simple_bind = g_object_ref (bind_to); 1808 g_signal_connect (holder->priv->simple_bind, "changed", 1809 G_CALLBACK (bound_holder_changed_cb), holder); 1810 1811 if (bind_to->priv->g_type == GDA_TYPE_NULL) 1812 holder->priv->simple_bind_type_changed_id = g_signal_connect (bind_to, "notify::g-type", 1813 G_CALLBACK (bind_to_notify_cb), 1814 holder); 1815 else if (holder->priv->g_type == GDA_TYPE_NULL) 1816 g_object_set ((GObject*) holder, "g-type", bind_to->priv->g_type , NULL); 1817 1818 /* if bind_to has a different value than holder, then we set holder to the new value */ 1819 if (value1) 1820 gda_value_free (value1); 1821 retval = gda_holder_set_value (holder, value2, error); 1822 } 1823 else 1824 retval = gda_holder_take_value (holder, value1, error); 1825 1826 gda_holder_unlock ((GdaLockable*) holder); 1827 return retval; 1828 } 1829 1830 /* 1831 * gda_holder_set_full_bind 1832 * @holder: a #GdaHolder 1833 * @alias_of: a #GdaHolder or %NULL 1834 * 1835 * Sets @holder to change when @alias_of changes and makes @alias_of change when @holder changes. 1836 * The difference with gda_holder_set_bind is that when @holder changes, then @alias_of also 1837 * changes. 1838 */ 1839 static void 1840 gda_holder_set_full_bind (GdaHolder *holder, GdaHolder *alias_of) 1841 { 1842 const GValue *cvalue; 1843 GValue *value1 = NULL, *value2 = NULL; 1844 1845 g_return_if_fail (GDA_IS_HOLDER (holder)); 1846 g_return_if_fail (holder->priv); 1847 1848 gda_holder_lock ((GdaLockable*) holder); 1849 if (holder->priv->full_bind == alias_of) { 1850 gda_holder_unlock ((GdaLockable*) holder); 1851 return; 1852 } 1853 1854 /* get a copy of the current values of @holder and @alias_of */ 1855 if (alias_of) { 1856 g_return_if_fail (GDA_IS_HOLDER (alias_of)); 1857 g_return_if_fail (alias_of->priv); 1858 g_return_if_fail (holder->priv->g_type == alias_of->priv->g_type); 1859 cvalue = gda_holder_get_value (alias_of); 1860 if (cvalue && !GDA_VALUE_HOLDS_NULL ((GValue*)cvalue)) 1861 value2 = gda_value_copy ((GValue*)cvalue); 1862 } 1863 1864 cvalue = gda_holder_get_value (holder); 1865 if (cvalue && !GDA_VALUE_HOLDS_NULL ((GValue*)cvalue)) 1866 value1 = gda_value_copy ((GValue*)cvalue); 1867 1868 /* get rid of the old alias */ 1869 if (holder->priv->full_bind) { 1870 g_signal_handlers_disconnect_by_func (holder->priv->full_bind, 1871 G_CALLBACK (full_bound_holder_changed_cb), holder); 1872 g_object_unref (holder->priv->full_bind); 1873 holder->priv->full_bind = NULL; 1874 } 1875 1876 /* setting the new alias or reseting the value if there is no new alias */ 1877 if (alias_of) { 1878 gboolean equal = FALSE; 1879 1880 /* get rid of the internal holder's value */ 1881 if (holder->priv->value) { 1882 if (holder->priv->is_freeable) 1883 gda_value_free (holder->priv->value); 1884 holder->priv->value = NULL; 1885 } 1886 1887 holder->priv->full_bind = g_object_ref (alias_of); 1888 g_signal_connect (holder->priv->full_bind, "changed", 1889 G_CALLBACK (full_bound_holder_changed_cb), holder); 1890 1891 /* if alias_of has a different value than holder, then we emit a CHANGED signal */ 1892 if (value1 && value2 && 1893 (G_VALUE_TYPE (value1) == G_VALUE_TYPE (value2))) 1894 equal = !gda_value_compare (value1, value2); 1895 else { 1896 if (!value1 && !value2) 1897 equal = TRUE; 1898 } 1899 1900 if (!equal) 1901 g_signal_emit (holder, gda_holder_signals[CHANGED], 0); 1902 } 1903 else { 1904 /* restore the value that was in the previous alias holder, 1905 * if there was such a value, and don't emit a signal */ 1906 g_assert (! holder->priv->value); 1907 if (value1) 1908 holder->priv->value = value1; 1909 value1 = NULL; 1910 } 1911 1912 if (value1) gda_value_free (value1); 1913 if (value2) gda_value_free (value2); 1914 gda_holder_unlock ((GdaLockable*) holder); 1915 } 1916 1917 static void 1918 full_bound_holder_changed_cb (GdaHolder *alias_of, GdaHolder *holder) 1919 { 1920 gda_holder_lock ((GdaLockable*) holder); 1921 gda_holder_lock ((GdaLockable*) alias_of); 1922 1923 g_assert (alias_of == holder->priv->full_bind); 1924 g_signal_emit (holder, gda_holder_signals [CHANGED], 0); 1925 1926 gda_holder_unlock ((GdaLockable*) holder); 1927 gda_holder_unlock ((GdaLockable*) alias_of); 1928 } 1929 1930 static void 1931 bound_holder_changed_cb (GdaHolder *alias_of, GdaHolder *holder) 1932 { 1933 gda_holder_lock ((GdaLockable*) holder); 1934 gda_holder_lock ((GdaLockable*) alias_of); 1935 1936 g_assert (alias_of == holder->priv->simple_bind); 1937 const GValue *cvalue; 1938 GError *lerror = NULL; 1939 cvalue = gda_holder_get_value (alias_of); 1940 if (! gda_holder_set_value (holder, cvalue, &lerror)) { 1941 if (lerror && ((lerror->domain != GDA_HOLDER_ERROR) || (lerror->code != GDA_HOLDER_VALUE_NULL_ERROR))) 1942 g_warning (_("Could not change GdaHolder to match value change in bound GdaHolder: %s"), 1943 lerror && lerror->message ? lerror->message : _("No detail")); 1944 g_clear_error (&lerror); 1945 } 1946 gda_holder_unlock ((GdaLockable*) holder); 1947 gda_holder_unlock ((GdaLockable*) alias_of); 1948 } 1949 1950 /** 1951 * gda_holder_get_bind: 1952 * @holder: a #GdaHolder 1953 * 1954 * Get the holder which makes @holder change its value when the holder's value is changed. 1955 * 1956 * Returns: (transfer none): the #GdaHolder or %NULL 1957 */ 1958 GdaHolder * 1959 gda_holder_get_bind (GdaHolder *holder) 1960 { 1961 g_return_val_if_fail (GDA_IS_HOLDER (holder), NULL); 1962 g_return_val_if_fail (holder->priv, NULL); 1963 1964 return holder->priv->simple_bind; 1965 } 1966 1967 /** 1968 * gda_holder_get_alphanum_id: 1969 * @holder: a #GdaHolder object 1970 * 1971 * Get an "encoded" version of @holder's name. The "encoding" consists in replacing non 1972 * alphanumeric character with the string "__gdaXX" where XX is the hex. representation 1973 * of the non alphanumeric char. 1974 * 1975 * This method is just a wrapper around the gda_text_to_alphanum() function. 1976 * 1977 * Returns: (transfer full): a new string 1978 */ 1979 gchar * 1980 gda_holder_get_alphanum_id (GdaHolder *holder) 1981 { 1982 g_return_val_if_fail (GDA_IS_HOLDER (holder), NULL); 1983 g_return_val_if_fail (holder->priv, NULL); 1984 return gda_text_to_alphanum (holder->priv->id); 1985 } 1986 1987 /** 1988 * gda_holder_get_attribute: 1989 * @holder: a #GdaHolder 1990 * @attribute: attribute name as a string 1991 * 1992 * Get the value associated to a named attribute. 1993 * 1994 * Attributes can have any name, but Libgda proposes some default names, see <link linkend="libgda-40-Attributes-manager.synopsis">this section</link>. 1995 * 1996 * Returns: a read-only #GValue, or %NULL if not attribute named @attribute has been set for @holder 1997 */ 1998 const GValue * 1999 gda_holder_get_attribute (GdaHolder *holder, const gchar *attribute) 2000 { 2001 g_return_val_if_fail (GDA_IS_HOLDER (holder), NULL); 2002 /*g_print ("GdaHolder %p ATTR '%s' get => '%s'\n", holder, attribute, 2003 gda_value_stringify (gda_attributes_manager_get (gda_holder_attributes_manager, holder, attribute))); */ 2004 return gda_attributes_manager_get (gda_holder_attributes_manager, holder, attribute); 2005 } 2006 2007 /** 2008 * gda_holder_set_attribute: 2009 * @holder: a #GdaHolder 2010 * @attribute: attribute name 2011 * @value: a #GValue, or %NULL 2012 * @destroy: a function to be called when @attribute is not needed anymore, or %NULL 2013 * 2014 * Set the value associated to a named attribute. The @attribute string is 'stolen' by this method, and 2015 * the memory it uses will be freed using the @destroy function when no longer needed (if @destroy is %NULL, 2016 * then the string will not be freed at all). 2017 * 2018 * Attributes can have any name, but Libgda proposes some default names, 2019 * see <link linkend="libgda-5.0-Attributes-manager.synopsis">this section</link>. 2020 * 2021 * For example one would use it as: 2022 * 2023 * <code>gda_holder_set_attribute (holder, g_strdup (my_attribute), my_value, g_free);</code> 2024 * <code>gda_holder_set_attribute (holder, GDA_ATTRIBUTE_NAME, my_value, NULL);</code> 2025 * 2026 * If there is already an attribute named @attribute set, then its value is replaced with the new value (@value is 2027 * copied), except if @value is %NULL, in which case the attribute is removed. 2028 */ 2029 void 2030 gda_holder_set_attribute (GdaHolder *holder, const gchar *attribute, const GValue *value, GDestroyNotify destroy) 2031 { 2032 const GValue *cvalue; 2033 g_return_if_fail (GDA_IS_HOLDER (holder)); 2034 2035 gda_holder_lock ((GdaLockable*) holder); 2036 cvalue = gda_attributes_manager_get (gda_holder_attributes_manager, holder, attribute); 2037 if ((value && cvalue && !gda_value_differ (cvalue, value)) || 2038 (!value && !cvalue)) { 2039 gda_holder_unlock ((GdaLockable*) holder); 2040 return; 2041 } 2042 2043 gda_attributes_manager_set_full (gda_holder_attributes_manager, holder, attribute, value, destroy); 2044 //g_print ("GdaHolder %p ATTR '%s' set to '%s'\n", holder, attribute, gda_value_stringify (value)); 2045 gda_holder_unlock ((GdaLockable*) holder); 2046 } 2047 2048 static void 2049 gda_holder_lock (GdaLockable *lockable) 2050 { 2051 GdaHolder *holder = (GdaHolder *) lockable; 2052 gda_mutex_lock (holder->priv->mutex); 2053 } 2054 2055 static gboolean 2056 gda_holder_trylock (GdaLockable *lockable) 2057 { 2058 GdaHolder *holder = (GdaHolder *) lockable; 2059 return gda_mutex_trylock (holder->priv->mutex); 2060 } 2061 2062 static void 2063 gda_holder_unlock (GdaLockable *lockable) 2064 { 2065 GdaHolder *holder = (GdaHolder *) lockable; 2066 gda_mutex_unlock (holder->priv->mutex); 2067 } 2068