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 */
gda_holder_error_quark(void)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
gda_holder_get_type(void)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
validate_change_accumulator(G_GNUC_UNUSED GSignalInvocationHint * ihint,GValue * return_accu,const GValue * handler_return,G_GNUC_UNUSED gpointer data)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 *
m_validate_change(G_GNUC_UNUSED GdaHolder * holder,G_GNUC_UNUSED const GValue * new_value)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
holder_attribute_set_cb(GObject * obj,const gchar * att_name,const GValue * value,G_GNUC_UNUSED gpointer data)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
gda_holder_class_init(GdaHolderClass * class)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
gda_holder_lockable_init(GdaLockableIface * iface)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
gda_holder_init(GdaHolder * holder)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 *
gda_holder_new(GType type)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 *
gda_holder_copy(GdaHolder * orig)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 *
gda_holder_new_inline(GType type,const gchar * id,...)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
gda_holder_dispose(GObject * object)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
gda_holder_finalize(GObject * object)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
gda_holder_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)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
gda_holder_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)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
gda_holder_get_g_type(GdaHolder * holder)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 *
gda_holder_get_id(GdaHolder * holder)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 *
gda_holder_get_value(GdaHolder * holder)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 *
gda_holder_get_value_str(GdaHolder * holder,GdaDataHandler * dh)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
gda_holder_set_value(GdaHolder * holder,const GValue * value,GError ** error)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
gda_holder_set_value_str(GdaHolder * holder,GdaDataHandler * dh,const gchar * value,GError ** error)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
gda_holder_take_value(GdaHolder * holder,GValue * value,GError ** error)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
real_gda_holder_set_value(GdaHolder * holder,GValue * value,gboolean do_copy,GError ** error)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 *
real_gda_holder_set_const_value(GdaHolder * holder,const GValue * value,gboolean * value_changed,GError ** error)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 *
gda_holder_take_static_value(GdaHolder * holder,const GValue * value,gboolean * value_changed,GError ** error)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
gda_holder_force_invalid(GdaHolder * holder)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
gda_holder_force_invalid_e(GdaHolder * holder,GError * error)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
gda_holder_is_valid(GdaHolder * holder)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
gda_holder_is_valid_e(GdaHolder * holder,GError ** error)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
gda_holder_set_value_to_default(GdaHolder * holder)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
gda_holder_value_is_default(GdaHolder * holder)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 *
gda_holder_get_default_value(GdaHolder * holder)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
gda_holder_set_default_value(GdaHolder * holder,const GValue * value)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
gda_holder_set_not_null(GdaHolder * holder,gboolean not_null)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
gda_holder_get_not_null(GdaHolder * holder)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
gda_holder_set_source_model(GdaHolder * holder,GdaDataModel * model,gint col,GError ** error)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 *
gda_holder_get_source_model(GdaHolder * holder,gint * col)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
bind_to_notify_cb(GdaHolder * bind_to,G_GNUC_UNUSED GParamSpec * pspec,GdaHolder * holder)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
gda_holder_set_bind(GdaHolder * holder,GdaHolder * bind_to,GError ** error)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
gda_holder_set_full_bind(GdaHolder * holder,GdaHolder * alias_of)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
full_bound_holder_changed_cb(GdaHolder * alias_of,GdaHolder * holder)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
bound_holder_changed_cb(GdaHolder * alias_of,GdaHolder * holder)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 *
gda_holder_get_bind(GdaHolder * holder)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 *
gda_holder_get_alphanum_id(GdaHolder * holder)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 *
gda_holder_get_attribute(GdaHolder * holder,const gchar * attribute)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
gda_holder_set_attribute(GdaHolder * holder,const gchar * attribute,const GValue * value,GDestroyNotify destroy)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
gda_holder_lock(GdaLockable * lockable)2049 gda_holder_lock (GdaLockable *lockable)
2050 {
2051 GdaHolder *holder = (GdaHolder *) lockable;
2052 gda_mutex_lock (holder->priv->mutex);
2053 }
2054
2055 static gboolean
gda_holder_trylock(GdaLockable * lockable)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
gda_holder_unlock(GdaLockable * lockable)2063 gda_holder_unlock (GdaLockable *lockable)
2064 {
2065 GdaHolder *holder = (GdaHolder *) lockable;
2066 gda_mutex_unlock (holder->priv->mutex);
2067 }
2068