## MgQuery

MgQuery — Represents any kind of DML query

## Synopsis

    struct      MgQuery;
    enum        MgQueryType;
    guint       mg_query_get_type               (void);
    GObject*    mg_query_new                    (MgConf *conf);
    GObject*    mg_query_new_from_sql           (MgConf *conf,
                                                 const gchar *sql,
                                                 GError **error);
    GObject*    mg_query_new_copy               (MgQuery *orig,
                                                 GHashTable *replacements);
    void        mg_query_set_query_type         (MgQuery *query,
                                                 MgQueryType type);
    MgQueryType mg_query_get_query_type         (MgQuery *query);
    const gchar* mg_query_get_query_type_string (MgQuery *query);
    gboolean    mg_query_is_select_query        (MgQuery *query);
    gboolean    mg_query_is_modif_query         (MgQuery *query);
    MgQuery*    mg_query_get_parent_query       (MgQuery *query);
    gboolean    mg_query_is_equal_to            (MgQuery *query,
                                                 MgQuery *compare_to);
    MgQfield*   mg_query_get_field_by_sql_naming
                                                (MgQuery *query,
                                                 const gchar *sql_naming);
    GSList*     mg_query_get_fields_by_target   (MgQuery *query,
                                                 MgTarget *target,
                                                 gboolean visible_fields_only);
    MgQfield*   mg_query_get_visible_field_by_ref_field
                                                (MgQuery *query,
                                                 MgTarget *target,
                                                 MgField *ref_field);
    MgQfield*   mg_query_get_any_field_by_ref_field
                                                (MgQuery *query,
                                                 MgTarget *target,
                                                 MgField *ref_field);
    void        mg_query_set_sql_text           (MgQuery *query,
                                                 const gchar *sql,
                                                 GError **error);
    const gchar* mg_query_get_sql_text          (MgQuery *query);
    GSList*     mg_query_get_sub_queries        (MgQuery *query);
    void        mg_query_add_sub_query          (MgQuery *query,
                                                 MgQuery *sub_query);
    void        mg_query_del_sub_query          (MgQuery *query,
                                                 MgQuery *sub_query);
    const GSList* mg_query_get_param_sources    (MgQuery *query);
    void        mg_query_add_param_source       (MgQuery *query,
                                                 MgQuery *param_source);
    void        mg_query_del_param_source       (MgQuery *query,
                                                 MgQuery *param_source);
    gboolean    mg_query_add_target             (MgQuery *query,
                                                 MgTarget *target,
                                                 GError **error);
    void        mg_query_del_target             (MgQuery *query,
                                                 MgTarget *target);
    GSList*     mg_query_get_targets            (MgQuery *query);
    MgTarget*   mg_query_get_target_by_xml_id   (MgQuery *query,
                                                 const gchar *xml_id);
    MgTarget*   mg_query_get_target_by_alias    (MgQuery *query,
                                                 const gchar *alias_or_name);
    GSList*     mg_query_get_target_pkfields    (MgQuery *query,
                                                 MgTarget *target);
    GSList*     mg_query_get_joins              (MgQuery *query);
    MgJoin*     mg_query_get_join_by_targets    (MgQuery *query,
                                                 MgTarget *target1,
                                                 MgTarget *target2);
    gboolean    mg_query_add_join               (MgQuery *query,
                                                 MgJoin *join);
    void        mg_query_del_join               (MgQuery *query,
                                                 MgJoin *join);
    void        mg_query_set_condition          (MgQuery *query,
                                                 MgCondition *cond);
    MgCondition* mg_query_get_condition         (MgQuery *query);
    GSList*     mg_query_get_main_conditions    (MgQuery *query);
    void        mg_query_set_order_by_field     (MgQuery *query,
                                                 MgQfield *field,
                                                 gint order,
                                                 gboolean ascendant);
    gint        mg_query_get_order_by_field     (MgQuery *query,
                                                 MgQfield *field,
                                                 gboolean *ascendant);
    GSList*     mg_query_expand_all_field       (MgQuery *query,
                                                 MgTarget *target);
    void        mg_query_order_fields_using_join_conds
                                                (MgQuery *query);

## Object Hierarchy

      GObject
       +----MgBase
             +----MgQuery

## Implemented Interfaces

MgQuery implements MgXmlStorage, MgRenderer, MgReferer and MgEntity.

## Properties

      "cond-serial"          guint                : Read
      "field-serial"         guint                : Read
      "really-all-fields"    gpointer             : Read
      "target-serial"        guint                : Read

