3
* Copyright (C) 2003 Vivien Malerba
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License as
7
* published by the Free Software Foundation; either version 2 of the
8
* License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22
#include "mg-qfield.h"
25
#include "mg-qf-all.h"
26
#include "mg-qf-field.h"
27
#include "mg-qf-value.h"
28
#include "mg-qf-func.h"
29
#include "mg-xml-storage.h"
30
#include "mg-ref-base.h"
31
#include "mg-server.h"
34
* Main static functions
36
static void mg_qfield_class_init (MgQfieldClass *class);
37
static void mg_qfield_init (MgQfield *qfield);
38
static void mg_qfield_dispose (GObject *object);
39
static void mg_qfield_finalize (GObject *object);
41
static void mg_qfield_set_property (GObject *object,
45
static void mg_qfield_get_property (GObject *object,
50
static void attach_to_query (MgQfield *qfield, MgQuery *query);
52
/* get a pointer to the parents to be able to call their destructor */
53
static GObjectClass *parent_class = NULL;
61
static gint mg_qfield_signals[LAST_SIGNAL] = { };
71
struct _MgQfieldPrivate
79
GQuark mg_qfield_error_quark (void)
83
quark = g_quark_from_static_string ("mg_qfield_error");
89
mg_qfield_get_type (void)
91
static GType type = 0;
94
static const GTypeInfo info = {
95
sizeof (MgQfieldClass),
97
(GBaseFinalizeFunc) NULL,
98
(GClassInitFunc) mg_qfield_class_init,
103
(GInstanceInitFunc) mg_qfield_init
106
type = g_type_register_static (MG_BASE_TYPE, "MgQfield", &info, 0);
112
mg_qfield_class_init (MgQfieldClass * class)
114
GObjectClass *object_class = G_OBJECT_CLASS (class);
116
parent_class = g_type_class_peek_parent (class);
120
/* virtual functions */
122
class->is_equal = NULL;
124
object_class->dispose = mg_qfield_dispose;
125
object_class->finalize = mg_qfield_finalize;
128
object_class->set_property = mg_qfield_set_property;
129
object_class->get_property = mg_qfield_get_property;
130
g_object_class_install_property (object_class, PROP,
131
g_param_spec_pointer ("prop", NULL, NULL,
132
(G_PARAM_READABLE | G_PARAM_WRITABLE)));
136
mg_qfield_init (MgQfield *qfield)
138
qfield->priv = g_new0 (MgQfieldPrivate, 1);
139
qfield->priv->alias = NULL;
140
qfield->priv->visible = TRUE;
141
qfield->priv->internal = FALSE;
145
* mg_qfield_new_from_xml
146
* @query: a #MgQuery object
147
* @node: an XML node corresponding to a MG_QFIELD tag
148
* @error: location to store error, or %NULL
150
* This is an object factory which does create instances of class inheritants of the #MgDfield class.
151
* Ths #MgQfield object MUST then be attached to @query
153
* Returns: the newly created object
156
mg_qfield_new_from_xml (MgQuery *query, xmlNodePtr node, GError **error)
161
g_return_val_if_fail (query && IS_MG_QUERY (query), NULL);
162
g_return_val_if_fail (node, NULL);
163
g_return_val_if_fail (!strcmp (node->name, "MG_QF"), NULL);
165
prop = xmlGetProp (node, "type");
167
gboolean done = FALSE;
168
if (!strcmp (prop, "ALL")) {
172
target = xmlGetProp (node, "target");
174
obj = mg_qf_all_new_with_xml_id (query, target);
180
MG_QF_ALL_XML_LOAD_ERROR,
181
_("Missing 'target' attribute in <MG_QF>"));
186
if (!done && !strcmp (prop, "FIELD")) {
187
gchar *target, *field;
190
target = xmlGetProp (node, "target");
191
field = xmlGetProp (node, "object");
193
obj = mg_qf_field_new_with_xml_ids (query, target, field);
203
MG_QF_ALL_XML_LOAD_ERROR,
204
_("Missing 'target' attribute in <MG_QF>"));
210
if (!done && !strcmp (prop, "AGG")) {
214
if (!done && !strcmp (prop, "FUNC")) {
217
func = xmlGetProp (node, "object");
219
obj = mg_qf_func_new_with_xml_id (query, func);
226
MG_QF_ALL_XML_LOAD_ERROR,
227
_("Missing 'object' attribute in <MG_QF>"));
232
if (!done && !strcmp (prop, "VAL")) {
236
srvt = xmlGetProp (node, "srv_type");
238
MgServerDataType *dt;
240
dt = mg_server_get_data_type_by_xml_id (mg_conf_get_server (mg_base_get_conf (MG_BASE (query))),
243
obj = mg_qf_value_new (query, dt);
247
MG_QF_ALL_XML_LOAD_ERROR,
248
_("Can't find data type %s for query field"), srvt);
256
MG_QF_ALL_XML_LOAD_ERROR,
257
_("Missing 'srv_type' attribute for VALUE query field"));
266
attach_to_query (MG_QFIELD (obj), query);
267
if (!mg_xml_storage_load_from_xml (MG_XML_STORAGE (obj), node, error))
273
MG_QF_ALL_XML_LOAD_ERROR,
274
_("Missing Implementation in loading <MG_QF>"));
279
MG_QFIELD_XML_LOAD_ERROR,
280
_("Unknown value for 'type' attribute in <MG_QF>"));
290
* @orig: a #MgQfield to copy
292
* This is a copy constructor
294
* Returns: the new object
297
mg_qfield_new_copy (MgQfield *orig)
299
MgQfieldClass *class;
304
g_return_val_if_fail (orig && IS_MG_QFIELD (orig), NULL);
305
g_return_val_if_fail (orig->priv, NULL);
306
g_object_get (G_OBJECT (orig), "query", &query, NULL);
307
g_return_val_if_fail (query, NULL);
309
class = MG_QFIELD_CLASS (G_OBJECT_GET_CLASS (orig));
310
g_return_val_if_fail (class->copy, NULL);
312
obj = (class->copy) (orig);
313
newfield = MG_QFIELD (obj);
314
newfield->priv->visible = orig->priv->visible;
315
newfield->priv->internal = orig->priv->internal;
317
attach_to_query (MG_QFIELD (obj), query);
323
attach_to_query (MgQfield *qfield, MgQuery *query)
325
g_object_set (G_OBJECT (qfield), "query", query, NULL);
330
mg_qfield_dispose (GObject *object)
334
g_return_if_fail (object != NULL);
335
g_return_if_fail (IS_MG_QFIELD (object));
337
qfield = MG_QFIELD (object);
339
if (qfield->priv->alias) {
340
g_free (qfield->priv->alias);
341
qfield->priv->alias = NULL;
346
parent_class->dispose (object);
350
mg_qfield_finalize (GObject * object)
354
g_return_if_fail (object != NULL);
355
g_return_if_fail (IS_MG_QFIELD (object));
357
qfield = MG_QFIELD (object);
359
g_free (qfield->priv);
364
parent_class->finalize (object);
369
mg_qfield_set_property (GObject *object,
376
qfield = MG_QFIELD (object);
386
mg_qfield_get_property (GObject *object,
393
qfield = MG_QFIELD (object);
404
* mg_qfield_set_alias
405
* @qfield: a #MgQfield object
406
* @alias: the alias to set @qfield to
408
* Sets @qfield's alias
411
mg_qfield_set_alias (MgQfield *qfield, const gchar *alias)
413
g_return_if_fail (qfield && IS_MG_QFIELD (qfield));
414
g_return_if_fail (qfield->priv);
416
if (qfield->priv->alias) {
417
g_free (qfield->priv->alias);
418
qfield->priv->alias = NULL;
422
qfield->priv->alias = g_strdup (alias);
426
* mg_qfield_get_alias
427
* @qfield: a #MgQfield object
429
* Get @qfield's alias
434
mg_qfield_get_alias (MgQfield *qfield)
436
g_return_val_if_fail (qfield && IS_MG_QFIELD (qfield), NULL);
437
g_return_val_if_fail (qfield->priv, NULL);
439
return qfield->priv->alias;
444
* mg_qfield_set_visible
445
* @qfield: a #MgQfield object
448
* Sets the visibility of @qfield. A visible field will appear in the query's
449
* corresponding (virtual) entity, whereas a non visible one will be hidden (and
450
* possibly not taking part in the query).
453
mg_qfield_set_visible (MgQfield *qfield, gboolean visible)
457
g_return_if_fail (qfield && IS_MG_QFIELD (qfield));
458
g_return_if_fail (qfield->priv);
459
g_object_get (G_OBJECT (qfield), "query", &query, NULL);
460
g_return_if_fail (query);
462
if (qfield->priv->visible != visible) {
463
qfield->priv->visible = visible;
465
g_signal_emit_by_name (G_OBJECT (query), "field_added", MG_FIELD (qfield));
467
g_signal_emit_by_name (G_OBJECT (query), "field_removed", MG_FIELD (qfield));
473
* mg_qfield_is_visible
474
* @qfield: a #MgQfield object
476
* Returns: TRUE if @field is visible
479
mg_qfield_is_visible (MgQfield *qfield)
481
g_return_val_if_fail (qfield && IS_MG_QFIELD (qfield), FALSE);
482
g_return_val_if_fail (qfield->priv, FALSE);
484
return qfield->priv->visible;
488
* mg_qfield_set_internal
489
* @qfield: a #MgQfield object
492
* Sets weather @qfield is internal or not. Internal fields in a query are fields added
493
* or changed by libmergeant itself, such fields may or may not be visible.
496
mg_qfield_set_internal (MgQfield *qfield, gboolean internal)
498
g_return_if_fail (qfield && IS_MG_QFIELD (qfield));
499
g_return_if_fail (qfield->priv);
501
qfield->priv->internal = internal;
506
* mg_qfield_is_internal
507
* @qfield: a #MgQfield object
509
* Returns: TRUE if @field is internal
512
mg_qfield_is_internal (MgQfield *qfield)
514
g_return_val_if_fail (qfield && IS_MG_QFIELD (qfield), FALSE);
515
g_return_val_if_fail (qfield->priv, FALSE);
517
return qfield->priv->internal;
521
* mg_qfield_get_data_type
522
* @qfield: a #MgQfield object
524
* Get the #MgServerDataType represented by the @qfield object: for a function it returns
525
* the return type, for a value, it returns its type, etc.
527
* Returns: the data type, or %NULL if @qfield does not have a data type.
530
mg_qfield_get_data_type (MgQfield *qfield)
532
g_return_val_if_fail (qfield && IS_MG_QFIELD (qfield), NULL);
533
g_return_val_if_fail (qfield->priv, NULL);
535
/* it is assumed that qfield really implements the MgField interface */
536
return mg_field_get_data_type (MG_FIELD (qfield));
540
* mg_qfield_get_parameters
541
* @qfield: a #MgQfield object
543
* Get a list of all the parameters needed to @qfield to be
544
* rendered as a valid statement
546
* Returns: a new list of parameters for @qfield
549
mg_qfield_get_parameters (MgQfield *qfield)
551
MgQfieldClass *class;
553
g_return_val_if_fail (qfield && IS_MG_QFIELD (qfield), NULL);
554
g_return_val_if_fail (qfield->priv, NULL);
555
class = MG_QFIELD_CLASS (G_OBJECT_GET_CLASS (qfield));
557
if (class->get_params)
558
return (class->get_params) (qfield);
565
* @qfield1: a #MgQfield object
566
* @qfield2: a #MgQfield object
568
* Compares the @qfield1 and @qfield2. The name and aliases of the two fields are
569
* not compared, only the contents of the fields are.
571
* Returns: TRUE if they are equal and FALSE otherwise
574
mg_qfield_is_equal (MgQfield *qfield1, MgQfield *qfield2)
576
MgQfieldClass *class1, *class2;
579
g_return_val_if_fail (qfield1 && IS_MG_QFIELD (qfield1), FALSE);
580
g_return_val_if_fail (qfield2 && IS_MG_QFIELD (qfield2), FALSE);
581
g_return_val_if_fail (qfield1->priv, FALSE);
582
g_return_val_if_fail (qfield2->priv, FALSE);
583
g_object_get (G_OBJECT (qfield1), "query", &q1, NULL);
584
g_object_get (G_OBJECT (qfield2), "query", &q2, NULL);
585
g_return_val_if_fail (q1, FALSE);
586
g_return_val_if_fail (q2, FALSE);
591
class1 = MG_QFIELD_CLASS (G_OBJECT_GET_CLASS (qfield1));
592
class2 = MG_QFIELD_CLASS (G_OBJECT_GET_CLASS (qfield2));
593
if (class1 != class2)
596
g_return_val_if_fail (class1->is_equal, FALSE);
598
return (class1->is_equal) (qfield1, qfield2);
604
* @qfield: a #MgQfield object
606
* Tells if @qfield can potentially represent a list of values.
608
* Returns: TRUE if @field can be a list of values
611
mg_qfield_is_list (MgQfield *qfield)
613
MgQfieldClass *class;
615
g_return_val_if_fail (qfield && IS_MG_QFIELD (qfield), FALSE);
616
g_return_val_if_fail (qfield->priv, FALSE);
618
class = MG_QFIELD_CLASS (G_OBJECT_GET_CLASS (qfield));
620
return (class->is_list) (qfield);