Primera version funcional

This commit is contained in:
Juan Ferrer Toribio 2014-05-27 09:55:01 +02:00
parent 030ccc8335
commit 02da9752e1
25 changed files with 603 additions and 684 deletions

View File

@ -143,6 +143,7 @@ typedef struct
{ {
DbModel * obj; DbModel * obj;
GQueue * operations; GQueue * operations;
SqlList * stmts;
} }
DbModelRequest; DbModelRequest;
@ -254,13 +255,6 @@ static void db_model_manage_join (DbModel * obj
,DbIter * iter ,DbIter * iter
,gint col); ,gint col);
static void db_model_post_process_query (DbModel * obj); static void db_model_post_process_query (DbModel * obj);
static void db_model_finish_insert (DbModel * obj
,DbRow * req_row, gint i
,DbRow * row, gint j
,DbIter * iter);
static gboolean db_model_table_row_all_null (DbModel * model
,DbRow * row
,gint col);
// Signal Handlers // Signal Handlers
@ -469,125 +463,112 @@ static void db_model_on_join_query_done (DbRequest * request, JoinData * join_da
static void db_model_on_stmt_changed (SqlStmt * stmt, DbModel * obj) static void db_model_on_stmt_changed (SqlStmt * stmt, DbModel * obj)
{ {
if (obj->priv->conn && obj->priv->stmt) db_model_refresh (obj);
{
if (sql_object_is_ready (SQL_OBJECT (obj->priv->stmt)))
db_model_refresh (obj);
else
{
db_model_clear (obj);
db_model_set_status (obj, DB_MODEL_STATUS_CLEAN);
}
}
} }
static void db_model_on_batch_changed (SqlBatch * batch, DbModel * obj) static void db_model_on_batch_changed (SqlBatch * batch, DbModel * obj)
{ {
db_model_on_stmt_changed (NULL, obj); db_model_refresh (obj);
}
static void db_model_process_insert (DbModel * obj, DbRequest * request, DbRow * row, GError * err)
{
gint i, j;
DbModelPrivate * priv = obj->priv;
DbResult * result;
DbRow * req_row;
DbIter iter;
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);
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))
{
GValue * v;
gboolean emit = TRUE;
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)
{
priv->updated_col = j;
g_signal_emit (obj, db_model_signal[LINE_UPDATED], 0, &iter);
}
}
}
if (result)
db_result_free (result);
} }
static void db_model_on_operations_done (DbRequest * request, DbModelRequest * data) static void db_model_on_operations_done (DbRequest * request, DbModelRequest * data)
{ {
guint i = 0;
DbOperation * op; DbOperation * op;
GError * err = NULL; GError * err = NULL;
DbModel * obj = data->obj; DbModel * obj = data->obj;
DbModelPrivate * priv = obj->priv; DbModelPrivate * priv = obj->priv;
obj->priv->pending_request = priv->pending_request =
g_slist_remove (priv->pending_request, request); g_slist_remove (priv->pending_request, request);
while (db_request_fetch_non_select (request, &err) != -1) while ((op = g_queue_pop_head (data->operations))
&& db_request_fetch_non_select (request, &err) != -1)
{ {
gint i, j; DbRow * row = op->row;
DbResult * result; db_request_fetch_non_select (request, &err);
DbRow * req_row, * row;
op = g_queue_pop_head (data->operations); g_hash_table_remove (priv->row_ops, row);
row = op->row;
g_hash_table_remove (priv->row_ops, op->row);
if (op->type & DB_MODEL_ROW_OP_DELETE) // DELETE if (op->type & DB_MODEL_ROW_OP_DELETE) // DELETE
{ {
g_signal_emit g_signal_emit (obj,
(obj, db_model_signal[LINE_DELETED], 0, DB_ROW_POSITION (row)); db_model_signal[LINE_DELETED], 0, DB_ROW_POSITION (row));
} }
else if (op->type & DB_MODEL_ROW_OP_INSERT) // INSERT else if (op->type & DB_MODEL_ROW_OP_INSERT) // INSERT + SELECT
{ // Catch the SELECT associated with each INSERT
result = db_request_fetch_result (request, &err);
if (result)
{
if (result->data && result->nrows > 0)
{
req_row = g_ptr_array_index (result->data, 0);
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, priv->main_table))
{
DbIter iter;
db_model_finish_insert (obj, req_row, i, row, j, &iter);
}
}
db_result_free (result);
}
}
else if (op->type & DB_MODEL_ROW_OP_UPDATE)// UPDATE
if (priv->join)
{ {
GSList * n; db_model_process_insert (obj, request, row, err);
DbUpdatedField * u; }
DbIter iter; else if (op->type & DB_MODEL_ROW_OP_UPDATE) // UPDATE || INSERT + SELECT
iter.stamp = priv->stamp; {
iter.data = row; guint j;
SqlList * list;
SqlObject * multi = sql_list_get (data->stmts, i);
g_object_get (multi, "stmts", &list, NULL);
for (n = op->updated; n; n = n->next) for (j = 0; j < sql_list_length (list); j++)
{ if (G_OBJECT_TYPE (sql_list_get (list, j)) == SQL_TYPE_MULTI_STMT)
u = n->data; db_model_process_insert (obj, request, row, err);
/* if (r->next && r->next->data
&& ((DbResult *) r->next->data)->column)*/
if (priv->column_default
&& gvn_value_is_null (u->value)
&& g_strcmp0 (priv->column[u->column].table, priv->main_table)
&& db_model_table_row_all_null (obj, row, u->column))
{ // INSERT + SELECT "update"
result = db_request_fetch_result (request, &err);
if (result)
{
if (result->data && result->nrows > 0)
{
req_row = g_ptr_array_index (result->data, 0);
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)
|| !result->column[i].table))
db_model_finish_insert (obj, req_row, i, row, j, &iter);
}
db_result_free (result);
}
}
/*
if (n->next && (u = ((DbUpdatedField *) n->next->data))
&& priv->column_default
&& gvn_value_is_null (u->value)
&& g_strcmp0 (priv->column[u->column].table, priv->main_table)
&& db_model_table_row_all_null (obj, row, u->column))
r = r->next;
*/
}
} }
db_model_free_operation (obj, op); db_model_free_operation (obj, op);
i++;
} }
//XXX Iterate both the result list and the queue at the same time //XXX Iterate both the result list and the queue at the same time
@ -654,6 +635,7 @@ static void db_model_request_free (DbModelRequest * req)
{ {
g_queue_free (req->operations); g_queue_free (req->operations);
g_object_unref (req->obj); g_object_unref (req->obj);
g_object_unref (req->stmts);
} }
g_free (req); g_free (req);
@ -1237,7 +1219,7 @@ static void db_model_manage_join (DbModel * obj, DbIter * iter, gint col)
if (!g_strcmp0 (priv->column[i].table, other_field->table)) if (!g_strcmp0 (priv->column[i].table, other_field->table))
{ {
sql_object_add_child (select, "exprs", sql_object_add_child (select, "exprs",
sql_field_new (priv->column[i].name, other_field->table, NULL)); sql_field_new_with_table (priv->column[i].name, other_field->table, NULL));
} }
else if (!g_strcmp0 (priv->column[i].table, main_field->table)) else if (!g_strcmp0 (priv->column[i].table, main_field->table))
{ {
@ -1248,7 +1230,7 @@ static void db_model_manage_join (DbModel * obj, DbIter * iter, gint col)
SqlObject * equal = sql_operation_new (SQL_OPERATION_TYPE_EQUAL); SqlObject * equal = sql_operation_new (SQL_OPERATION_TYPE_EQUAL);
sql_object_add_child (equal, "operators", sql_object_add_child (equal, "operators",
sql_field_new (g_ptr_array_index (other_field->name, j) sql_field_new_with_table (g_ptr_array_index (other_field->name, j)
,other_field->table, NULL)); ,other_field->table, NULL));
sql_object_add_child (equal, "operators", sql_object_add_child (equal, "operators",
@ -1286,40 +1268,6 @@ static void db_model_manage_join (DbModel * obj, DbIter * iter, gint col)
} }
} }
static void db_model_finish_insert (DbModel * obj,
DbRow * req_row, gint i, DbRow * row, gint j, DbIter * iter)
{
GValue * v;
gboolean emit = TRUE;
iter->stamp = obj->priv->stamp;
iter->data = row;
obj->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 (obj->priv->updated_value, G_VALUE_TYPE (v));
gvn_value_copy (v, obj->priv->updated_value);
}
else if (gvn_value_is_null (DB_ROW_FIELD (row, j)))
{
g_value_init (obj->priv->updated_value, GVN_TYPE_NULL);
}
else
{
emit = FALSE;
g_free (obj->priv->updated_value);
}
if (emit)
{
obj->priv->updated_col = j;
g_signal_emit (obj, db_model_signal[LINE_UPDATED], 0, iter);
}
}
static void db_model_clear (DbModel * obj) static void db_model_clear (DbModel * obj)
{ {
DbModelPrivate * priv = obj->priv; DbModelPrivate * priv = obj->priv;
@ -1351,40 +1299,6 @@ static void db_model_clear (DbModel * obj)
} }
} }
static gboolean db_model_table_row_all_null (DbModel * obj, DbRow * row, gint col)
{
DbUpdatedField * u;
GSList * n;
gboolean updated;
gint i;
for (i = 0; i < row->len; i++)
{
updated = FALSE;
if (!g_strcmp0 (obj->priv->column[col].table, obj->priv->column[i].table)
&& i != col)
{
DbOperation * operation = g_hash_table_lookup (obj->priv->row_ops, row);
if (operation)
for (n = operation->updated; n; n = n->next)
if ((u = (DbUpdatedField *) n->data) && u->column == i)
{
updated = TRUE;
if (!gvn_value_is_null (u->value))
return FALSE;
}
if (!updated && !gvn_value_is_null (DB_ROW_FIELD (row, i)))
return FALSE;
}
}
return TRUE;
}
// Memory allocate functions // Memory allocate functions
static void param_def_free (ParamDef * def) static void param_def_free (ParamDef * def)
@ -1427,12 +1341,17 @@ static void db_model_alloc_link_data (DbModel * obj)
if (!priv->internal_batch) if (!priv->internal_batch)
{ {
SqlList * operators;
priv->internal_batch = g_object_ref_sink (sql_batch_new ()); priv->internal_batch = g_object_ref_sink (sql_batch_new ());
g_signal_connect (priv->internal_batch, "changed", g_signal_connect (priv->internal_batch, "changed",
G_CALLBACK (db_model_on_batch_changed), obj); G_CALLBACK (db_model_on_batch_changed), obj);
priv->link_op = sql_operation_new (SQL_OPERATION_TYPE_AND); priv->link_op = sql_operation_new (SQL_OPERATION_TYPE_AND);
sql_batch_add (priv->internal_batch, "link", priv->link_op); 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);
} }
} }
@ -1780,7 +1699,7 @@ void db_model_set_default_value_from_column (DbModel * obj,
void db_model_set_default_value_from_param (DbModel * obj, void db_model_set_default_value_from_param (DbModel * obj,
const gchar * field, GvnParam * param, gboolean link) const gchar * field, GvnParam * param, gboolean link)
{ {
SqlObject * equal_op = NULL; SqlObject * equal = NULL;
g_return_if_fail (DB_IS_MODEL (obj)); g_return_if_fail (DB_IS_MODEL (obj));
g_return_if_fail (field); g_return_if_fail (field);
@ -1788,24 +1707,25 @@ void db_model_set_default_value_from_param (DbModel * obj,
if (link) if (link)
{ {
SqlObject * value; SqlList * operands, * link_operands;
db_model_alloc_link_data (obj); db_model_alloc_link_data (obj);
link_operands = sql_operation_get_operands (SQL_OPERATION (obj->priv->link_op));
equal_op = sql_operation_new (SQL_OPERATION_TYPE_EQUAL); equal = sql_operation_new (SQL_OPERATION_TYPE_EQUAL);
sql_object_add_child (obj->priv->link_op, "operators", equal_op); sql_list_add (link_operands, equal);
sql_object_add_child (equal_op, "operators", sql_field_new (field, NULL, NULL)); operands = sql_list_new (SQL_TYPE_EXPR);
sql_list_add (operands, sql_field_new (field));
value = sql_value_new (); sql_list_add (operands, sql_value_new_with_param (param));
sql_value_set_param (SQL_VALUE (value), param); sql_operation_set_operands (SQL_OPERATION (equal), operands);
sql_object_add_child (equal_op, "operators", value);
} }
ParamDef * def = g_new (ParamDef, 1); ParamDef * def = g_new (ParamDef, 1);
def->param = g_object_ref (param); def->param = g_object_ref (param);
def->link = link; def->link = link;
def->equal_op = equal_op; def->equal_op = equal;
def->obj = obj; def->obj = obj;
g_hash_table_insert (obj->priv->defaults, g_strdup (field), def); g_hash_table_insert (obj->priv->defaults, g_strdup (field), def);
g_hash_table_remove (obj->priv->column_default, field); g_hash_table_remove (obj->priv->column_default, field);
@ -2176,27 +2096,12 @@ gboolean db_model_insert (DbModel * obj, DbIter * iter)
for (i = 0; i < row->len; i++) for (i = 0; i < row->len; i++)
{ {
gchar * column = priv->column[i].name;
const GValue * def_value = NULL; const GValue * def_value = NULL;
ParamDef * def = g_hash_table_lookup (priv->defaults, column); ParamDef * def = g_hash_table_lookup (priv->defaults, priv->column[i].display);
if (def) if (def)
def_value = gvn_param_get_value (def->param); def_value = gvn_param_get_value (def->param);
if (!def_value)
{
gchar * column_def = g_hash_table_lookup (priv->column_default, column);
if (column_def)
{
gint col = db_model_get_column_index (obj, column_def);
if (col != -1
&& !g_strcmp0 (priv->column[col].table, priv->column[i].table))
def_value = &row->value[col];
}
}
if (!def_value) if (!def_value)
def_value = gvn_param_spec_get_default (priv->column[i].spec); def_value = gvn_param_spec_get_default (priv->column[i].spec);
@ -2431,17 +2336,20 @@ static SqlObject * db_model_create_where (DbModel * obj,
SqlObject * value; SqlObject * value;
DbRow * row = operation->row; DbRow * row = operation->row;
DbModelPrivate * priv = obj->priv; DbModelPrivate * priv = obj->priv;
SqlObject * where = sql_operation_new (SQL_OPERATION_TYPE_AND); SqlObject * where;
SqlList * and_operands;
where = sql_operation_new (SQL_OPERATION_TYPE_AND);
and_operands = sql_list_new (SQL_TYPE_EXPR);
sql_operation_set_operands (SQL_OPERATION (where), and_operands);
for (i = 0; i < row->len; i++) for (i = 0; i < row->len; i++)
if ((priv->column[i].info & DB_COLUMN_PRI_KEY) if ((priv->column[i].info & DB_COLUMN_PRI_KEY)
&& !g_strcmp0 (priv->column[i].table, table)) && !g_strcmp0 (priv->column[i].table, table))
{ {
SqlObject * equal = sql_operation_new (SQL_OPERATION_TYPE_EQUAL); SqlObject * equal;
sql_object_add_child (where, "operators", equal); SqlList * operands;
sql_object_add_child (equal, "operators",
sql_field_new (priv->column[i].name, NULL, NULL));
value = NULL; value = NULL;
@ -2464,14 +2372,20 @@ static SqlObject * db_model_create_where (DbModel * obj,
} }
else else
value = sql_value_new_with_value (g_value); value = sql_value_new_with_value (g_value);
if (!value) if (!value)
{ {
g_object_unref (g_object_ref_sink (where)); g_object_unref (g_object_ref_sink (where));
return NULL; return NULL;
} }
sql_object_add_child (equal, "operators", value); equal = sql_operation_new (SQL_OPERATION_TYPE_EQUAL);
sql_list_add (and_operands, equal);
operands = sql_list_new (SQL_TYPE_EXPR);
sql_list_add (operands, sql_field_new (priv->column[i].name));
sql_list_add (operands, value);
sql_operation_set_operands (SQL_OPERATION (equal), operands);
} }
return where; return where;
@ -2483,41 +2397,75 @@ static SqlObject * db_model_create_insert (DbModel * obj,
gint i; gint i;
DbModelPrivate * priv = obj->priv; DbModelPrivate * priv = obj->priv;
DbRow * row = operation->row; DbRow * row = operation->row;
SqlObject * target, * insert, * set, * select, * val, * stmts; GValue * value;
SqlList * targets, * stmts, * sets, * fields, * values, * exprs;
SqlObject * target, * insert, * set, * select;
SqlObject * where = db_model_create_where (obj, table, operation, TRUE); SqlObject * where = db_model_create_where (obj, table, operation, TRUE);
if (!where) if (!where)
return NULL; return NULL;
stmts = sql_multi_stmt_new ();
target = sql_table_new (table); target = sql_table_new (table);
fields = sql_list_new (SQL_TYPE_FIELD);
insert = g_object_new (SQL_TYPE_INSERT, "table", target, NULL); sets = sql_list_new (SQL_TYPE_SET);
set = g_object_new (SQL_TYPE_SET, NULL); values = sql_list_new (SQL_TYPE_EXPR);
sql_object_add_child (insert, "values", set); set = g_object_new (SQL_TYPE_SET
,"exprs", values
,NULL
);
sql_list_add (sets, set);
select = sql_select_new (); insert = g_object_new (SQL_TYPE_INSERT
sql_object_add_child (select, "targets", target); ,"table", target
sql_object_set (select, "where", where); ,"fields", fields
,"values", sets
,NULL
);
exprs = sql_list_new (SQL_TYPE_EXPR);
targets = sql_list_new (SQL_TYPE_TARGET);
sql_list_add (targets, target);
select = g_object_new (SQL_TYPE_SELECT
,"exprs", exprs
,"targets", targets
,"where", where
,NULL
);
for (i = 0; i < row->len; i++) for (i = 0; i < row->len; i++)
if (!g_strcmp0 (priv->column[i].table, table)) if (!g_strcmp0 (priv->column[i].table, table))
{ {
val = sql_value_new_with_value (&row->value[i]); if (gvn_value_is_null (&row->value[i]))
{
gchar * column_def = g_hash_table_lookup (priv->column_default,
priv->column[i].display);
gint col = db_model_get_column_index (obj, column_def);
if (col != -1)
value = &row->value[col];
else
value = NULL;
}
else
value = &row->value[i];
sql_object_add_child (insert, "fields", if (value)
sql_field_new (priv->column[i].name, NULL, NULL)); {
sql_object_add_child (set, "exprs", sql_list_add (fields, sql_field_new (priv->column[i].name));
gvn_value_is_null (&row->value[i]) ? NULL : val); sql_list_add (values, sql_value_new_with_value (value));
}
sql_object_add_child (select, "exprs", sql_list_add (exprs, sql_field_new (priv->column[i].name));
sql_field_new (priv->column[i].name,
priv->column[i].table, NULL));
} }
sql_object_add_child (stmts, "stmts", insert); stmts = sql_list_new (SQL_TYPE_STMT);
sql_object_add_child (stmts, "stmts", select); sql_list_add (stmts, insert);
return stmts; sql_list_add (stmts, select);
return g_object_new (SQL_TYPE_MULTI_STMT, "stmts", stmts, NULL);
} }
/** /**
@ -2562,6 +2510,8 @@ void db_model_perform_operations (DbModel * obj, gboolean retry)
while (!error && (op_elem = g_queue_pop_head (priv->operation))) while (!error && (op_elem = g_queue_pop_head (priv->operation)))
{ {
SqlObject * stmt = NULL;
op_elem->locked = TRUE; op_elem->locked = TRUE;
row = op_elem->row; row = op_elem->row;
@ -2576,32 +2526,31 @@ void db_model_perform_operations (DbModel * obj, gboolean retry)
} }
else if ((where = db_model_create_where (obj, priv->main_table, op_elem, FALSE))) else if ((where = db_model_create_where (obj, priv->main_table, op_elem, FALSE)))
{ {
SqlObject * delete = sql_delete_new (); SqlList * targets = sql_list_new (SQL_TYPE_TARGET);
sql_object_add_child (delete, "targets", sql_list_add (targets, sql_table_new (priv->main_table));
sql_table_new (priv->main_table));
sql_object_set (delete, "where", where); stmt = g_object_new (SQL_TYPE_DELETE
sql_list_add (stmts, delete); ,"where", where
,"targets", targets
,NULL
);
} }
else else
error = TRUE; error = TRUE;
} }
else if (op_elem->type & DB_MODEL_ROW_OP_INSERT) // INSERT else if (op_elem->type & DB_MODEL_ROW_OP_INSERT) // INSERT + SELECT
{ {
SqlObject * insert = db_model_create_insert (obj, priv->main_table, op_elem); stmt = db_model_create_insert (obj, priv->main_table, op_elem);
if (insert) if (!stmt)
sql_list_add (stmts, insert);
else
error = TRUE; error = TRUE;
} }
else if (op_elem->type & DB_MODEL_ROW_OP_UPDATE) // UPDATE else if (op_elem->type & DB_MODEL_ROW_OP_UPDATE) // UPDATE || INSERT + SELECT
{ {
// Depending on the field, generate an UPDATE or INSERT+SELECT
GSList * l; GSList * l;
GHashTableIter iter; GHashTableIter iter;
gpointer table; gpointer table;
SqlList * update_list;
GHashTable * tables = g_hash_table_new ( GHashTable * tables = g_hash_table_new (
g_str_hash, g_str_equal); g_str_hash, g_str_equal);
@ -2612,6 +2561,7 @@ void db_model_perform_operations (DbModel * obj, gboolean retry)
g_hash_table_add (tables, priv->column[u->column].table); g_hash_table_add (tables, priv->column[u->column].table);
} }
update_list = sql_list_new (SQL_TYPE_STMT);
g_hash_table_iter_init (&iter, tables); g_hash_table_iter_init (&iter, tables);
while (g_hash_table_iter_next (&iter, &table, NULL)) while (g_hash_table_iter_next (&iter, &table, NULL))
@ -2621,49 +2571,57 @@ void db_model_perform_operations (DbModel * obj, gboolean retry)
if (where) if (where)
{ {
DbUpdatedField * u; DbUpdatedField * u;
SqlObject * update = g_object_new (SQL_TYPE_UPDATE, SqlList * sets = sql_list_new (SQL_TYPE_UPDATE_SET);
"where", where, NULL); SqlList * targets = sql_list_new (SQL_TYPE_TARGET);
sql_object_add_child (update, "targets", sql_list_add (targets, sql_table_new (table));
sql_table_new (table));
for (l = op_elem->updated; l && (u = l->data); l = l->next) for (l = op_elem->updated; l && (u = l->data); l = l->next)
if (!g_strcmp0 (priv->column[u->column].table, table)) if (!g_strcmp0 (priv->column[u->column].table, table))
{ {
GValue * new_value = DB_ROW_FIELD (row, u->column); GValue * new_value = DB_ROW_FIELD (row, u->column);
sql_object_add_child (update, "sets", sql_list_add (sets, g_object_new (SQL_TYPE_UPDATE_SET
g_object_new (SQL_TYPE_UPDATE_SET, ,"field", sql_field_new (priv->column[u->column].name)
"field", sql_field_new (priv->column[u->column].name, NULL, NULL), ,"expr", sql_value_new_with_value (new_value)
"expr", sql_value_new_with_value (new_value), ,NULL
NULL)); ));
} }
sql_list_add (stmts, update); sql_list_add (update_list, g_object_new (SQL_TYPE_UPDATE
,"where", where
,"targets", targets
,"sets", sets
,NULL
));
} }
else else
{ {
SqlObject * insert = db_model_create_insert (obj, table, op_elem); SqlObject * insert = db_model_create_insert (obj, table, op_elem);
if (insert) if (insert)
sql_list_add (stmts, insert); sql_list_add (update_list, insert);
} }
} }
g_hash_table_destroy (tables); g_hash_table_destroy (tables);
stmt = g_object_new (SQL_TYPE_MULTI_STMT, "stmts", update_list, NULL);
} }
g_queue_push_tail (req_ops, op_elem); if (stmt)
sql_list_add (stmts, stmt);
if (op_elem)
g_queue_push_tail (req_ops, op_elem);
} }
if (sql_list_length (stmts) > 0) if (sql_list_length (stmts) > 0)
{ {
SqlObject * multi = g_object_new (SQL_TYPE_MULTI_STMT, SqlObject * multi = g_object_new (SQL_TYPE_MULTI_STMT, "stmts", stmts, NULL);
"stmts", stmts, NULL);
DbModelRequest * data = g_new (DbModelRequest, 1); DbModelRequest * data = g_new (DbModelRequest, 1);
data->obj = g_object_ref (obj); data->obj = g_object_ref (obj);
data->operations = req_ops; data->operations = req_ops;
data->stmts = g_object_ref_sink (stmts);
request = db_conn_query_with_stmt_async (priv->conn request = db_conn_query_with_stmt_async (priv->conn
,SQL_STMT (multi) ,SQL_STMT (multi)
@ -2693,19 +2651,33 @@ void db_model_refresh (DbModel * obj)
DbModelPrivate * priv; DbModelPrivate * priv;
g_return_if_fail (DB_IS_MODEL (obj)); g_return_if_fail (DB_IS_MODEL (obj));
priv = obj->priv; priv = obj->priv;
g_return_if_fail (priv->stmt);
db_model_clear (obj); db_model_clear (obj);
db_model_set_status (obj, DB_MODEL_STATUS_LOADING);
if (priv->conn
priv->request = db_conn_query_with_stmt_async (priv->conn && priv->stmt && sql_object_is_ready (SQL_OBJECT (priv->stmt))
,priv->stmt && (!priv->batch || sql_batch_is_ready (priv->batch))
,priv->batch && (!priv->internal_batch || sql_batch_is_ready (priv->internal_batch)))
,(DbRequestDoneCallback) db_model_on_data_ready {
,g_object_ref (obj) SqlBatch * tmp_batch = sql_batch_new ();
,(GDestroyNotify) g_object_unref sql_batch_merge (tmp_batch, priv->batch);
); sql_batch_merge (tmp_batch, priv->internal_batch);
db_model_set_status (obj, DB_MODEL_STATUS_LOADING);
priv->request = db_conn_query_with_stmt_async (priv->conn
,priv->stmt
,tmp_batch
,(DbRequestDoneCallback) db_model_on_data_ready
,g_object_ref (obj)
,(GDestroyNotify) g_object_unref
);
g_object_unref (g_object_ref_sink (tmp_batch));
}
else
db_model_set_status (obj, DB_MODEL_STATUS_CLEAN);
} }
/** /**

View File

@ -75,11 +75,15 @@ DbRequest * db_request_new (DbConn * conn, const gchar * sql)
**/ **/
DbRequest * db_request_new_with_stmt (DbConn * conn, SqlStmt * stmt, SqlBatch * batch) DbRequest * db_request_new_with_stmt (DbConn * conn, SqlStmt * stmt, SqlBatch * batch)
{ {
DbRequest * obj;
g_return_val_if_fail (DB_IS_CONN (conn), NULL); g_return_val_if_fail (DB_IS_CONN (conn), NULL);
g_return_val_if_fail (SQL_IS_STMT (stmt), NULL); g_return_val_if_fail (SQL_IS_STMT (stmt), NULL);
g_return_val_if_fail (SQL_IS_BATCH (batch) || !batch, NULL); g_return_val_if_fail (SQL_IS_BATCH (batch) || !batch, NULL);
return g_object_new (DB_TYPE_REQUEST, "conn", conn, "batch", batch, "stmt", stmt, NULL); obj = g_object_new (DB_TYPE_REQUEST, "conn", conn, NULL);
obj->sql = db_conn_render (conn, stmt, batch, NULL);
return obj;
} }
/** /**
@ -352,8 +356,6 @@ typedef enum
{ {
PROP_CONN = 1 PROP_CONN = 1
,PROP_SQL ,PROP_SQL
,PROP_STMT
,PROP_BATCH
,PROP_RESULT_SET ,PROP_RESULT_SET
,PROP_ERROR ,PROP_ERROR
} }
@ -370,27 +372,7 @@ static void db_request_set_property (DbRequest * obj, guint property_id,
obj->conn = g_value_dup_object (value); obj->conn = g_value_dup_object (value);
break; break;
case PROP_SQL: case PROP_SQL:
{ obj->sql = g_value_dup_string (value);
gchar * sql = g_value_dup_string (value);
if (sql)
obj->sql = sql;
break;
}
case PROP_STMT:
{
SqlStmt * stmt = g_value_get_object (value);
if (obj->conn && stmt)
obj->sql = db_conn_render (obj->conn, stmt, obj->batch, NULL);
else if (!obj->conn)
g_warning ("DbRequest: Can't render stmt, conn property not set");
break;
}
case PROP_BATCH:
obj->batch = g_value_dup_object (value);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
@ -468,20 +450,6 @@ static void db_request_class_init (DbRequestClass * k)
,NULL ,NULL
,G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE ,G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE
)); ));
g_object_class_install_property (klass, PROP_STMT,
g_param_spec_object ("stmt"
,_("Statement")
,_("The statement to execute")
,SQL_TYPE_STMT
,G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE
));
g_object_class_install_property (klass, PROP_BATCH,
g_param_spec_object ("batch"
,_("Batch")
,_("The batch for render the statement")
,SQL_TYPE_BATCH
,G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE
));
g_object_class_install_property (klass, PROP_RESULT_SET, g_object_class_install_property (klass, PROP_RESULT_SET,
g_param_spec_boxed ("result-set" g_param_spec_boxed ("result-set"
,_("Result") ,_("Result")

View File

@ -60,7 +60,6 @@ struct _DbRequest
/* <private> */ /* <private> */
DbConn * conn; DbConn * conn;
SqlBatch * batch;
gchar * sql; gchar * sql;
DbResultSet * result_set; DbResultSet * result_set;
GError * error; GError * error;

View File

@ -72,6 +72,7 @@ struct _DbColumn
DbColumnInfo info; DbColumnInfo info;
GvnParamSpec * spec; GvnParamSpec * spec;
gchar * table; gchar * table;
gchar * table_alias;
gchar * name; gchar * name;
gchar * display; gchar * display;
}; };

View File

@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.2 -->
<interface> <interface>
<!-- interface-requires gtk+ 3.0 --> <requires lib="gtk+" version="3.0"/>
<!-- interface-requires vn 0.0 --> <requires lib="vn" version="0.0"/>
<!-- interface-local-resource-path ../image --> <!-- interface-local-resource-path ../image -->
<object class="DbIterator" id="homes"> <object class="DbIterator" id="homes">
<property name="sql">SELECT id, street, pc, city, province, ok FROM user_address WHERE #p ORDER BY id</property> <property name="sql">SELECT id, street, pc, city, province, ok FROM user_address WHERE #link ORDER BY id</property>
</object> </object>
<object class="DbIterator" id="info"> <object class="DbIterator" id="info">
<property name="sql">SELECT id, name, credit, active, born, photo, object_id FROM "user" ORDER BY id</property> <property name="sql">SELECT id, name, credit, active, born, photo, object_id FROM "user" ORDER BY id</property>
@ -49,8 +50,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -63,8 +62,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -77,8 +74,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -91,8 +86,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">2</property> <property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -105,8 +98,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">3</property> <property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -119,8 +110,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">4</property> <property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -133,8 +122,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">5</property> <property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -147,8 +134,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -161,8 +146,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">2</property> <property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -176,8 +159,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">4</property> <property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -190,8 +171,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">5</property> <property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -204,8 +183,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">3</property> <property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
</object> </object>

View File

@ -1,42 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.2 -->
<interface> <interface>
<!-- interface-requires vn 0.0 --> <requires lib="gtk+" version="3.0"/>
<!-- interface-requires gtk+ 3.0 --> <requires lib="vn" version="0.0"/>
<object class="DbIterator" id="account"> <object class="DbIterator" id="account">
<property name="mode">on-iter</property> <property name="mode">on-iter</property>
<property name="sql">SELECT user_id, group_id, uid, last_change, expire FROM account WHERE #p</property> <property name="sql">SELECT user_id, group_id, uid, last_change, expire FROM account WHERE #link</property>
</object> </object>
<object class="DbIterator" id="alias"> <object class="DbIterator" id="alias">
<property name="sql">SELECT mail_alias_id, user_id FROM mail_alias_account WHERE #p</property> <property name="sql">SELECT mail_alias_id, user_id FROM mail_alias_account WHERE #link</property>
</object> </object>
<object class="GtkBox" id="main"> <object class="GtkDialog" id="password-dialog">
<property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="border_width">6</property> <property name="border_width">5</property>
<property name="orientation">vertical</property> <property name="title" translatable="yes">Change password</property>
<property name="spacing">6</property> <property name="resizable">False</property>
<child> <property name="modal">True</property>
<object class="GtkFrame" id="frame1"> <property name="destroy_with_parent">True</property>
<property name="visible">True</property> <property name="type_hint">dialog</property>
<signal name="delete-event" handler="gtk_true" swapped="no"/>
<signal name="response" handler="vn_users_on_dialog_response" swapped="no"/>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox2">
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label_xalign">0</property> <property name="orientation">vertical</property>
<property name="shadow_type">none</property> <property name="spacing">2</property>
<child> <child>
<object class="GtkAlignment" id="alignment1"> <object class="GtkInfoBar" id="password-infobar">
<property name="visible">True</property> <property name="app_paintable">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="left_padding">30</property> <child internal-child="action_area">
<child> <object class="GtkButtonBox" id="infobar-action_area1">
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="spacing">6</property> <property name="border_width">5</property>
<property name="orientation">vertical</property>
<property name="layout_style">end</property>
<child> <child>
<object class="GtkLabel" id="label2"> <placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child internal-child="content_area">
<object class="GtkBox" id="infobar-content_area1">
<property name="can_focus">False</property>
<property name="border_width">8</property>
<property name="spacing">8</property>
<child>
<object class="GtkLabel" id="password-error">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">User name:</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -44,37 +61,117 @@
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child>
<object class="VnEntry" id="entry-search">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="param">search-user</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object> </object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child type="label"> <child>
<object class="GtkLabel" id="label1"> <object class="GtkGrid" id="grid6">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Search&lt;/b&gt;</property> <property name="border_width">6</property>
<property name="use_markup">True</property> <property name="row_spacing">6</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="label23">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Password:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label22">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Repeat password:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="password-entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="repeat-password">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area2">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child> </child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
</object>
<object class="DbParam" id="search-user"/>
<object class="DbIterator" id="sip">
<property name="mode">on-iter</property>
<property name="sql">SELECT user_id, extension, secret, callerid FROM account_sip WHERE #link</property>
</object>
<object class="DbIterator" id="users">
<property name="sql">SELECT u.id, u.name, u.mysql_user_id, m.user, u.active FROM `user` u JOIN mysql_user m ON u.mysql_user_id = m.id</property>
</object>
<object class="GtkBox" id="main">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child> <child>
<object class="GtkScrolledWindow" id="scrolledwindow1"> <object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property> <property name="visible">True</property>
@ -168,8 +265,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -182,8 +277,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">2</property> <property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -196,8 +289,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">3</property> <property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -210,8 +301,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">4</property> <property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -224,8 +313,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">4</property> <property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -239,8 +326,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -255,8 +340,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -269,8 +352,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -284,8 +365,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">3</property> <property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -295,15 +374,12 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="clicked" handler="vn_users_on_set_password_clicked" swapped="no"/> <signal name="clicked" handler="vn_users_on_set_password_clicked" swapped="no"/>
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">2</property> <property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
</object> </object>
@ -351,8 +427,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -366,8 +440,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -381,8 +453,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -395,8 +465,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -409,8 +477,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">2</property> <property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -423,8 +489,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">3</property> <property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -437,8 +501,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">2</property> <property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -451,8 +513,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">3</property> <property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
</object> </object>
@ -590,8 +650,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -604,8 +662,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -618,22 +674,6 @@
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">2</property> <property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label18">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Call group:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -647,8 +687,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -661,8 +699,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -675,22 +711,6 @@
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">2</property> <property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="VnSpin" id="spin3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="iterator">sip</property>
<property name="column_name">callgroup</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing> </packing>
</child> </child>
</object> </object>
@ -740,170 +760,4 @@
</packing> </packing>
</child> </child>
</object> </object>
<object class="GtkDialog" id="password-dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Change password</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
<signal name="delete-event" handler="gtk_true" swapped="no"/>
<signal name="response" handler="vn_users_on_dialog_response" swapped="no"/>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox2">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkInfoBar" id="password-infobar">
<property name="app_paintable">True</property>
<property name="can_focus">False</property>
<child internal-child="content_area">
<object class="GtkBox" id="infobar-content_area1">
<property name="can_focus">False</property>
<property name="border_width">8</property>
<property name="spacing">8</property>
<child>
<object class="GtkLabel" id="password-error">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkButtonBox" id="infobar-action_area1">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="orientation">vertical</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="grid6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="row_spacing">6</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="label23">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Password:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label22">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Repeat password:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="password-entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="repeat-password">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area2">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
<object class="DbParam" id="search-user"/>
<object class="DbIterator" id="sip">
<property name="mode">on-iter</property>
<property name="sql">SELECT user_id, extension, secret, callerid, callgroup FROM account_sip WHERE #p</property>
</object>
<object class="DbIterator" id="users">
<property name="sql">SELECT u.id, u.name, u.mysql_user_id, m.user, u.active FROM `user` u JOIN mysql_user m ON u.mysql_user_id = m.id</property>
</object>
</interface> </interface>

View File

@ -228,6 +228,7 @@ static DbResultSet * db_mysql_query (DbMysql * obj, const gchar * sql, GError **
column->name = g_strdup (field[i].org_name); column->name = g_strdup (field[i].org_name);
column->display = g_strdup (field[i].name); column->display = g_strdup (field[i].name);
column->table = g_strdup (field[i].org_table); column->table = g_strdup (field[i].org_table);
column->table_alias = g_strdup (field[i].table);
switch (field[i].type) switch (field[i].type)
{ {

View File

@ -709,8 +709,10 @@ static DbResultSet * __db_pg_query
GValue * v = g_new0 (GValue, 1); GValue * v = g_new0 (GValue, 1);
gchar ** split = g_strsplit_set (pg_val, "(':)", G_MAXINT8); gchar ** split = g_strsplit_set (pg_val, "(':)", G_MAXINT8);
SqlObject * function = sql_function_new ("currval", NULL); SqlObject * function = sql_function_new ("currval", NULL);
SqlList * params = sql_list_new (SQL_TYPE_EXPR);
g_value_set_string (g_value_init (v, G_TYPE_STRING), split[2]); g_value_set_string (g_value_init (v, G_TYPE_STRING), split[2]);
sql_object_add_child (function, "params", sql_value_new_with_value (v)); sql_list_add (params, sql_value_new_with_value (v));
g_object_set (function, "params", params, NULL);
g_value_unset (v); g_value_unset (v);
g_free (v); g_free (v);
g_value_take_object (g_value_init (&def[j], SQL_TYPE_FUNCTION), g_value_take_object (g_value_init (&def[j], SQL_TYPE_FUNCTION),

View File

@ -386,7 +386,7 @@ join(A) ::= target(left) join_type(type) target(right) join_cond(condition).
SQL_TABLE (right)->schema : NULL; SQL_TABLE (right)->schema : NULL;
sql_list_add (equal, sql_list_add (equal,
sql_field_new (SQL_FIELD (n->data)->name, target, schema)); sql_field_new_with_table (SQL_FIELD (n->data)->name, target, schema));
sql_list_add (exprs, op); sql_list_add (exprs, op);
} }

View File

@ -41,11 +41,18 @@ SqlBatch * sql_batch_new ()
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_batch_child_changed (SqlBatch * child, SqlBatch * obj) static void sql_batch_child_changed (SqlObject * child, SqlBatch * obj)
{ {
sql_batch_changed (obj); sql_batch_changed (obj);
} }
static void sql_batch_free_child (SqlBatch * obj, SqlObject * child)
{
g_signal_handlers_disconnect_by_func (child,
sql_batch_child_changed, obj);
g_object_unref (child);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
/** /**
@ -120,15 +127,14 @@ void sql_batch_add (SqlBatch * obj, const gchar * id, SqlObject * object)
); );
g_signal_connect (object, "changed", g_signal_connect (object, "changed",
G_CALLBACK (sql_batch_child_changed), obj G_CALLBACK (sql_batch_child_changed), obj);
);
g_hash_table_replace (obj->items, g_hash_table_replace (obj->items,
g_strdup (id), g_object_ref_sink (object)); g_strdup (id), g_object_ref_sink (object));
} }
/** /**
* sql_batch_add_from_param: * sql_batch_add_from_param:
* @obj: the #SqlString * @obj: a #SqlBatch
* @id: the id assigned to the item * @id: the id assigned to the item
**/ **/
void sql_batch_add_from_param (SqlBatch * obj, const gchar * id, GvnParam * param) void sql_batch_add_from_param (SqlBatch * obj, const gchar * id, GvnParam * param)
@ -145,7 +151,7 @@ void sql_batch_add_from_param (SqlBatch * obj, const gchar * id, GvnParam * para
/** /**
* sql_batch_add_from_value: * sql_batch_add_from_value:
* @obj: the #SqlString * @obj: a #SqlBatch
* @id: the id assigned to the item * @id: the id assigned to the item
**/ **/
void sql_batch_add_from_value (SqlBatch * obj, const gchar * id, GType type, gpointer content) void sql_batch_add_from_value (SqlBatch * obj, const gchar * id, GType type, gpointer content)
@ -166,6 +172,7 @@ void sql_batch_add_from_value (SqlBatch * obj, const gchar * id, GType type, gpo
/** /**
* sql_batch_remove: * sql_batch_remove:
* @obj: a #SqlBatch
* @id: the id of the #SqlHolder * @id: the id of the #SqlHolder
* *
* Removes a held object from the batch. * Removes a held object from the batch.
@ -175,17 +182,39 @@ void sql_batch_remove (SqlBatch * obj, const gchar * id)
g_return_val_if_fail (SQL_IS_BATCH (obj), NULL); g_return_val_if_fail (SQL_IS_BATCH (obj), NULL);
g_return_val_if_fail (id, NULL); g_return_val_if_fail (id, NULL);
SqlObject * object = sql_batch_get (obj, id); SqlObject * child = sql_batch_get (obj, id);
if (object) if (child)
{ {
g_signal_handlers_disconnect_by_func (object, sql_batch_free_child (obj, child);
sql_batch_child_changed, obj);
g_object_unref (object);
g_hash_table_remove (obj->items, id); g_hash_table_remove (obj->items, id);
} }
} }
/**
* sql_batch_merge:
* @obj: a #SqlBatch
* @batch: a #SqlBatch
*
* Meges the batch with another batch.
**/
void sql_batch_merge (SqlBatch * obj, SqlBatch * batch)
{
GHashTableIter iter;
gpointer key, value;
g_return_if_fail (SQL_IS_BATCH (obj));
g_return_if_fail (SQL_IS_BATCH (batch) || !batch);
if (!batch)
return;
g_hash_table_iter_init (&iter, batch->items);
while (g_hash_table_iter_next (&iter, &key, &value))
sql_batch_add (obj, key, value);
}
/** /**
* sql_batch_changed: * sql_batch_changed:
* @obj: a #SqlBatch * @obj: a #SqlBatch
@ -194,6 +223,8 @@ void sql_batch_remove (SqlBatch * obj, const gchar * id)
**/ **/
void sql_batch_changed (SqlBatch * obj) void sql_batch_changed (SqlBatch * obj)
{ {
g_return_if_fail (SQL_IS_BATCH (obj));
g_signal_emit (obj, signals[CHANGED], 0); g_signal_emit (obj, signals[CHANGED], 0);
} }
@ -207,7 +238,17 @@ static void sql_batch_init (SqlBatch * obj)
static void sql_batch_finalize (SqlBatch * obj) static void sql_batch_finalize (SqlBatch * obj)
{ {
if (obj->items) if (obj->items)
{
GHashTableIter iter;
gpointer child;
g_hash_table_iter_init (&iter, obj->items);
while (g_hash_table_iter_next (&iter, NULL, &child))
sql_batch_free_child (obj, child);
g_hash_table_destroy (obj->items); g_hash_table_destroy (obj->items);
}
G_OBJECT_CLASS (sql_batch_parent_class)->finalize (G_OBJECT (obj)); G_OBJECT_CLASS (sql_batch_parent_class)->finalize (G_OBJECT (obj));
} }

View File

@ -51,6 +51,7 @@ void sql_batch_add (SqlBatch * obj, const gchar * id, SqlObject * object);
void sql_batch_add_from_param (SqlBatch * obj, const gchar * id, GvnParam * param); void sql_batch_add_from_param (SqlBatch * obj, const gchar * id, GvnParam * param);
void sql_batch_add_from_value (SqlBatch * obj, const gchar * id, GType type, gpointer content); void sql_batch_add_from_value (SqlBatch * obj, const gchar * id, GType type, gpointer content);
void sql_batch_remove (SqlBatch * obj, const gchar * id); void sql_batch_remove (SqlBatch * obj, const gchar * id);
void sql_batch_merge (SqlBatch * obj, SqlBatch * batch);
void sql_batch_changed (SqlBatch * obj); void sql_batch_changed (SqlBatch * obj);
#endif #endif

View File

@ -29,6 +29,22 @@ G_DEFINE_TYPE (SqlField, sql_field, SQL_TYPE_EXPR);
/** /**
* sql_field_new: * sql_field_new:
* @name: the name of the field * @name: the name of the field
*
* Creates a new #SqlField.
*
* Return value: an #SqlExpr
*/
SqlObject * sql_field_new (const gchar * name)
{
return g_object_new (SQL_TYPE_FIELD
,"name", name
,NULL
);
}
/**
* sql_field_new_with_table:
* @name: the name of the field
* @target: (allow-none): the table from which the field is selected * @target: (allow-none): the table from which the field is selected
* @schema: (allow-none): the schema from which the table and field are selected * @schema: (allow-none): the schema from which the table and field are selected
* *
@ -36,7 +52,7 @@ G_DEFINE_TYPE (SqlField, sql_field, SQL_TYPE_EXPR);
* *
* Return value: an #SqlExpr * Return value: an #SqlExpr
*/ */
SqlObject * sql_field_new (const gchar * name, const gchar * target, const gchar * schema) SqlObject * sql_field_new_with_table (const gchar * name, const gchar * target, const gchar * schema)
{ {
return g_object_new (SQL_TYPE_FIELD return g_object_new (SQL_TYPE_FIELD
,"name", name ,"name", name

View File

@ -42,10 +42,11 @@ struct _SqlFieldClass
SqlExprClass parent; SqlExprClass parent;
}; };
GType sql_field_get_type (); GType sql_field_get_type ();
SqlObject * sql_field_new (const gchar * name SqlObject * sql_field_new (const gchar * name);
,const gchar * target SqlObject * sql_field_new_with_table (const gchar * name
,const gchar * schema); ,const gchar * target
void sql_field_set_name (SqlField * obj, const gchar * name); ,const gchar * schema);
void sql_field_set_name (SqlField * obj, const gchar * name);
#endif #endif

View File

@ -107,7 +107,7 @@ static void sql_holder_init (SqlHolder * obj)
static void sql_holder_finalize (SqlHolder * obj) static void sql_holder_finalize (SqlHolder * obj)
{ {
g_free (obj->id); g_free (obj->id);
G_OBJECT_CLASS (sql_holder_finalize)->finalize (G_OBJECT (obj)); G_OBJECT_CLASS (sql_holder_parent_class)->finalize (G_OBJECT (obj));
} }
static void sql_holder_class_init (SqlHolderClass * k) static void sql_holder_class_init (SqlHolderClass * k)

View File

@ -30,6 +30,20 @@ SqlList * sql_list_new (GType gtype)
return g_object_new (SQL_TYPE_LIST, "gtype", gtype, NULL); return g_object_new (SQL_TYPE_LIST, "gtype", gtype, NULL);
} }
SqlList * sql_list_new_with_items (GType gtype, ...)
{
va_list vl;
SqlObject * item;
SqlList * obj = g_object_new (SQL_TYPE_LIST, "gtype", gtype, NULL);
va_start (vl, gtype);
while ((item = va_arg (vl, SqlObject *)))
sql_list_add (obj, item);
return obj;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_list_render (SqlList * obj, SqlRender * render) static void sql_list_render (SqlList * obj, SqlRender * render)
@ -268,7 +282,7 @@ static void sql_list_finalize (SqlList * obj)
} }
g_queue_clear (&obj->items); g_queue_clear (&obj->items);
G_OBJECT_CLASS (sql_list_finalize)->finalize (G_OBJECT (obj)); G_OBJECT_CLASS (sql_list_parent_class)->finalize (G_OBJECT (obj));
} }
static void sql_list_class_init (SqlListClass * k) static void sql_list_class_init (SqlListClass * k)
@ -293,6 +307,6 @@ static void sql_list_class_init (SqlListClass * k)
,_("GType") ,_("GType")
,_("The allowed type for the items") ,_("The allowed type for the items")
,SQL_TYPE_OBJECT ,SQL_TYPE_OBJECT
,G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY ,G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
)); ));
} }