## Signal Prototypes

    "condition-changed"
                void        user_function      (MgQuery *mgquery,
                                                gpointer user_data);
    "join-added"
                void        user_function      (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);
    "join-removed"
                void        user_function      (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);
    "join-updated"
                void        user_function      (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);
    "sub-query-added"
                void        user_function      (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);
    "sub-query-removed"
                void        user_function      (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);
    "sub-query-updated"
                void        user_function      (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);
    "target-added"
                void        user_function      (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);
    "target-removed"
                void        user_function      (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);
    "target-updated"
                void        user_function      (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);
    "type-changed"
                void        user_function      (MgQuery *mgquery,
                                                gpointer user_data);

## Description

Any query (which can be of any type, see the MgQueryType enum) can be represented by a MgQuery object. Also a query may require some parameters to be provided before in can be executed; each parameter is then represented by a MgParameter object, and parameters required for a query are organised within a MgContext object.

It implements the MgEntity, MgXmlStorage, MgReferer and MgRenderer interfaces.

## Details

### struct MgQuery

    struct MgQuery;

### enum MgQueryType

    typedef enum {
            MG_QUERY_TYPE_SELECT,
    	MG_QUERY_TYPE_INSERT,
    	MG_QUERY_TYPE_UPDATE,
    	MG_QUERY_TYPE_DELETE,
            MG_QUERY_TYPE_UNION,
            MG_QUERY_TYPE_INTERSECT,
    	MG_QUERY_TYPE_EXCEPT,
            MG_QUERY_TYPE_NON_PARSED_SQL
    } MgQueryType;

`MG_QUERY_TYPE_SELECT` |
`MG_QUERY_TYPE_INSERT` |
`MG_QUERY_TYPE_UPDATE` |
`MG_QUERY_TYPE_DELETE` |
`MG_QUERY_TYPE_UNION` | Union of SELECT queries
`MG_QUERY_TYPE_INTERSECT` | Intersection of SELECT queries
`MG_QUERY_TYPE_EXCEPT` | A SELECT query minus another SELECT query
`MG_QUERY_TYPE_NON_PARSED_SQL` |

### mg_query_get_type ()

    guint       mg_query_get_type               (void);

Returns : |

### mg_query_new ()

    GObject*    mg_query_new                    (MgConf *conf);

Creates a new MgQuery object

`conf` : | a MgConf object
Returns : | the new object

### mg_query_new_from_sql ()

    GObject*    mg_query_new_from_sql           (MgConf *conf,
                                                 const gchar *sql,
                                                 GError **error);

Creates a new MgQuery object and fills its structure by parsing the `sql`. If the parsing failed, then the returned query is of type MG_QUERY_TYPE_NON_PARSED_SQL.

To be parsed successfully, the expected SQL must respect the SQL standard; some extensions have been added to be able to define variables within the SQL statement. See the introduction to the MgQuery for more information.

The `error` is set only if the SQL statement parsing produced an error; there is always a new MgQuery object which is returned.

`conf` : | a MgConf object
`sql` : | an SQL statement
`error` : | location to store error, or `NULL`
Returns : | a new MgQuery

### mg_query_new_copy ()

    GObject*    mg_query_new_copy               (MgQuery *orig,
                                                 GHashTable *replacements);

Copy constructor

`orig` : | a MgQuery to make a copy of
`replacements` : | a hash table to store replacements, or `NULL`
Returns : | a the new copy of `orig`

### mg_query_set_query_type ()

    void        mg_query_set_query_type         (MgQuery *query,
                                                 MgQueryType type);

Sets the type of `query`

`query` : | a MgQuery object
`type` : | the new type of query

### mg_query_get_query_type ()

    MgQueryType mg_query_get_query_type         (MgQuery *query);

Get the type of a query

`query` : | a MgQuery object
Returns : | the type of `query`

### mg_query_get_query_type_string ()

    const gchar* mg_query_get_query_type_string (MgQuery *query);

Get the type of a query as a human readable string

`query` : | a MgQuery object
Returns : | a string for the type of `query`

### mg_query_is_select_query ()

    gboolean    mg_query_is_select_query        (MgQuery *query);

Tells if `query` is a SELECTION query (a simple SELECT, UNION, INTERSECT or EXCEPT); pure SQL queries are not handled and will always return FALSE.

`query` : | a # MgQuery object
Returns : | TRUE if `query` is a selection query

### mg_query_is_modif_query ()

    gboolean    mg_query_is_modif_query         (MgQuery *query);

