|
|
|
@ -51,34 +51,15 @@ struct _DbModelPrivate
|
|
|
|
|
SqlStmt * stmt;
|
|
|
|
|
gchar * sql;
|
|
|
|
|
gboolean use_file;
|
|
|
|
|
Table * main_table;
|
|
|
|
|
DbModelUpdateFlags update_flags;
|
|
|
|
|
SqlBatch * batch;
|
|
|
|
|
|
|
|
|
|
GPtrArray * data;
|
|
|
|
|
DbColumn * column;
|
|
|
|
|
GHashTable * column_index;
|
|
|
|
|
DbResult * result;
|
|
|
|
|
guint result_pos;
|
|
|
|
|
DbRequest * request;
|
|
|
|
|
DbModelStatus status;
|
|
|
|
|
DbModelMode mode;
|
|
|
|
|
gchar * user_main_table;
|
|
|
|
|
DbModelUpdateFlags user_update_flags;
|
|
|
|
|
guint result_pos;
|
|
|
|
|
GQueue * operation;
|
|
|
|
|
GHashTable * row_ops;
|
|
|
|
|
gint updated_col;
|
|
|
|
|
GValue * updated_value;
|
|
|
|
|
|
|
|
|
|
GHashTable * column_index;
|
|
|
|
|
GSList * pending_request;
|
|
|
|
|
GSList * join;
|
|
|
|
|
|
|
|
|
|
SqlObject * link_op;
|
|
|
|
|
SqlBatch * internal_batch;
|
|
|
|
|
GHashTable * column_defaults;
|
|
|
|
|
GHashTable * tables;
|
|
|
|
|
gboolean updatable_data_allocated;
|
|
|
|
|
|
|
|
|
|
gint stamp;
|
|
|
|
|
|
|
|
|
|
gboolean fresh;
|
|
|
|
@ -92,6 +73,23 @@ struct _DbModelPrivate
|
|
|
|
|
DbIterCompareFunc sort_func;
|
|
|
|
|
gpointer sort_data;
|
|
|
|
|
GDestroyNotify sort_destroy;
|
|
|
|
|
|
|
|
|
|
SqlObject * link_op;
|
|
|
|
|
SqlBatch * internal_batch;
|
|
|
|
|
GHashTable * column_defaults;
|
|
|
|
|
|
|
|
|
|
gboolean updatable_data_allocated;
|
|
|
|
|
DbModelUpdateFlags update_flags;
|
|
|
|
|
DbModelUpdateFlags user_update_flags;
|
|
|
|
|
Table * main_table;
|
|
|
|
|
gchar * user_main_table;
|
|
|
|
|
GHashTable * tables;
|
|
|
|
|
gint updated_col;
|
|
|
|
|
GQueue * operation;
|
|
|
|
|
GHashTable * row_ops;
|
|
|
|
|
GValue * updated_value;
|
|
|
|
|
GSList * pending_request;
|
|
|
|
|
GSList * join;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Helper structures and methods
|
|
|
|
@ -212,62 +210,6 @@ static void db_model_alloc_link_data (DbModel * obj)
|
|
|
|
|
sql_operation_set_operands (SQL_OPERATION (priv->link_op), operators);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void db_model_free_stmt_data (DbModel * obj)
|
|
|
|
|
{
|
|
|
|
|
if (obj->priv->tables)
|
|
|
|
|
g_hash_table_destroy (obj->priv->tables);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void db_model_alloc_stmt_data (DbModel * obj)
|
|
|
|
|
{
|
|
|
|
|
gint i;
|
|
|
|
|
Table table;
|
|
|
|
|
TableData * table_data;
|
|
|
|
|
DbModelPrivate * priv = obj->priv;
|
|
|
|
|
|
|
|
|
|
if (!priv->updatable_data_allocated)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
db_model_free_stmt_data (obj);
|
|
|
|
|
|
|
|
|
|
priv->tables = g_hash_table_new_full (
|
|
|
|
|
(GHashFunc) table_hash,
|
|
|
|
|
(GEqualFunc) table_equal,
|
|
|
|
|
(GDestroyNotify) table_free,
|
|
|
|
|
(GDestroyNotify) table_data_free
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->result->ncols; i++)
|
|
|
|
|
if ((priv->column[i].info & DB_COLUMN_PRI_KEY))
|
|
|
|
|
{
|
|
|
|
|
table.name = priv->column[i].table;
|
|
|
|
|
table.schema = priv->column[i].schema;
|
|
|
|
|
|
|
|
|
|
table_data = g_hash_table_lookup (priv->tables, &table);
|
|
|
|
|
|
|
|
|
|
if (!table_data)
|
|
|
|
|
{
|
|
|
|
|
table_data = g_new0 (TableData, 1);
|
|
|
|
|
table_data->pkeys = NULL;
|
|
|
|
|
g_hash_table_insert (priv->tables, table_copy (&table), table_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
table_data->pkeys = g_slist_prepend (table_data->pkeys, GINT_TO_POINTER (i));
|
|
|
|
|
g_hash_table_insert (priv->tables, table_copy (&table), table_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->result->ncols; i++)
|
|
|
|
|
{
|
|
|
|
|
table.name = priv->column[i].table;
|
|
|
|
|
table.schema = priv->column[i].schema;
|
|
|
|
|
|
|
|
|
|
table_data = g_hash_table_lookup (priv->tables, &table);
|
|
|
|
|
|
|
|
|
|
if (table_data && table_data->pkeys)
|
|
|
|
|
gvn_param_spec_set_editable (priv->column[i].spec, TRUE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Signal Handlers
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
@ -323,9 +265,64 @@ static void db_model_calculate_update_flags (DbModel * obj)
|
|
|
|
|
{
|
|
|
|
|
gint i;
|
|
|
|
|
Table table;
|
|
|
|
|
TableData * table_data;
|
|
|
|
|
DbModelPrivate * priv = obj->priv;
|
|
|
|
|
|
|
|
|
|
priv->main_table = NULL;
|
|
|
|
|
// Allocates aditional memory when the model is updatable
|
|
|
|
|
|
|
|
|
|
if (priv->user_update_flags && !priv->updatable_data_allocated)
|
|
|
|
|
{
|
|
|
|
|
priv->updatable_data_allocated = TRUE;
|
|
|
|
|
priv->operation = g_queue_new ();
|
|
|
|
|
priv->row_ops = g_hash_table_new (g_direct_hash, g_direct_equal);
|
|
|
|
|
priv->tables = g_hash_table_new_full (
|
|
|
|
|
(GHashFunc) table_hash,
|
|
|
|
|
(GEqualFunc) table_equal,
|
|
|
|
|
(GDestroyNotify) table_free,
|
|
|
|
|
(GDestroyNotify) table_data_free
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (priv->user_update_flags && priv->fresh && priv->result)
|
|
|
|
|
{
|
|
|
|
|
g_hash_table_remove_all (priv->tables);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->result->ncols; i++)
|
|
|
|
|
if ((priv->column[i].info & DB_COLUMN_PRI_KEY))
|
|
|
|
|
{
|
|
|
|
|
table.name = priv->column[i].table;
|
|
|
|
|
table.schema = priv->column[i].schema;
|
|
|
|
|
|
|
|
|
|
table_data = g_hash_table_lookup (priv->tables, &table);
|
|
|
|
|
|
|
|
|
|
if (!table_data)
|
|
|
|
|
{
|
|
|
|
|
table_data = g_new0 (TableData, 1);
|
|
|
|
|
table_data->pkeys = NULL;
|
|
|
|
|
g_hash_table_insert (priv->tables, table_copy (&table), table_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
table_data->pkeys = g_slist_prepend (table_data->pkeys, GINT_TO_POINTER (i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (priv->result)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < priv->result->ncols; i++)
|
|
|
|
|
{
|
|
|
|
|
table.name = priv->column[i].table;
|
|
|
|
|
table.schema = priv->column[i].schema;
|
|
|
|
|
|
|
|
|
|
table_data = g_hash_table_lookup (priv->tables, &table);
|
|
|
|
|
|
|
|
|
|
if (table_data && table_data->pkeys)
|
|
|
|
|
gvn_param_spec_set_editable (priv->column[i].spec, TRUE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Searchs for the main table
|
|
|
|
|
|
|
|
|
|
table.name = NULL;
|
|
|
|
|
|
|
|
|
|
if (priv->result)
|
|
|
|
|
{
|
|
|
|
@ -336,39 +333,29 @@ static void db_model_calculate_update_flags (DbModel * obj)
|
|
|
|
|
{
|
|
|
|
|
table.name = priv->column[i].table;
|
|
|
|
|
table.schema = priv->column[i].schema;
|
|
|
|
|
priv->main_table = g_hash_table_lookup (priv->tables, &table);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
table_parse (&table, priv->user_main_table);
|
|
|
|
|
priv->main_table = g_hash_table_lookup (priv->tables, &table);
|
|
|
|
|
|
|
|
|
|
if (!priv->main_table)
|
|
|
|
|
g_log (g_quark_to_string (DB_MODEL_LOG_DOMAIN), G_LOG_LEVEL_WARNING,
|
|
|
|
|
"Can't set '%s' as main table", table.name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!table.name
|
|
|
|
|
|| !g_hash_table_lookup_extended (priv->tables, &table, (gpointer) &priv->main_table, NULL))
|
|
|
|
|
{
|
|
|
|
|
priv->main_table = NULL;
|
|
|
|
|
|
|
|
|
|
if (priv->user_main_table)
|
|
|
|
|
g_log (g_quark_to_string (DB_MODEL_LOG_DOMAIN), G_LOG_LEVEL_WARNING,
|
|
|
|
|
"Can't set '%s' as main table", priv->user_main_table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sets the updatable flags
|
|
|
|
|
|
|
|
|
|
if (priv->main_table)
|
|
|
|
|
priv->update_flags = DB_MODEL_ALL & priv->user_update_flags;
|
|
|
|
|
else
|
|
|
|
|
priv->update_flags = 0;
|
|
|
|
|
|
|
|
|
|
if (!priv->updatable_data_allocated && priv->update_flags)
|
|
|
|
|
{
|
|
|
|
|
priv->updatable_data_allocated = TRUE;
|
|
|
|
|
priv->operation = g_queue_new ();
|
|
|
|
|
priv->row_ops = g_hash_table_new (g_direct_hash, g_direct_equal);
|
|
|
|
|
|
|
|
|
|
priv->column_defaults = g_hash_table_new_full (
|
|
|
|
|
(GHashFunc) field_hash,
|
|
|
|
|
(GEqualFunc) field_equal,
|
|
|
|
|
(GDestroyNotify) field_free,
|
|
|
|
|
(GDestroyNotify) column_def_free
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void db_model_on_data_ready (DbRequest * request, DbModel * obj)
|
|
|
|
@ -388,8 +375,6 @@ static void db_model_on_data_ready (DbRequest * request, DbModel * obj)
|
|
|
|
|
|
|
|
|
|
if ((r = db_request_fetch_result (request, NULL)))
|
|
|
|
|
{
|
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
|
|
priv->column = r->column;
|
|
|
|
|
priv->data = r->data;
|
|
|
|
|
|
|
|
|
@ -404,9 +389,6 @@ static void db_model_on_data_ready (DbRequest * request, DbModel * obj)
|
|
|
|
|
|
|
|
|
|
if (priv->fresh)
|
|
|
|
|
{
|
|
|
|
|
db_model_calculate_update_flags (obj);
|
|
|
|
|
db_model_alloc_stmt_data (obj);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->result->ncols; i++)
|
|
|
|
|
g_hash_table_insert (priv->column_index,
|
|
|
|
|
g_strdup (priv->column[i].alias), GINT_TO_POINTER (i));
|
|
|
|
@ -417,6 +399,9 @@ static void db_model_on_data_ready (DbRequest * request, DbModel * obj)
|
|
|
|
|
db_model_set_sort_column_id (obj,
|
|
|
|
|
priv->old_sort_column_id, priv->old_order);
|
|
|
|
|
|
|
|
|
|
db_model_calculate_update_flags (obj);
|
|
|
|
|
priv->fresh = FALSE;
|
|
|
|
|
|
|
|
|
|
db_model_set_status (obj, DB_MODEL_STATUS_READY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -445,32 +430,17 @@ static void db_model_process_insert (DbModel * obj, DbRequest * request, DbRow *
|
|
|
|
|
for (i = 0; i < result->ncols; i++)
|
|
|
|
|
for (j = 0; j < priv->result->ncols; j++)
|
|
|
|
|
if (!g_strcmp0 (priv->column[j].name, result->column[i].name)
|
|
|
|
|
&& !g_strcmp0 (priv->column[j].table, result->column[i].table))
|
|
|
|
|
&& !g_strcmp0 (priv->column[j].table, result->column[i].table)
|
|
|
|
|
&& !g_strcmp0 (priv->column[j].schema, result->column[i].schema))
|
|
|
|
|
{
|
|
|
|
|
GValue * v;
|
|
|
|
|
gboolean emit = TRUE;
|
|
|
|
|
GValue * new_value = &req_row->value[i];
|
|
|
|
|
|
|
|
|
|
priv->updated_value = g_new0 (GValue, 1);
|
|
|
|
|
|
|
|
|
|
if ((v = &req_row->value[i]) && G_IS_VALUE (v)
|
|
|
|
|
&& !gvn_value_is_null (DB_ROW_FIELD (req_row, i))
|
|
|
|
|
&& gvn_value_is_null (DB_ROW_FIELD (row, j)))
|
|
|
|
|
{
|
|
|
|
|
g_value_init (priv->updated_value, G_VALUE_TYPE (v));
|
|
|
|
|
gvn_value_copy (v, priv->updated_value);
|
|
|
|
|
}
|
|
|
|
|
else if (gvn_value_is_null (DB_ROW_FIELD (row, j)))
|
|
|
|
|
{
|
|
|
|
|
g_value_init (priv->updated_value, GVN_TYPE_NULL);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
emit = FALSE;
|
|
|
|
|
g_free (priv->updated_value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (emit)
|
|
|
|
|
if (!gvn_value_compare (new_value, DB_ROW_FIELD (row, j)))
|
|
|
|
|
{
|
|
|
|
|
priv->updated_value = g_new0 (GValue, 1);
|
|
|
|
|
g_value_init (priv->updated_value, G_VALUE_TYPE (new_value));
|
|
|
|
|
g_value_copy (new_value, priv->updated_value);
|
|
|
|
|
|
|
|
|
|
priv->updated_col = j;
|
|
|
|
|
g_signal_emit (obj, db_model_signal[LINE_UPDATED], 0, &iter);
|
|
|
|
|
}
|
|
|
|
@ -485,13 +455,11 @@ static void db_model_on_operations_done (DbRequest * request, DbModelRequest * d
|
|
|
|
|
{
|
|
|
|
|
GList * l;
|
|
|
|
|
guint i = 0;
|
|
|
|
|
DbIter iter;
|
|
|
|
|
DbOperation * op;
|
|
|
|
|
GError * err = NULL;
|
|
|
|
|
DbModel * obj = data->obj;
|
|
|
|
|
DbModelPrivate * priv = obj->priv;
|
|
|
|
|
|
|
|
|
|
priv->pending_request =
|
|
|
|
|
g_slist_remove (priv->pending_request, request);
|
|
|
|
|
|
|
|
|
|
l = g_queue_peek_head_link (data->operations);
|
|
|
|
|
|
|
|
|
@ -507,7 +475,7 @@ static void db_model_on_operations_done (DbRequest * request, DbModelRequest * d
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (db_request_fetch_non_select (request, &err) == -1)
|
|
|
|
|
if (!request || db_request_fetch_non_select (request, &err) == -1)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
g_hash_table_remove (priv->row_ops, op->row);
|
|
|
|
@ -525,7 +493,6 @@ static void db_model_on_operations_done (DbRequest * request, DbModelRequest * d
|
|
|
|
|
{
|
|
|
|
|
guint j;
|
|
|
|
|
SqlList * list;
|
|
|
|
|
DbIter iter;
|
|
|
|
|
SqlObject * multi = sql_list_get (data->stmts, i);
|
|
|
|
|
|
|
|
|
|
g_object_get (multi, "stmts", &list, NULL);
|
|
|
|
@ -538,7 +505,7 @@ static void db_model_on_operations_done (DbRequest * request, DbModelRequest * d
|
|
|
|
|
if (G_OBJECT_TYPE (sql_list_get (list, j)) == SQL_TYPE_MULTI_STMT)
|
|
|
|
|
db_model_process_insert (obj, request, op->row, err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
iter.stamp = priv->stamp;
|
|
|
|
|
iter.data = op->row;
|
|
|
|
|
g_signal_emit (obj, db_model_signal[LINE_UPDATED], 0, &iter);
|
|
|
|
@ -547,6 +514,13 @@ static void db_model_on_operations_done (DbRequest * request, DbModelRequest * d
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (request)
|
|
|
|
|
{
|
|
|
|
|
priv->pending_request =
|
|
|
|
|
g_slist_remove (priv->pending_request, request);
|
|
|
|
|
g_object_unref (request);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!err)
|
|
|
|
|
{
|
|
|
|
|
while ((op = g_queue_pop_head (data->operations)))
|
|
|
|
@ -554,12 +528,11 @@ static void db_model_on_operations_done (DbRequest * request, DbModelRequest * d
|
|
|
|
|
|
|
|
|
|
g_signal_emit (obj, db_model_signal[OPERATIONS_DONE], 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_object_unref (request);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void db_model_on_stmt_changed (SqlStmt * stmt, DbModel * obj)
|
|
|
|
|
{
|
|
|
|
|
obj->priv->fresh = TRUE;
|
|
|
|
|
db_model_refresh (obj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -679,8 +652,6 @@ static void db_operation_add_updated (DbOperation * op, gint col)
|
|
|
|
|
u->column = col;
|
|
|
|
|
op->type |= DB_MODEL_ROW_OP_UPDATE;
|
|
|
|
|
op->updated = g_slist_prepend (op->updated, u);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean db_model_set_row_operation (DbModel * obj,
|
|
|
|
@ -698,12 +669,7 @@ static gboolean db_model_set_row_operation (DbModel * obj,
|
|
|
|
|
|
|
|
|
|
if (type & DB_MODEL_ROW_OP_UPDATE)
|
|
|
|
|
db_operation_add_updated (new_op, col);
|
|
|
|
|
/* if (!db_operation_add_updated (new_op, col))
|
|
|
|
|
{
|
|
|
|
|
g_free (new_op);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
g_hash_table_insert (obj->priv->row_ops, row, new_op);
|
|
|
|
|
g_queue_push_tail (obj->priv->operation, new_op);
|
|
|
|
|
}
|
|
|
|
@ -714,8 +680,6 @@ static gboolean db_model_set_row_operation (DbModel * obj,
|
|
|
|
|
|
|
|
|
|
if (type & DB_MODEL_ROW_OP_UPDATE)
|
|
|
|
|
db_operation_add_updated (op, col);
|
|
|
|
|
// if (!db_operation_add_updated (op, col))
|
|
|
|
|
// return FALSE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return FALSE;
|
|
|
|
@ -1302,16 +1266,14 @@ static void db_model_clear (DbModel * obj)
|
|
|
|
|
priv->result = NULL;
|
|
|
|
|
priv->column = NULL;
|
|
|
|
|
priv->data = NULL;
|
|
|
|
|
|
|
|
|
|
g_free (priv->main_table);
|
|
|
|
|
priv->main_table = NULL;
|
|
|
|
|
priv->update_flags = 0;
|
|
|
|
|
|
|
|
|
|
priv->fresh = FALSE;
|
|
|
|
|
priv->old_order = priv->order;
|
|
|
|
|
priv->old_sort_column_id = priv->sort_column_id;
|
|
|
|
|
priv->sort_column_id = DB_MODEL_UNSORTED_SORT_COLUMN_ID;
|
|
|
|
|
priv->stamp = g_random_int ();
|
|
|
|
|
|
|
|
|
|
priv->main_table = NULL;
|
|
|
|
|
priv->update_flags = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1674,7 +1636,7 @@ void db_model_set_default_value_from_param (DbModel * obj,
|
|
|
|
|
g_return_if_fail (GVN_IS_PARAM (param));
|
|
|
|
|
|
|
|
|
|
field = field_new_from_string (field_str);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (link)
|
|
|
|
|
{
|
|
|
|
|
SqlList * operands, * link_operands;
|
|
|
|
@ -2311,7 +2273,10 @@ gboolean db_model_has_pending_operations (DbModel * obj)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (DB_IS_MODEL (obj), FALSE);
|
|
|
|
|
|
|
|
|
|
return g_hash_table_size (obj->priv->row_ops) > 0;
|
|
|
|
|
if (obj->priv->row_ops)
|
|
|
|
|
return g_hash_table_size (obj->priv->row_ops) > 0;
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static SqlObject * db_model_create_where (DbModel * obj,
|
|
|
|
@ -2330,11 +2295,12 @@ static SqlObject * db_model_create_where (DbModel * obj,
|
|
|
|
|
|
|
|
|
|
and_operands = sql_list_new (SQL_TYPE_EXPR);
|
|
|
|
|
sql_operation_set_operands (SQL_OPERATION (where), and_operands);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TableData * table_data = g_hash_table_lookup (priv->tables, table);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (l = table_data->pkeys; l; l = l->next)
|
|
|
|
|
{
|
|
|
|
|
GSList * n;
|
|
|
|
|
SqlObject * equal;
|
|
|
|
|
SqlList * operands;
|
|
|
|
|
gint col = GPOINTER_TO_INT (l->data);
|
|
|
|
@ -2343,7 +2309,7 @@ static SqlObject * db_model_create_where (DbModel * obj,
|
|
|
|
|
|
|
|
|
|
g_value = &row->value[col];
|
|
|
|
|
|
|
|
|
|
for (l = operation->updated; l && (u = l->data); l = l->next)
|
|
|
|
|
for (n = operation->updated; n && (u = n->data); n = n->next)
|
|
|
|
|
if (u->column == col)
|
|
|
|
|
{
|
|
|
|
|
g_value = u->value;
|
|
|
|
@ -2624,9 +2590,8 @@ void db_model_perform_operations (DbModel * obj, gboolean retry)
|
|
|
|
|
sql_list_add (stmts, stmt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sql_list_length (stmts) > 0 && !error)
|
|
|
|
|
if (!error)
|
|
|
|
|
{
|
|
|
|
|
SqlObject * multi = g_object_new (SQL_TYPE_MULTI_STMT, "stmts", stmts, NULL);
|
|
|
|
|
GQueue * ops = g_queue_new ();
|
|
|
|
|
|
|
|
|
|
while ((op = g_queue_pop_head (priv->operation)))
|
|
|
|
@ -2636,18 +2601,29 @@ void db_model_perform_operations (DbModel * obj, gboolean retry)
|
|
|
|
|
data->obj = g_object_ref (obj);
|
|
|
|
|
data->operations = ops;
|
|
|
|
|
data->stmts = g_object_ref_sink (stmts);
|
|
|
|
|
|
|
|
|
|
request = db_conn_query_with_stmt_async (priv->conn
|
|
|
|
|
,SQL_STMT (multi)
|
|
|
|
|
,NULL
|
|
|
|
|
,(DbRequestDoneCallback) db_model_on_operations_done
|
|
|
|
|
,data
|
|
|
|
|
,(GDestroyNotify) db_model_request_free
|
|
|
|
|
);
|
|
|
|
|
db_model_add_pending_request (obj, request);
|
|
|
|
|
|
|
|
|
|
if (sql_list_length (stmts) > 0)
|
|
|
|
|
{
|
|
|
|
|
SqlObject * multi = g_object_new (
|
|
|
|
|
SQL_TYPE_MULTI_STMT, "stmts", stmts, NULL);
|
|
|
|
|
|
|
|
|
|
request = db_conn_query_with_stmt_async (priv->conn
|
|
|
|
|
,SQL_STMT (multi)
|
|
|
|
|
,NULL
|
|
|
|
|
,(DbRequestDoneCallback) db_model_on_operations_done
|
|
|
|
|
,data
|
|
|
|
|
,(GDestroyNotify) db_model_request_free
|
|
|
|
|
);
|
|
|
|
|
db_model_add_pending_request (obj, request);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
db_model_on_operations_done (NULL, data);
|
|
|
|
|
db_model_request_free (data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
g_warning ("DbModel: Error performing operations");
|
|
|
|
|
g_warning ("DbModel: Error performing operations.");
|
|
|
|
|
|
|
|
|
|
g_object_unref (stmts);
|
|
|
|
|
}
|
|
|
|
@ -3054,13 +3030,18 @@ static void db_model_init (DbModel *obj)
|
|
|
|
|
|
|
|
|
|
priv->link_op = NULL;
|
|
|
|
|
priv->internal_batch = NULL;
|
|
|
|
|
priv->column_defaults = g_hash_table_new_full (
|
|
|
|
|
(GHashFunc) field_hash,
|
|
|
|
|
(GEqualFunc) field_equal,
|
|
|
|
|
(GDestroyNotify) field_free,
|
|
|
|
|
(GDestroyNotify) column_def_free
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
priv->updatable_data_allocated = FALSE;
|
|
|
|
|
priv->update_flags = 0;
|
|
|
|
|
priv->user_update_flags = DB_MODEL_ALL;
|
|
|
|
|
priv->main_table = NULL;
|
|
|
|
|
priv->user_main_table = NULL;
|
|
|
|
|
priv->column_defaults = NULL;
|
|
|
|
|
priv->operation = NULL;
|
|
|
|
|
priv->row_ops = NULL;
|
|
|
|
|
priv->join = NULL;
|
|
|
|
@ -3083,15 +3064,15 @@ static void db_model_finalize (DbModel * obj)
|
|
|
|
|
|
|
|
|
|
g_clear_object (&priv->link_op);
|
|
|
|
|
g_clear_object (&priv->internal_batch);
|
|
|
|
|
g_hash_table_destroy (priv->column_defaults);
|
|
|
|
|
|
|
|
|
|
if (priv->updatable_data_allocated)
|
|
|
|
|
{
|
|
|
|
|
g_free (priv->user_main_table);
|
|
|
|
|
g_hash_table_destroy (priv->column_defaults);
|
|
|
|
|
g_queue_free (priv->operation);
|
|
|
|
|
g_hash_table_destroy (priv->row_ops);
|
|
|
|
|
g_slist_free_full (priv->join, (GDestroyNotify) db_join_free);
|
|
|
|
|
db_model_free_stmt_data (obj);
|
|
|
|
|
g_hash_table_destroy (priv->tables);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parent->finalize (G_OBJECT (obj));
|
|
|
|
|