View File

@ -42,6 +42,7 @@ struct _SqlListClass
GType sql_list_get_type (); GType sql_list_get_type ();
SqlList * sql_list_new (GType gtype); SqlList * sql_list_new (GType gtype);
SqlList * sql_list_new_with_items (GType gtype, ...);
void sql_list_add (SqlList * obj, gpointer item); void sql_list_add (SqlList * obj, gpointer item);
void sql_list_insert (SqlList * obj, gpointer item, guint index); void sql_list_insert (SqlList * obj, gpointer item, guint index);
gpointer sql_list_get (SqlList * obj, guint index); gpointer sql_list_get (SqlList * obj, guint index);

View File

@ -215,6 +215,8 @@ void sql_object_get_holders (SqlObject * obj, GQueue * holders)
**/ **/
void sql_object_changed (SqlObject * obj) void sql_object_changed (SqlObject * obj)
{ {
g_return_if_fail (SQL_IS_OBJECT (obj));
g_signal_emit (obj, signals[CHANGED], 0); g_signal_emit (obj, signals[CHANGED], 0);
} }

View File

@ -31,7 +31,7 @@ G_DEFINE_TYPE (SqlOperation, sql_operation, SQL_TYPE_EXPR);
SqlObject * sql_operation_new (SqlOperationType type) SqlObject * sql_operation_new (SqlOperationType type)
{ {
return g_object_new (SQL_TYPE_OPERATION, "type", type, NULL); return g_object_new (SQL_TYPE_OPERATION, "operator", type, NULL);
} }
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
@ -61,67 +61,120 @@ static const gchar * SQL_OPERATION_TYPE[] =
,"IN" ,"IN"
}; };
static void sql_operation_render (SqlOperation * obj, SqlRender * render) static void sql_operation_render (SqlOperation * self, SqlRender * render)
{ {
sql_render_add_espace (render); sql_render_add_espace (render);
sql_render_append (render, "("); sql_render_append (render, "(");
sql_render_add_list (render, TRUE, NULL, obj->operators, sql_render_add_list (render, TRUE, NULL, self->operands,
SQL_OPERATION_TYPE[obj->type]); SQL_OPERATION_TYPE[self->type]);
sql_render_append (render, ")"); sql_render_append (render, ")");
} }
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
/**
* sql_operation_get_operator:
* @self: a #SqlOperation
*
* Return value: the operation type
**/
SqlOperationType sql_operation_get_operator (SqlOperation * self)
{
g_return_val_if_fail (SQL_IS_OPERATION (self), 0);
return self->type;
}
/**
* sql_operation_set_operand:
* @self: a #SqlOperation
* @type: the operation type
**/
void sql_operation_set_operator (SqlOperation * self, SqlOperationType type)
{
g_return_if_fail (SQL_IS_OPERATION (self));
self->type = type;
}
/**
* sql_operation_get_operands:
* @self: a #SqlOperation
*
* Return value: (allow-none) (transfer full): a #SqlList
**/
SqlList * sql_operation_get_operands (SqlOperation * self)
{
g_return_val_if_fail (SQL_IS_OPERATION (self), NULL);
return self->operands;
}
/**
* sql_operation_set_operands:
* @self: a #SqlOperation
* @operators: (allow-none): a #SqlList
**/
void sql_operation_set_operands (SqlOperation * self, SqlList * operands)
{
g_return_if_fail (SQL_IS_OPERATION (self));
g_return_if_fail (SQL_IS_LIST (operands) || !operands);
sql_object_remove (self, self->operands);
self->operands = sql_object_add (self, operands);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum enum
{ {
PROP_TYPE = 1 PROP_TYPE = 1
,PROP_OPERATORS ,PROP_OPERANDS
}; };
static void sql_operation_set_property (SqlOperation * obj, guint id, static void sql_operation_set_property (SqlOperation * self, guint id,
const GValue * value, GParamSpec * pspec) const GValue * value, GParamSpec * pspec)
{ {
switch (id) switch (id)
{ {
case PROP_TYPE: case PROP_TYPE:
obj->type = g_value_get_enum (value); self->type = g_value_get_enum (value);
break; break;
case PROP_OPERATORS: case PROP_OPERANDS:
sql_object_remove (obj, obj->operators); sql_operation_set_operands (self, g_value_get_object (value));
obj->operators = sql_object_add (obj, g_value_get_object (value));
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
} }
} }
static void sql_operation_get_property (SqlOperation * obj, guint id, static void sql_operation_get_property (SqlOperation * self, guint id,
GValue * value, GParamSpec * pspec) GValue * value, GParamSpec * pspec)
{ {
switch (id) switch (id)
{ {
case PROP_TYPE: case PROP_TYPE:
g_value_set_enum (value, obj->type); g_value_set_enum (value, self->type);
break; break;
case PROP_OPERATORS: case PROP_OPERANDS:
g_value_set_object (value, obj->operators); g_value_set_object (value, self->operands);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
} }
} }
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_operation_init (SqlOperation * obj) static void sql_operation_init (SqlOperation * self)
{ {
obj->operators = NULL; self->operands = NULL;
} }
static void sql_operation_finalize (SqlOperation * obj) static void sql_operation_finalize (SqlOperation * self)
{ {
sql_object_remove (obj, obj->operators); sql_object_remove (self, self->operands);
G_OBJECT_CLASS (sql_operation_parent_class)->finalize (G_OBJECT (obj)); G_OBJECT_CLASS (sql_operation_parent_class)->finalize (G_OBJECT (self));
} }
static void sql_operation_class_init (SqlOperationClass * klass) static void sql_operation_class_init (SqlOperationClass * klass)
@ -133,17 +186,17 @@ static void sql_operation_class_init (SqlOperationClass * klass)
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_operation_render; SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_operation_render;
g_object_class_install_property (k, PROP_TYPE, g_object_class_install_property (k, PROP_TYPE,
g_param_spec_enum ("type" g_param_spec_enum ("operator"
,("Type") ,("Type")
,("The type of the operation") ,("The type of the operation")
,SQL_TYPE_OPERATION_TYPE ,SQL_TYPE_OPERATION_TYPE
,SQL_OPERATION_TYPE_AND ,SQL_OPERATION_TYPE_AND
,G_PARAM_READWRITE ,G_PARAM_READWRITE
)); ));
g_object_class_install_property (k, PROP_OPERATORS, g_object_class_install_property (k, PROP_OPERANDS,
sql_param_list ("operators" sql_param_list ("operands"
,("Operators") ,("Operators")
,("The list of operators") ,("The list of operands")
,SQL_TYPE_EXPR ,SQL_TYPE_EXPR
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT ,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
)); ));

View File

@ -66,7 +66,7 @@ SqlOperationType;
struct _SqlOperation struct _SqlOperation
{ {
SqlExpr parent; SqlExpr parent;
SqlList * operators; // List of SqlExpr SqlList * operands; // List of SqlExpr
SqlOperationType type; SqlOperationType type;
}; };
@ -76,9 +76,13 @@ struct _SqlOperationClass
SqlExprClass parent; SqlExprClass parent;
}; };
GType sql_operation_get_type (); GType sql_operation_get_type ();
GType sql_operation_type_get_type (); GType sql_operation_type_get_type ();
SqlObject * sql_operation_new (SqlOperationType type); SqlObject * sql_operation_new (SqlOperationType type);
SqlList * sql_operation_get_operands (SqlOperation * self);
void sql_operation_set_operands (SqlOperation * self, SqlList * operands);
SqlOperationType sql_operation_get_operator (SqlOperation * self);
void sql_operation_set_operator (SqlOperation * self, SqlOperationType type);
#endif #endif