Tells if `query` is a modification query (a simple UPDATE, DELETE, INSERT).; pure SQL queries are not handled and will always return FALSE.

`query` : | a # MgQuery object
Returns : | TRUE if `query` is a modification query

### mg_query_get_parent_query ()

    MgQuery*    mg_query_get_parent_query       (MgQuery *query);

Get the parent query of `query`

`query` : | a MgQuery object
Returns : | the parent query, or NULL if `query` does not have any parent

### mg_query_is_equal_to ()

    gboolean    mg_query_is_equal_to            (MgQuery *query,
                                                 MgQuery *compare_to);

Compares `query` and `compare_to` from the point of view of the result of the execution of the two queries.

`query` : | a MgQuery object
`compare_to` : | a MgQuery object
Returns : | TRUE is `query` and `compare_to` represent the same query

### mg_query_get_field_by_sql_naming ()

    MgQfield*   mg_query_get_field_by_sql_naming
                                                (MgQuery *query,
                                                 const gchar *sql_naming);

`query` : | a MgQuery object
`sql_naming` : |
Returns : |

### mg_query_get_fields_by_target ()

    GSList*     mg_query_get_fields_by_target   (MgQuery *query,
                                                 MgTarget *target,
                                                 gboolean visible_fields_only);

Get a list of all the MgQfield objects in `query` which depent on the existance of `target`.

`query` : | a MgQuery object
`target` : | a MgTarget object representing a target in `query`
`visible_fields_only` : |
Returns : | a new list of MgQfield objects

### mg_query_get_visible_field_by_ref_field ()

    MgQfield*   mg_query_get_visible_field_by_ref_field
                                                (MgQuery *query,
                                                 MgTarget *target,
                                                 MgField *ref_field);

Finds the first visible MgQfield object in `query` which represents `ref_field`. The returned object will be a MgQfField object which represents `ref_field`.

If `target` is specified, then the returned field will be linked to that MgTarget object.

`query` : | a MgQuery object
`target` : | a MgTarget, or `NULL`
`ref_field` : | a MgField object
Returns : | a MgQfField object or `NULL`

### mg_query_get_any_field_by_ref_field ()

    MgQfield*   mg_query_get_any_field_by_ref_field
                                                (MgQuery *query,
                                                 MgTarget *target,
                                                 MgField *ref_field);

Finds the first (visible or not) MgQfField object in `query` which represents `ref_field`. The returned object will be a MgQfField object which represents `ref_field`.

If `target` is specified, then the returned field will be linked to that MgTarget object.

`query` : | a MgQuery object
`target` : | a MgTarget, or `NULL`
`ref_field` : | a MgField object
Returns : | a MgQfField object or `NULL`

### mg_query_set_sql_text ()

    void        mg_query_set_sql_text           (MgQuery *query,
                                                 const gchar *sql,
                                                 GError **error);

Defines `query`'s contents from an SQL statement. The SQL text is parsed and the internal query structured is built from that; the query type is also set. If the SQL text cannot be parsed, then the internal structure of the query is emptied and the query type is set to MG_QUERY_TYPE_NON_PARSED_SQL.

To be parsed successfully, the expected SQL must respect the SQL standard; some extensions have been added to be able to define variables within the SQL statement. See the introduction to the MgQuery for more information.

`query` : | a # MgQuery object
`sql` : | the SQL statement
`error` : | location to store parsing error, or `NULL`

### mg_query_get_sql_text ()

    const gchar* mg_query_get_sql_text          (MgQuery *query);

Obtain a new string representing the SQL version of the query.

WARNING: the returned SQL statement may contain some extensions which allow for the definition of variables (see the introduction to the MgQuery for more information). As such the returned SQL cannot be executed as it may provoque errors. To get an executable statement, use the MgRenderer interface's methods.

`query` : | a MgQuery object
Returns : | the new string

### mg_query_get_sub_queries ()

    GSList*     mg_query_get_sub_queries        (MgQuery *query);

Get a list of all the sub-queries managed by `query`

`query` : | a MgQuery object
Returns : | a new list of the sub-queries

### mg_query_add_sub_query ()

    void        mg_query_add_sub_query          (MgQuery *query,
                                                 MgQuery *sub_query);

Add `sub_query` to `query`. Sub queries are managed by their parent query, and as such they are destroyed when their parent query is destroyed.

`query` : | a MgQuery object
`sub_query` : | a MgQuery object

