diff --git a/db/db-model-private.c b/db/db-model-private.c
index 5595d18..b9bd08a 100644
--- a/db/db-model-private.c
+++ b/db/db-model-private.c
@@ -17,6 +17,8 @@
* along with this program. If not, see .
*/
+#define remove_delimiters(str) (g_strdup (g_strstrip (g_strdelimit (str, "`\"", ' '))))
+
/*
* DbUpdatedField:
* @column: the position of the field in the row
@@ -80,6 +82,41 @@ typedef struct
}
DbModelRequest;
+//----------------------------------------------- Table
+
+typedef struct
+{
+ gchar * name;
+ gchar * schema;
+}
+Table;
+
+static Table * table_copy (Table * src)
+{
+ Table * table = g_new0 (Table, 1);
+ table->name = g_strdup (src->name);
+ table->schema = g_strdup (src->schema);
+ return table;
+}
+
+static void table_free (Table * table)
+{
+ g_free (table->name);
+ g_free (table->schema);
+ g_free (table);
+}
+
+static gboolean table_equal (const Table * a, const Table * b)
+{
+ return !g_strcmp0 (a->name, b->name)
+ && !g_strcmp0 (a->schema, b->schema);
+}
+
+static guint table_hash (const Table * table)
+{
+ return g_str_hash (table->name);
+}
+
//----------------------------------------------- Field
typedef struct
@@ -90,8 +127,6 @@ typedef struct
}
Field;
-#define remove_delimiters(str) (g_strdup (g_strstrip (g_strdelimit (str, "`\"", ' '))))
-
static void field_parse (Field * field, const gchar * string)
{
gchar ** split = g_strsplit (string, ".", 0);
@@ -136,133 +171,61 @@ static guint field_hash (const Field * field)
return g_str_hash (field->name);
}
-//----------------------------------------------- Table
+//----------------------------------------------- TableInfo
typedef struct
{
gchar * name;
gchar * schema;
-}
-Table;
-
-static void table_parse (Table * table, const gchar * string)
-{
- gchar ** split = g_strsplit (string, ".", 0);
- guint len = g_strv_length (split);
-
- table->name = len > 0 ? remove_delimiters (split[--len]) : NULL;
- table->schema = len > 0 ? remove_delimiters (split[--len]) : NULL;
-
- g_strfreev (split);
-}
-
-static Table * table_copy (Table * src)
-{
- Table * table = g_new0 (Table, 1);
- table->name = g_strdup (src->name);
- table->schema = g_strdup (src->schema);
- return table;
-}
-
-static void table_free (Table * table)
-{
- g_free (table->name);
- g_free (table->schema);
- g_free (table);
-}
-
-static gboolean table_equal (const Table * a, const Table * b)
-{
- return !g_strcmp0 (a->name, b->name)
- && !g_strcmp0 (a->schema, b->schema);
-}
-
-static guint table_hash (const Table * table)
-{
- return g_str_hash (table->name);
-}
-
-static gboolean table_has_column (Table * table, DbColumn * column)
-{
- return !g_strcmp0 (column->table, table->name)
- && !g_strcmp0 (column->schema, table->schema);
-}
-
-//----------------------------------------------- TableData
-
-typedef struct
-{
+ gchar * alias;
GSList * pkeys;
+ GHashTable * columns;
+ GSList * parent_columns;
+ GSList * child_columns;
}
-TableData;
+TableInfo;
-static void table_data_free (TableData * table_data)
+static void table_info_free (TableInfo * table_info)
{
- g_slist_free (table_data->pkeys);
- g_free (table_data);
-}
-
-//----------------------------------------------- ParamDef
-
-typedef struct
-{
- GvnParam * param;
- SqlObject * equal_op;
- SqlObject * link_op;
-}
-ParamDef;
-
-static void param_def_free (ParamDef * def)
-{
- g_object_unref (def->param);
-
- if (def->equal_op)
- {
- SqlObject * operators = sql_object_get (def->link_op, "operators");
- sql_list_remove_item (SQL_LIST (operators), def->equal_op);
- }
-
- g_free (def);
+ g_free (table_info->name);
+ g_free (table_info->schema);
+ g_free (table_info->alias);
+ g_slist_free (table_info->pkeys);
+ g_hash_table_unref (table_info->columns);
+ g_slist_free (table_info->parent_columns);
+ g_slist_free (table_info->child_columns);
}
//----------------------------------------------- ColumnDef
-typedef enum
-{
- PARAM_DEF,
- FIELD_DEF
-}
-DefType;
-
typedef struct
{
- Field * field;
- gpointer def;
- DefType type;
+ gulong link;
+ GvnParam * param;
+ Field * src_column;
}
ColumnDef;
-static ColumnDef * column_def_new (DefType type, gpointer def)
+static ColumnDef * column_def_new ()
{
ColumnDef * column_def = g_new (ColumnDef, 1);
- column_def->type = type;
- column_def->def = def;
+ column_def->link = 0;
+ column_def->param = NULL;
+ column_def->src_column = NULL;
return column_def;
}
static void column_def_free (ColumnDef * def)
{
- field_free (def->field);
-
- switch (def->type)
+ if (def->param)
{
- case PARAM_DEF:
- param_def_free (def->def);
- break;
- case FIELD_DEF:
- field_free (def->def);
- break;
+ if (def->link)
+ g_signal_handler_disconnect (def->param, def->link);
+
+ g_object_unref (def->param);
}
+ if (def->src_column)
+ field_free (def->src_column);
g_free (def);
}
diff --git a/db/db-model.c b/db/db-model.c
index 421e3fb..c2fdb3c 100644
--- a/db/db-model.c
+++ b/db/db-model.c
@@ -59,9 +59,10 @@ struct _DbModelPrivate
guint result_pos;
DbRequest * request;
DbModelStatus status;
- DbModelMode mode;
gint stamp;
+ GHashTable * defaults;
+
gboolean fresh;
gint sort_column_id;
gint old_sort_column_id;
@@ -73,22 +74,20 @@ 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;
+ DbModelUpdateFlags update_flags;
+ TableInfo * main_table;
+ DbModelMode mode;
GHashTable * tables;
gint updated_col;
GQueue * operation;
GHashTable * row_ops;
GValue * updated_value;
GSList * pending_request;
+ TableInfo ** column_table;
+ gboolean partial_delete;
GSList * join;
};
@@ -187,28 +186,6 @@ static void db_model_free_operation (DbModel * obj
static void db_model_manage_join (DbModel * obj
,DbIter * iter
,gint col);
-static void db_model_post_process_query (DbModel * obj);
-
-// Memory allocate functions
-
-static void db_model_alloc_link_data (DbModel * obj)
-{
- SqlList * operators;
- DbModelPrivate * priv = obj->priv;
-
- if (priv->link_op)
- return;
-
- priv->internal_batch = g_object_ref_sink (sql_batch_new ());
- g_signal_connect (priv->internal_batch, "changed",
- G_CALLBACK (db_model_on_batch_changed), obj);
-
- priv->link_op = sql_operation_new (SQL_OPERATION_TYPE_AND);
- sql_batch_add (priv->internal_batch, "link", priv->link_op);
-
- operators = sql_list_new (SQL_TYPE_EXPR);
- sql_operation_set_operands (SQL_OPERATION (priv->link_op), operators);
-}
// Signal Handlers
@@ -265,9 +242,9 @@ static void db_model_calculate_update_flags (DbModel * obj)
{
gint i;
Table table;
- TableData * table_data;
+ TableInfo * tinfo;
DbModelPrivate * priv = obj->priv;
-
+
// Allocates aditional memory when the model is updatable
if (priv->user_update_flags && !priv->updatable_data_allocated)
@@ -276,78 +253,79 @@ static void db_model_calculate_update_flags (DbModel * obj)
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
+ (GHashFunc) table_hash
+ ,(GEqualFunc) table_equal
+ ,(GDestroyNotify) table_free
+ ,(GDestroyNotify) table_info_free
);
}
-
+
if (priv->user_update_flags && priv->fresh && priv->result)
{
+ GArray * cols;
+
+ g_free (priv->column_table);
g_hash_table_remove_all (priv->tables);
+ priv->column_table = g_new (TableInfo *, priv->result->ncols);
+
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)
+ DbColumn col = priv->column[i];
+
+ if (!col.table)
{
- table_data = g_new0 (TableData, 1);
- table_data->pkeys = NULL;
- g_hash_table_insert (priv->tables, table_copy (&table), table_data);
+ priv->column_table[i] = NULL;
+ continue;
+ }
+
+ table.name = col.table_alias;
+ table.schema = col.schema;
+ tinfo = g_hash_table_lookup (priv->tables, &table);
+
+ if (!tinfo)
+ {
+ tinfo = g_new (TableInfo, 1);
+ tinfo->name = g_strdup (col.table);
+ tinfo->schema = g_strdup (col.schema);
+ tinfo->alias = g_strdup (col.table_alias);
+ tinfo->columns = g_hash_table_new_full (
+ g_str_hash
+ ,g_str_equal
+ ,NULL
+ ,(GDestroyNotify) g_array_free
+ );
+ tinfo->pkeys = NULL;
+ tinfo->parent_columns = NULL;
+ tinfo->child_columns = NULL;
+ g_hash_table_insert (priv->tables, table_copy (&table), tinfo);
}
- 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;
+ priv->column_table[i] = tinfo;
- 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);
+ if (col.info & DB_COLUMN_PRI_KEY)
+ tinfo->pkeys = g_slist_prepend (tinfo->pkeys, GINT_TO_POINTER (i));
+
+ cols = g_hash_table_lookup (tinfo->columns, col.name);
+
+ if (!cols)
+ {
+ cols = g_array_sized_new (TRUE, FALSE, sizeof (gint), 1);
+ g_hash_table_insert (tinfo->columns, g_strdup (col.name), cols);
+ }
+
+ g_array_append_val (cols, i);
}
}
// Searchs for the main table
- table.name = NULL;
-
if (priv->result)
+ for (i = 0; i < priv->result->ncols; i++)
+ if (priv->column[i].info & DB_COLUMN_PRI_KEY)
{
- if (!priv->user_main_table)
- {
- 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;
- break;
- }
- }
- else
- table_parse (&table, priv->user_main_table);
- }
-
- 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);
+ priv->main_table = priv->column_table[i];
+ break;
}
// Sets the updatable flags
@@ -356,6 +334,18 @@ static void db_model_calculate_update_flags (DbModel * obj)
priv->update_flags = DB_MODEL_ALL & priv->user_update_flags;
else
priv->update_flags = 0;
+
+ // Sets the params editable
+
+ if (priv->result)
+ for (i = 0; i < priv->result->ncols; i++)
+ {
+ gboolean editable = priv->column_table[i]
+ && priv->column_table[i]->pkeys
+ && priv->update_flags & DB_MODEL_UPDATE;
+
+ gvn_param_spec_set_editable (priv->column[i].spec, editable);
+ }
}
static void db_model_on_data_ready (DbRequest * request, DbModel * obj)
@@ -392,8 +382,6 @@ static void db_model_on_data_ready (DbRequest * request, DbModel * 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));
-
- db_model_post_process_query (obj);
}
else
db_model_set_sort_column_id (obj,
@@ -418,37 +406,44 @@ static void db_model_process_insert (DbModel * obj, DbRequest * request, DbRow *
DbResult * result;
DbRow * req_row;
DbIter iter;
+ Table table;
+ TableInfo * tinfo;
result = db_request_fetch_result (request, &err);
- if (result && result->data && result->nrows > 0 )
- {
- iter.stamp = priv->stamp;
- iter.data = row;
- req_row = g_ptr_array_index (result->data, 0);
+ if (!(result && result->data && result->nrows > 0))
+ goto exit;
- 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].schema, result->column[i].schema))
+ iter.data = row;
+ iter.stamp = priv->stamp;
+ req_row = g_ptr_array_index (result->data, 0);
+
+ table.name = result->column[0].table_alias;
+ table.schema = result->column[0].schema;
+
+ if ((tinfo = g_hash_table_lookup (priv->tables, &table)))
+ for (i = 0; i < result->ncols; i++)
+ {
+ GArray * cols = g_hash_table_lookup (tinfo->columns, result->column[i].name);
+
+ for (j = 0; j < cols->len; j++)
{
GValue * new_value = &req_row->value[i];
- 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);
- }
+ if (gvn_value_compare (new_value, DB_ROW_FIELD (row, i)))
+ continue;
+
+ 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 = g_array_index (cols, gint, j);
+ g_signal_emit (obj, db_model_signal[LINE_UPDATED], 0, &iter);
}
}
- if (result)
- db_result_free (result);
+ exit:
+ db_result_free (result);
}
static void db_model_on_operations_done (DbRequest * request, DbModelRequest * data)
@@ -460,15 +455,15 @@ static void db_model_on_operations_done (DbRequest * request, DbModelRequest * d
GError * err = NULL;
DbModel * obj = data->obj;
DbModelPrivate * priv = obj->priv;
-
- l = g_queue_peek_head_link (data->operations);
- for (; l; l = l->next)
+ for (l = data->operations->head; l; l = l->next)
{
op = l->data;
+ iter.stamp = priv->stamp;
+ iter.data = op->row;
- if (op->type & DB_MODEL_ROW_OP_DELETE
- && op->type & DB_MODEL_ROW_OP_INSERT) // DELETE + INSERT
+ if (op->type & DB_MODEL_ROW_OP_INSERT
+ && op->type & DB_MODEL_ROW_OP_DELETE) // INSERT + DELETE
{
g_signal_emit (obj,
db_model_signal[LINE_DELETED], 0, DB_ROW_POSITION (op->row));
@@ -482,8 +477,20 @@ static void db_model_on_operations_done (DbRequest * request, DbModelRequest * d
if (op->type & DB_MODEL_ROW_OP_DELETE) // DELETE
{
- g_signal_emit (obj,
- db_model_signal[LINE_DELETED], 0, DB_ROW_POSITION (op->row));
+ if (priv->partial_delete)
+ {
+ for (i = 0; i < priv->result->ncols; i++)
+ if (priv->column_table[i] == priv->main_table)
+ {
+ priv->updated_col = i;
+ priv->updated_value =
+ g_value_init (g_new0 (GValue, 1), GVN_TYPE_NULL);
+ g_signal_emit (obj, db_model_signal[LINE_UPDATED], 0, &iter);
+ }
+ }
+ else
+ g_signal_emit (obj,
+ db_model_signal[LINE_DELETED], 0, DB_ROW_POSITION (op->row));
}
else if (op->type & DB_MODEL_ROW_OP_INSERT) // INSERT + SELECT
{
@@ -506,8 +513,6 @@ static void db_model_on_operations_done (DbRequest * request, DbModelRequest * d
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);
}
@@ -554,25 +559,26 @@ static void db_model_on_join_query_done (DbRequest * request, JoinData * join_da
{
for (i = 0; i < priv->result->ncols; i++)
for (j = 0; j < r->ncols; j++)
- if (!g_strcmp0 (r->column[j].table, priv->column[i].table)
- && !g_strcmp0 (r->column[j].name, priv->column[i].name))
+ if (!g_strcmp0 (r->column[j].name, priv->column[i].name)
+ && !g_strcmp0 (r->column[j].table, priv->column[i].table)
+ && !g_strcmp0 (r->column[j].schema, priv->column[i].schema))
+ {
+ if (r->nrows > 0)
{
- if (r->nrows > 0)
- {
- GValue * new_value =
- DB_ROW_FIELD (g_ptr_array_index (r->data, 0), j);
+ GValue * new_value =
+ DB_ROW_FIELD (g_ptr_array_index (r->data, 0), j);
- priv->updated_value = g_new0 (GValue, 1);
- g_value_init (priv->updated_value, G_VALUE_TYPE (new_value));
- gvn_value_copy (new_value, priv->updated_value);
- }
- else
- priv->updated_value =
- g_value_init (g_new0 (GValue, 1), GVN_TYPE_NULL);
-
- priv->updated_col = i;
- g_signal_emit (obj, db_model_signal[LINE_UPDATED], 0, iter);
+ priv->updated_value = g_new0 (GValue, 1);
+ g_value_init (priv->updated_value, G_VALUE_TYPE (new_value));
+ gvn_value_copy (new_value, priv->updated_value);
}
+ else
+ priv->updated_value =
+ g_value_init (g_new0 (GValue, 1), GVN_TYPE_NULL);
+
+ priv->updated_col = i;
+ g_signal_emit (obj, db_model_signal[LINE_UPDATED], 0, iter);
+ }
db_result_free (r);
}
@@ -738,293 +744,7 @@ void db_model_reverse_operations (DbModel * obj)
}
}
-static DbModelField * db_model_field_new (const gchar * table, const gchar * schema)
-{
- DbModelField * field = g_new (DbModelField, 1);
- field->schema = g_strdup (schema);
- field->table = g_strdup (table);
- field->name = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
- field->main = FALSE;
- return field;
-}
-
-static DbModelField * db_model_field_new_from_string (const gchar * str)
-{
- DbModelField * field = NULL;
- gchar * new_str = g_strdup (str), ** aux, ** f;
- gint i, f_len;
- g_strstrip (new_str);
- f = g_strsplit (new_str, ".", G_MAXINT);
- g_free (new_str);
- f_len = g_strv_length (f);
-
- for (i = 0; i < f_len; i++)
- {
- aux = g_strsplit (f[i], "\"", G_MAXINT);
-
- if (g_strcmp0 (aux[0], ""))
- {
- g_strfreev (aux);
- break;
- }
-
- g_free (f[i]);
- f[i] = g_strdup (aux[1]);
- g_strfreev (aux);
- }
-
- switch (f_len)
- {
- case 3:
- {
- field = db_model_field_new (f[1], f[0]);
- g_ptr_array_add (field->name, g_strdup (f[2]));
- break;
- }
- case 2:
- {
- field = db_model_field_new (f[0], NULL);
- g_ptr_array_add (field->name, g_strdup (f[1]));
- break;
- }
- case 1:
- {
- field = db_model_field_new (NULL, NULL);
- g_ptr_array_add (field->name, g_strdup (f[0]));
- }
- }
-
- g_strfreev (f);
-
- return field;
-}
-
-static void db_model_field_free (DbModelField * field)
-{
- if (field)
- {
- if (field->schema)
- g_free (field->schema);
- if (field->table)
- g_free (field->table);
- if (field->name)
- g_ptr_array_free (field->name, TRUE);
- }
-
- g_free (field);
-}
-
-static void db_join_free (DbJoin * join)
-{
- if (join)
- {
- if (join->left)
- db_model_field_free (join->left);
- if (join->right)
- db_model_field_free (join->right);
- }
-
- g_free (join);
-}
-/*
-static void db_model_calculate_col_def (DbModel * obj, SqlJoin * join,
- SqlField * l_field, SqlField * r_field)
-{
- gint i, col = -1;
- gchar * dst = NULL;
- DbModelPrivate * priv = obj->priv;
- SqlField * f = NULL;
- SqlTarget * l_table = join->target_left, * r_table = join->target_right;
-
- for (i = 0; i < priv->result->ncols; i++)
- {
- f = NULL;
-
- if (!g_strcmp0 (priv->column[i].name, l_field->name))
- {
- f = l_field;
- dst = (join->type == SQL_JOIN_TYPE_RIGHT) ?
- l_field->name : r_field->name;
- }
- else if (!g_strcmp0 (priv->column[i].name, r_field->name))
- {
- f = r_field;
- dst = (join->type == SQL_JOIN_TYPE_LEFT) ?
- l_field->name : r_field->name;
- }
-
- if (f)
- {//TODO add schema checks
- if (f->target)
- {
- if (!g_strcmp0 (priv->column[i].table, f->target)
- || (!g_strcmp0 (priv->column[i].table, SQL_TABLE (l_table)->name)
- && !g_strcmp0 (f->target, l_table->alias)))
- {
- col = i;
- break;
- }
- else if (!g_strcmp0 (priv->column[i].table, SQL_TABLE (r_table)->name)
- && !g_strcmp0 (f->target, r_table->alias))
- {
- col = i;
- break;
- }
- }
- else
- {
- col = i;
- break;
- }
- }
- }
-
- if (f)
- db_model_set_default_value_from_column (obj, dst, col);
-}
-
-static void db_model_set_join_fields (DbModel * obj, SqlJoin * join,
- SqlField * lsql_field, SqlField * rsql_field,
- DbModelField * lfield, DbModelField * rfield)
-{
- gboolean check;
- SqlTarget * ltarget = join->target_left, * rtarget = join->target_right;
-
- check = !g_strcmp0 (lfield->schema, lsql_field->schema)
- || !g_strcmp0 (lfield->table, lsql_field->target)
- || !g_strcmp0 (ltarget->alias, lsql_field->target)
- || !g_strcmp0 (rfield->schema, rfield->schema)
- || !g_strcmp0 (rfield->table, rsql_field->target)
- || !g_strcmp0 (rtarget->alias, rsql_field->target);
-
- g_ptr_array_add (lfield->name,
- g_strdup (check ? lsql_field->name : rsql_field->name));
- g_ptr_array_add (rfield->name,
- g_strdup (check ? rsql_field->name : lsql_field->name));
-}
-*/
-static void db_model_post_process_query (DbModel * obj)
-{
-/*
-// TODO When parser gets fully functional, these 3 lines won't be needed,
-// because obj->stmt will be a parsed stmt:
- gchar * rend = db_conn_render (obj->priv->conn, obj->priv->stmt, obj->priv->batch, NULL);
- SqlObject * stmt = sql_parser_parse (rend);
-
- g_free (rend);
-
- if (stmt && SQL_IS_SELECT (stmt))
- {
- DbModelField * lfield, * rfield;
- SqlJoin * join;
- GList * n;
- SqlSelect * select = SQL_SELECT (stmt);
- gboolean calculate_join = FALSE;
-
- for (n = sql_list_get_items (SQL_DML (select)->targets); n; n = n->next)
- if ((join = n->data)
- && SQL_IS_JOIN (join)
- && SQL_IS_TABLE (join->target_left)
- && SQL_IS_TABLE (join->target_right)
- && SQL_IS_OPERATION (join->condition))
- {
-// DbJoin and ColDef creation
- GList * operators;
- SqlOperation * op = SQL_OPERATION (join->condition);
- SqlField * lsql_field = NULL, * rsql_field = NULL;
-
- lfield = db_model_field_new (SQL_TABLE (join->target_left)->name, NULL);
- rfield = db_model_field_new (SQL_TABLE (join->target_right)->name, NULL);
-
- if (join->type == SQL_JOIN_TYPE_RIGHT)
- rfield->main = TRUE;
- else
- lfield->main = TRUE;
-
- if (op->type == SQL_OPERATION_TYPE_AND)
- {
- GList * l;
-
- for (l = sql_list_get_items (op->operators); l; l = l->next)
- {
- SqlOperation * subop = l->data;
- operators = sql_list_get_items (subop->operators);
-
- if (SQL_IS_OPERATION (subop)
- && subop->type == SQL_OPERATION_TYPE_EQUAL
- && operators->data // Left Field
- && operators->next && operators->next->data) // Right Field
- {
- lsql_field = SQL_FIELD (operators->data);
- rsql_field = SQL_FIELD (operators->next->data);
-
- db_model_set_join_fields (obj, join,
- lsql_field, rsql_field, lfield, rfield);
-
- calculate_join = TRUE;
-
- if (join->type != SQL_JOIN_TYPE_INNER)
- db_model_calculate_col_def
- (obj, join, lsql_field, rsql_field);
- }
- else
- {
- calculate_join = FALSE;
- break;
- }
- }
- }
- else
- {
- operators = sql_list_get_items (op->operators);
-
- if (op->type == SQL_OPERATION_TYPE_EQUAL && operators->data
- && operators->next && operators->next->data)
- {
- lsql_field = SQL_FIELD (operators->data);
- rsql_field = SQL_FIELD (operators->next->data);
-
- db_model_set_join_fields (obj, join,
- lsql_field, rsql_field, lfield, rfield);
-
- calculate_join = TRUE;
-
- if (join->type != SQL_JOIN_TYPE_INNER)
- db_model_calculate_col_def
- (obj, join ,lsql_field, rsql_field);
- }
- }
-
- if (calculate_join)
- {
- DbJoin * join_res = g_new (DbJoin, 1);
- join_res->left = lfield;
- join_res->right = rfield;
-
- obj->priv->join = g_slist_prepend (obj->priv->join, join_res);
- }
- else
- {
- db_model_field_free (lfield);
- db_model_field_free (rfield);
- }
- }
- }
-
- if (G_IS_OBJECT (stmt))
- g_object_unref (stmt);
-*/
-}
-
-static inline gboolean stored (const gint * v, const gint length, const gint target)
-{
- gint i;
-
- for (i = 0; i < length; i++)
- if (v[i] == target)
- return TRUE;
- return FALSE;
-}
+// Utility functions
/*
* Comparison between values, using case-insensitive and UTF-8 strings
@@ -1133,6 +853,37 @@ static void db_model_add_pending_request (DbModel * obj, DbRequest * request)
request);
}
+static void db_model_clear (DbModel * obj)
+{
+ DbModelPrivate * priv = obj->priv;
+
+ if (priv->request)
+ {
+ db_request_cancel (priv->request);
+ priv->request = NULL;
+ }
+ else if (priv->result)
+ {
+ db_model_clean_operations (obj);
+ db_model_cancel_pending_requests (obj);
+
+ db_result_free (priv->result);
+ priv->result = NULL;
+ priv->column = NULL;
+ priv->data = NULL;
+
+ 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;
+ }
+}
+
+// Join related functions
+
static void db_model_manage_join (DbModel * obj, DbIter * iter, gint col)
{
DbModelPrivate * priv = obj->priv;
@@ -1146,18 +897,18 @@ static void db_model_manage_join (DbModel * obj, DbIter * iter, gint col)
gboolean send_request = FALSE, end = FALSE;
SqlList * stmts = g_object_ref_sink (sql_list_new (SQL_TYPE_MULTI_STMT));
-/*FIXME
- for (i = 0; i < obj->ncols; i++)
- // Check for multi-field pkeys to be fully set
- // need to know the total number of pkey fields
- if (i != col && obj->column[i].info & DB_COLUMN_PRI_KEY
- && gvn_value_is_null (DB_ROW_FIELD (iter->data, i))
- && !g_strcmp0 (obj->column[i].table, obj->column[col].table))
- {
- end = TRUE;
- break;
- }
-*/
+// FIXME
+// for (i = 0; i < obj->ncols; i++)
+// // Check for multi-field pkeys to be fully set
+// // need to know the total number of pkey fields
+// if (i != col && obj->column[i].info & DB_COLUMN_PRI_KEY
+// && gvn_value_is_null (DB_ROW_FIELD (iter->data, i))
+// && !g_strcmp0 (obj->column[i].table, obj->column[col].table))
+// {
+// end = TRUE;
+// break;
+// }
+
if (!end)
for (n = priv->join; n; n = n->next)
{
@@ -1247,39 +998,345 @@ static void db_model_manage_join (DbModel * obj, DbIter * iter, gint col)
g_object_unref (stmts);
}
}
-
-static void db_model_clear (DbModel * obj)
+/*
+static DbModelField * db_model_field_new (const gchar * table, const gchar * schema)
{
- DbModelPrivate * priv = obj->priv;
-
- if (priv->request)
- {
- db_request_cancel (priv->request);
- priv->request = NULL;
- }
- else if (priv->result)
- {
- db_model_clean_operations (obj);
- db_model_cancel_pending_requests (obj);
-
- db_result_free (priv->result);
- priv->result = NULL;
- priv->column = NULL;
- priv->data = NULL;
-
- 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;
- }
+ DbModelField * field = g_new (DbModelField, 1);
+ field->schema = g_strdup (schema);
+ field->table = g_strdup (table);
+ field->name = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
+ field->main = FALSE;
+ return field;
}
+static void db_model_field_free (DbModelField * field)
+{
+ if (field)
+ {
+ if (field->schema)
+ g_free (field->schema);
+ if (field->table)
+ g_free (field->table);
+ if (field->name)
+ g_ptr_array_free (field->name, TRUE);
+ }
+
+ g_free (field);
+}
+
+static void db_join_free (DbJoin * join)
+{
+ if (join)
+ {
+ if (join->left)
+ db_model_field_free (join->left);
+ if (join->right)
+ db_model_field_free (join->right);
+ }
+
+ g_free (join);
+}
+
+static void db_model_calculate_col_def (DbModel * obj, SqlJoin * join,
+ SqlField * l_field, SqlField * r_field)
+{
+ gint i, col = -1;
+ gchar * dst = NULL;
+ DbModelPrivate * priv = obj->priv;
+ SqlField * f = NULL;
+ SqlTarget * l_table = join->target_left, * r_table = join->target_right;
+
+ for (i = 0; i < priv->result->ncols; i++)
+ {
+ f = NULL;
+
+ if (!g_strcmp0 (priv->column[i].name, l_field->name))
+ {
+ f = l_field;
+ dst = (join->type == SQL_JOIN_TYPE_RIGHT) ?
+ l_field->name : r_field->name;
+ }
+ else if (!g_strcmp0 (priv->column[i].name, r_field->name))
+ {
+ f = r_field;
+ dst = (join->type == SQL_JOIN_TYPE_LEFT) ?
+ l_field->name : r_field->name;
+ }
+
+ if (f)
+ {//TODO add schema checks
+ if (f->target)
+ {
+ if (!g_strcmp0 (priv->column[i].table, f->target)
+ || (!g_strcmp0 (priv->column[i].table, SQL_TABLE (l_table)->name)
+ && !g_strcmp0 (f->target, l_table->alias)))
+ {
+ col = i;
+ break;
+ }
+ else if (!g_strcmp0 (priv->column[i].table, SQL_TABLE (r_table)->name)
+ && !g_strcmp0 (f->target, r_table->alias))
+ {
+ col = i;
+ break;
+ }
+ }
+ else
+ {
+ col = i;
+ break;
+ }
+ }
+ }
+
+ if (f)
+ db_model_set_default_value_from_column (obj, dst, col);
+}
+
+static void db_model_set_join_fields (DbModel * obj, SqlJoin * join,
+ SqlField * lsql_field, SqlField * rsql_field,
+ DbModelField * lfield, DbModelField * rfield)
+{
+ gboolean check;
+ SqlTarget * ltarget = join->target_left, * rtarget = join->target_right;
+
+ check = !g_strcmp0 (lfield->schema, lsql_field->schema)
+ || !g_strcmp0 (lfield->table, lsql_field->target)
+ || !g_strcmp0 (ltarget->alias, lsql_field->target)
+ || !g_strcmp0 (rfield->schema, rfield->schema)
+ || !g_strcmp0 (rfield->table, rsql_field->target)
+ || !g_strcmp0 (rtarget->alias, rsql_field->target);
+
+ g_ptr_array_add (lfield->name,
+ g_strdup (check ? lsql_field->name : rsql_field->name));
+ g_ptr_array_add (rfield->name,
+ g_strdup (check ? rsql_field->name : lsql_field->name));
+}
+
+static void db_model_post_process_query (DbModel * obj)
+{
+// TODO When parser gets fully functional, these 3 lines won't be needed,
+// because obj->stmt will be a parsed stmt:
+ gchar * rend = db_conn_render (obj->priv->conn, obj->priv->stmt, obj->priv->batch, NULL);
+ SqlObject * stmt = sql_parser_parse (rend);
+
+ g_free (rend);
+
+ if (stmt && SQL_IS_SELECT (stmt))
+ {
+ DbModelField * lfield, * rfield;
+ SqlJoin * join;
+ GList * n;
+ SqlSelect * select = SQL_SELECT (stmt);
+ gboolean calculate_join = FALSE;
+
+ for (n = sql_list_get_items (SQL_DML (select)->targets); n; n = n->next)
+ if ((join = n->data)
+ && SQL_IS_JOIN (join)
+ && SQL_IS_TABLE (join->target_left)
+ && SQL_IS_TABLE (join->target_right)
+ && SQL_IS_OPERATION (join->condition))
+ {
+// DbJoin and ColDef creation
+ GList * operators;
+ SqlOperation * op = SQL_OPERATION (join->condition);
+ SqlField * lsql_field = NULL, * rsql_field = NULL;
+
+ lfield = db_model_field_new (SQL_TABLE (join->target_left)->name, NULL);
+ rfield = db_model_field_new (SQL_TABLE (join->target_right)->name, NULL);
+
+ if (join->type == SQL_JOIN_TYPE_RIGHT)
+ rfield->main = TRUE;
+ else
+ lfield->main = TRUE;
+
+ if (op->type == SQL_OPERATION_TYPE_AND)
+ {
+ GList * l;
+
+ for (l = sql_list_get_items (op->operators); l; l = l->next)
+ {
+ SqlOperation * subop = l->data;
+ operators = sql_list_get_items (subop->operators);
+
+ if (SQL_IS_OPERATION (subop)
+ && subop->type == SQL_OPERATION_TYPE_EQUAL
+ && operators->data // Left Field
+ && operators->next && operators->next->data) // Right Field
+ {
+ lsql_field = SQL_FIELD (operators->data);
+ rsql_field = SQL_FIELD (operators->next->data);
+
+ db_model_set_join_fields (obj, join,
+ lsql_field, rsql_field, lfield, rfield);
+
+ calculate_join = TRUE;
+
+ if (join->type != SQL_JOIN_TYPE_INNER)
+ db_model_calculate_col_def
+ (obj, join, lsql_field, rsql_field);
+ }
+ else
+ {
+ calculate_join = FALSE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ operators = sql_list_get_items (op->operators);
+
+ if (op->type == SQL_OPERATION_TYPE_EQUAL && operators->data
+ && operators->next && operators->next->data)
+ {
+ lsql_field = SQL_FIELD (operators->data);
+ rsql_field = SQL_FIELD (operators->next->data);
+
+ db_model_set_join_fields (obj, join,
+ lsql_field, rsql_field, lfield, rfield);
+
+ calculate_join = TRUE;
+
+ if (join->type != SQL_JOIN_TYPE_INNER)
+ db_model_calculate_col_def
+ (obj, join ,lsql_field, rsql_field);
+ }
+ }
+
+ if (calculate_join)
+ {
+ DbJoin * join_res = g_new (DbJoin, 1);
+ join_res->left = lfield;
+ join_res->right = rfield;
+
+ obj->priv->join = g_slist_prepend (obj->priv->join, join_res);
+ }
+ else
+ {
+ db_model_field_free (lfield);
+ db_model_field_free (rfield);
+ }
+ }
+ }
+
+ if (G_IS_OBJECT (stmt))
+ g_object_unref (stmt);
+
+}
+
+static gboolean db_model_analyse_join_op (DbModel * obj, SqlOperation * op)
+{
+ gint i;
+ gint noperands;
+ SqlList * operands;
+ SqlOperationType operator = sql_operation_get_operator (op);
+
+ noperands = sql_list_length (operands);
+ g_object_get (op, "operands", &operands, NULL);
+
+ if (operator == SQL_OPERATION_TYPE_EQUAL && noperands == 2)
+ {
+ gpointer field1 = sql_list_get (operands, 0);
+ gpointer field2 = sql_list_get (operands, 1);
+
+ if (!SQL_IS_FIELD (field1) || !SQL_IS_FIELD (field2)
+ || (g_strcmp0 (sql_field_get_target (field1), sql_field_get_target (field2))
+ && g_strcmp0 (sql_field_get_schema (field1), sql_field_get_schema (field2))))
+ return FALSE;
+
+
+ }
+ else if (operator == SQL_OPERATION_TYPE_AND)
+ {
+ for (i = 0; i < noperands; i++)
+ if (!db_model_analyse_join_op (obj, sql_list_get (operands, i)))
+ return FALSE;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void db_model_analyse_join (DbModel * obj, SqlTarget * target)
+{
+ SqlJoin * join;
+ SqlTarget * left;
+ SqlTarget * right;
+ SqlOperation * on;
+
+ if (!SQL_IS_JOIN (target))
+ return;
+
+ join = SQL_JOIN (target);
+ g_object_get (join
+ ,"target-left", &left
+ ,"target-right", &right
+ ,"condition", &on
+ ,NULL
+ );
+
+ if (SQL_IS_TABLE (left) || SQL_IS_TABLE (right))
+ db_model_analyse_join_op (obj, on);
+
+ switch ((gint) sql_join_get_join_type (join))
+ {
+ case SQL_JOIN_TYPE_INNER:
+ break;
+ case SQL_JOIN_TYPE_LEFT:
+ break;
+ case SQL_JOIN_TYPE_RIGHT:
+ break;
+ }
+
+ db_model_analyse_join (obj, left);
+ db_model_analyse_join (obj, right);
+}
+
+static void db_model_load_join (DbModel * obj)
+{
+ gchar * sql;
+ SqlObject * stmt;
+ SqlObject * select;
+ DbModelPrivate * priv = obj->priv;
+
+ sql = db_conn_render (obj->priv->conn, obj->priv->stmt, NULL, NULL);
+ stmt = sql_parser_parse (sql);
+ g_free (sql);
+
+ if (!stmt)
+ return;
+
+ g_object_ref_sink (stmt);
+
+ if (SQL_IS_MULTI_STMT (stmt))
+ {
+ SqlList * stmts;
+ g_object_get (stmt, "stmts", &stmts, NULL);
+ select = sql_list_get (stmts, priv->result_pos);
+ }
+ else
+ select = stmt;
+
+ if (!SQL_IS_SELECT (select))
+ goto exit;
+
+ gint i;
+ SqlList * targets;
+
+ g_object_get (select, "targets", &targets, NULL);
+
+ for (i = 0; i < sql_list_length (targets); i++)
+ db_model_analyse_join (obj, sql_list_get (targets, i));
+
+ exit:
+ g_object_unref (stmt);
+}
+*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
-// Set&Get methods
+// Setters & getters
/**
* db_model_set_conn:
@@ -1542,8 +1599,8 @@ void db_model_add_join_columns (DbModel * obj, const gchar * left, const gchar *
g_return_if_fail (DB_IS_MODEL (obj));
DbJoin * join = g_new (DbJoin, 1);
- join->left = db_model_field_new_from_string (left);
- join->right = db_model_field_new_from_string (right);
+// join->left = db_model_field_new_from_string (left);
+// join->right = db_model_field_new_from_string (right);
obj->priv->join = g_slist_prepend (obj->priv->join, join);
}
@@ -1592,6 +1649,30 @@ void db_model_set_batch (DbModel * obj, SqlBatch * batch)
priv->batch = batch;
}
+static ColumnDef * db_model_create_column_def (DbModel * obj, const gchar * field_str)
+{
+ Field * field = field_new_from_string (field_str);
+
+ if (field->name && field->target && !field->schema)
+ {
+ ColumnDef * def = column_def_new ();
+ g_hash_table_insert (obj->priv->defaults, field, def);
+ return def;
+ }
+ else
+ {
+ g_warning ("DbModel: Field string shoud specify name and table alias: %s", field_str);
+ field_free (field);
+ }
+
+ return NULL;
+}
+
+static void db_model_on_param_changed (GvnParam * param, GValue * value, DbModel * obj)
+{
+ db_model_refresh (obj);
+}
+
/**
* db_model_set_default_value_from_column:
* @obj: a #DbModel
@@ -1601,17 +1682,16 @@ void db_model_set_batch (DbModel * obj, SqlBatch * batch)
void db_model_set_default_value_from_column (DbModel * obj,
const gchar * field_str, const gchar * column_str)
{
- Field * field;
- ColumnDef * column_def;
+ ColumnDef * def;
g_return_if_fail (DB_IS_MODEL (obj));
g_return_if_fail (field_str);
g_return_if_fail (column_str);
-
- field = field_new_from_string (field_str);
- column_def = column_def_new (FIELD_DEF, field_new_from_string (column_str));
- g_hash_table_insert (obj->priv->column_defaults, field, column_def);
+ def = db_model_create_column_def (obj, field_str);
+
+ if (def)
+ def->src_column = field_new_from_string (column_str);
}
/**
@@ -1626,58 +1706,22 @@ void db_model_set_default_value_from_column (DbModel * obj,
void db_model_set_default_value_from_param (DbModel * obj,
const gchar * field_str, GvnParam * param, gboolean link)
{
- Field * field;
- ParamDef * param_def;
- ColumnDef * column_def;
- SqlObject * equal = NULL;
+ ColumnDef * def;
g_return_if_fail (DB_IS_MODEL (obj));
g_return_if_fail (field_str);
g_return_if_fail (GVN_IS_PARAM (param));
- field = field_new_from_string (field_str);
-
- if (link)
- {
- SqlList * operands, * link_operands;
+ def = db_model_create_column_def (obj, field_str);
- db_model_alloc_link_data (obj);
-
- link_operands = sql_operation_get_operands (SQL_OPERATION (obj->priv->link_op));
+ if (!def)
+ return;
- equal = sql_operation_new (SQL_OPERATION_TYPE_EQUAL);
- sql_list_add (link_operands, equal);
-
- operands = sql_list_new (SQL_TYPE_EXPR);
- sql_list_add (operands, sql_field_new_with_target (field->name, field->target, field->schema));
- sql_list_add (operands, sql_value_new_with_param (param));
- sql_operation_set_operands (SQL_OPERATION (equal), operands);
- }
-
- param_def = g_new (ParamDef, 1);
- param_def->param = g_object_ref (param);
- param_def->equal_op = equal;
- param_def->link_op = obj->priv->link_op;
-
- column_def = column_def_new (PARAM_DEF, param_def);
- g_hash_table_insert (obj->priv->column_defaults, field, column_def);
-}
-
-/**
- * db_model_request_main_table:
- * @obj: a #DbModel
- * @table: the name of the new main table of @model
- *
- * Requests the main table of @model. The main table is the only table on a
- * #DbModel whose rows can be deleted or inserted.
- **/
-void db_model_request_main_table (DbModel * obj, const gchar * table)
-{
- g_return_if_fail (DB_IS_MODEL (obj));
-
- g_free (obj->priv->user_main_table);
- obj->priv->user_main_table = g_strdup (table);
- db_model_calculate_update_flags (obj);
+ def->param = g_object_ref_sink (param);
+
+ if (link)
+ def->link = g_signal_connect (param, "value-changed",
+ G_CALLBACK (db_model_on_param_changed), obj);
}
/**
@@ -1943,17 +1987,7 @@ gboolean db_model_set_value (DbModel * obj, DbIter * iter, gint col, const GValu
GvnParamSpec * spec = priv->column[col].spec;
if (!gvn_param_spec_validate (spec, value, err))
- {
return FALSE;
- }
-
- if (!(priv->update_flags & DB_MODEL_UPDATE)
- && !(row_op & DB_MODEL_ROW_OP_INSERT))
- {
- g_set_error (err, DB_MODEL_LOG_DOMAIN
- ,DB_MODEL_ERROR_NOT_UPDATABLE, "Model not updatable");
- return FALSE;
- }
if (!gvn_value_is_null (value))
{
@@ -2033,21 +2067,17 @@ gboolean db_model_insert (DbModel * obj, DbIter * iter)
for (i = 0; i < row->len; i++)
{
Field field;
- ColumnDef * column_def;
+ ColumnDef * def;
const GValue * def_value = NULL;
DbColumn col = priv->column[i];
field.name = col.name;
- field.target = col.table;
- field.schema = col.schema;
-
- column_def = g_hash_table_lookup (priv->column_defaults, &field);
-
- if (column_def && column_def->type == PARAM_DEF)
- {
- ParamDef * param_def = column_def->def;
- def_value = gvn_param_get_value (param_def->param);
- }
+ field.target = priv->column_table[i]->alias;
+ field.schema = NULL;
+ def = g_hash_table_lookup (priv->defaults, &field);
+
+ if (def && def->param)
+ def_value = gvn_param_get_value (def->param);
if (!def_value)
def_value = gvn_param_spec_get_default (col.spec);
@@ -2280,7 +2310,7 @@ gboolean db_model_has_pending_operations (DbModel * obj)
}
static SqlObject * db_model_create_where (DbModel * obj,
- Table * table, DbOperation * operation, gboolean for_insert)
+ TableInfo * tinfo, DbOperation * operation, gboolean for_insert)
{
GSList * l;
DbUpdatedField * u;
@@ -2296,9 +2326,7 @@ 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)
+ for (l = tinfo->pkeys; l; l = l->next)
{
GSList * n;
SqlObject * equal;
@@ -2348,20 +2376,24 @@ static SqlObject * db_model_create_where (DbModel * obj,
}
static SqlObject * db_model_create_insert (DbModel * obj,
- Table * table, DbOperation * operation)
+ TableInfo * tinfo, DbOperation * operation)
{
gint i;
DbModelPrivate * priv = obj->priv;
DbRow * row = operation->row;
const GValue * value;
SqlList * targets, * stmts, * sets, * fields, * values, * select_fields;
- SqlObject * target, * insert, * set, * select;
- SqlObject * where = db_model_create_where (obj, table, operation, TRUE);
+ SqlObject * target, * insert, * set, * select, * where;
+ GHashTableIter iter;
+ Field * field;
+ ColumnDef * def;
+ GArray * cols;
+ gchar * colname;
+
+ where = db_model_create_where (obj, tinfo, operation, TRUE);
if (!where)
return NULL;
-
- target = sql_table_new (table->name, table->schema);
fields = sql_list_new (SQL_TYPE_FIELD);
@@ -2373,6 +2405,7 @@ static SqlObject * db_model_create_insert (DbModel * obj,
);
sql_list_add (sets, set);
+ target = sql_table_new (tinfo->name, tinfo->schema);
insert = g_object_new (SQL_TYPE_INSERT
,"table", target
,"fields", fields
@@ -2383,6 +2416,9 @@ static SqlObject * db_model_create_insert (DbModel * obj,
select_fields = sql_list_new (SQL_TYPE_EXPR);
targets = sql_list_new (SQL_TYPE_TARGET);
+
+ target = sql_table_new (tinfo->name, tinfo->schema);
+ sql_target_set_alias (SQL_TARGET (target), tinfo->alias);
sql_list_add (targets, target);
select = g_object_new (SQL_TYPE_SELECT
@@ -2392,28 +2428,16 @@ static SqlObject * db_model_create_insert (DbModel * obj,
,NULL
);
- GHashTableIter iter;
- ColumnDef * column_def;
- Field * field;
-
- g_hash_table_iter_init (&iter, priv->column_defaults);
+ g_hash_table_iter_init (&iter, priv->defaults);
- while (g_hash_table_iter_next (&iter, (gpointer) &field, (gpointer) &column_def))
- if (!g_strcmp0 (field->target, table->name)
- && !g_strcmp0 (field->schema, table->schema))
+ while (g_hash_table_iter_next (&iter, (gpointer) &field, (gpointer) &def))
+ if (!g_strcmp0 (field->target, tinfo->alias)
+ && !g_hash_table_lookup (tinfo->columns, field->name))
{
- switch (column_def->type)
- {
- case PARAM_DEF:
- {
- ParamDef * param_def = column_def->def;
- value = gvn_param_get_value (param_def->param);
- break;
- }
- case FIELD_DEF:
- value = NULL; // FIXME
- break;
- }
+ if (def->param)
+ value = gvn_param_get_value (def->param);
+ else
+ value = NULL;
if (value)
{
@@ -2422,20 +2446,22 @@ static SqlObject * db_model_create_insert (DbModel * obj,
}
}
- for (i = 0; i < row->len; i++)
- if (table_has_column (table, &priv->column[i]))
+ g_hash_table_iter_init (&iter, tinfo->columns);
+
+ while (g_hash_table_iter_next (&iter, (gpointer) &colname, (gpointer) &cols))
{
+ i = g_array_index (cols, gint, 0);
value = &row->value[i];
if (!gvn_value_is_null (value))
{
- sql_list_add (fields, sql_field_new (priv->column[i].name));
+ sql_list_add (fields, sql_field_new (colname));
sql_list_add (values, sql_value_new_with_value (value));
}
- sql_list_add (select_fields, sql_field_new (priv->column[i].name));
+ sql_list_add (select_fields, sql_field_new (colname));
}
-
+
stmts = sql_list_new (SQL_TYPE_STMT);
sql_list_add (stmts, insert);
sql_list_add (stmts, select);
@@ -2482,9 +2508,7 @@ void db_model_perform_operations (DbModel * obj, gboolean retry)
stmts = sql_list_new (SQL_TYPE_STMT);
g_object_ref_sink (stmts);
- l = g_queue_peek_head_link (priv->operation);
-
- for (; l && !error; l = l->next)
+ for (l = priv->operation->head; l && !error; l = l->next)
{
SqlObject * stmt = NULL;
@@ -2525,36 +2549,50 @@ void db_model_perform_operations (DbModel * obj, gboolean retry)
}
else if (op->type & DB_MODEL_ROW_OP_UPDATE) // UPDATE || INSERT + SELECT
{
- Table * table;
+ GList * l;
+ GSList * n;
+ GQueue * fields;
+ TableInfo * tinfo;
GHashTableIter iter;
SqlList * update_list;
+ DbUpdatedField * u;
+
+ GHashTable * tables = g_hash_table_new_full (
+ g_direct_hash
+ ,g_direct_equal
+ ,NULL
+ ,(GDestroyNotify) g_queue_free
+ );
+
+ for (n = op->updated; n && (u = n->data); n = n->next)
+ {
+ tinfo = priv->column_table[u->column];
+ fields = g_hash_table_lookup (tables, tinfo);
+
+ if (!fields)
+ {
+ fields = g_queue_new ();
+ g_hash_table_insert (tables, tinfo, fields);
+ }
+
+ g_queue_push_tail (fields, u);
+ }
update_list = sql_list_new (SQL_TYPE_STMT);
- g_hash_table_iter_init (&iter, priv->tables);
+ g_hash_table_iter_init (&iter, tables);
- while (g_hash_table_iter_next (&iter, (gpointer) &table, NULL))
+ while (g_hash_table_iter_next (&iter, (gpointer) &tinfo, (gpointer) &fields))
{
- GSList * l;
- DbUpdatedField * u;
- GSList * fields = NULL;
-
- for (l = op->updated; l && (u = l->data); l = l->next)
- if (table_has_column (table, &priv->column[u->column]))
- fields = g_slist_prepend (fields, u);
-
- if (!fields)
- continue;
-
- where = db_model_create_where (obj, table, op, FALSE);
+ where = db_model_create_where (obj, tinfo, op, FALSE);
if (where)
{
SqlList * sets = sql_list_new (SQL_TYPE_UPDATE_SET);
SqlList * targets = sql_list_new (SQL_TYPE_TARGET);
- sql_list_add (targets, sql_table_new (table->name, table->schema));
+ sql_list_add (targets, sql_table_new (tinfo->name, tinfo->schema));
- for (l = fields; l && (u = l->data); l = l->next)
+ for (l = fields->head; l && (u = l->data); l = l->next)
{
GValue * new_value = DB_ROW_FIELD (row, u->column);
@@ -2574,15 +2612,14 @@ void db_model_perform_operations (DbModel * obj, gboolean retry)
}
else
{
- SqlObject * insert = db_model_create_insert (obj, table, op);
+ SqlObject * insert = db_model_create_insert (obj, tinfo, op);
if (insert)
sql_list_add (update_list, insert);
}
-
- g_slist_free (fields);
}
+ g_hash_table_unref (tables);
stmt = g_object_new (SQL_TYPE_MULTI_STMT, "stmts", update_list, NULL);
}
@@ -2646,10 +2683,53 @@ void db_model_refresh (DbModel * obj)
if (priv->conn && priv->stmt)
{
- SqlBatch * tmp_batch = sql_batch_new ();
+ Field * field;
+ ColumnDef * def;
+ SqlObject * link_op;
+ SqlList * link_operands;
+ SqlBatch * tmp_batch;
+ GHashTableIter iter;
+
+ // Gets all the holders from the statement
+
+ tmp_batch = sql_batch_new ();
+ g_object_ref_sink (tmp_batch);
sql_object_get_holders (SQL_OBJECT (priv->stmt), tmp_batch);
sql_batch_merge (tmp_batch, priv->batch);
- sql_batch_merge (tmp_batch, priv->internal_batch);
+
+ // Creates the link operation
+
+ link_op = sql_operation_new (SQL_OPERATION_TYPE_AND);
+ g_object_ref_sink (link_op);
+
+ link_operands = sql_list_new (SQL_TYPE_EXPR);
+ sql_operation_set_operands (SQL_OPERATION (link_op), link_operands);
+
+ g_hash_table_iter_init (&iter, priv->defaults);
+
+ while (g_hash_table_iter_next (&iter, (gpointer) &field, (gpointer) &def))
+ if (def->link)
+ {
+ SqlObject * sql_field;
+ SqlObject * equal_op;
+ SqlList * equal_operands;
+
+ equal_op = sql_operation_new (SQL_OPERATION_TYPE_EQUAL);
+ sql_list_add (link_operands, equal_op);
+
+ sql_field = sql_field_new_with_target (
+ field->name, field->target, NULL);
+
+ equal_operands = sql_list_new (SQL_TYPE_EXPR);
+ sql_list_add (equal_operands, sql_field);
+ sql_list_add (equal_operands, sql_value_new_with_param (def->param));
+ sql_operation_set_operands (SQL_OPERATION (equal_op), equal_operands);
+ }
+
+ if (sql_list_length (link_operands) > 0)
+ sql_batch_add (tmp_batch, "link", link_op);
+
+ // Executes the statement if its ready
if (sql_batch_is_ready (tmp_batch))
{
@@ -2663,9 +2743,10 @@ void db_model_refresh (DbModel * obj)
,g_object_ref (obj)
,(GDestroyNotify) g_object_unref
);
-
- g_object_unref (g_object_ref_sink (tmp_batch));
}
+
+ g_object_unref (link_op);
+ g_object_unref (tmp_batch);
}
if (!is_ready)
@@ -2931,6 +3012,7 @@ typedef enum
,PROP_MAIN_TABLE
,PROP_UPDATE_FLAGS
,PROP_RESULT_POS
+ ,PROP_PARTIAL_DELETE
}
DbModelProp;
@@ -2951,15 +3033,15 @@ static void db_model_set_property (DbModel * obj, guint property_id,
case PROP_USE_FILE:
obj->priv->use_file = g_value_get_boolean (value);
break;
- case PROP_MAIN_TABLE:
- db_model_request_main_table (obj, g_value_get_string (value));
- break;
case PROP_UPDATE_FLAGS:
db_model_request_update_flags (obj, g_value_get_flags (value));
break;
case PROP_RESULT_POS:
obj->priv->result_pos = g_value_get_uint (value);
break;
+ case PROP_PARTIAL_DELETE:
+ obj->priv->partial_delete = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
}
@@ -2991,6 +3073,9 @@ static void db_model_get_property (DbModel * obj, guint property_id,
case PROP_RESULT_POS:
g_value_set_uint (value, obj->priv->result_pos);
break;
+ case PROP_PARTIAL_DELETE:
+ g_value_set_boolean (value, obj->priv->partial_delete);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
}
@@ -3008,11 +3093,11 @@ static void db_model_init (DbModel *obj)
priv->sql = NULL;
priv->request = NULL;
priv->status = DB_MODEL_STATUS_CLEAN;
- priv->mode = DB_MODEL_MODE_ON_CHANGE;
priv->result = NULL;
priv->result_pos = 0;
priv->data = NULL;
priv->column = NULL;
+ priv->stamp = g_random_int ();
priv->column_index = g_hash_table_new_full (
g_str_hash,
g_str_equal,
@@ -3020,33 +3105,31 @@ static void db_model_init (DbModel *obj)
NULL
);
- priv->stamp = g_random_int ();
+ priv->defaults = g_hash_table_new_full (
+ (GHashFunc) field_hash,
+ (GEqualFunc) field_equal,
+ (GDestroyNotify) field_free,
+ (GDestroyNotify) column_def_free
+ );
priv->fresh = TRUE;
priv->sort_column_id = DB_MODEL_UNSORTED_SORT_COLUMN_ID;
priv->default_sort_data = NULL;
priv->default_sort_func = NULL;
priv->default_sort_destroy = NULL;
-
- 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->update_flags = 0;
priv->main_table = NULL;
- priv->user_main_table = NULL;
+ priv->mode = DB_MODEL_MODE_ON_CHANGE;
priv->operation = NULL;
priv->row_ops = NULL;
- priv->join = NULL;
priv->pending_request = NULL;
priv->tables = NULL;
+ priv->column_table = NULL;
+ priv->partial_delete = FALSE;
+ priv->join = NULL;
}
static void db_model_finalize (DbModel * obj)
@@ -3061,18 +3144,15 @@ static void db_model_finalize (DbModel * obj)
g_free (priv->sql);
g_hash_table_destroy (priv->column_index);
db_model_set_batch (obj, NULL);
-
- g_clear_object (&priv->link_op);
- g_clear_object (&priv->internal_batch);
- g_hash_table_destroy (priv->column_defaults);
+ g_hash_table_destroy (priv->defaults);
if (priv->updatable_data_allocated)
{
- g_free (priv->user_main_table);
g_queue_free (priv->operation);
- g_hash_table_destroy (priv->row_ops);
- g_slist_free_full (priv->join, (GDestroyNotify) db_join_free);
- g_hash_table_destroy (priv->tables);
+ g_hash_table_unref (priv->row_ops);
+ g_hash_table_unref (priv->tables);
+ g_free (priv->column_table);
+// g_slist_free_full (priv->join, (GDestroyNotify) db_join_free);
}
parent->finalize (G_OBJECT (obj));
@@ -3241,7 +3321,7 @@ static void db_model_class_init (DbModelClass *k)
,_("Main Table")
,_("The main table of the model")
,NULL
- ,G_PARAM_READWRITE
+ ,G_PARAM_READABLE
));
g_object_class_install_property (klass, PROP_UPDATE_FLAGS,
@@ -3263,6 +3343,15 @@ static void db_model_class_init (DbModelClass *k)
,0
,G_PARAM_READWRITE
));
+
+ g_object_class_install_property (klass, PROP_PARTIAL_DELETE,
+ g_param_spec_boolean ("partial-delete"
+ ,_("Partial delete")
+ ,_("When a row is deleted set all the fields from "
+ "the table to null rather than delete it.")
+ ,FALSE
+ ,G_PARAM_READWRITE
+ ));
}
GType db_model_update_flags_get_type ()
diff --git a/db/db-model.h b/db/db-model.h
index 831988e..b8f6c0f 100644
--- a/db/db-model.h
+++ b/db/db-model.h
@@ -197,7 +197,6 @@ void db_model_add_pre_stmt (DbModel * obj, SqlStmt * stmt);
void db_model_add_post_stmt (DbModel * obj, SqlStmt * stmt);
DbModelStatus db_model_get_status (DbModel * obj);
const gchar * db_model_get_main_table (DbModel * obj);
-void db_model_request_main_table (DbModel * obj, const gchar * table);
DbModelUpdateFlags db_model_get_update_flags (DbModel * obj);
void db_model_request_update_flags (DbModel * obj
,DbModelUpdateFlags flags);
diff --git a/db/db-result.c b/db/db-result.c
index 2e89d9d..44aca24 100644
--- a/db/db-result.c
+++ b/db/db-result.c
@@ -72,6 +72,8 @@ DbResult * db_result_copy (const DbResult * obj)
result->column[n].info = obj->column[n].info;
result->column[n].spec = gvn_param_spec_copy (obj->column[n].spec);
result->column[n].table = g_strdup (obj->column[n].table);
+ result->column[n].table_alias = g_strdup (obj->column[n].table_alias);
+ result->column[n].schema = g_strdup (obj->column[n].schema);
result->column[n].name = g_strdup (obj->column[n].name);
result->column[n].alias = g_strdup (obj->column[n].alias);
}
@@ -107,6 +109,8 @@ void db_result_free (DbResult * obj)
g_free (col.name);
g_free (col.alias);
g_free (col.table);
+ g_free (col.table_alias);
+ g_free (col.schema);
}
g_free (obj->column);
diff --git a/db/db-result.h b/db/db-result.h
index 6c9be48..8a1a3fd 100644
--- a/db/db-result.h
+++ b/db/db-result.h
@@ -69,13 +69,13 @@ DbColumnInfo;
**/
struct _DbColumn
{
- DbColumnInfo info;
- GvnParamSpec * spec;
- gchar * schema;
- gchar * table;
- gchar * table_alias;
gchar * name;
gchar * alias;
+ gchar * table;
+ gchar * table_alias;
+ gchar * schema;
+ DbColumnInfo info;
+ GvnParamSpec * spec;
};
GType db_result_get_type ();
diff --git a/module/data/customer.glade b/module/data/customer.glade
index 27e07b4..223d9c0 100644
--- a/module/data/customer.glade
+++ b/module/data/customer.glade
@@ -1,11 +1,11 @@
-
+
+
+
+
diff --git a/plugin/pg/db-pg.c b/plugin/pg/db-pg.c
index 6d5325f..3ab937e 100644
--- a/plugin/pg/db-pg.c
+++ b/plugin/pg/db-pg.c
@@ -628,6 +628,7 @@ static DbResultSet * __db_pg_query
r->column[j].info = 0;
r->column[j].name = NULL;
r->column[j].table = NULL;
+ r->column[j].table_alias = NULL;
r->column[j].schema = NULL;
if (GPOINTER_TO_INT (g_ptr_array_index (col_iter, j)) == 0)
@@ -650,6 +651,7 @@ static DbResultSet * __db_pg_query
r->column[j].alias = g_strdup (r->column[j].name);
r->column[j].table = g_strdup ("");
+ r->column[j].table_alias = g_strdup ("");
r->column[j].spec = gvn_param_spec_new_with_attrs
(((GType*) g_ptr_array_index (types, ind))[j]
, FALSE, FALSE, NULL);
@@ -763,8 +765,12 @@ static DbResultSet * __db_pg_query
guint n;
if (!r->column[j].table)
+ {
r->column[j].table =
g_strdup (PQgetvalue (res_col, k, 1));
+ r->column[j].table_alias =
+ g_strdup (r->column[j].table);
+ }
g_strfreev (pkey);
pkey = g_strsplit (PQgetvalue (res_col, k, 2), " ", G_MAXINT);
diff --git a/sql/sql-batch.c b/sql/sql-batch.c
index 4436b2c..8b79382 100644
--- a/sql/sql-batch.c
+++ b/sql/sql-batch.c
@@ -48,9 +48,12 @@ static void sql_batch_item_changed (SqlObject * item, SqlBatch * obj)
static void sql_batch_free_item (SqlBatch * obj, SqlObject * item)
{
- g_signal_handlers_disconnect_by_func (item,
- sql_batch_item_changed, obj);
- g_object_unref (item);
+ if (item)
+ {
+ g_signal_handlers_disconnect_by_func (item,
+ sql_batch_item_changed, obj);
+ g_object_unref (item);
+ }
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
diff --git a/sql/sql-field.h b/sql/sql-field.h
index f21e85b..064bbe6 100644
--- a/sql/sql-field.h
+++ b/sql/sql-field.h
@@ -22,8 +22,8 @@
#include "sql-target.h"
#define SQL_TYPE_FIELD (sql_field_get_type ())
-#define SQL_FIELD(object) (G_TYPE_CHECK_INSTANCE_CAST (object, SQL_TYPE_FIELD, SqlField))
-#define SQL_IS_FIELD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SQL_TYPE_FIELD))
+#define SQL_FIELD(self) (G_TYPE_CHECK_INSTANCE_CAST (self, SQL_TYPE_FIELD, SqlField))
+#define SQL_IS_FIELD(self) (G_TYPE_CHECK_INSTANCE_TYPE ((self), SQL_TYPE_FIELD))
typedef struct _SqlField SqlField;
typedef struct _SqlFieldClass SqlFieldClass;
@@ -49,10 +49,10 @@ SqlObject * sql_field_new_with_target (const gchar * name
,const gchar * schema);
const gchar * sql_field_get_name (SqlField * self);
-void sql_field_set_name (SqlField * obj, const gchar * name);
+void sql_field_set_name (SqlField * self, const gchar * name);
const gchar * sql_field_get_target (SqlField * self);
-void sql_field_set_target (SqlField * obj, const gchar * target);
+void sql_field_set_target (SqlField * self, const gchar * target);
const gchar * sql_field_get_schema (SqlField * self);
-void sql_field_set_schema (SqlField * obj, const gchar * schema);
+void sql_field_set_schema (SqlField * self, const gchar * schema);
#endif
diff --git a/sql/sql-holder.c b/sql/sql-holder.c
index 36df2a5..c44d255 100644
--- a/sql/sql-holder.c
+++ b/sql/sql-holder.c
@@ -31,36 +31,36 @@ SqlObject * sql_holder_new (const gchar * id)
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
-static void sql_holder_render (SqlHolder * obj, SqlRender * render, SqlBatch * batch)
+static void sql_holder_render (SqlHolder * self, SqlRender * render, SqlBatch * batch)
{
- SqlObject * object = batch ? sql_batch_get (batch, obj->id) : NULL;
+ SqlObject * object = batch ? sql_batch_get (batch, self->id) : NULL;
if (object)
sql_render_add_object (render, object);
else
- sql_render_printf (render, "#%s", obj->id);
+ sql_render_printf (render, "#%s", self->id);
}
-static void sql_holder_find_holders (SqlHolder * obj, SqlBatch * batch)
+static void sql_holder_find_holders (SqlHolder * self, SqlBatch * batch)
{
- sql_batch_add (batch, obj->id, NULL);
+ sql_batch_add (batch, self->id, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
/**
* sql_holder_get_id:
- * @obj: the #SqlHolder
+ * @self: the #SqlHolder
*
* Gets the identifier assigned to the holder.
*
* Return value: (transfer none): the id
**/
-const gchar * sql_holder_get_id (SqlHolder * obj)
+const gchar * sql_holder_get_id (SqlHolder * self)
{
- g_return_val_if_fail (SQL_IS_HOLDER (obj), NULL);
+ g_return_val_if_fail (SQL_IS_HOLDER (self), NULL);
- return obj->id;
+ return self->id;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@@ -70,44 +70,44 @@ enum
PROP_ID = 1
};
-static void sql_holder_set_property (SqlHolder * obj, guint id,
+static void sql_holder_set_property (SqlHolder * self, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_ID:
- g_free (obj->id);
- obj->id = g_value_dup_string (value);
+ g_free (self->id);
+ self->id = g_value_dup_string (value);
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
-static void sql_holder_get_property (SqlHolder * obj, guint id,
+static void sql_holder_get_property (SqlHolder * self, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_ID:
- g_value_set_string (value, sql_holder_get_id (obj));
+ g_value_set_string (value, sql_holder_get_id (self));
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
-static void sql_holder_init (SqlHolder * obj)
+static void sql_holder_init (SqlHolder * self)
{
- obj->id = NULL;
+ self->id = NULL;
}
-static void sql_holder_finalize (SqlHolder * obj)
+static void sql_holder_finalize (SqlHolder * self)
{
- g_free (obj->id);
- G_OBJECT_CLASS (sql_holder_parent_class)->finalize (G_OBJECT (obj));
+ g_free (self->id);
+ G_OBJECT_CLASS (sql_holder_parent_class)->finalize (G_OBJECT (self));
}
static void sql_holder_class_init (SqlHolderClass * k)
diff --git a/sql/sql-holder.h b/sql/sql-holder.h
index 76da647..03487a7 100644
--- a/sql/sql-holder.h
+++ b/sql/sql-holder.h
@@ -19,8 +19,8 @@
#define SQL_HOLDER_H
#define SQL_TYPE_HOLDER (sql_holder_get_type ())
-#define SQL_HOLDER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_HOLDER, SqlHolder))
-#define SQL_IS_HOLDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_HOLDER))
+#define SQL_HOLDER(self) (G_TYPE_CHECK_INSTANCE_CAST (self, SQL_TYPE_HOLDER, SqlHolder))
+#define SQL_IS_HOLDER(self) (G_TYPE_CHECK_INSTANCE_TYPE (self, SQL_TYPE_HOLDER))
typedef struct _SqlHolder SqlHolder;
typedef struct _SqlHolderClass SqlHolderClass;
@@ -41,6 +41,6 @@ struct _SqlHolderClass
GType sql_holder_get_type ();
SqlObject * sql_holder_new (const gchar * id);
-const gchar * sql_holder_get_id (SqlHolder * obj);
+const gchar * sql_holder_get_id (SqlHolder * self);
#endif
\ No newline at end of file
diff --git a/sql/sql-join.c b/sql/sql-join.c
index 9c88c23..592e433 100644
--- a/sql/sql-join.c
+++ b/sql/sql-join.c
@@ -47,51 +47,58 @@ static const gchar * SQL_JOIN_TYPE[] =
,"RIGHT"
};
-static void sql_join_render (SqlJoin * obj, SqlRender * render)
+static void sql_join_render (SqlJoin * self, SqlRender * render)
{
- sql_render_add_item (render, TRUE, NULL, obj->target_left);
- sql_render_add_token (render, SQL_JOIN_TYPE[obj->type]);
+ sql_render_add_item (render, TRUE, NULL, self->target_left);
+ sql_render_add_token (render, SQL_JOIN_TYPE[self->type]);
sql_render_add_token (render, "JOIN");
- sql_render_add_item (render, TRUE, NULL, obj->target_right);
+ sql_render_add_item (render, TRUE, NULL, self->target_right);
- if (obj->has_using)
+ if (self->has_using)
{
sql_render_add_token (render, "USING");
sql_render_append (render, "(");
- sql_render_add_list (render, TRUE, NULL, obj->using_fields, ",");
+ sql_render_add_list (render, TRUE, NULL, self->using_fields, ",");
sql_render_append (render, ")");
}
else
- sql_render_add_item (render, FALSE, "ON", obj->condition);
+ sql_render_add_item (render, FALSE, "ON", self->condition);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
-void sql_join_set_target_left (SqlJoin * obj, SqlTarget * target)
+SqlJoinType sql_join_get_join_type (SqlJoin * self)
{
- g_return_if_fail (SQL_IS_JOIN (obj));
- g_return_if_fail (SQL_IS_TARGET (target) || SQL_IS_HOLDER (target) || !target);
-
- sql_object_remove (obj, obj->target_left);
- obj->target_left = sql_object_add (obj, target);
+ g_return_if_fail (SQL_IS_JOIN (self));
+
+ return self->type;
}
-void sql_join_set_target_right (SqlJoin * obj, SqlTarget * target)
+void sql_join_set_target_left (SqlJoin * self, SqlTarget * target)
{
- g_return_if_fail (SQL_IS_JOIN (obj));
+ g_return_if_fail (SQL_IS_JOIN (self));
g_return_if_fail (SQL_IS_TARGET (target) || SQL_IS_HOLDER (target) || !target);
- sql_object_remove (obj, obj->target_right);
- obj->target_right = sql_object_add (obj, target);
+ sql_object_remove (self, self->target_left);
+ self->target_left = sql_object_add (self, target);
}
-void sql_join_set_condition (SqlJoin * obj, SqlExpr * condition)
+void sql_join_set_target_right (SqlJoin * self, SqlTarget * target)
{
- g_return_if_fail (SQL_IS_JOIN (obj));
+ g_return_if_fail (SQL_IS_JOIN (self));
+ g_return_if_fail (SQL_IS_TARGET (target) || SQL_IS_HOLDER (target) || !target);
+
+ sql_object_remove (self, self->target_right);
+ self->target_right = sql_object_add (self, target);
+}
+
+void sql_join_set_condition (SqlJoin * self, SqlExpr * condition)
+{
+ g_return_if_fail (SQL_IS_JOIN (self));
g_return_if_fail (SQL_IS_EXPR (condition) || SQL_IS_HOLDER (condition) || !condition);
- sql_object_remove (obj, obj->condition);
- obj->condition = sql_object_add (obj, condition);
+ sql_object_remove (self, self->condition);
+ self->condition = sql_object_add (self, condition);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@@ -106,80 +113,80 @@ enum
,PROP_USING_FIELDS
};
-static void sql_join_set_property (SqlJoin * obj, guint id,
+static void sql_join_set_property (SqlJoin * self, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_TARGET_LEFT:
- sql_join_set_target_left (obj, g_value_get_object (value));
+ sql_join_set_target_left (self, g_value_get_object (value));
break;
case PROP_TARGET_RIGHT:
- sql_join_set_target_right (obj, g_value_get_object (value));
+ sql_join_set_target_right (self, g_value_get_object (value));
break;
case PROP_TYPE:
- obj->type = g_value_get_enum (value);
+ self->type = g_value_get_enum (value);
break;
case PROP_CONDITION:
- sql_join_set_condition (obj, g_value_get_object (value));
+ sql_join_set_condition (self, g_value_get_object (value));
break;
case PROP_HAS_USING:
- obj->has_using = g_value_get_boolean (value);
+ self->has_using = g_value_get_boolean (value);
break;
case PROP_USING_FIELDS:
- sql_object_remove (obj, obj->using_fields);
- obj->using_fields = sql_object_add (obj, g_value_get_object (value));
+ sql_object_remove (self, self->using_fields);
+ self->using_fields = sql_object_add (self, g_value_get_object (value));
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
-static void sql_join_get_property (SqlJoin * obj, guint id,
+static void sql_join_get_property (SqlJoin * self, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_TARGET_LEFT:
- g_value_set_object (value, obj->target_left);
+ g_value_set_object (value, self->target_left);
break;
case PROP_TARGET_RIGHT:
- g_value_set_object (value, obj->target_right);
+ g_value_set_object (value, self->target_right);
break;
case PROP_TYPE:
- g_value_set_enum (value, obj->type);
+ g_value_set_enum (value, self->type);
break;
case PROP_CONDITION:
- g_value_set_object (value, obj->condition);
+ g_value_set_object (value, self->condition);
break;
case PROP_HAS_USING:
- g_value_set_boolean (value, obj->has_using);
+ g_value_set_boolean (value, self->has_using);
break;
case PROP_USING_FIELDS:
- g_value_set_object (value, obj->using_fields);
+ g_value_set_object (value, self->using_fields);
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
-static void sql_join_init (SqlJoin * obj)
+static void sql_join_init (SqlJoin * self)
{
- obj->target_left = NULL;
- obj->target_right = NULL;
- obj->condition = NULL;
- obj->using_fields = NULL;
+ self->target_left = NULL;
+ self->target_right = NULL;
+ self->condition = NULL;
+ self->using_fields = NULL;
}
-static void sql_join_finalize (SqlJoin * obj)
+static void sql_join_finalize (SqlJoin * self)
{
- sql_object_remove (obj, obj->target_left);
- sql_object_remove (obj, obj->target_right);
- sql_object_remove (obj, obj->condition);
- sql_object_remove (obj, obj->using_fields);
- G_OBJECT_CLASS (sql_join_parent_class)->finalize (G_OBJECT (obj));
+ sql_object_remove (self, self->target_left);
+ sql_object_remove (self, self->target_right);
+ sql_object_remove (self, self->condition);
+ sql_object_remove (self, self->using_fields);
+ G_OBJECT_CLASS (sql_join_parent_class)->finalize (G_OBJECT (self));
}
static void sql_join_class_init (SqlJoinClass * klass)
diff --git a/sql/sql-join.h b/sql/sql-join.h
index 7e342c4..3058d3d 100644
--- a/sql/sql-join.h
+++ b/sql/sql-join.h
@@ -22,8 +22,8 @@
#include "sql-expr.h"
#define SQL_TYPE_JOIN (sql_join_get_type ())
-#define SQL_IS_JOIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_JOIN))
-#define SQL_JOIN(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_JOIN, SqlJoin))
+#define SQL_IS_JOIN(self) (G_TYPE_CHECK_INSTANCE_TYPE (self, SQL_TYPE_JOIN))
+#define SQL_JOIN(self) (G_TYPE_CHECK_INSTANCE_CAST (self, SQL_TYPE_JOIN, SqlJoin))
#define SQL_TYPE_JOIN_TYPE (sql_join_type_get_type ())
@@ -60,8 +60,9 @@ GType sql_join_get_type ();
GType sql_join_type_get_type ();
SqlObject * sql_join_new (SqlTarget * left, SqlTarget * right, SqlJoinType type);
-void sql_join_set_condition (SqlJoin * obj, SqlExpr * condition);
-void sql_join_set_target_right (SqlJoin * obj, SqlTarget * target);
-void sql_join_set_target_left (SqlJoin * obj, SqlTarget * target);
+SqlJoinType sql_join_get_join_type (SqlJoin * self);
+void sql_join_set_condition (SqlJoin * self, SqlExpr * condition);
+void sql_join_set_target_right (SqlJoin * self, SqlTarget * target);
+void sql_join_set_target_left (SqlJoin * self, SqlTarget * target);
#endif
\ No newline at end of file
diff --git a/sql/sql-table.c b/sql/sql-table.c
index e03e223..c2c3f0d 100644
--- a/sql/sql-table.c
+++ b/sql/sql-table.c
@@ -33,18 +33,68 @@ SqlObject * sql_table_new (const gchar * name, const gchar * schema)
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
-static void sql_table_render (SqlTable * obj, SqlRender * render)
+static void sql_table_render (SqlTable * self, SqlRender * render)
{
- if (obj->schema)
+ if (self->schema)
{
- sql_render_add_identifier (render, obj->schema);
+ sql_render_add_identifier (render, self->schema);
sql_render_append (render, ".");
}
- sql_render_add_identifier (render, obj->name);
+ sql_render_add_identifier (render, self->name);
- if (g_strcmp0 (obj->name, SQL_TARGET (obj)->alias))
- sql_render_add_identifier (render, SQL_TARGET (obj)->alias);
+ if (SQL_TARGET (self)->alias)
+ sql_render_add_identifier (render, SQL_TARGET (self)->alias);
+}
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
+
+/**
+ * sql_table_get_name:
+ * @self: the #SqlTable
+ *
+ * Return value: the table name
+ **/
+const gchar * sql_table_get_name (SqlTable * self)
+{
+ return self->name;
+}
+
+/**
+ * sql_table_set_name:
+ * @self: the #SqlTable
+ * @target: the target name
+ **/
+void sql_table_set_name (SqlTable * self, const gchar * name)
+{
+ g_return_if_fail (SQL_IS_TABLE (self));
+
+ g_free (self->name);
+ self->name = g_strdup (name);
+}
+
+/**
+ * sql_table_get_schema:
+ * @self: the #SqlTable
+ *
+ * Return value: the schema name
+ **/
+const gchar * sql_table_get_schema (SqlTable * self)
+{
+ return self->schema;
+}
+
+/**
+ * sql_table_set_schema:
+ * @self: the #SqlTable
+ * @schema: the schema name
+ **/
+void sql_table_set_schema (SqlTable * self, const gchar * schema)
+{
+ g_return_if_fail (SQL_IS_TABLE (self));
+
+ g_free (self->schema);
+ self->schema = g_strdup (schema);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@@ -55,53 +105,53 @@ enum
,PROP_SCHEMA
};
-static void sql_table_set_property (SqlTable * obj, guint id,
+static void sql_table_set_property (SqlTable * self, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_NAME:
- g_free (obj->name);
- obj->name = g_value_dup_string (value);
+ g_free (self->name);
+ self->name = g_value_dup_string (value);
break;
case PROP_SCHEMA:
- g_free (obj->schema);
- obj->schema = g_value_dup_string (value);
+ g_free (self->schema);
+ self->schema = g_value_dup_string (value);
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
-static void sql_table_get_property (SqlTable * obj, guint id,
+static void sql_table_get_property (SqlTable * self, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_NAME:
- g_value_set_string (value, obj->name);
+ g_value_set_string (value, self->name);
break;
case PROP_SCHEMA:
- g_value_set_string (value, obj->schema);
+ g_value_set_string (value, self->schema);
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
-static void sql_table_init (SqlTable * obj)
+static void sql_table_init (SqlTable * self)
{
- obj->name = NULL;
- obj->schema = NULL;
+ self->name = NULL;
+ self->schema = NULL;
}
-static void sql_table_finalize (SqlTable * obj)
+static void sql_table_finalize (SqlTable * self)
{
- g_free (obj->name);
- g_free (obj->schema);
- G_OBJECT_CLASS (sql_table_parent_class)->finalize (G_OBJECT (obj));
+ g_free (self->name);
+ g_free (self->schema);
+ G_OBJECT_CLASS (sql_table_parent_class)->finalize (G_OBJECT (self));
}
static void sql_table_class_init (SqlTableClass * klass)
diff --git a/sql/sql-table.h b/sql/sql-table.h
index ed7f5b6..62c4fc1 100644
--- a/sql/sql-table.h
+++ b/sql/sql-table.h
@@ -21,8 +21,8 @@
#include "sql-target.h"
#define SQL_TYPE_TABLE (sql_table_get_type ())
-#define SQL_TABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_TABLE, SqlTable))
-#define SQL_IS_TABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_TABLE))
+#define SQL_TABLE(self) (G_TYPE_CHECK_INSTANCE_CAST (self, SQL_TYPE_TABLE, SqlTable))
+#define SQL_IS_TABLE(self) (G_TYPE_CHECK_INSTANCE_TYPE (self, SQL_TYPE_TABLE))
typedef struct _SqlTable SqlTable;
typedef struct _SqlTableClass SqlTableClass;
@@ -40,7 +40,11 @@ struct _SqlTableClass
SqlTargetClass parent;
};
-GType sql_table_get_type ();
-SqlObject * sql_table_new (const gchar * name, const gchar * schema);
+GType sql_table_get_type ();
+SqlObject * sql_table_new (const gchar * name, const gchar * schema);
+const gchar * sql_table_get_name (SqlTable * self);
+void sql_table_set_name (SqlTable * self, const gchar * name);
+const gchar * sql_table_get_schema (SqlTable * self);
+void sql_table_set_schema (SqlTable * self, const gchar * schema);
#endif
diff --git a/sql/sql-target.c b/sql/sql-target.c
index 8213d9a..703867d 100644
--- a/sql/sql-target.c
+++ b/sql/sql-target.c
@@ -29,12 +29,28 @@ G_DEFINE_ABSTRACT_TYPE (SqlTarget, sql_target, SQL_TYPE_OBJECT);
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
-void sql_target_set_alias (SqlTarget * obj, const gchar * alias)
+/**
+ * sql_target_set_alias:
+ * @self: the #SqlTargetClass
+ * @alias: the target alias
+ **/
+void sql_target_set_alias (SqlTarget * self, const gchar * alias)
{
- g_return_if_fail (SQL_IS_TARGET (obj));
+ g_return_if_fail (SQL_IS_TARGET (self));
- g_free (obj->alias);
- obj->alias = g_strdup (alias);
+ g_free (self->alias);
+ self->alias = g_strdup (alias);
+}
+
+/**
+ * sql_target_get_alias:
+ * @self: the #SqlTargetClass
+ **/
+const gchar * sql_target_get_alias (SqlTarget * self)
+{
+ g_return_if_fail (SQL_IS_TARGET (self));
+
+ return self->alias;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@@ -44,43 +60,43 @@ enum
PROP_ALIAS = 1
};
-static void sql_target_set_property (SqlTarget * obj, guint id,
+static void sql_target_set_property (SqlTarget * self, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_ALIAS:
- sql_target_set_alias (obj, g_value_get_string (value));
+ sql_target_set_alias (self, g_value_get_string (value));
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
-static void sql_target_get_property (SqlTarget * obj, guint id,
+static void sql_target_get_property (SqlTarget * self, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_ALIAS:
- g_value_set_string (value, obj->alias);
+ g_value_set_string (value, self->alias);
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
-static void sql_target_init (SqlTarget * obj)
+static void sql_target_init (SqlTarget * self)
{
- obj->alias = NULL;
+ self->alias = NULL;
}
-static void sql_target_finalize (SqlTarget * obj)
+static void sql_target_finalize (SqlTarget * self)
{
- g_free (obj->alias);
- G_OBJECT_CLASS (sql_target_parent_class)->finalize (G_OBJECT (obj));
+ g_free (self->alias);
+ G_OBJECT_CLASS (sql_target_parent_class)->finalize (G_OBJECT (self));
}
static void sql_target_class_init (SqlTargetClass * k)
diff --git a/sql/sql-target.h b/sql/sql-target.h
index 43a20e4..bafd2b3 100644
--- a/sql/sql-target.h
+++ b/sql/sql-target.h
@@ -21,8 +21,8 @@
#include "sql-object.h"
#define SQL_TYPE_TARGET (sql_target_get_type ())
-#define SQL_TARGET(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_TARGET, SqlTarget))
-#define SQL_IS_TARGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_TARGET))
+#define SQL_TARGET(self) (G_TYPE_CHECK_INSTANCE_CAST (self, SQL_TYPE_TARGET, SqlTarget))
+#define SQL_IS_TARGET(self) (G_TYPE_CHECK_INSTANCE_TYPE (self, SQL_TYPE_TARGET))
typedef struct _SqlTarget SqlTarget;
typedef struct _SqlTargetClass SqlTargetClass;
@@ -39,7 +39,8 @@ struct _SqlTargetClass
SqlObjectClass parent;
};
-GType sql_target_get_type ();
-void sql_target_set_alias (SqlTarget * obj, const gchar * alias);
+GType sql_target_get_type ();
+void sql_target_set_alias (SqlTarget * self, const gchar * alias);
+const gchar * sql_target_get_alias (SqlTarget * self);
#endif
\ No newline at end of file