[libgda/LIBGDA_4.2] Added gda_data_select_compute_modification_statements_ext()
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda/LIBGDA_4.2] Added gda_data_select_compute_modification_statements_ext()
- Date: Wed, 31 Aug 2011 19:59:41 +0000 (UTC)
commit 1ba542b7c37e4a7f3e08674a05cf56f24a4898ef
Author: Vivien Malerba <malerba gnome-db org>
Date: Fri Aug 5 16:33:34 2011 +0200
Added gda_data_select_compute_modification_statements_ext()
doc/C/libgda-sections.txt | 2 +
libgda/gda-data-proxy.c | 1 +
libgda/gda-data-select.c | 35 ++++++++++++++++-
libgda/gda-data-select.h | 16 ++++++++
libgda/gda-util.c | 90 ++++++++++++++++++++++++++++++++++++++------
libgda/libgda.symbols | 1 +
6 files changed, 130 insertions(+), 15 deletions(-)
---
diff --git a/doc/C/libgda-sections.txt b/doc/C/libgda-sections.txt
index fd125a9..200f544 100644
--- a/doc/C/libgda-sections.txt
+++ b/doc/C/libgda-sections.txt
@@ -1484,6 +1484,8 @@ gda_data_select_compute_row_selection_condition
gda_data_select_set_modification_statement
gda_data_select_set_modification_statement_sql
gda_data_select_compute_modification_statements
+GdaDataSelectConditionType
+gda_data_select_compute_modification_statements_ext
gda_data_select_compute_columns_attributes
gda_data_select_rerun
gda_data_select_add_exception
diff --git a/libgda/gda-data-proxy.c b/libgda/gda-data-proxy.c
index f36eb27..ca03ea2 100644
--- a/libgda/gda-data-proxy.c
+++ b/libgda/gda-data-proxy.c
@@ -1455,6 +1455,7 @@ gda_data_proxy_get_value_attributes (GdaDataProxy *proxy, gint proxy_row, gint c
gda_mutex_unlock (proxy->priv->mutex);
+ /*g_print ("%s (%p, %d, %d) => %d\n", __FUNCTION__, proxy, col, proxy_row, flags);*/
return flags;
}
diff --git a/libgda/gda-data-select.c b/libgda/gda-data-select.c
index 41b5f9f..4a62fc4 100644
--- a/libgda/gda-data-select.c
+++ b/libgda/gda-data-select.c
@@ -1286,6 +1286,9 @@ gda_data_select_set_modification_statement (GdaDataSelect *model, GdaStatement *
gda_column_set_g_type (gdacol, gda_holder_get_g_type (holder));
coltypeschanged = TRUE;
}
+ if (model->prep_stmt && model->prep_stmt->types &&
+ (model->prep_stmt->types [num] == GDA_TYPE_NULL))
+ model->prep_stmt->types [num] = gda_holder_get_g_type (holder);
}
}
@@ -1357,11 +1360,36 @@ gda_data_select_set_modification_statement (GdaDataSelect *model, GdaStatement *
* Makes @model try to compute INSERT, UPDATE and DELETE statements to be used when modifying @model's contents.
* Note: any modification statement set using gda_data_select_set_modification_statement() will first be unset
*
+ * This function is similar to calling gda_data_select_compute_modification_statements_ext with
+ * @cond_type set to %GDA_DATA_SELECT_COND_PK
+ *
* Returns: %TRUE if no error occurred. If %FALSE is returned, then some modification statement may still have been computed
*/
gboolean
gda_data_select_compute_modification_statements (GdaDataSelect *model, GError **error)
{
+ return gda_data_select_compute_modification_statements_ext (model, GDA_DATA_SELECT_COND_PK,
+ error);
+}
+
+/**
+ * gda_data_select_compute_modification_statements_ext:
+ * @model: a #GdaDataSelect data model
+ * @cond_type: the type of condition for the modifications where one row only should be identified
+ * @error: a place to store errors, or %NULL
+ *
+ * Makes @model try to compute INSERT, UPDATE and DELETE statements to be used when modifying @model's contents.
+ * Note: any modification statement set using gda_data_select_set_modification_statement() will first be unset
+ *
+ * Returns: %TRUE if no error occurred. If %FALSE is returned, then some modification statement may still have been computed
+ *
+ * Since: 4.2.9
+ */
+gboolean
+gda_data_select_compute_modification_statements_ext (GdaDataSelect *model,
+ GdaDataSelectConditionType cond_type,
+ GError **error)
+{
GdaStatement *stmt;
ModType mtype;
gboolean retval = TRUE;
@@ -1384,10 +1412,12 @@ gda_data_select_compute_modification_statements (GdaDataSelect *model, GError **
model->priv->sh->modif_internals->modif_stmts[mtype] = NULL;
}
- retval = gda_compute_dml_statements (model->priv->cnc, stmt, TRUE,
+ retval = gda_compute_dml_statements (model->priv->cnc, stmt,
+ cond_type == GDA_DATA_SELECT_COND_PK ? TRUE : FALSE,
&(modif_stmts[INS_QUERY]),
NULL, NULL, error);
- retval = gda_compute_dml_statements (model->priv->cnc, stmt, TRUE,
+ retval = gda_compute_dml_statements (model->priv->cnc, stmt,
+ cond_type == GDA_DATA_SELECT_COND_PK ? TRUE : FALSE,
NULL,
&(modif_stmts[UPD_QUERY]),
&(modif_stmts[DEL_QUERY]), error) && retval;
@@ -1414,6 +1444,7 @@ gda_data_select_compute_modification_statements (GdaDataSelect *model, GError **
return retval;
}
+
static gboolean
row_selection_condition_foreach_func (GdaSqlAnyPart *part, G_GNUC_UNUSED gpointer data, GError **error)
{
diff --git a/libgda/gda-data-select.h b/libgda/gda-data-select.h
index 53e387e..a0f7a63 100644
--- a/libgda/gda-data-select.h
+++ b/libgda/gda-data-select.h
@@ -50,6 +50,19 @@ typedef enum {
GDA_DATA_SELECT_SAFETY_LOCKED_ERROR
} GdaDataSelectError;
+/**
+ * GdaDataSelectConditionType:
+ * @GDA_DATA_SELECT_COND_PK: only primary key fields are used
+ * @GDA_DATA_SELECT_COND_ALL_COLUMNS: all the columns of the tables are used
+ *
+ * Defines what criteria gda_data_select_compute_modification_statements_ext() uses
+ * to uniquely identify a single row in a table when creating modification statements.
+ */
+typedef enum {
+ GDA_DATA_SELECT_COND_PK,
+ GDA_DATA_SELECT_COND_ALL_COLUMNS
+} GdaDataSelectConditionType;
+
struct _GdaDataSelect {
GObject object;
GdaDataSelectPrivate *priv;
@@ -107,6 +120,9 @@ gboolean gda_data_select_compute_row_selection_condition (GdaDataSelect *m
gboolean gda_data_select_set_modification_statement (GdaDataSelect *model, GdaStatement *mod_stmt, GError **error);
gboolean gda_data_select_set_modification_statement_sql (GdaDataSelect *model, const gchar *sql, GError **error);
gboolean gda_data_select_compute_modification_statements (GdaDataSelect *model, GError **error);
+gboolean gda_data_select_compute_modification_statements_ext (GdaDataSelect *model,
+ GdaDataSelectConditionType cond_type,
+ GError **error);
gboolean gda_data_select_compute_columns_attributes (GdaDataSelect *model, GError **error);
GdaConnection *gda_data_select_get_connection (GdaDataSelect *model);
diff --git a/libgda/gda-util.c b/libgda/gda-util.c
index 1ed65ba..af4fcd1 100644
--- a/libgda/gda-util.c
+++ b/libgda/gda-util.c
@@ -915,17 +915,16 @@ gda_compute_unique_table_row_condition_with_cnc (GdaConnection *cnc, GdaSqlState
GdaSqlOperation *and_cond = NULL;
g_return_val_if_fail (!cnc || GDA_IS_CONNECTION (cnc), NULL);
-
- if (mtable->pk_cols_nb == 0) {
- g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
- "%s", _("Table does not have any primary key"));
- return NULL;
- }
expr = gda_sql_expr_new (NULL); /* no parent */
if (require_pk) {
if (mtable->pk_cols_nb == 0) {
g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
+ "%s", _("Table does not have any primary key"));
+ goto onerror;
+ }
+ if (mtable->pk_cols_nb == 0) {
+ g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
"%s", _("Table does not have any primary key"));
goto onerror;
}
@@ -939,10 +938,10 @@ gda_compute_unique_table_row_condition_with_cnc (GdaConnection *cnc, GdaSqlState
GdaMetaTableColumn *tcol;
GSList *list;
gint index;
-
+
tcol = (GdaMetaTableColumn *) g_slist_nth_data (mtable->columns, mtable->pk_cols_array[i]);
- for (index = 0, list = stsel->expr_list;
- list;
+ for (index = 0, list = stsel->expr_list;
+ list;
index++, list = list->next) {
sfield = (GdaSqlSelectField *) list->data;
if (sfield->validity_meta_table_column == tcol)
@@ -952,7 +951,7 @@ gda_compute_unique_table_row_condition_with_cnc (GdaConnection *cnc, GdaSqlState
}
if (!sfield) {
g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
- "%s", _("Table's primary key is not selected"));
+ "%s", _("Table's primary key is not part of SELECT"));
goto onerror;
}
else {
@@ -992,9 +991,74 @@ gda_compute_unique_table_row_condition_with_cnc (GdaConnection *cnc, GdaSqlState
}
}
else {
- TO_IMPLEMENT;
- gda_sql_expr_free (expr);
- expr = NULL;
+ GSList *columns;
+ if (! mtable->columns) {
+ g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
+ "%s", _("Table does not have any column"));
+ goto onerror;
+ }
+ else if (mtable->columns->next) {
+ and_cond = gda_sql_operation_new (GDA_SQL_ANY_PART (expr));
+ and_cond->operator_type = GDA_SQL_OPERATOR_TYPE_AND;
+ expr->cond = and_cond;
+ }
+ for (columns = mtable->columns; columns; columns = columns->next) {
+ GdaSqlSelectField *sfield = NULL;
+ GdaMetaTableColumn *tcol;
+ GSList *list;
+ gint index;
+
+ tcol = (GdaMetaTableColumn *) columns->data;
+ for (index = 0, list = stsel->expr_list;
+ list;
+ index++, list = list->next) {
+ sfield = (GdaSqlSelectField *) list->data;
+ if (sfield->validity_meta_table_column == tcol)
+ break;
+ else
+ sfield = NULL;
+ }
+ if (!sfield) {
+ g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
+ _("Table's column '%s' is not part of SELECT"),
+ tcol->column_name);
+ goto onerror;
+ }
+ else {
+ GdaSqlOperation *op;
+ GdaSqlExpr *opexpr;
+ GdaSqlParamSpec *pspec;
+
+ /* equal condition */
+ if (and_cond) {
+ opexpr = gda_sql_expr_new (GDA_SQL_ANY_PART (and_cond));
+ op = gda_sql_operation_new (GDA_SQL_ANY_PART (opexpr));
+ opexpr->cond = op;
+ and_cond->operands = g_slist_append (and_cond->operands, opexpr);
+ }
+ else {
+ op = gda_sql_operation_new (GDA_SQL_ANY_PART (expr));
+ expr->cond = op;
+ }
+ op->operator_type = GDA_SQL_OPERATOR_TYPE_EQ;
+ /* left operand */
+ gchar *str;
+ opexpr = gda_sql_expr_new (GDA_SQL_ANY_PART (op));
+ str = gda_sql_identifier_quote (tcol->column_name, cnc, NULL, FALSE, FALSE);
+ g_value_take_string (opexpr->value = gda_value_new (G_TYPE_STRING), str);
+
+ op->operands = g_slist_append (op->operands, opexpr);
+
+ /* right operand */
+ opexpr = gda_sql_expr_new (GDA_SQL_ANY_PART (op));
+ pspec = g_new0 (GdaSqlParamSpec, 1);
+ pspec->name = g_strdup_printf ("-%d", index);
+ pspec->g_type = (tcol->gtype != GDA_TYPE_NULL) ? tcol->gtype: G_TYPE_STRING;
+ pspec->nullok = tcol->nullok;
+ opexpr->param_spec = pspec;
+ op->operands = g_slist_append (op->operands, opexpr);
+ }
+ }
}
return expr;
diff --git a/libgda/libgda.symbols b/libgda/libgda.symbols
index 95c4047..f1a0801 100644
--- a/libgda/libgda.symbols
+++ b/libgda/libgda.symbols
@@ -321,6 +321,7 @@
gda_data_select_add_exception
gda_data_select_compute_columns_attributes
gda_data_select_compute_modification_statements
+ gda_data_select_compute_modification_statements_ext
gda_data_select_compute_row_selection_condition
gda_data_select_error_quark
gda_data_select_get_connection
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]