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;
GQueue * operations;
SqlList * stmts;
}
DbModelRequest;
@ -254,13 +255,6 @@ static void db_model_manage_join (DbModel * obj
,DbIter * iter
,gint col);
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
@ -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)
{
if (obj->priv->conn && obj->priv->stmt)
{
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);
}
}
db_model_refresh (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)
{
guint i = 0;
DbOperation * op;
GError * err = NULL;
DbModel * obj = data->obj;
DbModelPrivate * priv = obj->priv;
obj->priv->pending_request =
priv->pending_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;
DbResult * result;
DbRow * req_row, * row;
DbRow * row = op->row;
db_request_fetch_non_select (request, &err);
op = g_queue_pop_head (data->operations);
row = op->row;
g_hash_table_remove (priv->row_ops, op->row);
g_hash_table_remove (priv->row_ops, row);
if (op->type & DB_MODEL_ROW_OP_DELETE) // DELETE
{
g_signal_emit
(obj, db_model_signal[LINE_DELETED], 0, DB_ROW_POSITION (row));
g_signal_emit (obj,
db_model_signal[LINE_DELETED], 0, DB_ROW_POSITION (row));
}
else if (op->type & DB_MODEL_ROW_OP_INSERT) // INSERT
{ // 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)
else if (op->type & DB_MODEL_ROW_OP_INSERT) // INSERT + SELECT
{
GSList * n;
DbUpdatedField * u;
DbIter iter;
iter.stamp = priv->stamp;
iter.data = row;
db_model_process_insert (obj, request, row, err);
}
else if (op->type & DB_MODEL_ROW_OP_UPDATE) // UPDATE || INSERT + SELECT
{
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)
{
u = n->data;
/* 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;
*/
}
for (j = 0; j < sql_list_length (list); j++)
if (G_OBJECT_TYPE (sql_list_get (list, j)) == SQL_TYPE_MULTI_STMT)
db_model_process_insert (obj, request, row, err);
}
db_model_free_operation (obj, op);
i++;
}
//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_object_unref (req->obj);
g_object_unref (req->stmts);
}
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))
{
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))
{
@ -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);
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));
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)
{
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
static void param_def_free (ParamDef * def)
@ -1427,12 +1341,17 @@ static void db_model_alloc_link_data (DbModel * obj)
if (!priv->internal_batch)
{
SqlList * operators;
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);
}
}
@ -1780,7 +1699,7 @@ void db_model_set_default_value_from_column (DbModel * obj,
void db_model_set_default_value_from_param (DbModel * obj,
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 (field);
@ -1788,24 +1707,25 @@ void db_model_set_default_value_from_param (DbModel * obj,
if (link)
{
SqlObject * value;
SqlList * operands, * link_operands;
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);
sql_object_add_child (obj->priv->link_op, "operators", equal_op);
sql_object_add_child (equal_op, "operators", sql_field_new (field, NULL, NULL));
value = sql_value_new ();
sql_value_set_param (SQL_VALUE (value), param);
sql_object_add_child (equal_op, "operators", value);
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 (field));
sql_list_add (operands, sql_value_new_with_param (param));
sql_operation_set_operands (SQL_OPERATION (equal), operands);
}
ParamDef * def = g_new (ParamDef, 1);
def->param = g_object_ref (param);
def->link = link;
def->equal_op = equal_op;
def->equal_op = equal;
def->obj = obj;
g_hash_table_insert (obj->priv->defaults, g_strdup (field), def);
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++)
{
gchar * column = priv->column[i].name;
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)
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)
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;
DbRow * row = operation->row;
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++)
if ((priv->column[i].info & DB_COLUMN_PRI_KEY)
&& !g_strcmp0 (priv->column[i].table, table))
{
SqlObject * equal = sql_operation_new (SQL_OPERATION_TYPE_EQUAL);
sql_object_add_child (where, "operators", equal);
sql_object_add_child (equal, "operators",
sql_field_new (priv->column[i].name, NULL, NULL));
SqlObject * equal;
SqlList * operands;
value = NULL;
@ -2464,14 +2372,20 @@ static SqlObject * db_model_create_where (DbModel * obj,
}
else
value = sql_value_new_with_value (g_value);
if (!value)
{
g_object_unref (g_object_ref_sink (where));
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;
@ -2483,41 +2397,75 @@ static SqlObject * db_model_create_insert (DbModel * obj,
gint i;
DbModelPrivate * priv = obj->priv;
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);
if (!where)
return NULL;
stmts = sql_multi_stmt_new ();
target = sql_table_new (table);
fields = sql_list_new (SQL_TYPE_FIELD);
insert = g_object_new (SQL_TYPE_INSERT, "table", target, NULL);
set = g_object_new (SQL_TYPE_SET, NULL);
sql_object_add_child (insert, "values", set);
sets = sql_list_new (SQL_TYPE_SET);
values = sql_list_new (SQL_TYPE_EXPR);
set = g_object_new (SQL_TYPE_SET
,"exprs", values
,NULL
);
sql_list_add (sets, set);
select = sql_select_new ();
sql_object_add_child (select, "targets", target);
sql_object_set (select, "where", where);
insert = g_object_new (SQL_TYPE_INSERT
,"table", target
,"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++)
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",
sql_field_new (priv->column[i].name, NULL, NULL));
sql_object_add_child (set, "exprs",
gvn_value_is_null (&row->value[i]) ? NULL : val);
if (value)
{
sql_list_add (fields, sql_field_new (priv->column[i].name));
sql_list_add (values, sql_value_new_with_value (value));
}
sql_object_add_child (select, "exprs",
sql_field_new (priv->column[i].name,
priv->column[i].table, NULL));
sql_list_add (exprs, sql_field_new (priv->column[i].name));
}
sql_object_add_child (stmts, "stmts", insert);
sql_object_add_child (stmts, "stmts", select);
return stmts;
stmts = sql_list_new (SQL_TYPE_STMT);
sql_list_add (stmts, insert);
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)))
{
SqlObject * stmt = NULL;
op_elem->locked = TRUE;
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)))
{
SqlObject * delete = sql_delete_new ();
sql_object_add_child (delete, "targets",
sql_table_new (priv->main_table));
SqlList * targets = sql_list_new (SQL_TYPE_TARGET);
sql_list_add (targets, sql_table_new (priv->main_table));
sql_object_set (delete, "where", where);
sql_list_add (stmts, delete);
stmt = g_object_new (SQL_TYPE_DELETE
,"where", where
,"targets", targets
,NULL
);
}
else
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)
sql_list_add (stmts, insert);
else
if (!stmt)
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;
GHashTableIter iter;
gpointer table;
SqlList * update_list;
GHashTable * tables = g_hash_table_new (
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);
}
update_list = sql_list_new (SQL_TYPE_STMT);
g_hash_table_iter_init (&iter, tables);
while (g_hash_table_iter_next (&iter, &table, NULL))
@ -2621,49 +2571,57 @@ void db_model_perform_operations (DbModel * obj, gboolean retry)
if (where)
{
DbUpdatedField * u;
SqlObject * update = g_object_new (SQL_TYPE_UPDATE,
"where", where, NULL);
SqlList * sets = sql_list_new (SQL_TYPE_UPDATE_SET);
SqlList * targets = sql_list_new (SQL_TYPE_TARGET);
sql_object_add_child (update, "targets",
sql_table_new (table));
sql_list_add (targets, sql_table_new (table));
for (l = op_elem->updated; l && (u = l->data); l = l->next)
if (!g_strcmp0 (priv->column[u->column].table, table))
{
GValue * new_value = DB_ROW_FIELD (row, u->column);
sql_object_add_child (update, "sets",
g_object_new (SQL_TYPE_UPDATE_SET,
"field", sql_field_new (priv->column[u->column].name, NULL, NULL),
"expr", sql_value_new_with_value (new_value),
NULL));
sql_list_add (sets, g_object_new (SQL_TYPE_UPDATE_SET
,"field", sql_field_new (priv->column[u->column].name)
,"expr", sql_value_new_with_value (new_value)
,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
{
SqlObject * insert = db_model_create_insert (obj, table, op_elem);
if (insert)
sql_list_add (stmts, insert);
sql_list_add (update_list, insert);
}
}
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)
{
SqlObject * multi = g_object_new (SQL_TYPE_MULTI_STMT,
"stmts", stmts, NULL);
SqlObject * multi = g_object_new (SQL_TYPE_MULTI_STMT, "stmts", stmts, NULL);
DbModelRequest * data = g_new (DbModelRequest, 1);
data->obj = g_object_ref (obj);
data->operations = req_ops;
data->stmts = g_object_ref_sink (stmts);
request = db_conn_query_with_stmt_async (priv->conn
,SQL_STMT (multi)
@ -2693,19 +2651,33 @@ void db_model_refresh (DbModel * obj)
DbModelPrivate * priv;
g_return_if_fail (DB_IS_MODEL (obj));
priv = obj->priv;
g_return_if_fail (priv->stmt);
db_model_clear (obj);
db_model_set_status (obj, DB_MODEL_STATUS_LOADING);
priv->request = db_conn_query_with_stmt_async (priv->conn
,priv->stmt
,priv->batch
,(DbRequestDoneCallback) db_model_on_data_ready
,g_object_ref (obj)
,(GDestroyNotify) g_object_unref
);
if (priv->conn
&& priv->stmt && sql_object_is_ready (SQL_OBJECT (priv->stmt))
&& (!priv->batch || sql_batch_is_ready (priv->batch))
&& (!priv->internal_batch || sql_batch_is_ready (priv->internal_batch)))
{
SqlBatch * tmp_batch = sql_batch_new ();
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 * obj;
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_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_SQL
,PROP_STMT
,PROP_BATCH
,PROP_RESULT_SET
,PROP_ERROR
}
@ -370,27 +372,7 @@ static void db_request_set_property (DbRequest * obj, guint property_id,
obj->conn = g_value_dup_object (value);
break;
case PROP_SQL:
{
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);
obj->sql = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
@ -468,20 +450,6 @@ static void db_request_class_init (DbRequestClass * k)
,NULL
,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_param_spec_boxed ("result-set"
,_("Result")

View File

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

View File

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

View File

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

View File

@ -1,42 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.2 -->
<interface>
<!-- interface-requires vn 0.0 -->
<!-- interface-requires gtk+ 3.0 -->
<requires lib="gtk+" version="3.0"/>
<requires lib="vn" version="0.0"/>
<object class="DbIterator" id="account">
<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 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 class="GtkBox" id="main">
<property name="visible">True</property>
<object class="GtkDialog" id="password-dialog">
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkFrame" id="frame1">
<property name="visible">True</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="label_xalign">0</property>
<property name="shadow_type">none</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<object class="GtkInfoBar" id="password-infobar">
<property name="app_paintable">True</property>
<property name="can_focus">False</property>
<property name="left_padding">30</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="infobar-action_area1">
<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>
<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="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">User name:</property>
</object>
<packing>
<property name="expand">False</property>
@ -44,37 +61,117 @@
<property name="position">0</property>
</packing>
</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>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child type="label">
<object class="GtkLabel" id="label1">
<child>
<object class="GtkGrid" id="grid6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Search&lt;/b&gt;</property>
<property name="use_markup">True</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>
</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>
<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>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</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>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
@ -168,8 +265,6 @@
<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>
@ -182,8 +277,6 @@
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
@ -196,8 +289,6 @@
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
@ -210,8 +301,6 @@
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
@ -224,8 +313,6 @@
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
@ -239,8 +326,6 @@
<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>
@ -255,8 +340,6 @@
<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>
@ -269,8 +352,6 @@
<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>
<child>
@ -284,8 +365,6 @@
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
@ -295,15 +374,12 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="vn_users_on_set_password_clicked" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
@ -351,8 +427,6 @@
<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>
<child>
@ -366,8 +440,6 @@
<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>
@ -381,8 +453,6 @@
<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>
@ -395,8 +465,6 @@
<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>
@ -409,8 +477,6 @@
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
@ -423,8 +489,6 @@
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
@ -437,8 +501,6 @@
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
@ -451,8 +513,6 @@
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
@ -590,8 +650,6 @@
<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>
@ -604,8 +662,6 @@
<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>
@ -618,22 +674,6 @@
<packing>
<property name="left_attach">0</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>
</child>
<child>
@ -647,8 +687,6 @@
<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>
@ -661,8 +699,6 @@
<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>
<child>
@ -675,22 +711,6 @@
<packing>
<property name="left_attach">1</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>
</child>
</object>
@ -740,170 +760,4 @@
</packing>
</child>
</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>

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->display = g_strdup (field[i].name);
column->table = g_strdup (field[i].org_table);
column->table_alias = g_strdup (field[i].table);
switch (field[i].type)
{

View File

@ -709,8 +709,10 @@ static DbResultSet * __db_pg_query
GValue * v = g_new0 (GValue, 1);
gchar ** split = g_strsplit_set (pg_val, "(':)", G_MAXINT8);
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]);
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_free (v);
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_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);
}

View File

@ -41,11 +41,18 @@ SqlBatch * sql_batch_new ()
//+++++++++++++++++++++++++++++++++++++++++++++++++++ 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);
}
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
/**
@ -120,15 +127,14 @@ void sql_batch_add (SqlBatch * obj, const gchar * id, SqlObject * object)
);
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_strdup (id), g_object_ref_sink (object));
}
/**
* sql_batch_add_from_param:
* @obj: the #SqlString
* @obj: a #SqlBatch
* @id: the id assigned to the item
**/
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:
* @obj: the #SqlString
* @obj: a #SqlBatch
* @id: the id assigned to the item
**/
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:
* @obj: a #SqlBatch
* @id: the id of the #SqlHolder
*
* 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 (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_child_changed, obj);
g_object_unref (object);
sql_batch_free_child (obj, child);
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:
* @obj: a #SqlBatch
@ -194,6 +223,8 @@ void sql_batch_remove (SqlBatch * obj, const gchar * id)
**/
void sql_batch_changed (SqlBatch * obj)
{
g_return_if_fail (SQL_IS_BATCH (obj));
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)
{
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_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_value (SqlBatch * obj, const gchar * id, GType type, gpointer content);
void sql_batch_remove (SqlBatch * obj, const gchar * id);
void sql_batch_merge (SqlBatch * obj, SqlBatch * batch);
void sql_batch_changed (SqlBatch * obj);
#endif

View File

@ -29,6 +29,22 @@ G_DEFINE_TYPE (SqlField, sql_field, SQL_TYPE_EXPR);
/**
* sql_field_new:
* @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
* @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
*/
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
,"name", name

View File

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

View File

@ -107,7 +107,7 @@ static void sql_holder_init (SqlHolder * obj)
static void sql_holder_finalize (SqlHolder * obj)
{
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)

View File

@ -30,6 +30,20 @@ SqlList * sql_list_new (GType gtype)
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
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_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)
@ -293,6 +307,6 @@ static void sql_list_class_init (SqlListClass * k)
,_("GType")
,_("The allowed type for the items")
,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 ();
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_insert (SqlList * obj, gpointer item, 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)
{
g_return_if_fail (SQL_IS_OBJECT (obj));
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)
{
return g_object_new (SQL_TYPE_OPERATION, "type", type, NULL);
return g_object_new (SQL_TYPE_OPERATION, "operator", type, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
@ -61,67 +61,120 @@ static const gchar * SQL_OPERATION_TYPE[] =
,"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_append (render, "(");
sql_render_add_list (render, TRUE, NULL, obj->operators,
SQL_OPERATION_TYPE[obj->type]);
sql_render_add_list (render, TRUE, NULL, self->operands,
SQL_OPERATION_TYPE[self->type]);
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
enum
{
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)
{
switch (id)
{
case PROP_TYPE:
obj->type = g_value_get_enum (value);
self->type = g_value_get_enum (value);
break;
case PROP_OPERATORS:
sql_object_remove (obj, obj->operators);
obj->operators = sql_object_add (obj, g_value_get_object (value));
case PROP_OPERANDS:
sql_operation_set_operands (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_operation_get_property (SqlOperation * obj, guint id,
static void sql_operation_get_property (SqlOperation * self, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_TYPE:
g_value_set_enum (value, obj->type);
g_value_set_enum (value, self->type);
break;
case PROP_OPERATORS:
g_value_set_object (value, obj->operators);
case PROP_OPERANDS:
g_value_set_object (value, self->operands);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ 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);
G_OBJECT_CLASS (sql_operation_parent_class)->finalize (G_OBJECT (obj));
sql_object_remove (self, self->operands);
G_OBJECT_CLASS (sql_operation_parent_class)->finalize (G_OBJECT (self));
}
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;
g_object_class_install_property (k, PROP_TYPE,
g_param_spec_enum ("type"
g_param_spec_enum ("operator"
,("Type")
,("The type of the operation")
,SQL_TYPE_OPERATION_TYPE
,SQL_OPERATION_TYPE_AND
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_OPERATORS,
sql_param_list ("operators"
g_object_class_install_property (k, PROP_OPERANDS,
sql_param_list ("operands"
,("Operators")
,("The list of operators")
,("The list of operands")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));

View File

@ -66,7 +66,7 @@ SqlOperationType;
struct _SqlOperation
{
SqlExpr parent;
SqlList * operators; // List of SqlExpr
SqlList * operands; // List of SqlExpr
SqlOperationType type;
};
@ -76,9 +76,13 @@ struct _SqlOperationClass
SqlExprClass parent;
};
GType sql_operation_get_type ();
GType sql_operation_type_get_type ();
GType sql_operation_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

View File

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

View File

@ -32,8 +32,6 @@ sql_param_object (const gchar * name, const gchar * nick,
,blurb
,flags
);
pspec->value_type = object_type;
return pspec;
}
@ -54,7 +52,7 @@ sql_param_object_validate (GParamSpec * pspec, GValue * value)
GObject * object = g_value_get_object (value);
if (!object)
return TRUE;
return FALSE;
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,
GUINT_TO_POINTER (G_OBJECT_TYPE (object)));
obj->ancestors = g_slist_prepend (obj->ancestors, object);
if (function)
function (object, obj, obj->batch);
else

View File

@ -33,9 +33,15 @@ SqlObject * sql_value_new ()
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)
{
g_return_val_if_fail (value, NULL);
g_return_val_if_fail (G_IS_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
enum

View File

@ -44,8 +44,10 @@ struct _SqlValueClass
GType sql_value_get_type ();
SqlObject * sql_value_new ();
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);
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);
#endif

View File

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