## GdaSet

GdaSet — Container for several values

## Synopsis

                        GdaSet;
    GdaSet *            gda_set_new                         (GSList *holders);
    GdaSet *            gda_set_copy                        (GdaSet *set);
    GdaSet *            gda_set_new_inline                  (gint nb,
                                                             ...);
    GdaSet *            gda_set_new_from_spec_string        (const gchar *xml_spec,
                                                             GError **error);
    GdaSet *            gda_set_new_from_spec_node          (xmlNodePtr xml_spec,
                                                             GError **error);
    gboolean            gda_set_is_valid                    (GdaSet *set,
                                                             GError **error);
    const GValue *      gda_set_get_holder_value            (GdaSet *set,
                                                             const gchar *holder_id);
    gboolean            gda_set_set_holder_value            (GdaSet *set,
                                                             GError **error,
                                                             const gchar *holder_id,
                                                             ...);

    GdaHolder *         gda_set_get_holder                  (GdaSet *set,
                                                             const gchar *holder_id);
    gboolean            gda_set_add_holder                  (GdaSet *set,
                                                             GdaHolder *holder);
    void                gda_set_remove_holder               (GdaSet *set,
                                                             GdaHolder *holder);
    void                gda_set_merge_with_set              (GdaSet *set,
                                                             GdaSet *set_to_merge);

                        GdaSetNode;
    GdaSetNode *        gda_set_get_node                    (GdaSet *set,
                                                             GdaHolder *holder);
                        GdaSetSource;
    GdaSetSource *      gda_set_get_source_for_model        (GdaSet *set,
                                                             GdaDataModel *model);
    GdaSetSource *      gda_set_get_source                  (GdaSet *set,
                                                             GdaHolder *holder);
                        GdaSetGroup;
    GdaSetGroup *       gda_set_get_group                   (GdaSet *set,
                                                             GdaHolder *holder);

## Object Hierarchy

      GObject
       +----GdaSet
             +----GdaDataModelIter

## Properties

      "description"              gchar*                : Read / Write
      "holders"                  gpointer              : Write / Construct Only
      "id"                       gchar*                : Read / Write
      "name"                     gchar*                : Read / Write

## Signals

      "holder-attr-changed"                            : Run First
      "holder-changed"                                 : Run First
      "public-data-changed"                            : Run First
      "validate-holder-change"                         : Run Last
      "validate-set"                                   : Run Last

## Description

The GdaSet object is a container for several values (as GdaHolder objects). The list of GdaHolder objects is publicly accessible (and should not be modified), using the "holders" attribute. Each GdaSet object also maintains some publicly accessible information about the GdaHolder objects, through the GdaSetNode, GdaSetSource and GdaSetGroup structures (see `gda_set_get_node()`, `gda_set_get_source()` and `gda_set_get_group()`).

It is possible to control the values a GdaHolder can have in the GdaSet by connecting to the "before-holder-change" signal.

## Details

### GdaSet

    typedef struct _GdaSet GdaSet;

### gda_set_new ()

    GdaSet *            gda_set_new                         (GSList *holders);

Creates a new GdaSet object, and populates it with the list given as argument. The list can then be freed as it is copied. All the value holders in `holders` are referenced counted and modified, so they should not be used anymore afterwards.

`holders` : | a list of GdaHolder objects
Returns : | a new GdaSet object

### gda_set_copy ()

    GdaSet *            gda_set_copy                        (GdaSet *set);

Creates a new GdaSet object, opy of `set`

`set` : | a GdaSet object
Returns : | a new GdaSet object

### gda_set_new_inline ()

    GdaSet *            gda_set_new_inline                  (gint nb,
                                                             ...);

Creates a new GdaSet containing holders defined by each triplet in ... For each triplet (id, Glib type and value), the value must be of the correct type (gchar * if type is G_STRING, ...)

Note that this function is a utility function and that anly a limited set of types are supported. Trying to use an unsupported type will result in a warning, and the returned value holder holding a safe default value.

`nb` : | the number of value holders which will be contained in the new GdaSet
`...` : | a serie of a (const gchar*) id, (GType) type, and value
Returns : | a new GdaSet object

### gda_set_new_from_spec_string ()

    GdaSet *            gda_set_new_from_spec_string        (const gchar *xml_spec,
                                                             GError **error);

Creates a new GdaSet object from the `xml_spec` specifications

`xml_spec` : | a string
`error` : | a place to store the error, or `NULL`
Returns : | a new object, or `NULL` if an error occurred

### gda_set_new_from_spec_node ()

    GdaSet *            gda_set_new_from_spec_node          (xmlNodePtr xml_spec,
                                                             GError **error);

Creates a new GdaSet object from the `xml_spec` specifications

`xml_spec` : | a xmlNodePtr for a <holders> tag
`error` : | a place to store the error, or `NULL`
Returns : | a new object, or `NULL` if an error occurred