View File

@ -34,7 +34,6 @@ sql_param_list (const gchar * name, const gchar * nick,
); );
pspec->items_type = items_type; pspec->items_type = items_type;
G_PARAM_SPEC (pspec)->value_type = SQL_TYPE_LIST;
return G_PARAM_SPEC (pspec); return G_PARAM_SPEC (pspec);
} }
@ -56,7 +55,7 @@ sql_param_list_validate (GParamSpec * pspec, GValue * value)
gpointer object = g_value_get_object (value); gpointer object = g_value_get_object (value);
if (!object) if (!object)
return TRUE; return FALSE;
type = G_OBJECT_TYPE (object); type = G_OBJECT_TYPE (object);

View File

@ -32,8 +32,6 @@ sql_param_object (const gchar * name, const gchar * nick,
,blurb ,blurb
,flags ,flags
); );
pspec->value_type = object_type;
return pspec; return pspec;
} }
@ -54,7 +52,7 @@ sql_param_object_validate (GParamSpec * pspec, GValue * value)
GObject * object = g_value_get_object (value); GObject * object = g_value_get_object (value);
if (!object) if (!object)
return TRUE; return FALSE;
type = G_OBJECT_TYPE (object); type = G_OBJECT_TYPE (object);

View File

@ -145,7 +145,7 @@ void sql_render_add_object (SqlRender * obj, gpointer object)
function = g_hash_table_lookup (obj->custom_renderers, function = g_hash_table_lookup (obj->custom_renderers,
GUINT_TO_POINTER (G_OBJECT_TYPE (object))); GUINT_TO_POINTER (G_OBJECT_TYPE (object)));
obj->ancestors = g_slist_prepend (obj->ancestors, object); obj->ancestors = g_slist_prepend (obj->ancestors, object);
if (function) if (function)
function (object, obj, obj->batch); function (object, obj, obj->batch);
else else