### mg_query_del_sub_query ()

    void        mg_query_del_sub_query          (MgQuery *query,
                                                 MgQuery *sub_query);

Removes `sub_query` from `query`. `sub_query` MUST be present within `query`.

`query` : | a MgQuery object
`sub_query` : | a MgQuery object

### mg_query_get_param_sources ()

    const GSList* mg_query_get_param_sources    (MgQuery *query);

Get a list of the parameter source queries that are references as such by `query`.

`query` : | a MgQuery object
Returns : | the list of MgQuery objects

### mg_query_add_param_source ()

    void        mg_query_add_param_source       (MgQuery *query,
                                                 MgQuery *param_source);

Tells `query` that `param_source` is a query which potentially will constraint the possible values of one or more of `query`'s parameters. This implies that `query` keeps a reference on `param_source`.

`query` : | a MgQuery object
`param_source` : | a MgQuery object

### mg_query_del_param_source ()

    void        mg_query_del_param_source       (MgQuery *query,
                                                 MgQuery *param_source);

Tells `query` that it should no longer take care of `param_source`. The parameters which depend on `param_source` will still depend on it, though.

`query` : | a MgQuery object
`param_source` : | a MgQuery object

### mg_query_add_target ()

    gboolean    mg_query_add_target             (MgQuery *query,
                                                 MgTarget *target,
                                                 GError **error);

Adds a target to `query`. A target represents a entity (it can actually be a table, a view, or another query) which `query` will use.

For a SELECT query, the targets appear after the FROM clause. The targets can be joined two by two using MgJoin objects

For UPDATE, DELETE or INSERT queries, there can be only ONE MgTarget object which is the one where the data modifications are performed.

For UNION and INTERSECT queries, there is no possible MgTarget object.

`query` : | a MgQuery object
`target` : | a MgTarget to add to `query`
`error` : | location to store error, or `NULL`
Returns : | TRUE if no error occurred

### mg_query_del_target ()

    void        mg_query_del_target             (MgQuery *query,
                                                 MgTarget *target);

Removes `target` from `query`. `target` MUST be present within `query`. Warning: All the joins and fields which depended on `target` are also removed.

`query` : | a MgQuery object
`target` : | a MgTarget object

### mg_query_get_targets ()

    GSList*     mg_query_get_targets            (MgQuery *query);

Get a list of all the targets used in `query`

`query` : | a MgQuery object
Returns : | a new list of the targets

### mg_query_get_target_by_xml_id ()

    MgTarget*   mg_query_get_target_by_xml_id   (MgQuery *query,
                                                 const gchar *xml_id);

Get a pointer to a MgTarget (which must be within `query`) using its XML Id

`query` : | a MgQuery object
`xml_id` : | the XML Id of the requested MgTarget object
Returns : | the MgTarget object, or NULL if not found

### mg_query_get_target_by_alias ()

    MgTarget*   mg_query_get_target_by_alias    (MgQuery *query,
                                                 const gchar *alias_or_name);

Get a pointer to a MgTarget (which must be within `query`) using its alias (if not found then `alias_or_name` is interpreted as the target name)

`query` : | a MgQuery object
`alias_or_name` : | the alias or name
Returns : | the MgTarget object, or NULL if not found

### mg_query_get_target_pkfields ()

    GSList*     mg_query_get_target_pkfields    (MgQuery *query,
                                                 MgTarget *target);

Makes a list of the MgQfield objects which represent primary key fields of the entity represented by `target`.

If the entity represented by `target` does not have any primary key, or if the primary key's fields are not present in `query`, then the returned value is `NULL`.

`query` : | a MgQuery object
`target` : | a MgTarget object
Returns : | a new GSList, or `NULL`.

### mg_query_get_joins ()

    GSList*     mg_query_get_joins              (MgQuery *query);

Get a list of all the joins used in `query`

`query` : | a MgQuery object
Returns : | a new list of the joins

### mg_query_get_join_by_targets ()

    MgJoin*     mg_query_get_join_by_targets    (MgQuery *query,
                                                 MgTarget *target1,
                                                 MgTarget *target2);

Find a join in `query` which joins the `target1` and `target2` targets

`query` : | a MgQuery object
`target1` : | a MgTarget object
`target2` : | a MgTarget object
Returns : | the MgJoin object, or `NULL`

### mg_query_add_join ()

    gboolean    mg_query_add_join               (MgQuery *query,
                                                 MgJoin *join);

Add a join to `query`. A join is defined by the two MgTarget objects it joins and by a join condition which MUST ONLY make use of fields of the two entities represented by the targets.

