## MgWorkCore

MgWorkCore — Creates UPDATE, INSERT and DELETE queries form a SELECT query

## Synopsis

    struct      MgWorkCore;
    struct      MgWorkCoreNode;
    guint       mg_work_core_get_type           (void);
    GObject*    mg_work_core_new                (MgQuery *query,
                                                 MgTarget *modified);
    gboolean    mg_work_core_run_select_query   (MgWorkCore *core,
                                                 GError **error);
    MgParameter* mg_work_core_find_param        (MgWorkCore *core,
                                                 MgQfield *field,
                                                 gboolean in_exec_context);
    MgWorkCoreNode* mg_work_core_find_core_node (MgWorkCore *core,
                                                 MgParameter *param);

## Object Hierarchy

      GObject
       +----MgBase
             +----MgWorkCore

## Description

This object is used by the MgWorkForm widget to create and manage the modification queries (UPDATE, DELETE, INSERT) from a SELECT query given as argument, and an entity (a database table) to be modified, also given as argument. The SELECT query is copied and completely managed by the MgWorkCore object.

The way it works is quite complicated but it is necessary to understand a bit of it to be able to use the public attributes listed below. Basically what it does is in the following steps:

- It makes a copy of the 'query' argument provided in the `mg_work_core_new()` function and stores it in 'query_select'.

- If no target (representing a table) to be modified is provided, then the object simply creates a MgParameter for each field in the 'query_select' query, and creates a MgContext out of the list of created parameters (stored in 'work_context')

- If a target to be modified is provided, then the following steps are done:

  - It creates a distinct SELECT query for each target which appears in the 'query_select' with the fields in 'query_select' which reference that target (except for the target to be modified for which a copy of 'query_select' is done, into 'query_select_hybrid': that query will be a base to build the modification queries)

  - For the 'query_select_hybrid' query, MgQfValue fields are added for each field which reference the target to be modified, and sets the "value_provider" property of each of these field to the corresponding MgQfValue created.

  - For each join (between two distinct targets), it then uses the join condition (or for joins without conditions the PK/FK constraints on the database) to add, if they are not yet present, the query fields representing the join condition to the SELECT queries attached to each target of each join (and it also adds the same query fields to 'query_select'). Also, MgQfValue query fields are added for query fields in the role of the 'foreign key' field (and set the "value_provider" in the same way as in the precedent item).

  - The 'work_context' is extracted from the 'query_select_hybrid' query.

The object makes several pieces of information available as public data in its structure (they MUST NOT be modified), such as:

- The 'args_context': a MgContext object to manage the parameters required to execute the SELECT query given as argument to the `mg_work_core_new()` function.

- The 'work_context': a MGContext object to manage the parameters required to execute one of the modification queries generated by this object (UPDATE, DELETE, INSERT).

- The 'modif_target': the MgTarget which represents the entity to be modified by the modification queries (that object is part of the SELECT query managed by the MGWorkCore object, nit the original SELECT query).

- The 'work_context_qf_position': a hash table where the keys are visible MgQfField objects from any query in any of the MgContextNode structure and the keys the positions of the corresponding field in 'query_select' (by construction, there is at least one such corresponding field in 'query_select')

- The 'query_select': a copy of the MGQuery given as argument to the `mg_work_core_new()` function.

- The 'query_update': a MgQuery which is the UPDATE query created by the MgWorkCore object

- The 'query_delete': a MgQuery which is the DELETE query created by the MgWorkCore object

- The 'query_insert': a MgQuery which is the INSERT query created by the MgWorkCore object

- The 'data_rs': a MgResultSet object which holds the result of the execution of 'query_select'

- The 'nodes': a list of MgWorkCoreNode structures.

- The 'params_in_data_rs': a list of MgParameter objects belonging to 'work_context' which have a correspondance in the 'data_rs' resulset (ie. are listed in a MgWorkCoreNode in 'nodes')

- The 'params_not_in_data_rs': a list of MgParameter objects belonging to 'work_context' which do not have a correspondance in 'data_rs'

- The 'params_modif_queries_value_providers': a list of MGParameter object which are used by the modification queries as value providers for some fields.

- The 'no_show_params': a list of MgParameter parameter for which the corresponding data entry should be hidden: they correspond to condition parameters or internal fields.

## Details

### struct MgWorkCore

    struct MgWorkCore;

### struct MgWorkCoreNode

    struct MgWorkCoreNode {

            MgParameter *param;    /* each param in the query_select is also present in the 'work_context' and is only referenced there */
            gint         position; /* field position in query_select (and in the 'data_rs' MgResultSet) */
    };

Each structure holds a pointer to a MgParameter and a position. The parameter belongs to the 'work_context' which is the MgContext used by the UPDATE, DELETE and INSERT queries to be executed. The position is the column position in the execution's result of the 'query_select' query which can be used by the parameter.

### mg_work_core_get_type ()

    guint       mg_work_core_get_type           (void);

Returns : |

### mg_work_core_new ()

    GObject*    mg_work_core_new                (MgQuery *query,
                                                 MgTarget *modified);

Creates a new MgWorkCore object and fills it with appropriate data

`query` must be a SELECT query (no union, etc selection query)

The `modified` target must belong to `query` and represent modifiable entity (a MgDbTable for example). If `modified` is `NULL` then no modification will be allowed.

`query` : | a MgQuery object
`modified` : | a MgTarget object, or `NULL`
Returns : | the new object

### mg_work_core_run_select_query ()

    gboolean    mg_work_core_run_select_query   (MgWorkCore *core,
                                                 GError **error);

Runs the `core->selec_query` SELECT query and stores the resultset in `core->data_rs`

`core` : | a MgWorkCore object
`error` : | location to store error, or `NULL`
Returns : | TRUE if not error occurred

### mg_work_core_find_param ()

    MgParameter* mg_work_core_find_param        (MgWorkCore *core,
                                                 MgQfield *field,
                                                 gboolean in_exec_context);

Finds the MgParameter 'attached' to the values of `field`. The `in_exec_context` specifies if the parameter is to be searched among the required parameters to execute the SELECT query given as 'query' argument to `mg_work_core_new()`, or among the results of the execution of that query.

`core` : | a MgWorkCore object
`field` : | a MgQfield which belongs to the SELECT query given as 'query' argument to `mg_work_core_new()`, or to `core->query_select` (which is a copy of the query given as 'query' argument to `mg_work_core_new()`)
`in_exec_context` : | TRUE if to search in the exec context, or FALSE to search among the "data" context
Returns : | the requested MgParameter, or `NULL`

### mg_work_core_find_core_node ()

    MgWorkCoreNode* mg_work_core_find_core_node (MgWorkCore *core,
                                                 MgParameter *param);

Find the MgWorkCoreNode node which handles `param`.

`core` : | a MgWorkCoreNode object
`param` : | a MgParameter object
Returns : | the corresponding MgWorkCoreNode