View File

@ -33,9 +33,15 @@ SqlObject * sql_value_new ()
return g_object_new (SQL_TYPE_VALUE, NULL); return g_object_new (SQL_TYPE_VALUE, NULL);
} }
SqlObject * sql_value_new_with_param (GvnParam * param)
{
g_return_val_if_fail (GVN_IS_PARAM (param), NULL);
return g_object_new (SQL_TYPE_VALUE, "param", param, NULL);
}
SqlObject * sql_value_new_with_value (const GValue * value) SqlObject * sql_value_new_with_value (const GValue * value)
{ {
g_return_val_if_fail (value, NULL);
g_return_val_if_fail (G_IS_VALUE (value), NULL); g_return_val_if_fail (G_IS_VALUE (value), NULL);
return g_object_new (SQL_TYPE_VALUE, "value", value, NULL); return g_object_new (SQL_TYPE_VALUE, "value", value, NULL);
@ -159,6 +165,13 @@ void sql_value_set_param (SqlValue * obj, GvnParam * param)
} }
} }
GvnParam * sql_value_get_param (SqlValue * self)
{
g_return_if_fail (SQL_IS_VALUE (self));
return self->param;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum enum

View File

@ -44,8 +44,10 @@ struct _SqlValueClass
GType sql_value_get_type (); GType sql_value_get_type ();
SqlObject * sql_value_new (); SqlObject * sql_value_new ();
SqlObject * sql_value_new_with_value (const GValue * value); SqlObject * sql_value_new_with_value (const GValue * value);
SqlObject * sql_value_new_with_param (GvnParam * param);
const GValue * sql_value_get_value (SqlValue * obj); const GValue * sql_value_get_value (SqlValue * obj);
void sql_value_set_value (SqlValue * obj, const GValue * value); void sql_value_set_value (SqlValue * obj, const GValue * value);
GvnParam * sql_value_get_param (SqlValue * self);
void sql_value_set_param (SqlValue * obj, GvnParam * param); void sql_value_set_param (SqlValue * obj, GvnParam * param);
#endif #endif

View File

@ -187,27 +187,27 @@ static void vn_completion_create_model (VnCompletion * obj)
{ {
SqlObject * field; SqlObject * field;
SqlObject * stmt; SqlObject * stmt;
SqlObject * op; SqlObject * like;
SqlBatch * batch; SqlBatch * batch;
SqlList * ops; SqlList * operands;
if (!(obj->sql && obj->field)) if (!(obj->sql && obj->field))
return; return;
op = sql_operation_new (SQL_OPERATION_TYPE_LIKE); like = sql_operation_new (SQL_OPERATION_TYPE_LIKE);
ops = sql_list_new (SQL_TYPE_EXPR); operands = sql_list_new (SQL_TYPE_EXPR);
g_object_set (op, "operators", ops, NULL); g_object_set (like, "operands", operands, NULL);
field = sql_field_new (obj->field, NULL, NULL); field = sql_field_new (obj->field);
sql_list_add (ops, field); sql_list_add (operands, field);
obj->value = sql_value_new (); obj->value = sql_value_new ();
sql_list_add (ops, obj->value); sql_list_add (operands, obj->value);
batch = sql_batch_new (); batch = sql_batch_new ();
sql_batch_add (batch, "field", field); sql_batch_add (batch, "field", field);
sql_batch_add (batch, "filter", op); sql_batch_add (batch, "filter", like);
db_model_set_batch (obj->model, batch); db_model_set_batch (obj->model, batch);
stmt = sql_string_new (obj->sql); stmt = sql_string_new (obj->sql);