For any given couple of MgTarget objects, there can exist ONLY ONE MgJoin which joins the two.

`query` : | a MgQuery object
`join` : | a MgJoin object
Returns : | TRUE on success, and FALSE otherwise

### mg_query_del_join ()

    void        mg_query_del_join               (MgQuery *query,
                                                 MgJoin *join);

Removes `join` from `query`. `join` MUST be present within `query`.

`query` : | a MgQuery object
`join` : | a MgJoin object

### mg_query_set_condition ()

    void        mg_query_set_condition          (MgQuery *query,
                                                 MgCondition *cond);

Sets the query's associated condition

`query` : | a MgQuery object
`cond` : | a MgCondition object

### mg_query_get_condition ()

    MgCondition* mg_query_get_condition         (MgQuery *query);

Get the query's associated condition

`query` : | a MgQuery object
Returns : | the MgCondition object

### mg_query_get_main_conditions ()

    GSList*     mg_query_get_main_conditions    (MgQuery *query);

Makes a list of all the conditions (part of the WHERE clause) which are always verified by `query` when it is executed.

Examples: if the WHERE clause is: --> "A and B" then the list will contains {A, B} --> "A and (B or C)" it will contain {A, B or C} --> "A and (B and not C)", it will contain {A, B, not C}

`query` : | a MgQuery object
Returns : | a new list of MgCondition objects

### mg_query_set_order_by_field ()

    void        mg_query_set_order_by_field     (MgQuery *query,
                                                 MgQfield *field,
                                                 gint order,
                                                 gboolean ascendant);

Sets `field` to be used in the ORDER BY clause (using the `order` and `ascendant` attributes) if `order` >= 0. If `order` < 0, then `field` will not be used in the ORDER BY clause.

`query` : | a MgQuery
`field` : | a MgQfield which is in `query`
`order` : | the order in the list of ORDER BY fields (starts at 0), or -1
`ascendant` : | TRUE to sort ascending

### mg_query_get_order_by_field ()

    gint        mg_query_get_order_by_field     (MgQuery *query,
                                                 MgQfield *field,
                                                 gboolean *ascendant);

Tells if `field` (which MUST be in `query`) is part of the ORDER BY clause.

`query` : | a MgQuery
`field` : | a MgQfield which is in `query`
`ascendant` : | if not `NULL`, will be set TRUE if ascendant sorting and FALSE otherwise
Returns : | -1 if no, and the order where it appears in the ORDER BY list otherwise

### mg_query_expand_all_field ()

    GSList*     mg_query_expand_all_field       (MgQuery *query,
                                                 MgTarget *target);

Converts each visible "target.*" (MgQfAll) field into its list of fields. For example "t1.*" becomes "t1.a, t1.b" if table t1 is composed of fields "a" and "b". The original MgQfAll field is not removed, but simply rendered non visible.

The returned list must be free'd by the caller using `g_slist_free()`.

`query` : | a MgQuery object
`target` : | a MgTarget, or `NULL`
Returns : | a new list of the MgQfield objects which have been created

### mg_query_order_fields_using_join_conds ()

    void        mg_query_order_fields_using_join_conds
                                                (MgQuery *query);

Re-orders the fields in `query` using the joins' conditions: for each join condition, the used query fields are grouped together near the 1st visible field.

`query` : | a MgQuery object

## Properties

"`cond-serial`" (guint : Read) |
"`field-serial`" (guint : Read) |
"`really-all-fields`" (gpointer : Read) |
"`target-serial`" (guint : Read) |

## Signals

### The "condition-changed" signal

    void        user_function                  (MgQuery *mgquery,
                                                gpointer user_data);

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

### The "join-added" signal

    void        user_function                  (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);

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

### The "join-removed" signal

    void        user_function                  (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);

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

### The "join-updated" signal

    void        user_function                  (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);

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

### The "sub-query-added" signal

    void        user_function                  (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);

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

### The "sub-query-removed" signal

    void        user_function                  (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);

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

### The "sub-query-updated" signal

    void        user_function                  (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);

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

### The "target-added" signal

    void        user_function                  (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);

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

### The "target-removed" signal

    void        user_function                  (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);

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

### The "target-updated" signal

    void        user_function                  (MgQuery *mgquery,
                                                gpointer arg1,
                                                gpointer user_data);

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

### The "type-changed" signal

    void        user_function                  (MgQuery *mgquery,
                                                gpointer user_data);

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