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 (&registering);
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 (&registering);
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