### gda_set_is_valid ()

    gboolean            gda_set_is_valid                    (GdaSet *set,
                                                             GError **error);

This method tells if all `set`'s GdaHolder objects are valid, and if they represent a valid combination of values, as defined by rules external to Libgda: the "validate-set" signal is emitted and if none of the signal handlers return an error, then the returned value is TRUE, otherwise the return value is FALSE as soon as a signal handler returns an error.

`set` : | a GdaSet object
`error` : | a place to store validation errors, or `NULL`
Returns : | TRUE if the set is valid

### gda_set_get_holder_value ()

    const GValue *      gda_set_get_holder_value            (GdaSet *set,
                                                             const gchar *holder_id);

Get the value of the GdaHolder which ID is `holder_id`

`set` : | a GdaSet object
`holder_id` : | the ID of the holder to set the value
Returns : | the requested GValue, or `NULL` (see `gda_holder_get_value()`)

### gda_set_set_holder_value ()

    gboolean            gda_set_set_holder_value            (GdaSet *set,
                                                             GError **error,
                                                             const gchar *holder_id,
                                                             ...);

Set the value of the GdaHolder which ID is `holder_id` to a specified value

`set` : | a GdaSet object
`error` : | a place to store errors, or `NULL`
`holder_id` : | the ID of the holder to set the value
`...` : | value, of the correct type, depending on the requested holder's type (not NULL)
Returns : | TRUE if no error occurred and the value was set correctly

### gda_set_get_holder ()

    GdaHolder *         gda_set_get_holder                  (GdaSet *set,
                                                             const gchar *holder_id);

Finds a GdaHolder using its ID

`set` : | a GdaSet object
`holder_id` : | the ID of the requested value holder
Returns : | a GdaHolder or `NULL`

### gda_set_add_holder ()

    gboolean            gda_set_add_holder                  (GdaSet *set,
                                                             GdaHolder *holder);

Adds `holder` to the list of holders managed within `set`.

NOTE: if `set` already has a GdaHolder with the same ID as `holder`, then `holder` will not be added to the set (even if `holder`'s type or value is not the same as the one already in `set`).

`set` : | a GdaSet object
`holder` : | a GdaHolder object
Returns : | TRUE if `holder` has been added to `set` (and FALSE if it has not been added because there is another GdaHolder with the same ID)

### gda_set_remove_holder ()

    void                gda_set_remove_holder               (GdaSet *set,
                                                             GdaHolder *holder);

`set` : |
`holder` : |

### gda_set_merge_with_set ()

    void                gda_set_merge_with_set              (GdaSet *set,
                                                             GdaSet *set_to_merge);

Add to `set` all the holders of `set_to_merge`. Note1: only the GdaHolder of `set_to_merge` for which no holder in `set` has the same ID are merged Note2: all the GdaHolder merged in `set` are still used by `set_to_merge`.

`set` : | a GdaSet object
`set_to_merge` : | a GdaSet object

### GdaSetNode

    typedef struct {
    	GdaHolder    *holder;        /* Can't be NULL */
    	GdaDataModel *source_model;  /* may be NULL */
    	gint          source_column; /* unused if @source_model is NULL */

    	/* Padding for future expansion */
    	gpointer      _gda_reserved1;
    	gpointer      _gda_reserved2;
    } GdaSetNode;

For each GdaHolder object in the GdaSet object, there is a GdaSetNode structure which sums up all the information for each GdaHolder. Contains public fields, which must not be modified.

GdaHolder *`holder`; | a GdaHolder in the GdaSet
GdaDataModel *`source_model`; | if `gda_holder_set_source_model()` has been used with `holder`, the GdaDataModel used, or `NULL`
gint `source_column`; | if `gda_holder_set_source_model()` has been used with `holder`, the column used, or 0
gpointer `_gda_reserved1`; |
gpointer `_gda_reserved2`; |

### gda_set_get_node ()

    GdaSetNode *        gda_set_get_node                    (GdaSet *set,
                                                             GdaHolder *holder);

Finds a GdaSetNode holding information for `holder`, don't modify the returned structure

`set` : | a GdaSet object
`holder` : | a GdaHolder object
Returns : | a GdaSetNode or `NULL`

### GdaSetSource

    typedef struct {
    	GdaDataModel   *data_model;   /* Can't be NULL */
    	GSList         *nodes;        /* list of #GdaSetNode for which source_model == @data_model */

    	/* Padding for future expansion */
    	gpointer        _gda_reserved1;
    	gpointer        _gda_reserved2;
    	gpointer        _gda_reserved3;
    	gpointer        _gda_reserved4;
    } GdaSetSource;

There is a GdaSetSource structure for each GdaDataModel which restricts at least one GdaHolder in the GdaSet object.

GdaDataModel *`data_model`; | the GdaDataModel
GSList *`nodes`; | the list of GdaSetNode where the `source_model` attribute equals `data_model`
gpointer `_gda_reserved1`; |
gpointer `_gda_reserved2`; |
gpointer `_gda_reserved3`; |
gpointer `_gda_reserved4`; |

### gda_set_get_source_for_model ()

    GdaSetSource *      gda_set_get_source_for_model        (GdaSet *set,
                                                             GdaDataModel *model);

Finds the GdaSetSource structure used in `set` for which `model` is a the data model (the returned structure should not be modified).

`set` : | a GdaSet object
`model` : | a GdaDataModel object
Returns : | a GdaSetSource pointer or `NULL`.

### gda_set_get_source ()

    GdaSetSource *      gda_set_get_source                  (GdaSet *set,
                                                             GdaHolder *holder);

Finds a GdaSetSource which contains the GdaDataModel restricting the possible values of `holder`, don't modify the returned structure.

`set` : | a GdaSet object
`holder` : | a GdaHolder object
Returns : | a GdaSetSource or `NULL`

### GdaSetGroup

    typedef struct {
    	GSList       *nodes;       /* list of GdaSetNode, at least one entry */
    	GdaSetSource *nodes_source; /* if NULL, then @nodes contains exactly one entry */

    	/* Padding for future expansion */
    	gpointer      _gda_reserved1;
    	gpointer      _gda_reserved2;
    } GdaSetGroup;

There is one GdaSetGroup structure for each _independant_ GdaHolder (those which have the same restricting data model all appear in the same GdaSetGroup structure).

GSList *`nodes`; | a list of GdaSetNode structures, at least one entry
GdaSetSource *`nodes_source`; | a GdaSetSource pointer where the `nodes` attribute lists the same GdaHolder objects as `nodes`
gpointer `_gda_reserved1`; |
gpointer `_gda_reserved2`; |

### gda_set_get_group ()

    GdaSetGroup *       gda_set_get_group                   (GdaSet *set,
                                                             GdaHolder *holder);

Finds a GdaSetGroup which lists a GdaSetNode containing `holder`, don't modify the returned structure.

`set` : | a GdaSet object
`holder` : | a GdaHolder object
Returns : | a GdaSetGroup or `NULL`

## Property Details

### The `"description"` property

      "description"              gchar*                : Read / Write

Description.

Default value: NULL

### The `"holders"` property

      "holders"                  gpointer              : Write / Construct Only

GdaHolder objects the set should contain.

### The `"id"` property

      "id"                       gchar*                : Read / Write

Id.

Default value: NULL

### The `"name"` property

      "name"                     gchar*                : Read / Write

Name.

Default value: NULL

## Signal Details

### The `"holder-attr-changed"` signal

    void                user_function                      (GdaSet    *set,
                                                            GdaHolder *holder,
                                                            gchar     *attr_name,
                                                            GValue    *attr_value,
                                                            gpointer   user_data)       : Run First

Gets emitted when an attribute for any of the GdaHolder objects managed by `set` has changed

`set` : | the GdaSet
`holder` : | the GdaHolder for which an attribute changed
`attr_name` : | attribute's name
`attr_value` : | attribute's value
`user_data` : | user data set when the signal handler was connected.

### The `"holder-changed"` signal

    void                user_function                      (GdaSet    *gdaset,
                                                            GdaHolder *arg1,
                                                            gpointer   user_data)      : Run First

`gdaset` : | the object which received the signal.
`arg1` : |
`user_data` : | user data set when the signal handler was connected.

### The `"public-data-changed"` signal

    void                user_function                      (GdaSet  *set,
                                                            gpointer user_data)      : Run First

Gets emitted when `set`'s public data (GdaSetNode, GdaSetGroup or GdaSetSource values) have changed

`set` : | the GdaSet
`user_data` : | user data set when the signal handler was connected.

### The `"validate-holder-change"` signal

    GdaError*           user_function                      (GdaSet    *set,
                                                            GdaHolder *holder,
                                                            GValue    *new_value,
                                                            gpointer   user_data)      : Run Last

Gets emitted when a GdaHolder's in `set` is going to change its value. One can connect to this signal to control which values `holder` can have (for example to implement some business rules)

`set` : | the GdaSet
`holder` : | the GdaHolder which is going to change
`new_value` : | the proposed new value for `holder`
`user_data` : | user data set when the signal handler was connected.
Returns : | NULL if `holder` is allowed to change its value to `new_value`, or a GError otherwise.

### The `"validate-set"` signal

    GdaError*           user_function                      (GdaSet  *set,
                                                            gpointer user_data)      : Run Last

Gets emitted when `gda_set_is_valid()` is called, use this signal to control which combination of values `set`'s holder can have (for example to implement some business rules)

`set` : | the GdaSet
`user_data` : | user data set when the signal handler was connected.
Returns : | NULL if `set`'s contents has been validated, or a GError otherwise.