Merge de sql-holder con la rama principal

This commit is contained in:
Alejandro T. Colombini Gómez 2014-06-20 15:46:39 +02:00
commit e31183a233
97 changed files with 6167 additions and 3989 deletions

View File

@ -574,13 +574,16 @@ DbResultSet * db_conn_exec (DbConn * obj, const gchar * sql, GError ** err)
*
* Return value: (transfer full): the new #DbRequest
**/
DbRequest * db_conn_query (DbConn * obj, const gchar * sql)
DbRequest * db_conn_query (DbConn * obj, const gchar * sql, SqlBatch * batch)
{
SqlObject * string;
DbRequest * request;
g_return_val_if_fail (DB_IS_CONN (obj), NULL);
request = db_request_new (obj, sql);
string = sql_string_new (sql);
request = db_request_new_with_stmt (obj, SQL_STMT (string), batch);
db_request_exec (request, NULL);
return request;
}
@ -594,13 +597,13 @@ DbRequest * db_conn_query (DbConn * obj, const gchar * sql)
*
* Return value: (transfer full): the new #DbRequest
**/
DbRequest * db_conn_query_with_stmt (DbConn * obj, SqlStmt * stmt)
DbRequest * db_conn_query_with_stmt (DbConn * obj, SqlStmt * stmt, SqlBatch * batch)
{
DbRequest * request;
g_return_val_if_fail (DB_IS_CONN (obj), NULL);
request = db_request_new_with_stmt (obj, stmt);
request = db_request_new_with_stmt (obj, stmt, batch);
db_request_exec (request, NULL);
return request;
}
@ -615,14 +618,17 @@ DbRequest * db_conn_query_with_stmt (DbConn * obj, SqlStmt * stmt)
*
* Return value: (transfer full): the new #DbRequest
**/
DbRequest * db_conn_query_async (DbConn * obj, const gchar * sql,
DbRequest * db_conn_query_async (DbConn * obj, const gchar * sql, SqlBatch * batch,
DbRequestDoneCallback callback, gpointer user_data, GDestroyNotify notify)
{
SqlObject * string;
DbRequest * request;
g_return_val_if_fail (DB_IS_CONN (obj), NULL);
request = db_request_new (obj, sql);
string = sql_string_new (sql);
request = db_request_new_with_stmt (obj, SQL_STMT (string), batch);
db_request_set_callback (request, callback, user_data, notify);
db_conn_add_request (obj, request);
return request;
@ -638,14 +644,14 @@ DbRequest * db_conn_query_async (DbConn * obj, const gchar * sql,
*
* Return value: (transfer full): the new #DbRequest
**/
DbRequest * db_conn_query_with_stmt_async (DbConn * obj, SqlStmt * stmt,
DbRequest * db_conn_query_with_stmt_async (DbConn * obj, SqlStmt * stmt, SqlBatch * batch,
DbRequestDoneCallback callback, gpointer user_data, GDestroyNotify notify)
{
DbRequest * request;
g_return_val_if_fail (DB_IS_CONN (obj), NULL);
request = db_request_new_with_stmt (obj, stmt);
request = db_request_new_with_stmt (obj, stmt, batch);
db_request_set_callback (request, callback, user_data, notify);
db_conn_add_request (obj, request);
return request;
@ -662,14 +668,14 @@ DbRequest * db_conn_query_with_stmt_async (DbConn * obj, SqlStmt * stmt,
*
* Return value: %TRUE on success, %FALSE on failure
**/
gboolean db_conn_query_value (DbConn * obj, const gchar * sql, GValue * value, GError ** err)
gboolean db_conn_query_value (DbConn * obj, const gchar * sql, SqlBatch * batch, GValue * value, GError ** err)
{
gboolean success;
DbRequest * request;
g_return_val_if_fail (DB_IS_CONN (obj), FALSE);
request = db_conn_query (obj, sql);
request = db_conn_query (obj, sql, batch);
success = db_request_fetch_value (request, value, err);
g_object_unref (request);
@ -728,12 +734,13 @@ SqlStmt * db_conn_parse (DbConn * obj, gchar * sql)
*
* Return value: (transfer full): the rendered string, or %NULL if error.
**/
gchar * db_conn_render (DbConn * obj, gpointer object, GError ** err)
gchar * db_conn_render (DbConn * obj, gpointer object, SqlBatch * batch, GError ** err)
{
g_return_val_if_fail (DB_IS_CONN (obj), NULL);
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
g_return_val_if_fail (SQL_IS_BATCH (batch) || !batch, NULL);
return db_plugin_render (obj->plugin, object, err);
return db_plugin_render (obj->plugin, object, batch, err);
}
/**
@ -884,11 +891,11 @@ gchar * db_conn_get_schema (DbConn * obj)
*
* Return value: (transfer full): an #SqlString
**/
SqlString * db_conn_create_stmt_from_file (DbConn * obj, const gchar * query_file)
SqlObject * db_conn_create_stmt_from_file (DbConn * obj, const gchar * query_file)
{
gint i;
gchar * file;
SqlString * stmt = NULL;
SqlObject * stmt = NULL;
g_return_val_if_fail (DB_IS_CONN (obj), NULL);
g_return_val_if_fail (query_file, NULL);

View File

@ -119,27 +119,29 @@ gboolean db_conn_reconnect (DbConn * obj, GError ** err);
DbResultSet * db_conn_exec (DbConn * obj, const gchar * sql, GError ** err);
DbRequest * db_conn_query (DbConn * obj, const gchar * sql);
DbRequest * db_conn_query (DbConn * obj, const gchar * sql, SqlBatch * batch);
DbRequest * db_conn_query_async (DbConn * obj
,const gchar * sql
,SqlBatch * batch
,DbRequestDoneCallback callback
,gpointer user_data
,GDestroyNotify notify);
DbRequest * db_conn_query_with_stmt (DbConn * obj, SqlStmt * stmt);
DbRequest * db_conn_query_with_stmt (DbConn * obj, SqlStmt * stmt, SqlBatch * batch);
DbRequest * db_conn_query_with_stmt_async (DbConn * obj
,SqlStmt * stmt
,SqlBatch * batch
,DbRequestDoneCallback callback
,gpointer user_data
,GDestroyNotify notify);
gboolean db_conn_query_value (DbConn * obj, const gchar * sql, GValue * value, GError ** err);
gboolean db_conn_query_value (DbConn * obj, const gchar * sql, SqlBatch * batch, GValue * value, GError ** err);
void db_conn_retry (DbConn * obj);
void db_conn_kill_query (DbConn * obj);
SqlStmt * db_conn_parse (DbConn * obj, gchar * sql);
gchar * db_conn_render (DbConn * obj, gpointer object, GError ** err);
gchar * db_conn_render (DbConn * obj, gpointer object, SqlBatch * batch, GError ** err);
guchar * db_conn_escape_binary (DbConn * obj, const guchar * from, gsize from_size, gsize * to_size);
void db_conn_start_transaction (DbConn * obj);
@ -150,6 +152,6 @@ gchar * db_conn_get_user (DbConn * obj);
gchar * db_conn_get_host (DbConn * obj);
gchar * db_conn_get_schema (DbConn * obj);
SqlString * db_conn_create_stmt_from_file (DbConn * obj, const gchar * query_file);
SqlObject * db_conn_create_stmt_from_file (DbConn * obj, const gchar * query_file);
#endif

View File

@ -793,7 +793,7 @@ void db_iterator_link_with_param (DbIterator * obj, const gchar * field, GvnPara
g_return_if_fail (obj->model);
g_return_if_fail (field);
db_model_set_default_value_from_param (obj->model, field, param);
db_model_set_default_value_from_param (obj->model, field, param, TRUE);
}
/**

View File

@ -29,7 +29,7 @@ typedef struct _DbModelHolder DbModelHolder;
typedef struct _DbModelHolderInterface DbModelHolderInterface;
typedef DbModel * (* DbModelHolderGetModelFunc) (DbModelHolder * obj);
typedef void (* DbModelHolderSetModelFunc) (DbModelHolder * obj, DbModel * sql);
typedef void (* DbModelHolderSetModelFunc) (DbModelHolder * obj, DbModel * model);
struct _DbModelHolder;

227
db/db-model-private.c Normal file
View File

@ -0,0 +1,227 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This file is part of Hedera.
*
* Hedera is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define remove_delimiters(str) (g_strdup (g_strstrip (g_strdelimit (str, "`\"", ' '))))
/*
* DbUpdatedField:
* @column: the position of the field in the row
* @value: the old value of the updated field
*
* Previous value of an updated field.
**/
typedef struct
{
gint column;
GValue * value;
}
DbUpdatedField;
static void db_updated_field_free (DbUpdatedField * u)
{
if (u && u->value)
{
g_value_unset (u->value);
g_free (u->value);
}
g_free (u);
u = NULL;
}
/*
* DbOperation:
* @type: #DbModelRowOp flags
* @locked: %TRUE while the operation is being performed
* @row: the #DbRow over which the operation has been performed
* @updated: (element-type Db.UpdatedField): old values for the updated fields
* in @row
* @request: #DbRequest associated to the operation, once performed
*
* A structure explaining the operations performed over each #DbRow.
**/
typedef struct
{
DbModelRowOp type;
gboolean locked;
DbRow * row;
GSList * updated;
}
DbOperation;
/*
* DbModelRequest:
* @request: a DbRequest being performed
* @operations: a GQueue of operations being performed
* @model: the DbModel over which the operations are being performed
*
* This struct holds the information of a request performed but not yet
* finalized.
**/
typedef struct
{
DbModel * self;
GQueue * operations;
SqlList * stmts;
}
DbModelRequest;
//----------------------------------------------- Table
typedef struct
{
gchar * name;
gchar * schema;
}
Table;
static Table * table_copy (Table * src)
{
Table * table = g_new0 (Table, 1);
table->name = g_strdup (src->name);
table->schema = g_strdup (src->schema);
return table;
}
static void table_free (Table * table)
{
g_free (table->name);
g_free (table->schema);
g_free (table);
}
static gboolean table_equal (const Table * a, const Table * b)
{
return !g_strcmp0 (a->name, b->name)
&& !g_strcmp0 (a->schema, b->schema);
}
static guint table_hash (const Table * table)
{
return g_str_hash (table->name);
}
//----------------------------------------------- Field
typedef struct
{
gchar * name;
gchar * target;
gchar * schema;
}
Field;
static void field_parse (Field * field, const gchar * string)
{
gchar ** split = g_strsplit (string, ".", 0);
guint len = g_strv_length (split);
field->name = len > 0 ? remove_delimiters (split[--len]) : NULL;
field->target = len > 0 ? remove_delimiters (split[--len]) : NULL;
field->schema = len > 0 ? remove_delimiters (split[--len]) : NULL;
g_strfreev (split);
}
static Field * field_new_from_string (const gchar * string)
{
Field * field = g_new (Field, 1);
field_parse (field, string);
return field;
}
static void field_clear (Field * field)
{
g_free (field->name);
g_free (field->target);
g_free (field->schema);
}
static void field_free (Field * field)
{
field_clear (field);
g_free (field);
}
static gboolean field_equal (const Field * a, const Field * b)
{
return !g_strcmp0 (a->name, b->name)
&& !g_strcmp0 (a->target, b->target)
&& !g_strcmp0 (a->schema, b->schema);
}
static guint field_hash (const Field * field)
{
return g_str_hash (field->name);
}
//----------------------------------------------- TableInfo
typedef struct
{
gchar * name;
gchar * schema;
gchar * alias;
GSList * pkeys;
GHashTable * columns;
}
TableInfo;
static void table_info_free (TableInfo * table_info)
{
g_free (table_info->name);
g_free (table_info->schema);
g_free (table_info->alias);
g_slist_free (table_info->pkeys);
g_hash_table_unref (table_info->columns);
}
//----------------------------------------------- ColumnDef
typedef struct
{
gulong link;
GvnParam * param;
Field * src_column;
}
ColumnDef;
static ColumnDef * column_def_new ()
{
ColumnDef * column_def = g_new (ColumnDef, 1);
column_def->link = 0;
column_def->param = NULL;
column_def->src_column = NULL;
return column_def;
}
static void column_def_free (ColumnDef * def)
{
if (def->param)
{
if (def->link)
g_signal_handler_disconnect (def->param, def->link);
g_object_unref (def->param);
}
if (def->src_column)
field_free (def->src_column);
g_free (def);
}

File diff suppressed because it is too large Load Diff

View File

@ -27,11 +27,11 @@
#define DB_MODEL_LOG_DOMAIN (g_quark_from_string ("DbModel"))
#define DB_TYPE_MODEL (db_model_get_type())
#define DB_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DB_TYPE_MODEL, DbModel))
#define DB_IS_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DB_TYPE_MODEL))
#define DB_MODEL(self) (G_TYPE_CHECK_INSTANCE_CAST ((self), DB_TYPE_MODEL, DbModel))
#define DB_IS_MODEL(self) (G_TYPE_CHECK_INSTANCE_TYPE ((self), DB_TYPE_MODEL))
#define DB_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DB_TYPE_MODEL, DbModelClass))
#define DB_IS_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DB_TYPE_MODEL))
#define DB_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DB_TYPE_MODEL, DbModelClass))
#define DB_MODEL_GET_CLASS(self) (G_TYPE_INSTANCE_GET_CLASS ((self), DB_TYPE_MODEL, DbModelClass))
#define DB_TYPE_MODEL_UPDATE_FLAGS (db_model_update_flags_get_type())
@ -152,6 +152,21 @@ typedef enum
}
DbSortType;
/**
* DbIterCompareFunc:
* @model: a #DbModel
* @a: a #DbIter
* @b: a #DbIter
* @user_data: (closure): user-provided data to use while comparing two #DbIter
*
* Prototype of a function used to search some in a model using
* #DbIter to iterate through it.
**/
typedef gint (*DbIterCompareFunc) (DbModel * model
,DbIter * a
,DbIter * b
,gpointer user_data);
struct _DbModel
{
GObject parent;
@ -170,98 +185,103 @@ GType db_model_update_flags_get_type () G_GNUC_CONST;
DbModel * db_model_new (DbConn * conn, SqlStmt * stmt);
DbModel * db_model_new_with_sql (DbConn * conn, const gchar * sql);
DbModel * db_model_new_with_file (DbConn * conn, const gchar * file);
DbConn * db_model_get_conn (DbModel * obj);
void db_model_set_conn (DbModel * obj, DbConn * conn);
const GvnParamSpec * db_model_get_spec (DbModel * obj, gint col);
const gchar * db_model_get_column_name (DbModel * obj, gint col);
gint db_model_get_column_index (DbModel * obj, const gchar * name);
void db_model_refresh (DbModel * obj);
const SqlStmt * db_model_get_stmt (DbModel * obj);
void db_model_set_stmt (DbModel * obj, SqlStmt * stmt);
void db_model_add_pre_stmt (DbModel * obj, SqlStmt * stmt);
void db_model_add_post_stmt (DbModel * obj, SqlStmt * stmt);
DbModelStatus db_model_get_status (DbModel * obj);
const gchar * db_model_get_main_table (DbModel * obj);
void db_model_request_main_table (DbModel * obj, const gchar * table);
DbModelUpdateFlags db_model_get_update_flags (DbModel * obj);
void db_model_request_update_flags (DbModel * obj
DbConn * db_model_get_conn (DbModel * self);
void db_model_set_conn (DbModel * self, DbConn * conn);
const GvnParamSpec * db_model_get_spec (DbModel * self, gint col);
const gchar * db_model_get_column_name (DbModel * self, gint col);
gint db_model_get_column_index (DbModel * self, const gchar * name);
void db_model_refresh (DbModel * self);
const SqlStmt * db_model_get_stmt (DbModel * self);
void db_model_set_stmt (DbModel * self, SqlStmt * stmt);
void db_model_add_pre_stmt (DbModel * self, SqlStmt * stmt);
void db_model_add_post_stmt (DbModel * self, SqlStmt * stmt);
DbModelStatus db_model_get_status (DbModel * self);
const gchar * db_model_get_main_table (DbModel * self);
DbModelUpdateFlags db_model_get_update_flags (DbModel * self);
void db_model_request_update_flags (DbModel * self
,DbModelUpdateFlags flags);
void db_model_unset_update_flags (DbModel * obj
void db_model_unset_update_flags (DbModel * self
,DbModelUpdateFlags flags);
void db_model_set_mode (DbModel * obj, DbModelMode mode);
DbModelMode db_model_get_mode (DbModel * obj);
void db_model_toggle_mode (DbModel * obj);
void db_model_use_null_row (DbModel * obj, gboolean use);
gboolean db_model_get_last (DbModel * obj, DbIter * iter);
void db_model_get (DbModel * obj
void db_model_set_mode (DbModel * self, DbModelMode mode);
DbModelMode db_model_get_mode (DbModel * self);
void db_model_toggle_mode (DbModel * self);
void db_model_use_null_row (DbModel * self, gboolean use);
gboolean db_model_get_last (DbModel * self, DbIter * iter);
void db_model_get (DbModel * self
,DbIter * iter
,...);
void db_model_set (DbModel * obj
void db_model_set (DbModel * self
,DbIter * iter
,...);
const GValue * db_model_get_value (DbModel * obj,
const GValue * db_model_get_value (DbModel * self,
DbIter * iter,
gint col,
GError ** err);
gboolean db_model_set_value (DbModel * obj,
gboolean db_model_set_value (DbModel * self,
DbIter * iter,
gint col,
const GValue * value,
GError ** err);
gboolean db_model_insert (DbModel * obj, DbIter * iter);
void db_model_delete (DbModel * obj, DbIter * iter);
DbModelRowOp db_model_get_row_operations (DbModel * obj, DbIter * iter);
gboolean db_model_has_pending_operations (DbModel * obj);
void db_model_perform_operations (DbModel * obj, gboolean retry);
void db_model_reverse_operations (DbModel * obj);
void db_model_order_by (DbModel * obj,
gboolean db_model_insert (DbModel * self, DbIter * iter);
void db_model_delete (DbModel * self, DbIter * iter);
DbModelRowOp db_model_get_row_operations (DbModel * self, DbIter * iter);
gboolean db_model_has_pending_operations (DbModel * self);
void db_model_perform_operations (DbModel * self, gboolean retry);
void db_model_reverse_operations (DbModel * self);
void db_model_order_by (DbModel * self,
gint col,
DbSortType order);
gboolean db_model_search (DbModel * obj,
gboolean db_model_search (DbModel * self,
gint col,
DbIter * iter,
gpointer content);
gboolean db_model_search_value (DbModel * obj,
gboolean db_model_search_value (DbModel * self,
gint col,
DbIter * iter,
const GValue * value);
gint db_model_get_nrows (DbModel * obj);
gint db_model_get_nrows (DbModel * self);
gboolean db_model_iter_is_valid (DbIter * iter
,DbModel * model);
void db_model_add_join_columns (DbModel * obj
,const gchar * left
,const gchar * right);
void db_model_set_default_value_from_column (DbModel * obj
,const gchar * dst_field
,gint src_column);
void db_model_add_join (DbModel * self
,const gchar * master_field
,const gchar * slave_field);
SqlBatch * db_model_get_batch (DbModel * self);
void db_model_set_batch (DbModel * self, SqlBatch * batch);
void db_model_set_default_value_from_param (DbModel * obj
,const gchar * dst_field
,GvnParam * param);
void db_model_add_param (DbModel * obj
,GvnParam * param);
void db_model_set_default_value_from_column (DbModel * self, const gchar * field_str, const gchar * column_str);
void db_model_set_default_value_from_param (DbModel * self, const gchar * field_str, GvnParam * param, gboolean link);
//GtkTreeModel-like methods
gint db_model_get_ncols (DbModel * obj);
GType db_model_get_column_type (DbModel * obj, gint index);
gboolean db_model_get_iter_first (DbModel * obj, DbIter * iter);
gboolean db_model_get_iter (DbModel * obj,
gint db_model_get_ncols (DbModel * self);
GType db_model_get_column_type (DbModel * self, gint index);
gboolean db_model_get_iter_first (DbModel * self, DbIter * iter);
gboolean db_model_get_iter (DbModel * self,
DbIter * iter,
gint path);
gint db_model_get_path (DbModel * obj, DbIter * iter);
gboolean db_model_iter_next (DbModel * obj, DbIter * iter);
gboolean db_model_iter_prev (DbModel * obj, DbIter * iter);
void db_model_ref_node (DbModel * obj, DbIter * iter);
void db_model_unref_node (DbModel * obj, DbIter * iter);
gint db_model_get_path (DbModel * self, DbIter * iter);
gboolean db_model_iter_next (DbModel * self, DbIter * iter);
gboolean db_model_iter_prev (DbModel * self, DbIter * iter);
void db_model_ref_node (DbModel * self, DbIter * iter);
void db_model_unref_node (DbModel * self, DbIter * iter);
//GtkTreeSortable-like methods
gboolean db_model_get_sort_column_id (DbModel * obj,
gboolean db_model_get_sort_column_id (DbModel * self,
gint * sort_column_id,
DbSortType * order);
void db_model_set_sort_column_id (DbModel * obj,
void db_model_set_sort_column_id (DbModel * self,
gint sort_column_id,
DbSortType order);
void db_model_set_sort_func (DbModel * self,
gint sort_column_id,
DbIterCompareFunc func,
gpointer data,
GDestroyNotify destroy);
void db_model_set_default_sort_func (DbModel * self,
DbIterCompareFunc func,
gpointer data,
GDestroyNotify destroy);
gboolean db_model_has_default_sort_func (DbModel * self);
#endif

View File

@ -183,12 +183,13 @@ SqlStmt * db_plugin_parse (DbPlugin * obj, gchar * sql)
*
* Return value: (transfer full): the rendered string, or %NULL if error.
**/
gchar * db_plugin_render (DbPlugin * obj, gpointer object, GError ** err)
gchar * db_plugin_render (DbPlugin * obj, gpointer object, SqlBatch * batch, GError ** err)
{
g_return_val_if_fail (DB_IS_PLUGIN (obj), NULL);
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
g_return_val_if_fail (SQL_IS_BATCH (batch) || !batch, NULL);
return sql_render_get_string (obj->render, object, obj, err);
return sql_render_get_string (obj->render, object, batch, obj, err);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class

View File

@ -78,6 +78,6 @@ void db_plugin_set_ssl (DbPlugin * obj, const gchar * ca);
DbResultSet * db_plugin_query (DbPlugin * obj, const gchar * sql, GError ** err);
void db_plugin_kill_query (DbPlugin * obj);
SqlStmt * db_plugin_parse (DbPlugin * obj, gchar * sql);
gchar * db_plugin_render (DbPlugin * obj, gpointer object, GError ** err);
gchar * db_plugin_render (DbPlugin * obj, gpointer object, SqlBatch * batch, GError ** err);
#endif

View File

@ -73,12 +73,18 @@ DbRequest * db_request_new (DbConn * conn, const gchar * sql)
*
* Return value: a new #DbRequest
**/
DbRequest * db_request_new_with_stmt (DbConn * conn, SqlStmt * stmt)
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, "stmt", stmt, NULL);
obj = g_object_new (DB_TYPE_REQUEST, "conn", conn, NULL);
obj->sql = db_conn_render (conn, stmt, batch, NULL);
return obj;
}
/**
@ -351,7 +357,6 @@ typedef enum
{
PROP_CONN = 1
,PROP_SQL
,PROP_STMT
,PROP_RESULT_SET
,PROP_ERROR
}
@ -368,25 +373,8 @@ 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;
obj->sql = g_value_dup_string (value);
break;
}
case PROP_STMT:
{
SqlStmt * stmt = g_value_get_object (value);
if (obj->conn && stmt)
obj->sql = db_conn_render (obj->conn, stmt, NULL);
else if (!obj->conn)
g_warning ("DbRequest: Can't render stmt, conn property not set");
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
}
@ -463,13 +451,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_RESULT_SET,
g_param_spec_boxed ("result-set"
,_("Result")

View File

@ -78,7 +78,7 @@ struct _DbRequestClass
GType db_request_get_type ();
DbRequest * db_request_new (DbConn * conn, const gchar * sql);
DbRequest * db_request_new_with_stmt (DbConn * conn, SqlStmt * stmt);
DbRequest * db_request_new_with_stmt (DbConn * conn, SqlStmt * stmt, SqlBatch * batch);
DbResult * db_request_fetch_result (DbRequest * obj, GError ** err);
gint db_request_fetch_non_select (DbRequest * obj, GError ** err);
gboolean db_request_fetch_value (DbRequest * obj, GValue * value, GError ** err);

View File

@ -72,8 +72,10 @@ DbResult * db_result_copy (const DbResult * obj)
result->column[n].info = obj->column[n].info;
result->column[n].spec = gvn_param_spec_copy (obj->column[n].spec);
result->column[n].table = g_strdup (obj->column[n].table);
result->column[n].table_alias = g_strdup (obj->column[n].table_alias);
result->column[n].schema = g_strdup (obj->column[n].schema);
result->column[n].name = g_strdup (obj->column[n].name);
result->column[n].display = g_strdup (obj->column[n].display);
result->column[n].alias = g_strdup (obj->column[n].alias);
}
for (n = 0; n < obj->nrows; n++)
@ -105,8 +107,10 @@ void db_result_free (DbResult * obj)
DbColumn col = obj->column[i];
gvn_param_spec_free (col.spec);
g_free (col.name);
g_free (col.display);
g_free (col.alias);
g_free (col.table);
g_free (col.table_alias);
g_free (col.schema);
}
g_free (obj->column);

View File

@ -69,11 +69,13 @@ DbColumnInfo;
**/
struct _DbColumn
{
gchar * name;
gchar * alias;
gchar * table;
gchar * table_alias;
gchar * schema;
DbColumnInfo info;
GvnParamSpec * spec;
gchar * table;
gchar * name;
gchar * display;
};
GType db_result_get_type ();

View File

@ -46,16 +46,15 @@
variable VN_MODULE_LIB_PATH to the full path to the module or
modules <filename>.so</filename> files (separated by :), and
VN_MODULE_DATA_PATH pointing to the <filename>.xml</filename>,
<filename>.glade</filename>, <filename>.ui</filename> and any
other data of the module, there is also an optional third variable,
VN_MODULE_QUERY_PATH that points to <filename>.sql</filename>
files. Once these variables are set you'll have to run
the Hedera application normally, and it will look for the
values on the variables and load the module. Note that if you use
the Anjuta IDE with the project created by the wizzard, as you run
in Anjuta the variables will be automatically set pointing to your
project files (if the project folder is changed, you'll need to
manually reset the variables in Anjuta).
<filename>.glade</filename> and any other data of the module,
there is also an optional third variable, VN_MODULE_QUERY_PATH that
points to <filename>.sql</filename> files. Once these variables are
set you'll have to run the Hedera application normally, and it will
look for the values on the variables and load the module. Note that
if you use the Anjuta IDE with the project created by the wizzard,
as you run in Anjuta the variables will be automatically set
pointing to your project files (if the project folder is changed,
you'll need to manually reset the variables in Anjuta).
</para>
</refsection>
@ -71,19 +70,12 @@
The main of these requirements is to list the form in the
<filename>.xml</filename> file of the module. Also, the interface
description file must have the <filename>.glade</filename> extension
and contain a
#GtkContainer with the identifier "main" as the base widget, this
widget will be loaded inside a #GtkNotebook and will be the first
thing the user will see when the form gets loaded. This glade file
may also contain a #VnBatch with all the models needed by the form
and with the identifier "models", every model inside this batch will
get its connection set and a #GtkActionGroup idenfitied by "actions"
containing the actions that will be used in the toolbar and the menu
of the main application. To actually get these actions in the
toolbar and menu of the application the programmer must provide a
file with the extension <filename>.ui</filename> containing a
#GtkUIManager definition
using the actions in the "actions" group.
and contain a #GtkContainer with the identifier "main" as the base
widget, this widget will be loaded inside a #GtkNotebook and will be
the first thing the user will see when the form gets opened. This
glade file may also contain a #VnBatch with all the models needed by
the form and with the identifier "models", every model inside this
batch will get its connection property set automatically.
</para>
</refsection>
</refentry>

View File

@ -48,15 +48,12 @@
</para>
<para>
Additionally, the form can add menus to the main application
by adding a <link linkend="GtkActionGroup">GtkActionGroup</link>
named <literal>actions</literal> in the <filename>.glade</filename>
file, and using another file named also after the form, with the
extension <filename>.ui</filename>. This file uses the
<link linkend="GtkUIManager">GtkUIManager</link> syntax,
and will be used to define the strcuture of the menus and will
link the options to the actions defined in the previously mentioned
<literal>actions</literal>
<link linkend="GtkActionGroup">GtkActionGroup</link>.
by overriding the method <command>Vn.Form.get_actions</command> and
creating a file to describe the MenuModel used for the menu. The
name must be the name of the form prefixed by "-menu" and the
with the extension <filename>.glade</filename>. To know more about
the MenuModel definition see the GIO and GTK+ libraries
documentation on the MenuModel and the Application API.
</para>
<para>
There is also the possibility to define SQL files, to set and edit

View File

@ -136,6 +136,7 @@ static void glade_db_iterator_on_generate_params (GladeWidget * iterator)
DbModel * model = NULL;
GList * params = vn_iterator_get_params
(DB_ITERATOR (glade_widget_get_object (iterator)));
GError * err = NULL;
if (params)
{
@ -165,24 +166,39 @@ static void glade_db_iterator_on_generate_params (GladeWidget * iterator)
return;
}
select = SQL_SELECT (sql_parser_parse (sql, NULL));
select = SQL_SELECT (sql_parser_parse (sql, &err));
if (select && SQL_IS_SELECT (select))
if (!err)
{
//TODO Cambios cuando se use g_object_get (select, "fields", &fields, NULL)
GSList * l, * fields = select->expr;
SqlList * list;
GList * l, * fields;
GladeProject * project = glade_widget_get_project (iterator);
fields = g_slist_reverse (fields);
g_object_get (select, "fields", &list, NULL);
fields = sql_list_get_items (list);
glade_command_push_group (_("Automatic generation of params for %s"), name);
for (l = fields; l; l = l->next)
{
gchar * param_name, * param_new_name = NULL;
const gchar * param_name = NULL;
gchar * param_new_name = NULL;
GladeWidget * param;
SqlSelectField * field = l->data;
param = glade_command_create (glade_widget_adaptor_get_by_type (DB_TYPE_PARAM),
iterator, NULL, project);
param_name = sql_select_get_column_name (select, SQL_EXPR (l->data));
param_name = sql_select_field_get_alias (field);
if (!param_name)
{
SqlExpr * expr;
g_object_get (field, "expr", &expr, NULL);
if (SQL_IS_FIELD (expr))
param_name = sql_field_get_name (SQL_FIELD (expr));
}
if (param_name)
{
@ -193,9 +209,17 @@ static void glade_db_iterator_on_generate_params (GladeWidget * iterator)
glade_widget_property_set (param, "column-name", param_name);
g_free (param_new_name);
g_free (param_name);
}
}
glade_command_pop_group ();
g_object_unref (list);
}
else
{
g_warning ("%s", err->message);
g_error_free (err);
}
}

View File

@ -19,22 +19,13 @@
//+++++++++++++++++++++++++++++++++++++++++++++++++++ GladeModelEditor
GtkWidget * glade_model_editor_new (GladeWidgetAdaptor * adaptor,
GladeEditable * editable)
static void glade_model_editor_add_eprop (GladeModelEditor * obj,
GladeWidgetAdaptor * adaptor, const gchar * name, const gchar * tooltip)
{
GladeModelEditor * obj;
GladeEditorProperty * eprop;
GtkWidget * frame, * alignment, * vbox;
g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), NULL);
g_return_val_if_fail (GLADE_IS_EDITABLE (editable), NULL);
obj = g_object_new (GLADE_TYPE_MODEL_EDITOR,
"orientation", GTK_ORIENTATION_VERTICAL, NULL);
obj->base = GTK_WIDGET (editable);
gtk_box_pack_start (GTK_BOX (obj), GTK_WIDGET (editable), FALSE, FALSE, 0);
eprop = glade_widget_adaptor_create_eprop_by_name (adaptor, "links", FALSE, TRUE);
GladeEditorProperty * eprop =
glade_widget_adaptor_create_eprop_by_name (adaptor, name, FALSE, TRUE);
obj->props = g_list_prepend (obj->props, eprop);
frame = gtk_frame_new (NULL);
@ -51,7 +42,27 @@ GtkWidget * glade_model_editor_new (GladeWidgetAdaptor * adaptor,
gtk_container_add (GTK_CONTAINER (alignment), vbox);
gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (eprop), FALSE, FALSE, 4);
gtk_widget_set_tooltip_text (vbox, _("List of parameters linked to the model"));
gtk_widget_set_tooltip_text (vbox, tooltip);
}
GtkWidget * glade_model_editor_new (GladeWidgetAdaptor * adaptor,
GladeEditable * editable)
{
GladeModelEditor * obj;
g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), NULL);
g_return_val_if_fail (GLADE_IS_EDITABLE (editable), NULL);
obj = g_object_new (GLADE_TYPE_MODEL_EDITOR,
"orientation", GTK_ORIENTATION_VERTICAL, NULL);
obj->base = GTK_WIDGET (editable);
gtk_box_pack_start (GTK_BOX (obj), GTK_WIDGET (editable), FALSE, FALSE, 0);
glade_model_editor_add_eprop (obj, adaptor, "links",
_("List of parameters linked to the model"));
glade_model_editor_add_eprop (obj, adaptor, "batch",
_("List of SQLHolders and identifiers"));
gtk_widget_show_all (GTK_WIDGET (obj));
return GTK_WIDGET (obj);

View File

@ -32,7 +32,7 @@ typedef struct _GladeModelEditorClass GladeModelEditorClass;
struct _GladeModelEditor
{
GtkVBox parent;
GtkBox parent;
GtkWidget * base;
GList * props;

View File

@ -75,8 +75,6 @@ static void glade_eprop_sql_show_dialog (GtkButton * button, GladeEditorProperty
,NULL
));
/* gtk_dialog_set_alternative_button_order (dialog,
GTK_RESPONSE_OK, GTK_RESPONSE_REJECT, GTK_RESPONSE_CANCEL, -1);*/
gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
gtk_window_set_default_size (GTK_WINDOW (dialog), obj->width, obj->height);
@ -241,6 +239,7 @@ enum
{
FIELD_COL
,PARAM_COL
,LINKED_COL
,N_COLS
};
@ -352,9 +351,7 @@ static void glade_eporp_links_on_param_col_editing_started (GtkCellRendererText
g_signal_handlers_disconnect_by_data (entry, eprop);
}
g_object_set (entry
,"editable", FALSE
,NULL);
g_object_set (entry, "editable", FALSE, NULL);
}
}
@ -372,6 +369,30 @@ static void glade_eporp_links_on_field_col_edited (GtkCellRendererText * cell,
gtk_list_store_set (store, &iter, FIELD_COL, text, -1);
}
static void linked_col_cell_data (GtkTreeViewColumn * view, GtkCellRenderer * cell,
GtkTreeModel * model, GtkTreeIter * iter, gpointer data)
{
gboolean val;
gtk_tree_model_get (model, iter, LINKED_COL, &val, -1);
gtk_cell_renderer_toggle_set_active (GTK_CELL_RENDERER_TOGGLE (cell), val);
}
static void glade_eprop_links_on_linked_col_toggled (GtkCellRendererToggle * cell,
gchar * path, GladeEditorProperty * eprop)
{
gboolean val;
GtkTreeIter iter;
GladeProperty * p = glade_editor_property_get_property (eprop);
GladeDbList * list = g_value_get_boxed (glade_property_inline_value (p));
GtkListStore * store = list->list;
if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &iter, path))
return;
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, LINKED_COL, &val, -1);
gtk_list_store_set (store, &iter, LINKED_COL, !val, -1);
}
static void glade_widget_on_remove_widget (GladeProject * project,
GladeWidget * widget, GtkListStore * store)
{
@ -405,7 +426,8 @@ static void glade_eporp_links_on_add_clicked (GtkButton * button,
if (!(list = g_value_get_boxed (glade_property_inline_value (p))))
{
list = g_new (GladeDbList, 1);
list->list = gtk_list_store_new (N_COLS, G_TYPE_STRING, GLADE_TYPE_WIDGET);
list->list = gtk_list_store_new (N_COLS,
G_TYPE_STRING, GLADE_TYPE_WIDGET, G_TYPE_BOOLEAN);
glade_property_set (p, list);
g_signal_connect (glade_widget_get_project (glade_property_get_widget (p)),
@ -444,8 +466,8 @@ static void glade_eporp_links_on_remove_clicked (GtkButton * button,
gtk_tree_view_set_model (obj->view, NULL);
glade_command_set_property (p, NULL);
g_signal_handlers_disconnect_by_func (
glade_widget_get_project (glade_property_get_widget (p)),
g_signal_handlers_disconnect_by_func
(glade_widget_get_project (glade_property_get_widget (p)),
glade_widget_on_remove_widget, store);
}
}
@ -506,7 +528,6 @@ static GtkWidget * glade_eprop_links_create_input (GladeEditorProperty * eprop)
gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0);
obj->view = GTK_TREE_VIEW (gtk_tree_view_new ());
gtk_tree_view_set_grid_lines (obj->view, GTK_TREE_VIEW_GRID_LINES_BOTH);
g_signal_connect (obj->view, "key-press-event",
G_CALLBACK (glade_eprop_links_on_view_key_press), obj);
gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET (obj->view));
@ -529,6 +550,13 @@ static GtkWidget * glade_eprop_links_create_input (GladeEditorProperty * eprop)
G_CALLBACK (glade_eporp_links_on_param_col_editing_started), obj);
gtk_tree_view_append_column (obj->view, column);
cell = gtk_cell_renderer_toggle_new ();
column = gtk_tree_view_column_new_with_attributes (C_("Verb", "Link"), cell, NULL);
gtk_tree_view_column_set_cell_data_func (column, cell, linked_col_cell_data, obj, NULL);
g_signal_connect (cell, "toggled",
G_CALLBACK (glade_eprop_links_on_linked_col_toggled), obj);
gtk_tree_view_append_column (obj->view, column);
g_object_set (G_OBJECT (box), "height-request", 200, NULL);
gtk_widget_show_all (box);
return box;
@ -559,6 +587,35 @@ static void glade_eprop_links_load (GladeEditorProperty * eprop, GladeProperty *
gtk_tree_view_set_model (obj->view, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Batch Editor Property
/*
TODO Implementar!
typedef struct
{
GladeEditorProperty parent;
GtkTreeView * view;
gchar * path;
}
GladeEPropBatch;
GLADE_MAKE_EPROP (GladeEPropBatch, glade_eprop_batch)
#define GLADE_TYPE_EPROP_BATCH (glade_eprop_batch_get_type ())
#define GLADE_EPROP_BATCH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_EPROP_BATCH, GladeEPropBatch))
#define GLADE_EPROP_BATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_EPROP_BATCH, GladeEPropBatchClass))
#define GLADE_IS_EPROP_BATCH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_EPROP_BATCH))
#define GLADE_IS_EPROP_BATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_EPROP_BATCH))
#define GLADE_EPROP_BATCH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_EPROP_BATCH, GladeEPropBatchClass))
static GtkWidget * glade_eprop_links_create_input (GladeEditorProperty * eprop)
{}
static void glade_eprop_links_finalize (GObject * object)
{}
static void glade_eprop_links_load (GladeEditorProperty * eprop, GladeProperty * property)
{}
*/
//++++++++++++++++++++++++++++++++++++++++++++++++++ DbModel Widget Adaptor
GladeEditorProperty * glade_db_model_create_eprop (GladeWidgetAdaptor * adaptor,
@ -572,6 +629,7 @@ GladeEditorProperty * glade_db_model_create_eprop (GladeWidgetAdaptor * adaptor,
"property-class", klass,
"use-command", use_command, NULL);
else if (pspec->value_type == GLADE_TYPE_DB_LIST)
// TODO Encontrar una forma de diferenciar entre "Links" y "Batch"
eprop = g_object_new (GLADE_TYPE_EPROP_LINKS,
"property-class", klass,
"use-command", use_command, NULL);
@ -617,7 +675,7 @@ void glade_db_model_write_widget (GladeWidgetAdaptor * adaptor,
prop = glade_widget_get_property (widget, "links");
// Custom tag for the "links" property, e.g.:
// <links>
// <link field="table.name" param="param1"/>
// <link field="table.name" param="param1" linked="TRUE"/>
// </links>
if (!(l = g_value_get_boxed (glade_property_inline_value (prop))))
return;
@ -633,9 +691,14 @@ void glade_db_model_write_widget (GladeWidgetAdaptor * adaptor,
{
gchar * field;
GladeWidget * param;
gboolean linked;
GladeXmlNode * link_node;
gtk_tree_model_get (m, &iter, FIELD_COL, &field, PARAM_COL, &param, -1);
gtk_tree_model_get (m, &iter
,FIELD_COL, &field
,PARAM_COL, &param
,LINKED_COL, &linked
, -1);
link_node = glade_xml_node_new (context, "link");
glade_xml_node_append_child (links_node, link_node);
@ -643,6 +706,7 @@ void glade_db_model_write_widget (GladeWidgetAdaptor * adaptor,
field ? field : "");
glade_xml_node_set_property_string (link_node, "param",
param ? glade_widget_get_name (param) : "");
glade_xml_node_set_property_boolean (link_node, "linked", linked);
g_free (field);
}
@ -693,7 +757,7 @@ void glade_db_model_read_widget (GladeWidgetAdaptor * adaptor,
proj = glade_widget_get_project (widget);
list = g_new (GladeDbList, 1);
store = gtk_list_store_new (N_COLS, G_TYPE_STRING, GLADE_TYPE_WIDGET);
store = gtk_list_store_new (N_COLS, G_TYPE_STRING, GLADE_TYPE_WIDGET, G_TYPE_BOOLEAN);
list->list = store;
for (links_node = glade_xml_node_get_children (links_node); links_node;
@ -703,12 +767,14 @@ void glade_db_model_read_widget (GladeWidgetAdaptor * adaptor,
gint col = PARAM_COL;
gchar * field = glade_xml_get_property_string (links_node, "field"),
* param_name = glade_xml_get_property_string (links_node, "param");
gboolean linked = glade_xml_get_property_boolean (links_node, "linked", TRUE);
GladeWidget * param = glade_project_get_widget_by_name (proj, param_name);
gtk_list_store_append (store, &iter);
if (!param)
{
// If the parameter hasn't been read yet, load it after the parse
ParseData * pd;
pd = g_new (ParseData, 1);
pd->store = g_object_ref (store);
@ -723,6 +789,7 @@ void glade_db_model_read_widget (GladeWidgetAdaptor * adaptor,
gtk_list_store_set (store, &iter
,FIELD_COL, field
,LINKED_COL, linked
,col, param
,-1);

View File

@ -1,10 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<!-- interface-requires vn 0.0 -->
<!-- interface-requires gtk+ 3.0 -->
<requires lib="gtk+" version="3.0"/>
<requires lib="vn" version="0.0"/>
<!-- interface-local-resource-path ../image -->
<object class="VnIterator" id="homes"/>
<object class="VnIterator" id="info"/>
<object class="DbIterator" id="homes">
<property name="sql">SELECT id, street, pc, city, province, ok, user_id 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>
</object>
<object class="GtkBox" id="main">
<property name="visible">True</property>
<property name="can_focus">False</property>
@ -44,8 +49,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>
@ -57,8 +60,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>
@ -71,8 +72,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>
@ -85,8 +84,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>
@ -99,8 +96,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>
@ -113,8 +108,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>
@ -127,8 +120,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>
@ -141,8 +132,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>
@ -155,8 +144,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>
@ -169,8 +156,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>
@ -183,8 +168,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>
@ -197,8 +180,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>
@ -363,6 +344,13 @@
<property name="editable">True</property>
</object>
</child>
<child>
<object class="VnColumnEntry" id="col-user">
<property name="title" translatable="yes">User</property>
<property name="column_name">user_id</property>
<property name="editable">True</property>
</object>
</child>
</object>
</child>
</object>

View File

@ -178,6 +178,7 @@ void vn_consulter_send (GtkButton * button, VnConsulter * obj)
else
model = db_model_new_with_sql (VN_FORM (obj)->conn, sql);
db_model_request_update_flags (model, DB_MODEL_ALL);
// Get sure to connect after the columns do, to destroy them.
g_signal_connect_after (model, "status-changed",
G_CALLBACK (vn_consulter_model_status_changed), obj);

View File

@ -26,7 +26,7 @@ static void vn_customer_open (VnForm * obj, gpointer user_data)
DbIterator * info = vn_form_get (obj, "info");
DbIterator * homes = vn_form_get (obj, "homes");
db_iterator_link (homes, "user_id", info, "id");
db_iterator_link (homes, "user_address.user_id", info, "id");
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class

View File

@ -226,8 +226,10 @@ static DbResultSet * db_mysql_query (DbMysql * obj, const gchar * sql, GError **
column = &result->column[i];
column->info = 0;
column->name = g_strdup (field[i].org_name);
column->display = g_strdup (field[i].name);
column->alias = g_strdup (field[i].name);
column->table = g_strdup (field[i].org_table);
column->table_alias = g_strdup (field[i].table);
column->schema = g_strdup (field[i].db);
switch (field[i].type)
{
@ -271,7 +273,7 @@ static DbResultSet * db_mysql_query (DbMysql * obj, const gchar * sql, GError **
if (field[i].flags & AUTO_INCREMENT_FLAG)
{
SqlFunction * func = sql_function_new ("LAST_INSERT_ID", NULL);
SqlObject * func = sql_function_new ("LAST_INSERT_ID", NULL);
g_value_init (&def, SQL_TYPE_FUNCTION);
g_value_take_object (&def, g_object_ref_sink (func));
@ -374,7 +376,7 @@ static void db_mysql_kill_query (DbMysql * obj)
}
}
static void db_mysql_value_render (SqlValue * obj, SqlRender * render)
static void db_mysql_value_render (SqlValue * obj, SqlRender * render, SqlBatch * batch)
{
if (G_VALUE_TYPE (obj->value) == G_TYPE_BYTES)
{
@ -395,7 +397,7 @@ static void db_mysql_value_render (SqlValue * obj, SqlRender * render)
sql_render_append (render, "'");
}
else
sql_object_render (SQL_OBJECT (obj), render);
sql_object_render (SQL_OBJECT (obj), render, batch);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class

View File

@ -628,6 +628,8 @@ static DbResultSet * __db_pg_query
r->column[j].info = 0;
r->column[j].name = NULL;
r->column[j].table = NULL;
r->column[j].table_alias = NULL;
r->column[j].schema = NULL;
if (GPOINTER_TO_INT (g_ptr_array_index (col_iter, j)) == 0)
{
@ -647,8 +649,9 @@ static DbResultSet * __db_pg_query
else
r->column[j].name = fname;
r->column[j].display = g_strdup (r->column[j].name);
r->column[j].alias = g_strdup (r->column[j].name);
r->column[j].table = g_strdup ("");
r->column[j].table_alias = g_strdup ("");
r->column[j].spec = gvn_param_spec_new_with_attrs
(((GType*) g_ptr_array_index (types, ind))[j]
, FALSE, FALSE, NULL);
@ -676,7 +679,7 @@ static DbResultSet * __db_pg_query
fdisp = g_ptr_array_index (name_array, j);
r->column[j].name = g_strdup (fname);
r->column[j].display = g_strdup (fdisp);
r->column[j].alias = g_strdup (fdisp);
// Getting the default value from res_col //FIXME use the parser
if (!PQgetisnull (res_col, ctup, 3))
@ -702,15 +705,17 @@ static DbResultSet * __db_pg_query
g_strfreev (split);
}
else if (g_str_has_prefix (pg_val, "nextval"))
else
{
// Serial fields
if (g_str_has_prefix (pg_val, "nextval"))
{// Serial fields
GValue * v = g_new0 (GValue, 1);
gchar ** split = g_strsplit_set (pg_val, "(':)", G_MAXINT8);
SqlFunction * 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]);
sql_function_add_param (function, 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),
@ -720,6 +725,7 @@ static DbResultSet * __db_pg_query
else
db_pg_set_g_value (&def[j], type, pg_val);
}
}
else
g_value_init (&def[j], GVN_TYPE_NULL);
@ -757,8 +763,12 @@ static DbResultSet * __db_pg_query
guint n;
if (!r->column[j].table)
{
r->column[j].table =
g_strdup (PQgetvalue (res_col, k, 1));
r->column[j].table_alias =
g_strdup (r->column[j].table);
}
g_strfreev (pkey);
pkey = g_strsplit (PQgetvalue (res_col, k, 2), " ", G_MAXINT);
@ -867,7 +877,7 @@ static void db_pg_kill_query (DbPg * obj)
}
}
static void db_pg_value_render (SqlValue * obj, SqlRender * render)
static void db_pg_value_render (SqlValue * obj, SqlRender * render, SqlBatch * batch)
{
if (G_VALUE_TYPE (obj->value) == G_TYPE_BYTES)
{
@ -884,7 +894,7 @@ static void db_pg_value_render (SqlValue * obj, SqlRender * render)
PQfreemem (buffer);
}
else
sql_object_render (SQL_OBJECT (obj), render);
sql_object_render (SQL_OBJECT (obj), render, batch);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class

View File

@ -7,6 +7,14 @@ sql/sql-render.c
sql/parser/gram.c
sql/sql-value.c
sql/sql-string.c
sql/sql-delete.c
sql/sql-dml.c
sql/sql-field.c
sql/sql-function.c
sql/sql-holder.c
sql/sql-insert.c
sql/sql-list.c
sql/sql-select.c
plugin/mysql/db-mysql.c
plugin/pg/db-pg.c

View File

@ -5,15 +5,24 @@ SUBDIRS = parser
sql_lib_LTLIBRARIES = libsql.la
sql_include_HEADERS = \
sql.h \
sql-object.h \
sql-param-object.h \
sql-param-list.h \
sql-holder.h \
sql-list.h \
sql-batch.h \
sql-set.h \
sql-multi-stmt.h \
sql-string.h \
sql-target.h \
sql-expr.h \
sql-insert.h \
sql-object.h \
sql-select.h \
sql-select-field.h \
sql-select-order.h \
sql-subquery.h \
sql-update.h \
sql-update-set.h \
sql-delete.h \
sql-field.h \
sql-join.h \
@ -34,12 +43,21 @@ libsql_la_LIBADD = \
$(top_builddir)/gvn/libgvn.la
libsql_la_SOURCES = \
$(sql_include_HEADERS) \
sql-object.c \
sql-param-object.c \
sql-param-list.c \
sql-holder.c \
sql-list.c \
sql-batch.c \
sql-set.c \
sql-expr.c \
sql-insert.c \
sql-object.c \
sql-select.c \
sql-select-field.c \
sql-select-order.c \
sql-subquery.c \
sql-update.c \
sql-update-set.c \
sql-delete.c \
sql-field.c \
sql-join.c \

File diff suppressed because it is too large Load Diff

View File

@ -238,8 +238,9 @@ SqlObject * sql_parser_parse (const gchar * sql, GError ** err)
state = g_new (ParseState, 1);
state->object = NULL;
p = state->string = state->current = query;
state->failed = FALSE;
state->error = err;
state->string = state->current = p = query;
pe = p + strlen (p) + 1;
eof = pe;
@ -254,7 +255,7 @@ SqlObject * sql_parser_parse (const gchar * sql, GError ** err)
if (state->failed)
{
if (state->object && G_IS_OBJECT (state->object))
g_object_unref (state->object);
g_object_unref (g_object_ref_sink (state->object));
object = NULL;
}
else
@ -265,45 +266,3 @@ SqlObject * sql_parser_parse (const gchar * sql, GError ** err)
return object;
}
SqlField * sql_parser_parse_field (const gchar * field)
{
gchar ** split;
SqlExpr * object = NULL;
if (!field || !g_strcmp0 (field, ""))
return NULL;
split = g_strsplit (field, ".", 0);
switch (g_strv_length (split))
{
case 3:
{
object = sql_field_new
(g_strstrip (g_strdelimit (split[2], "`\"", ' '))
,g_strstrip (g_strdelimit (split[1], "`\"", ' '))
,g_strstrip (g_strdelimit (split[0], "`\"", ' ')));
break;
}
case 2:
{
object = sql_field_new
(g_strstrip (g_strdelimit (split[1], "`\"", ' '))
,g_strstrip (g_strdelimit (split[0], "`\"", ' '))
,NULL);
break;
}
case 1:
{
object = sql_field_new
(g_strstrip (g_strdelimit (split[0], "`\"", ' '))
,NULL
,NULL);
break;
}
}
g_strfreev (split);
return (SqlField *) object;
}

262
sql/sql-batch.c Normal file
View File

@ -0,0 +1,262 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sql-batch.h"
#include "sql-value.h"
/**
* SECTION: sql_batch
* @Short_description: represents an SQL statement or a part of it
* @Title: SqlBatch
*
* The #SqlBatch is the base class for all objects in SqlLib.
**/
G_DEFINE_TYPE (SqlBatch, sql_batch, G_TYPE_INITIALLY_UNOWNED);
enum {
CHANGED
,LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = {0};
SqlBatch * sql_batch_new ()
{
return g_object_new (SQL_TYPE_BATCH, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_batch_item_changed (SqlObject * item, SqlBatch * obj)
{
sql_batch_changed (obj);
}
static void sql_batch_free_item (SqlBatch * obj, SqlObject * item)
{
if (item)
{
g_signal_handlers_disconnect_by_func (item,
sql_batch_item_changed, obj);
g_object_unref (item);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
/**
* sql_batch_is_ready:
* @obj: a #SqlBatch
*
* Checks if @obj and all of its elements are ready to be rendered.
*
* Return value: %TRUE if ready, %FALSE otherwise.
**/
gboolean sql_batch_is_ready (SqlBatch * obj)
{
gpointer item;
GHashTableIter iter;
g_return_val_if_fail (SQL_IS_BATCH (obj), FALSE);
g_hash_table_iter_init (&iter, obj->items);
while (g_hash_table_iter_next (&iter, NULL, &item))
if (!item || !sql_object_is_ready (item))
return FALSE;
return TRUE;
}
/**
* sql_batch_get:
* @obj: a #SqlBatch
* @id: the id of the #SqlHolder
*
* Gets a held object by its id.
*
* Return value: (transfer none): the #SqlObject if an object with that id
* exists, %NULL otherwise
**/
SqlObject * sql_batch_get (SqlBatch * obj, const gchar * id)
{
g_return_val_if_fail (SQL_IS_BATCH (obj), NULL);
g_return_val_if_fail (id, NULL);
if (obj->items)
return g_hash_table_lookup (obj->items, id);
return NULL;
}
/**
* sql_batch_add:
* @obj: a #SqlBatch
* @id: the id of the #SqlHolder
* @item: the #SqlObject
*
* Adds a new item to the batch.
**/
void sql_batch_add (SqlBatch * obj, const gchar * id, SqlObject * item)
{
g_return_if_fail (SQL_IS_BATCH (obj));
g_return_if_fail (id);
g_return_if_fail (SQL_IS_OBJECT (item) || !item);
sql_batch_remove (obj, id);
if (item)
{
g_object_ref_sink (item);
g_signal_connect (item, "changed",
G_CALLBACK (sql_batch_item_changed), obj);
}
g_hash_table_replace (obj->items, g_strdup (id), item);
}
/**
* sql_batch_add_from_param:
* @obj: a #SqlBatch
* @id: the id assigned to the item
**/
void sql_batch_add_from_param (SqlBatch * obj, const gchar * id, GvnParam * param)
{
g_return_if_fail (SQL_IS_BATCH (obj));
g_return_if_fail (id);
g_return_if_fail (GVN_IS_PARAM (param));
sql_batch_add (obj, id, sql_value_new_with_param (param));
}
/**
* sql_batch_add_from_value:
* @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)
{
g_return_if_fail (SQL_IS_BATCH (obj));
g_return_if_fail (id);
GValue gvalue = {0};
gvn_value_new_with_content (&gvalue, type, content);
sql_batch_add (obj, id, sql_value_new_with_value (&gvalue));
g_value_unset (&gvalue);
}
/**
* sql_batch_remove:
* @obj: a #SqlBatch
* @id: the id of the #SqlHolder
*
* Removes a held object from the batch.
**/
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 * item = sql_batch_get (obj, id);
if (item)
{
sql_batch_free_item (obj, item);
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
*
* Emits the changed signal on #SqlBatch.
**/
void sql_batch_changed (SqlBatch * obj)
{
g_return_if_fail (SQL_IS_BATCH (obj));
g_signal_emit (obj, signals[CHANGED], 0);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_batch_init (SqlBatch * obj)
{
obj->items = g_hash_table_new_full (
g_str_hash
,g_str_equal
,g_free
,NULL
);
}
static void sql_batch_finalize (SqlBatch * obj)
{
gpointer item;
GHashTableIter iter;
g_hash_table_iter_init (&iter, obj->items);
while (g_hash_table_iter_next (&iter, NULL, &item))
sql_batch_free_item (obj, item);
g_hash_table_destroy (obj->items);
G_OBJECT_CLASS (sql_batch_parent_class)->finalize (G_OBJECT (obj));
}
static void sql_batch_class_init (SqlBatchClass * klass)
{
G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) sql_batch_finalize;
/**
* SqlBatch::changed:
* @obj: the object which emit the signal.
*
* This signal is emitted every time the batch or one of its attributes
* is modified.
*/
signals[CHANGED] = g_signal_new ("changed", SQL_TYPE_BATCH,
G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0
);
}

57
sql/sql-batch.h Normal file
View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2013 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SQL_BATCH_H
#define SQL_BATCH_H
#include <glib-object.h>
#define SQL_TYPE_BATCH (sql_batch_get_type ())
#define SQL_BATCH(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_BATCH, SqlBatch))
#define SQL_IS_BATCH(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_BATCH))
#define SQL_BATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST (klass, SQL_TYPE_BATCH, SqlBatchClass))
#define SQL_BATCH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS (obj, SQL_TYPE_BATCH, SqlBatchClass))
typedef struct _SqlBatch SqlBatch;
typedef struct _SqlBatchClass SqlBatchClass;
struct _SqlBatch
{
GInitiallyUnowned parent;
GHashTable * items;
};
struct _SqlBatchClass
{
/* <private> */
GInitiallyUnownedClass parent;
};
#include "sql-object.h"
GType sql_batch_get_type ();
SqlBatch * sql_batch_new ();
gboolean sql_batch_is_ready (SqlBatch * obj);
SqlObject * sql_batch_get (SqlBatch * obj, const gchar * id);
void sql_batch_add (SqlBatch * obj, const gchar * id, SqlObject * item);
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

@ -26,7 +26,7 @@
**/
G_DEFINE_TYPE (SqlDelete, sql_delete, SQL_TYPE_DML);
SqlDelete * sql_delete_new ()
SqlObject * sql_delete_new ()
{
return g_object_new (SQL_TYPE_DELETE, NULL);
}
@ -36,40 +36,75 @@ SqlDelete * sql_delete_new ()
static void sql_delete_render (SqlDelete * obj, SqlRender * render)
{
sql_render_add_token (render, "DELETE");
sql_render_add_object (render, obj->table);
sql_render_add_list (render, FALSE, NULL, obj->tables, ",");
if (SQL_DML (obj)->target)
if (SQL_DML (obj)->targets)
{
sql_render_add_list (render, T, "FROM", SQL_DML (obj)->target, ",");
sql_render_add_item (render, F, "WHERE", SQL_DML (obj)->where);
sql_render_add_list (render, TRUE, "FROM", SQL_DML (obj)->targets, ",");
sql_render_add_item (render, FALSE, "WHERE", SQL_DML (obj)->where);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
void sql_delete_add_table (SqlDelete * obj, SqlTable * table)
enum
{
g_return_if_fail (SQL_IS_DELETE (obj));
g_return_if_fail (SQL_IS_TABLE (table));
PROP_TABLES = 1
};
obj->table = g_slist_append (obj->table, g_object_ref_sink (table));
static void sql_delete_set_property (SqlDelete * obj, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_TABLES:
sql_object_remove (obj, obj->tables);
obj->tables = sql_object_add (obj, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
static void sql_delete_get_property (SqlDelete * obj, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_TABLES:
g_value_set_object (value, obj->tables);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_delete_init (SqlDelete * obj)
{
obj->table = NULL;
obj->tables = NULL;
}
static void sql_delete_finalize (SqlDelete * obj)
{
g_slist_free_full (obj->table, g_object_unref);
sql_object_remove (obj, obj->tables);
G_OBJECT_CLASS (sql_delete_parent_class)->finalize (G_OBJECT (obj));
}
static void sql_delete_class_init (SqlDeleteClass * klass)
{
G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) sql_delete_finalize;
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) sql_delete_finalize;
k->set_property = (GObjectSetPropertyFunc) sql_delete_set_property;
k->get_property = (GObjectGetPropertyFunc) sql_delete_get_property;
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_delete_render;
g_object_class_install_property (k, PROP_TABLES,
sql_param_list ("tables"
,_("Tables")
,_("A list of tables")
,SQL_TYPE_TABLE
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
}

View File

@ -30,12 +30,12 @@ typedef struct _SqlDeleteClass SqlDeleteClass;
/**
* SqlDelete:
* @table: (element-type Sql.Table): list of targeted tables
* @table: list of targeted tables
**/
struct _SqlDelete
{
SqlDml parent;
GSList * table;
SqlList * tables; // List of SqlTable
};
struct _SqlDeleteClass
@ -45,7 +45,6 @@ struct _SqlDeleteClass
};
GType sql_delete_get_type ();
SqlDelete * sql_delete_new ();
void sql_delete_add_table (SqlDelete * obj, SqlTable * table);
SqlObject * sql_delete_new ();
#endif

View File

@ -16,6 +16,7 @@
*/
#include "sql-dml.h"
#include "sql-holder.h"
/**
* SECTION: sql-dml
@ -28,42 +29,21 @@ G_DEFINE_ABSTRACT_TYPE (SqlDml, sql_dml, SQL_TYPE_STMT);
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
/**
* sql_dml_add_target:
* @obj: a #SqlDml
* @target: a #SqlTarget
*
* Add a target to the DML statement.
**/
void sql_dml_add_target (SqlDml * obj, SqlTarget * target)
void sql_dml_set_where (SqlDml * obj, SqlObject * where)
{
g_return_if_fail (SQL_IS_DML (obj));
g_return_if_fail (SQL_IS_TARGET (target));
g_return_if_fail (SQL_IS_EXPR (where) || SQL_IS_HOLDER (where) || !where);
obj->target = g_slist_append (obj->target, g_object_ref_sink (target));
}
/**
* sql_dml_set_where:
* @obj: a #SqlDml
* @expr: a #SqlExpr
*
* Sets the where expression of an DML statement.
**/
void sql_dml_set_where (SqlDml * obj, SqlExpr * where)
{
g_return_if_fail (SQL_IS_DML (obj));
g_return_if_fail (SQL_IS_EXPR (where));
g_clear_object (&obj->where);
obj->where = g_object_ref_sink (where);
sql_object_remove (obj, obj->where);
obj->where = sql_object_add (obj, where);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum
{
PROP_WHERE = 1
PROP_TARGETS = 1
,PROP_WHERE
};
static void sql_dml_set_property (SqlDml * obj, guint id,
@ -71,6 +51,10 @@ static void sql_dml_set_property (SqlDml * obj, guint id,
{
switch (id)
{
case PROP_TARGETS:
sql_object_remove (obj, obj->targets);
obj->targets = sql_object_add (obj, g_value_get_object (value));
break;
case PROP_WHERE:
sql_dml_set_where (obj, g_value_get_object (value));
break;
@ -84,6 +68,9 @@ static void sql_dml_get_property (SqlDml * obj, guint id,
{
switch (id)
{
case PROP_TARGETS:
g_value_set_object (value, obj->targets);
break;
case PROP_WHERE:
g_value_set_object (value, obj->where);
break;
@ -94,30 +81,37 @@ static void sql_dml_get_property (SqlDml * obj, guint id,
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_dml_finalize (SqlDml * obj)
{
g_clear_object (&obj->where);
g_slist_free_full (obj->target, g_object_unref);
G_OBJECT_CLASS (sql_dml_parent_class)->finalize (G_OBJECT (obj));
}
static void sql_dml_init (SqlDml * obj)
{
obj->target = NULL;
obj->targets = NULL;
obj->where = NULL;
}
static void sql_dml_class_init (SqlDmlClass * k)
static void sql_dml_finalize (SqlDml * obj)
{
GObjectClass * klass = G_OBJECT_CLASS (k);
klass->finalize = (GObjectFinalizeFunc) sql_dml_finalize;
klass->set_property = (GObjectSetPropertyFunc) sql_dml_set_property;
klass->get_property = (GObjectGetPropertyFunc) sql_dml_get_property;
sql_object_remove (obj, obj->targets);
sql_object_remove (obj, obj->where);
G_OBJECT_CLASS (sql_dml_parent_class)->finalize (G_OBJECT (obj));
}
g_object_class_install_property (klass, PROP_WHERE,
g_param_spec_object ("where"
,"Where"
,"The expression used to filter rows, it's the WHERE section of an statement"
static void sql_dml_class_init (SqlDmlClass * klass)
{
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) sql_dml_finalize;
k->set_property = (GObjectSetPropertyFunc) sql_dml_set_property;
k->get_property = (GObjectGetPropertyFunc) sql_dml_get_property;
g_object_class_install_property (k, PROP_TARGETS,
sql_param_list ("targets"
,_("Targets")
,_("A list of targets")
,SQL_TYPE_TARGET
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
g_object_class_install_property (k, PROP_WHERE,
sql_param_object ("where"
,_("Where")
,_("The WHERE section of an statement")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE
));

View File

@ -31,13 +31,13 @@ typedef struct _SqlDmlClass SqlDmlClass;
/**
* SqlDml:
* @target: (element-type Sql.Target): list of targets for the DML query
* @target: list of targets for the DML query
* @where: an #SqlExpr
**/
struct _SqlDml
{
SqlStmt parent;
GSList * target;
SqlList * targets; // List of SqlTarget
SqlExpr * where;
};
@ -48,7 +48,6 @@ struct _SqlDmlClass
};
GType sql_dml_get_type ();
void sql_dml_add_target (SqlDml * obj, SqlTarget * target);
void sql_dml_set_where (SqlDml * obj, SqlExpr * expr);
void sql_dml_set_where (SqlDml * obj, SqlObject * expr);
#endif

View File

@ -28,11 +28,6 @@
**/
G_DEFINE_ABSTRACT_TYPE (SqlExpr, sql_expr, SQL_TYPE_OBJECT);
SqlExpr * sql_expr_new ()
{
return g_object_new (SQL_TYPE_EXPR, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_expr_init (SqlExpr * obj) {}

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,49 +52,114 @@ G_DEFINE_TYPE (SqlField, sql_field, SQL_TYPE_EXPR);
*
* Return value: an #SqlExpr
*/
SqlExpr * sql_field_new (const gchar * name, const gchar * target, const gchar * schema)
SqlObject * sql_field_new_with_target (const gchar * name, const gchar * target, const gchar * schema)
{
return g_object_new (SQL_TYPE_FIELD
,"name", name
,"target", target
,"schema", schema
,NULL);
,NULL
);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_field_render (SqlField * obj, SqlRender * render)
static void sql_field_render (SqlField * self, SqlRender * render)
{
if (obj->target)
if (self->target)
{
if (obj->schema)
if (self->schema)
{
sql_render_add_identifier (render, obj->schema);
sql_render_add_identifier (render, self->schema);
sql_render_append (render, ".");
}
sql_render_add_identifier (render, obj->target);
sql_render_add_identifier (render, self->target);
sql_render_append (render, ".");
}
if (!g_strcmp0 (obj->name, "*"))
if (!g_strcmp0 (self->name, "*"))
{
sql_render_add_espace (render);
sql_render_append (render, "*");
}
else
sql_render_add_identifier (render, obj->name);
sql_render_add_identifier (render, self->name);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
void sql_field_set_name (SqlField * obj, const gchar * name)
/**
* sql_field_get_name:
* @self: the #SqlField
*
* Return value: the field name
**/
const gchar * sql_field_get_name (SqlField * self)
{
g_return_if_fail (SQL_IS_FIELD (obj));
return self->name;
}
/**
* sql_field_set_name:
* @self: the #SqlField
* @name: the field name
**/
void sql_field_set_name (SqlField * self, const gchar * name)
{
g_return_if_fail (SQL_IS_FIELD (self));
g_return_if_fail (name);
g_free (obj->name);
obj->name = g_strdup (name);
g_free (self->name);
self->name = g_strdup (name);
}
/**
* sql_field_get_target:
* @self: the #SqlField
*
* Return value: the target name
**/
const gchar * sql_field_get_target (SqlField * self)
{
return self->target;
}
/**
* sql_field_set_target:
* @self: the #SqlField
* @target: the target name
**/
void sql_field_set_target (SqlField * self, const gchar * target)
{
g_return_if_fail (SQL_IS_FIELD (self));
g_free (self->target);
self->target = g_strdup (target);
}
/**
* sql_field_get_schema:
* @self: the #SqlField
*
* Return value: the schema name
**/
const gchar * sql_field_get_schema (SqlField * self)
{
return self->schema;
}
/**
* sql_field_set_schema:
* @self: the #SqlField
* @schema: the schema name
**/
void sql_field_set_schema (SqlField * self, const gchar * schema)
{
g_return_if_fail (SQL_IS_FIELD (self));
g_free (self->schema);
self->schema = g_strdup (schema);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@ -90,63 +171,59 @@ enum
,PROP_SCHEMA
};
static void sql_field_set_property (SqlField * obj, guint id,
static void sql_field_set_property (SqlField * self, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_NAME:
g_free (obj->name);
obj->name = g_value_dup_string (value);
sql_field_set_name (self, g_value_get_string (value));
break;
case PROP_TARGET:
g_free (obj->target);
obj->target = g_value_dup_string (value);
sql_field_set_target (self, g_value_get_string (value));
break;
case PROP_SCHEMA:
g_free (obj->schema);
obj->schema = g_value_dup_string (value);
sql_field_set_schema (self, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
static void sql_field_get_property (SqlField * obj, guint id,
static void sql_field_get_property (SqlField * self, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_NAME:
g_value_set_string (value, obj->name);
g_value_set_string (value, self->name);
break;
case PROP_TARGET:
g_value_set_string (value, obj->target);
g_value_set_string (value, self->target);
break;
case PROP_SCHEMA:
g_value_set_string (value, obj->schema);
g_value_set_string (value, self->schema);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_field_init (SqlField * obj)
static void sql_field_init (SqlField * self)
{
obj->name = NULL;
obj->target = NULL;
obj->schema = NULL;
self->name = NULL;
self->target = NULL;
self->schema = NULL;
}
static void sql_field_finalize (SqlField * obj)
static void sql_field_finalize (SqlField * self)
{
g_free (obj->name);
g_free (obj->target);
g_free (obj->schema);
G_OBJECT_CLASS (sql_field_parent_class)->finalize (G_OBJECT (obj));
g_free (self->name);
g_free (self->target);
g_free (self->schema);
G_OBJECT_CLASS (sql_field_parent_class)->finalize (G_OBJECT (self));
}
static void sql_field_class_init (SqlFieldClass * klass)
@ -159,22 +236,22 @@ static void sql_field_class_init (SqlFieldClass * klass)
g_object_class_install_property (k, PROP_NAME,
g_param_spec_string ("name"
,"Name"
,"The column name"
,_("Name")
,_("The column name")
,NULL
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_TARGET,
g_param_spec_string ("target"
,"Target"
,"The target name"
,_("Target")
,_("The target name")
,NULL
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_SCHEMA,
g_param_spec_string ("schema"
,"Schema"
,"The schema name"
,_("Schema")
,_("The schema name")
,NULL
,G_PARAM_READWRITE
));

View File

@ -22,8 +22,8 @@
#include "sql-target.h"
#define SQL_TYPE_FIELD (sql_field_get_type ())
#define SQL_FIELD(object) (G_TYPE_CHECK_INSTANCE_CAST (object, SQL_TYPE_FIELD, SqlField))
#define SQL_IS_FIELD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SQL_TYPE_FIELD))
#define SQL_FIELD(self) (G_TYPE_CHECK_INSTANCE_CAST (self, SQL_TYPE_FIELD, SqlField))
#define SQL_IS_FIELD(self) (G_TYPE_CHECK_INSTANCE_TYPE ((self), SQL_TYPE_FIELD))
typedef struct _SqlField SqlField;
typedef struct _SqlFieldClass SqlFieldClass;
@ -43,9 +43,16 @@ struct _SqlFieldClass
};
GType sql_field_get_type ();
SqlExpr * sql_field_new (const gchar * name
SqlObject * sql_field_new (const gchar * name);
SqlObject * sql_field_new_with_target (const gchar * name
,const gchar * target
,const gchar * schema);
void sql_field_set_name (SqlField * obj, const gchar * name);
const gchar * sql_field_get_name (SqlField * self);
void sql_field_set_name (SqlField * self, const gchar * name);
const gchar * sql_field_get_target (SqlField * self);
void sql_field_set_target (SqlField * self, const gchar * target);
const gchar * sql_field_get_schema (SqlField * self);
void sql_field_set_schema (SqlField * self, const gchar * schema);
#endif

View File

@ -26,7 +26,7 @@
**/
G_DEFINE_TYPE (SqlFunction, sql_function, SQL_TYPE_EXPR);
SqlFunction * sql_function_new (const gchar * name, const gchar * schema)
SqlObject * sql_function_new (const gchar * name, const gchar * schema)
{
return g_object_new (SQL_TYPE_FUNCTION, "name", name, "schema", schema, NULL);
}
@ -42,23 +42,9 @@ static void sql_function_render (SqlFunction * obj, SqlRender * render)
}
sql_render_add_identifier (render, obj->name);
if (obj->name)
{
sql_render_append (render, "(");
sql_render_add_list (render, F, NULL, obj->param, ",");
sql_render_add_list (render, FALSE, NULL, obj->params, ",");
sql_render_append (render, ")");
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
void sql_function_add_param (SqlFunction * obj, SqlExpr * param)
{
g_return_if_fail (SQL_IS_FUNCTION (obj));
g_return_if_fail (SQL_IS_EXPR (param));
obj->param = g_slist_append (obj->param, g_object_ref_sink (param));
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@ -67,6 +53,7 @@ enum
{
PROP_NAME = 1
,PROP_SCHEMA
,PROP_PARAMS
};
static void sql_function_set_property (SqlFunction * obj, guint id,
@ -82,6 +69,10 @@ static void sql_function_set_property (SqlFunction * obj, guint id,
g_free (obj->schema);
obj->schema = g_value_dup_string (value);
break;
case PROP_PARAMS:
sql_object_remove (obj, obj->params);
obj->params = sql_object_add (obj, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
@ -98,6 +89,9 @@ static void sql_function_get_property (SqlFunction * obj, guint id,
case PROP_SCHEMA:
g_value_set_string (value, obj->schema);
break;
case PROP_PARAMS:
g_value_set_object (value, obj->params);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
@ -109,14 +103,14 @@ static void sql_function_init (SqlFunction * obj)
{
obj->name = NULL;
obj->schema = NULL;
obj->param = NULL;
obj->params = NULL;
}
static void sql_function_finalize (SqlFunction * obj)
{
g_free (obj->name);
g_free (obj->schema);
g_slist_free_full (obj->param, g_object_unref);
sql_object_remove (obj, obj->params);
G_OBJECT_CLASS (sql_function_parent_class)->finalize (G_OBJECT (obj));
}
@ -130,17 +124,23 @@ static void sql_function_class_init (SqlFunctionClass * klass)
g_object_class_install_property (k, PROP_NAME,
g_param_spec_string ("name"
,"Name"
,"The function name"
,_("Name")
,_("The function name")
,NULL
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_SCHEMA,
g_param_spec_string ("schema"
,"Schema"
,"The schema to which the function belongs"
,_("Schema")
,_("The schema to which the function belongs")
,NULL
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_PARAMS,
sql_param_list ("params"
,_("Parameters")
,_("The function parameters")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
}

View File

@ -37,7 +37,7 @@ struct _SqlFunction
SqlExpr parent;
gchar * schema;
gchar * name;
GSList * param; // Parameters for the function, list of SqlExpr
SqlList * params; // List of SqlExpr
};
struct _SqlFunctionClass
@ -47,7 +47,6 @@ struct _SqlFunctionClass
};
GType sql_function_get_type ();
SqlFunction * sql_function_new (const gchar * name, const gchar * schema);
void sql_function_add_param (SqlFunction * obj, SqlExpr * param);
SqlObject * sql_function_new (const gchar * name, const gchar * schema);
#endif

129
sql/sql-holder.c Normal file
View File

@ -0,0 +1,129 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sql-holder.h"
/**
* SECTION: sql-holder
* @Short_description:
* @Title: SqlHolder
**/
G_DEFINE_TYPE (SqlHolder, sql_holder, SQL_TYPE_OBJECT);
SqlObject * sql_holder_new (const gchar * id)
{
return g_object_new (SQL_TYPE_HOLDER, "id", id, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_holder_render (SqlHolder * self, SqlRender * render, SqlBatch * batch)
{
SqlObject * object = batch ? sql_batch_get (batch, self->id) : NULL;
if (object)
sql_render_add_object (render, object);
else
sql_render_printf (render, "#%s", self->id);
}
static void sql_holder_find_holders (SqlHolder * self, SqlBatch * batch)
{
sql_batch_add (batch, self->id, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
/**
* sql_holder_get_id:
* @self: the #SqlHolder
*
* Gets the identifier assigned to the holder.
*
* Return value: (transfer none): the id
**/
const gchar * sql_holder_get_id (SqlHolder * self)
{
g_return_val_if_fail (SQL_IS_HOLDER (self), NULL);
return self->id;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum
{
PROP_ID = 1
};
static void sql_holder_set_property (SqlHolder * self, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_ID:
g_free (self->id);
self->id = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
static void sql_holder_get_property (SqlHolder * self, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_ID:
g_value_set_string (value, sql_holder_get_id (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_holder_init (SqlHolder * self)
{
self->id = NULL;
}
static void sql_holder_finalize (SqlHolder * self)
{
g_free (self->id);
G_OBJECT_CLASS (sql_holder_parent_class)->finalize (G_OBJECT (self));
}
static void sql_holder_class_init (SqlHolderClass * k)
{
GObjectClass * klass = G_OBJECT_CLASS (k);
klass->finalize = (GObjectFinalizeFunc) sql_holder_finalize;
klass->set_property = (GObjectSetPropertyFunc) sql_holder_set_property;
klass->get_property = (GObjectGetPropertyFunc) sql_holder_get_property;
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_holder_render;
SQL_OBJECT_CLASS (klass)->find_holders = (SqlObjectFindHoldersFunc) sql_holder_find_holders;
g_object_class_install_property (klass, PROP_ID,
g_param_spec_string ("id"
,_("Identifier")
,_("The holder identifier")
,NULL
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
));
}

46
sql/sql-holder.h Normal file
View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SQL_HOLDER_H
#define SQL_HOLDER_H
#define SQL_TYPE_HOLDER (sql_holder_get_type ())
#define SQL_HOLDER(self) (G_TYPE_CHECK_INSTANCE_CAST (self, SQL_TYPE_HOLDER, SqlHolder))
#define SQL_IS_HOLDER(self) (G_TYPE_CHECK_INSTANCE_TYPE (self, SQL_TYPE_HOLDER))
typedef struct _SqlHolder SqlHolder;
typedef struct _SqlHolderClass SqlHolderClass;
#include "sql-object.h"
struct _SqlHolder
{
SqlObject parent;
gchar * id;
};
struct _SqlHolderClass
{
/* <private> */
SqlObjectClass parent;
};
GType sql_holder_get_type ();
SqlObject * sql_holder_new (const gchar * id);
const gchar * sql_holder_get_id (SqlHolder * self);
#endif

View File

@ -26,51 +26,28 @@
**/
G_DEFINE_TYPE (SqlInsert, sql_insert, SQL_TYPE_STMT);
SqlInsert * sql_insert_new ()
SqlObject * sql_insert_new ()
{
return g_object_new (SQL_TYPE_INSERT, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_insert_expr_free (SqlExpr * expr)
{
if (expr)
g_object_unref (expr);
}
static void sql_insert_render_expr (SqlExpr * obj, SqlRender * render)
{
if (obj)
sql_render_add_object (render, obj);
else
sql_render_add_token (render, "DEFAULT");
}
static void sql_insert_render_row (GSList * obj, SqlRender * render)
{
sql_render_add_espace (render);
sql_render_append (render, "(");
sql_render_add_list_with_func (render, T, NULL, obj, ",",
(SqlRenderFunc) sql_insert_render_expr);
sql_render_append (render, ")");
}
static void sql_insert_render (SqlInsert * obj, SqlRender * render)
{
sql_render_add_item (render, T, "INSERT INTO", obj->table);
sql_render_add_item (render, TRUE, "INSERT INTO", obj->table);
if (obj->table)
{
if (obj->expr)
if (obj->fields && sql_list_length (obj->fields) > 0)
{
sql_render_add_espace (render);
sql_render_append (render, "(");
sql_render_add_list (render, F, NULL, obj->field, ",");
sql_render_add_list (render, FALSE, NULL, obj->fields, ",");
sql_render_append (render, ")");
sql_render_add_token (render, "VALUES");
sql_render_add_list_with_func (render, F, NULL, obj->expr, ",",
(SqlRenderFunc) sql_insert_render_row);
sql_render_add_espace (render);
sql_render_add_list (render, FALSE, NULL, obj->values, ",");
}
else
sql_render_add_token (render, "DEFAULT VALUES");
@ -79,56 +56,19 @@ static void sql_insert_render (SqlInsert * obj, SqlRender * render)
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
void sql_insert_set_table (SqlInsert * obj, SqlTable * table)
void sql_insert_set_table_from_name (SqlInsert * obj, const gchar * table)
{
g_return_if_fail (SQL_IS_INSERT (obj));
g_return_if_fail (SQL_IS_TABLE (table));
g_return_if_fail (table);
g_clear_object (&obj->table);
obj->table = g_object_ref_sink (table);
}
void sql_insert_add_row (SqlInsert * obj)
{
g_return_if_fail (SQL_IS_INSERT (obj));
obj->iter = g_slist_alloc ();
obj->expr = g_slist_concat (obj->expr, obj->iter);
}
void sql_insert_add_field (SqlInsert * obj, SqlField * field)
{
g_return_if_fail (SQL_IS_INSERT (obj));
g_return_if_fail (SQL_IS_FIELD (field));
obj->field = g_slist_append (obj->field, g_object_ref_sink (field));
sql_object_remove (obj, obj->table);
obj->table = sql_object_add (obj, sql_table_new (table, NULL));
}
void sql_insert_add_expr (SqlInsert * obj, SqlExpr * expr)
{
g_return_if_fail (SQL_IS_INSERT (obj));
g_return_if_fail (SQL_IS_EXPR (expr) || !expr);
if (!obj->iter)
sql_insert_add_row (obj);
if (expr)
g_object_ref_sink (expr);
obj->iter->data = g_slist_append (obj->iter->data, expr);
}
void sql_insert_clean (SqlInsert * obj)
{
GSList * n;
g_return_if_fail (SQL_IS_INSERT (obj));
g_slist_free_full (obj->field, g_object_unref);
for (n = obj->expr; n; n = n->next)
g_slist_free_full (n->data, (GDestroyNotify) sql_insert_expr_free);
g_slist_free (obj->expr);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@ -136,6 +76,8 @@ void sql_insert_clean (SqlInsert * obj)
enum
{
PROP_TABLE = 1
,PROP_FIELDS
,PROP_VALUES
};
static void sql_insert_set_property (SqlInsert * obj, guint id,
@ -144,7 +86,16 @@ static void sql_insert_set_property (SqlInsert * obj, guint id,
switch (id)
{
case PROP_TABLE:
sql_insert_set_table (obj, g_value_get_object (value));
sql_object_remove (obj, obj->table);
obj->table = sql_object_add (obj, g_value_get_object (value));
break;
case PROP_FIELDS:
sql_object_remove (obj, obj->fields);
obj->fields = sql_object_add (obj, g_value_get_object (value));
break;
case PROP_VALUES:
sql_object_remove (obj, obj->values);
obj->values = sql_object_add (obj, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
@ -159,6 +110,12 @@ static void sql_insert_get_property (SqlInsert * obj, guint id,
case PROP_TABLE:
g_value_set_object (value, obj->table);
break;
case PROP_FIELDS:
g_value_set_object (value, obj->fields);
break;
case PROP_VALUES:
g_value_set_object (value, obj->values);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
@ -169,15 +126,15 @@ static void sql_insert_get_property (SqlInsert * obj, guint id,
static void sql_insert_init (SqlInsert * obj)
{
obj->table = NULL;
obj->field = NULL;
obj->expr = NULL;
obj->iter = NULL;
obj->fields = NULL;
obj->values = NULL;
}
static void sql_insert_finalize (SqlInsert * obj)
{
sql_insert_clean (obj);
g_clear_object (&obj->table);
sql_object_remove (obj, obj->table);
sql_object_remove (obj, obj->fields);
sql_object_remove (obj, obj->values);
G_OBJECT_CLASS (sql_insert_parent_class)->finalize (G_OBJECT (obj));
}
@ -190,10 +147,24 @@ static void sql_insert_class_init (SqlInsertClass * klass)
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_insert_render;
g_object_class_install_property (k, PROP_TABLE,
g_param_spec_object ("table"
,"Table"
,"The table where the row is inserted"
sql_param_object ("table"
,_("Table")
,_("The table where the row is inserted")
,SQL_TYPE_TABLE
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_FIELDS,
sql_param_list ("fields"
,_("Fields")
,_("The list of fields")
,SQL_TYPE_FIELD
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
g_object_class_install_property (k, PROP_VALUES,
sql_param_list ("values"
,_("Values")
,_("The list of values")
,SQL_TYPE_SET
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
}

View File

@ -19,13 +19,14 @@
#define SQL_INSERT_H
#define SQL_TYPE_INSERT (sql_insert_get_type ())
#define SQL_INSERT(object) (G_TYPE_CHECK_INSTANCE_CAST (object, SQL_TYPE_INSERT, SqlInsert))
#define SQL_IS_INSERT(object) (G_TYPE_CHECK_INSTANCE_TYPE (object, SQL_TYPE_INSERT))
#define SQL_INSERT(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_INSERT, SqlInsert))
#define SQL_IS_INSERT(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_INSERT))
#include "sql-stmt.h"
#include "sql-field.h"
#include "sql-value.h"
#include "sql-table.h"
#include "sql-set.h"
typedef struct _SqlInsert SqlInsert;
typedef struct _SqlInsertClass SqlInsertClass;
@ -40,9 +41,8 @@ struct _SqlInsert
{
SqlStmt parent;
SqlTable * table;
GSList * field; // List of SqlField
GSList * expr; // List of GSList of SqlExpr
GSList * iter;
SqlList * fields; // List of SqlField
SqlList * values; // List of SqlSet
};
struct _SqlInsertClass
@ -52,11 +52,7 @@ struct _SqlInsertClass
};
GType sql_insert_get_type ();
SqlInsert * sql_insert_new ();
void sql_insert_set_table (SqlInsert * obj, SqlTable * table);
void sql_insert_add_row (SqlInsert * obj);
void sql_insert_add_field (SqlInsert * obj, SqlField * field);
void sql_insert_add_expr (SqlInsert * obj, SqlExpr * expr);
void sql_insert_clean (SqlInsert * obj);
SqlObject * sql_insert_new ();
void sql_insert_set_table_from_name (SqlInsert * obj, const gchar * table);
#endif

View File

@ -16,6 +16,8 @@
*/
#include "sql-join.h"
#include "sql-field.h"
#include "sql-holder.h"
/**
* SECTION: sql-join
@ -26,7 +28,7 @@
**/
G_DEFINE_TYPE (SqlJoin, sql_join, SQL_TYPE_TARGET);
SqlTarget * sql_join_new (SqlTarget * left, SqlTarget * right, SqlJoinType type)
SqlObject * sql_join_new (SqlTarget * left, SqlTarget * right, SqlJoinType type)
{
return g_object_new (SQL_TYPE_JOIN
,"target-left" ,left
@ -45,42 +47,58 @@ static const gchar * SQL_JOIN_TYPE[] =
,"RIGHT"
};
static void sql_join_render (SqlJoin * obj, SqlRender * render)
static void sql_join_render (SqlJoin * self, SqlRender * render)
{
sql_render_add_item (render, T, NULL, obj->target_left);
sql_render_add_token (render, SQL_JOIN_TYPE[obj->type]);
sql_render_add_item (render, TRUE, NULL, self->target_left);
sql_render_add_token (render, SQL_JOIN_TYPE[self->type]);
sql_render_add_token (render, "JOIN");
sql_render_add_item (render, T, NULL, obj->target_right);
sql_render_add_item (render, F, "ON", obj->condition);
sql_render_add_item (render, TRUE, NULL, self->target_right);
if (self->has_using)
{
sql_render_add_token (render, "USING");
sql_render_append (render, "(");
sql_render_add_list (render, TRUE, NULL, self->using_fields, ",");
sql_render_append (render, ")");
}
else
sql_render_add_item (render, FALSE, "ON", self->condition);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
void sql_join_set_target_left (SqlJoin * obj, SqlTarget * target)
SqlJoinType sql_join_get_join_type (SqlJoin * self)
{
g_return_if_fail (SQL_IS_JOIN (obj));
g_return_if_fail (SQL_IS_TARGET (target));
g_return_if_fail (SQL_IS_JOIN (self));
g_clear_object (&obj->target_left);
obj->target_left = g_object_ref_sink (target);
return self->type;
}
void sql_join_set_target_right (SqlJoin * obj, SqlTarget * target)
void sql_join_set_target_left (SqlJoin * self, SqlTarget * target)
{
g_return_if_fail (SQL_IS_JOIN (obj));
g_return_if_fail (SQL_IS_TARGET (target));
g_return_if_fail (SQL_IS_JOIN (self));
g_return_if_fail (SQL_IS_TARGET (target) || SQL_IS_HOLDER (target) || !target);
g_clear_object (&obj->target_right);
obj->target_right = g_object_ref_sink (target);
sql_object_remove (self, self->target_left);
self->target_left = sql_object_add (self, target);
}
void sql_join_set_condition (SqlJoin * obj, SqlExpr * condition)
void sql_join_set_target_right (SqlJoin * self, SqlTarget * target)
{
g_return_if_fail (SQL_IS_JOIN (obj));
g_return_if_fail (SQL_IS_EXPR (condition));
g_return_if_fail (SQL_IS_JOIN (self));
g_return_if_fail (SQL_IS_TARGET (target) || SQL_IS_HOLDER (target) || !target);
g_clear_object (&obj->condition);
obj->condition = g_object_ref_sink (condition);
sql_object_remove (self, self->target_right);
self->target_right = sql_object_add (self, target);
}
void sql_join_set_condition (SqlJoin * self, SqlExpr * condition)
{
g_return_if_fail (SQL_IS_JOIN (self));
g_return_if_fail (SQL_IS_EXPR (condition) || SQL_IS_HOLDER (condition) || !condition);
sql_object_remove (self, self->condition);
self->condition = sql_object_add (self, condition);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@ -91,67 +109,84 @@ enum
,PROP_TARGET_RIGHT
,PROP_TYPE
,PROP_CONDITION
,PROP_HAS_USING
,PROP_USING_FIELDS
};
static void sql_join_set_property (SqlJoin * obj, guint id,
static void sql_join_set_property (SqlJoin * self, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_TARGET_LEFT:
sql_join_set_target_left (obj, g_value_get_object (value));
sql_join_set_target_left (self, g_value_get_object (value));
break;
case PROP_TARGET_RIGHT:
sql_join_set_target_right (obj, g_value_get_object (value));
sql_join_set_target_right (self, g_value_get_object (value));
break;
case PROP_TYPE:
obj->type = g_value_get_int (value);
self->type = g_value_get_enum (value);
break;
case PROP_CONDITION:
sql_join_set_condition (obj, g_value_get_object (value));
sql_join_set_condition (self, g_value_get_object (value));
break;
case PROP_HAS_USING:
self->has_using = g_value_get_boolean (value);
break;
case PROP_USING_FIELDS:
sql_object_remove (self, self->using_fields);
self->using_fields = sql_object_add (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
static void sql_join_get_property (SqlJoin * obj, guint id,
static void sql_join_get_property (SqlJoin * self, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_TARGET_LEFT:
g_value_set_object (value, obj->target_left);
g_value_set_object (value, self->target_left);
break;
case PROP_TARGET_RIGHT:
g_value_set_object (value, obj->target_right);
g_value_set_object (value, self->target_right);
break;
case PROP_TYPE:
g_value_set_int (value, obj->type);
g_value_set_enum (value, self->type);
break;
case PROP_CONDITION:
g_value_set_object (value, obj->condition);
g_value_set_object (value, self->condition);
break;
case PROP_HAS_USING:
g_value_set_boolean (value, self->has_using);
break;
case PROP_USING_FIELDS:
g_value_set_object (value, self->using_fields);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_join_init (SqlJoin * obj)
static void sql_join_init (SqlJoin * self)
{
obj->target_left = NULL;
obj->target_right = NULL;
obj->condition = NULL;
self->target_left = NULL;
self->target_right = NULL;
self->condition = NULL;
self->using_fields = NULL;
}
static void sql_join_finalize (SqlJoin * obj)
static void sql_join_finalize (SqlJoin * self)
{
g_clear_object (&obj->target_left);
g_clear_object (&obj->target_right);
g_clear_object (&obj->condition);
G_OBJECT_CLASS (sql_join_parent_class)->finalize (G_OBJECT (obj));
sql_object_remove (self, self->target_left);
sql_object_remove (self, self->target_right);
sql_object_remove (self, self->condition);
sql_object_remove (self, self->using_fields);
G_OBJECT_CLASS (sql_join_parent_class)->finalize (G_OBJECT (self));
}
static void sql_join_class_init (SqlJoinClass * klass)
@ -163,31 +198,67 @@ static void sql_join_class_init (SqlJoinClass * klass)
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_join_render;
g_object_class_install_property (k, PROP_TARGET_LEFT,
g_param_spec_object ("target-left"
,"Left target"
,"The left target in the join"
sql_param_list ("target-left"
,("Left target")
,("The left target in the join")
,SQL_TYPE_TARGET
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_TARGET_RIGHT,
g_param_spec_object ("target-right"
,"Right target"
,"The right target in the join"
sql_param_list ("target-right"
,("Right target")
,("The right target in the join")
,SQL_TYPE_TARGET
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_TYPE,
g_param_spec_int ("join-type"
,"Type"
,"The type of join"
,0, SQL_JOIN_TYPE_COUNT - 1, SQL_JOIN_TYPE_INNER
g_param_spec_enum ("join-type"
,("Type")
,("The type of join")
,SQL_TYPE_JOIN_TYPE
,SQL_JOIN_TYPE_INNER
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_CONDITION,
g_param_spec_object ("condition"
,"Condition"
,"The condition used for the join"
sql_param_list ("condition"
,("Condition")
,("The condition used for the join")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_HAS_USING,
g_param_spec_boolean ("has-using"
,("Has using")
,("Wether the condition is a USING")
,FALSE
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
g_object_class_install_property (k, PROP_CONDITION,
sql_param_list ("using-fields"
,("Using fields")
,("The list of fields of the USING")
,SQL_TYPE_FIELD
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
}
GType sql_join_type_get_type ()
{
static GType type = 0;
if (type == 0)
{
static const GEnumValue values[] =
{
{SQL_JOIN_TYPE_INNER ,"SQL_JOIN_TYPE_INNER" ,"inner"
},{SQL_JOIN_TYPE_LEFT ,"SQL_JOIN_TYPE_LEFT" ,"left"
},{SQL_JOIN_TYPE_RIGHT ,"SQL_JOIN_TYPE_RIGHT" ,"right"
},{0, NULL, NULL}
};
type = g_enum_register_static
(g_intern_static_string ("SqlJoinType"), values);
}
return type;
}

View File

@ -22,8 +22,10 @@
#include "sql-expr.h"
#define SQL_TYPE_JOIN (sql_join_get_type ())
#define SQL_IS_JOIN(object) (G_TYPE_CHECK_INSTANCE_TYPE (object, SQL_TYPE_JOIN))
#define SQL_JOIN(object) (G_TYPE_CHECK_INSTANCE_CAST (object, SQL_TYPE_JOIN, SqlJoin))
#define SQL_IS_JOIN(self) (G_TYPE_CHECK_INSTANCE_TYPE (self, SQL_TYPE_JOIN))
#define SQL_JOIN(self) (G_TYPE_CHECK_INSTANCE_CAST (self, SQL_TYPE_JOIN, SqlJoin))
#define SQL_TYPE_JOIN_TYPE (sql_join_type_get_type ())
typedef struct _SqlJoin SqlJoin;
typedef struct _SqlJoinClass SqlJoinClass;
@ -44,6 +46,8 @@ struct _SqlJoin
SqlTarget * target_right;
SqlJoinType type;
SqlExpr * condition;
gboolean has_using;
SqlList * using_fields;
};
struct _SqlJoinClass
@ -53,9 +57,12 @@ struct _SqlJoinClass
};
GType sql_join_get_type ();
SqlTarget * sql_join_new (SqlTarget * left, SqlTarget * right, SqlJoinType type);
void sql_join_set_condition (SqlJoin * obj, SqlExpr * condition);
void sql_join_set_target_right (SqlJoin * obj, SqlTarget * target);
void sql_join_set_target_left (SqlJoin * obj, SqlTarget * target);
GType sql_join_type_get_type ();
SqlObject * sql_join_new (SqlTarget * left, SqlTarget * right, SqlJoinType type);
SqlJoinType sql_join_get_join_type (SqlJoin * self);
void sql_join_set_condition (SqlJoin * self, SqlExpr * condition);
void sql_join_set_target_right (SqlJoin * self, SqlTarget * target);
void sql_join_set_target_left (SqlJoin * self, SqlTarget * target);
#endif

313
sql/sql-list.c Normal file
View File

@ -0,0 +1,313 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sql-list.h"
#include "sql-holder.h"
/**
* SECTION: sql-list
* @Short_description: Container for a list of #SqlObject of a certain type
* @Title: SqlList
**/
G_DEFINE_TYPE (SqlList, sql_list, SQL_TYPE_OBJECT);
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)
{
GList * i;
for (i = obj->items.head; i; i = i->next)
{
sql_render_add_object (render, i->data);
if (i->next)
sql_render_append (render, ", ");
}
}
static gboolean sql_list_is_ready (SqlList * obj)
{
GList * i;
for (i = obj->items.head; i; i = i->next)
if (!sql_object_is_ready (i->data))
return FALSE;
return TRUE;
}
static void sql_list_find_holders (SqlList * obj, SqlBatch * batch)
{
GList * i;
for (i = obj->items.head; i; i = i->next)
sql_object_get_holders (i->data, batch);
}
static void sql_list_item_changed (SqlObject * item, SqlObject * obj)
{
sql_object_changed (obj);
}
static void sql_list_item_unref (SqlList * obj, SqlObject * item)
{
g_signal_handlers_disconnect_by_func (item,
sql_list_item_changed, obj);
g_object_unref (item);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
/**
* sql_list_add:
* @obj: the #SqlList
* @item: (allow-none): the #SqlObject
*
* Adds an item to the end of the list.
**/
void sql_list_add (SqlList * obj, gpointer item)
{
g_return_if_fail (SQL_IS_LIST (obj));
sql_list_insert (obj, item, -1);
}
/**
* sql_list_insert:
* @obj: the #SqlList
* @item: (allow-none): the #SqlObject
* @index: the position in which to place the item
*
* Adds an item to the list. If position is a negative number the element will
* be added to the end of the list.
**/
void sql_list_insert (SqlList * obj, gpointer item, guint index)
{
g_return_if_fail (SQL_IS_LIST (obj));
g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (item, obj->gtype) || SQL_IS_HOLDER (item) || !item);
if (!g_queue_find (&obj->items, item))
g_signal_connect (item, "changed",
G_CALLBACK (sql_list_item_changed), obj);
if (index > 0)
g_queue_push_nth (&obj->items, g_object_ref_sink (item), index);
else
g_queue_push_tail (&obj->items, g_object_ref_sink (item));
}
/**
* sql_list_get:
* @obj: the #SqlList
* @index: the index of the item
*
* Gets an item from the list.
*
* Return value: (transfer none) (allow-none): the selected #SqlObject
**/
gpointer sql_list_get (SqlList * obj, guint index)
{
g_return_val_if_fail (SQL_IS_LIST (obj), NULL);
return g_queue_peek_nth (&obj->items, index);
}
/**
* sql_list_remove:
* @obj: the #SqlList
* @index: the index of the item to remove
*
* Removes an item from the list.
**/
void sql_list_remove (SqlList * obj, guint index)
{
SqlObject * item;
g_return_val_if_fail (SQL_IS_LIST (obj), NULL);
item = g_queue_pop_nth (&obj->items, index);
if (!g_queue_find (&obj->items, item))
sql_list_item_unref (obj, item);
}
/**
* sql_list_remove_item:
* @obj: the #SqlList
* @item: the item to remove
*
* Removes an item from the list.
**/
void sql_list_remove_item (SqlList * obj, SqlObject * item)
{
g_return_if_fail (SQL_IS_LIST (obj));
g_return_if_fail (SQL_IS_OBJECT (item));
g_queue_remove_all (&obj->items, item);
sql_list_item_unref (obj, item);
}
/**
* sql_list_get_items:
* @obj: the #SqlList
*
* Gets all list elements.
*
* Return value: (transfer none) (allow-none) (element-type Sql.Object): the
* list items
**/
GList * sql_list_get_items (SqlList * obj)
{
g_return_val_if_fail (SQL_IS_LIST (obj), NULL);
return obj->items.head;
}
/**
* sql_list_get_items_type:
* @obj: the #SqlList
*
* Gets the allowed type for the list elements.
*
* Return value: the #GType
**/
GType sql_list_get_items_type (SqlList * obj)
{
g_return_val_if_fail (SQL_IS_LIST (obj), 0);
return obj->gtype;
}
/**
* sql_list_lenght:
* @obj: the #SqlList
*
* Gets the number of items in the list.
*
* Return value: the number of items
**/
guint sql_list_length (SqlList * obj)
{
g_return_val_if_fail (SQL_IS_LIST (obj), 0);
return obj->items.length;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum
{
PROP_GTYPE = 1
,PROP_LENGTH
};
static void sql_list_set_property (SqlList * obj, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_GTYPE:
obj->gtype = g_value_get_gtype (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
static void sql_list_get_property (SqlList * obj, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_GTYPE:
g_value_set_gtype (value, obj->gtype);
break;
case PROP_LENGTH:
g_value_set_uint (value, sql_list_length (obj));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_list_init (SqlList * obj)
{
g_queue_init (&obj->items);
}
static void sql_list_finalize (SqlList * obj)
{
GList * i;
for (i = obj->items.head; i; i = i->next)
{
g_signal_handlers_disconnect_by_func (i->data,
sql_list_item_changed, obj);
g_object_unref (i->data);
}
g_queue_clear (&obj->items);
G_OBJECT_CLASS (sql_list_parent_class)->finalize (G_OBJECT (obj));
}
static void sql_list_class_init (SqlListClass * k)
{
GObjectClass * klass = G_OBJECT_CLASS (k);
klass->finalize = (GObjectFinalizeFunc) sql_list_finalize;
klass->set_property = (GObjectSetPropertyFunc) sql_list_set_property;
klass->get_property = (GObjectGetPropertyFunc) sql_list_get_property;
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_list_render;
SQL_OBJECT_CLASS (klass)->is_ready = (SqlObjectIsReadyFunc) sql_list_is_ready;
SQL_OBJECT_CLASS (klass)->find_holders = (SqlObjectFindHoldersFunc) sql_list_find_holders;
g_object_class_install_property (klass, PROP_LENGTH,
g_param_spec_uint ("length"
,_("Length")
,_("The length of the list")
,0, G_MAXUINT, 0
,G_PARAM_READABLE
));
g_object_class_install_property (klass, PROP_GTYPE,
g_param_spec_gtype ("gtype"
,_("GType")
,_("The allowed type for the items")
,SQL_TYPE_OBJECT
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
));
}

55
sql/sql-list.h Normal file
View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SQL_LIST_H
#define SQL_LIST_H
#define SQL_TYPE_LIST (sql_list_get_type ())
#define SQL_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_LIST, SqlList))
#define SQL_IS_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_LIST))
typedef struct _SqlList SqlList;
typedef struct _SqlListClass SqlListClass;
#include "sql-object.h"
struct _SqlList
{
SqlObject parent;
GType gtype;
GQueue items;
};
struct _SqlListClass
{
/* <private> */
SqlObjectClass parent;
};
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);
void sql_list_remove (SqlList * obj, guint index);
void sql_list_remove_item (SqlList * obj, SqlObject * item);
GList * sql_list_get_items (SqlList * obj);
GType sql_list_get_items_type (SqlList * obj);
guint sql_list_length (SqlList * obj);
#endif

View File

@ -26,7 +26,7 @@
**/
G_DEFINE_TYPE (SqlMultiStmt, sql_multi_stmt, SQL_TYPE_STMT);
SqlMultiStmt * sql_multi_stmt_new ()
SqlObject * sql_multi_stmt_new ()
{
return g_object_new (SQL_TYPE_MULTI_STMT, NULL);
}
@ -35,34 +35,69 @@ SqlMultiStmt * sql_multi_stmt_new ()
static void sql_multi_stmt_render (SqlMultiStmt * obj, SqlRender * render)
{
sql_render_add_list (render, T, NULL, obj->stmt, ";");
sql_render_add_list (render, TRUE, NULL, obj->stmts, ";");
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
void sql_multi_stmt_add_stmt (SqlMultiStmt * obj, SqlStmt * stmt)
enum
{
g_return_if_fail (SQL_IS_MULTI_STMT (obj));
g_return_if_fail (SQL_IS_STMT (stmt));
PROP_STMTS = 1
};
obj->stmt = g_slist_append (obj->stmt, g_object_ref_sink (stmt));
static void sql_mutli_stmt_set_property (SqlMultiStmt * obj, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_STMTS:
sql_object_remove (obj, obj->stmts);
obj->stmts = sql_object_add (obj, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
static void sql_mutli_stmt_get_property (SqlMultiStmt * obj, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_STMTS:
g_value_set_object (value, obj->stmts);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_multi_stmt_init (SqlMultiStmt * obj)
{
obj->stmt = NULL;
obj->stmts = NULL;
}
static void sql_multi_stmt_finalize (SqlMultiStmt * obj)
{
g_slist_free_full (obj->stmt, g_object_unref);
sql_object_remove (obj, obj->stmts);
G_OBJECT_CLASS (sql_multi_stmt_parent_class)->finalize (G_OBJECT (obj));
}
static void sql_multi_stmt_class_init (SqlMultiStmtClass * klass)
{
G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) sql_multi_stmt_finalize;
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) sql_multi_stmt_finalize;
k->set_property = (GObjectSetPropertyFunc) sql_mutli_stmt_set_property;
k->get_property = (GObjectGetPropertyFunc) sql_mutli_stmt_get_property;
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_multi_stmt_render;
g_object_class_install_property (k, PROP_STMTS,
sql_param_list ("stmts"
,("Statements")
,("The list of statements")
,SQL_TYPE_STMT
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
}

View File

@ -22,7 +22,7 @@
#define SQL_TYPE_MULTI_STMT (sql_multi_stmt_get_type ())
#define SQL_MULTI_STMT(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_MULTI_STMT, SqlMultiStmt))
#define SQL_IS_MULTI_STMT(object) (G_TYPE_CHECK_INSTANCE_TYPE (object, SQL_TYPE_MULTI_STMT))
#define SQL_IS_MULTI_STMT(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_MULTI_STMT))
typedef struct _SqlMultiStmt SqlMultiStmt;
typedef struct _SqlMultiStmtClass SqlMultiStmtClass;
@ -34,7 +34,7 @@ typedef struct _SqlMultiStmtClass SqlMultiStmtClass;
struct _SqlMultiStmt
{
SqlStmt parent;
GSList * stmt;
SqlList * stmts;
};
struct _SqlMultiStmtClass
@ -44,7 +44,6 @@ struct _SqlMultiStmtClass
};
GType sql_multi_stmt_get_type ();
SqlMultiStmt * sql_multi_stmt_new ();
void sql_multi_stmt_add_stmt (SqlMultiStmt * obj, SqlStmt * stmt);
SqlObject * sql_multi_stmt_new ();
#endif

View File

@ -16,6 +16,7 @@
*/
#include "sql-object.h"
#include "sql-value.h"
/**
* SECTION: sql-object
@ -35,65 +36,73 @@ static guint signals[LAST_SIGNAL] = {0};
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_object_list_changed (SqlObject * sub, SqlObject * obj)
static void sql_object_child_changed (SqlObject * child, SqlObject * obj)
{
g_signal_emit (obj, signals[CHANGED], 0);
sql_object_changed (obj);
}
static gboolean sql_object_is_ready_default (SqlObject * obj)
static void sql_object_find_holders (SqlObject * obj, SqlBatch * batch)
{
return TRUE;
guint i;
guint nparams;
GParamSpec ** params;
params = g_object_class_list_properties (G_OBJECT_GET_CLASS (obj), &nparams);
for (i = 0; i < nparams; i++)
if (SQL_IS_PARAM_OBJECT (params[i]) || SQL_IS_PARAM_LIST (params[i]))
{
SqlObject * child;
g_object_get (obj, params[i]->name, &child, NULL);
if (child)
sql_object_get_holders (child, batch);
}
g_free (params);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Protected
/**
* sql_object_list_add:
* @obj: #SqlObject where the new item will be appended
* @list: (element-type Sql.Object): #GSList where @sub is appened
* @sub: #SqlObject the object is appended
*
* Appends an item into a list of @obj. This function was created to perform an
* action very common in all objects that inherit from this class.
* sql_object_add:
* @obj: #SqlObject where the new item will be added
* @child: #SqlObject the object is added
*
* Note that this function is considered a protected method and should only
* be used in classes that inherit from #SqlObjectClass. Only this function
* should be able to modify @list. To release the list you can use
* sql_object_list_free().
* be used in classes that inherit from #SqlObjectClass.
*
* Return value: (transfer full):
**/
void sql_object_list_add (SqlObject * obj, GSList ** list, SqlObject * sub)
gpointer sql_object_add (gpointer obj, gpointer child)
{
*list = g_slist_append (*list, g_object_ref_sink (sub));
g_signal_connect (sub, "changed",
G_CALLBACK (sql_object_list_changed), obj
);
if (child)
{
g_object_ref_sink (child);
g_signal_connect (child, "changed",
G_CALLBACK (sql_object_child_changed), obj);
}
return child;
}
/**
* sql_object_list_free:
* @obj: #SqlObject where the item will be removed
* @list: (element-type Sql.Object): #GSList to release
*
* Releases a list of items, also disconnects its changed handler
* and calls g_object_unref() on every item.
* sql_object_remove:
* @obj: #SqlObject where the new item will be added
* @child: #SqlObject the object is added
*
* Note that this function is considered a protected method and should only
* be used in classes that inherit from #SqlObjectClass and whose list has only
* been handled by the function sql_object_list_add().
* be used in classes that inherit from #SqlObjectClass.
**/
void sql_object_list_free (SqlObject * obj, GSList * list)
void sql_object_remove (gpointer obj, gpointer child)
{
GSList * n;
for (n = list; n; n = n->next)
if (child)
{
g_signal_handlers_disconnect_by_func (n->data,
G_CALLBACK (sql_object_list_changed), obj
);
g_object_unref (n->data);
g_signal_handlers_disconnect_by_func (child,
sql_object_child_changed, obj);
g_object_unref (child);
}
g_slist_free (list);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
@ -105,12 +114,13 @@ void sql_object_list_free (SqlObject * obj, GSList * list)
*
* Renders the object into a SQL string and stores it into the renderer.
**/
void sql_object_render (SqlObject * obj, SqlRender * render)
void sql_object_render (SqlObject * obj, SqlRender * render, SqlBatch * batch)
{
g_return_if_fail (SQL_IS_OBJECT (obj));
g_return_if_fail (SQL_IS_RENDER (render));
g_return_if_fail (SQL_IS_BATCH (batch) || !batch);
return SQL_OBJECT_GET_CLASS (obj)->render (obj, render);
SQL_OBJECT_GET_CLASS (obj)->render (obj, render, batch);
}
/**
@ -123,28 +133,118 @@ void sql_object_render (SqlObject * obj, SqlRender * render)
**/
gboolean sql_object_is_ready (SqlObject * obj)
{
guint i;
guint nparams;
GParamSpec ** params;
gboolean is_ready = TRUE;
SqlObjectClass * klass;
g_return_val_if_fail (SQL_IS_OBJECT (obj), FALSE);
return SQL_OBJECT_GET_CLASS (obj)->is_ready (obj);
klass = SQL_OBJECT_GET_CLASS (obj);
params = g_object_class_list_properties (G_OBJECT_CLASS (klass), &nparams);
for (i = 0; i < nparams && is_ready; i++)
if (SQL_IS_PARAM_OBJECT (params[i]) || SQL_IS_PARAM_LIST (params[i]))
{
SqlObject * child;
g_object_get (obj, params[i]->name, &child, NULL);
is_ready = !child || sql_object_is_ready (child);
}
g_free (params);
if (klass->is_ready)
return klass->is_ready (obj);
else
return is_ready;
}
void sql_object_set (SqlObject * obj, const gchar * property, SqlObject * value)
{
g_return_if_fail (SQL_IS_OBJECT (obj));
g_return_if_fail (SQL_IS_OBJECT (value));
g_object_set (obj, property, value, NULL);
}
/**
* sql_object_get:
* Return value: (transfer none):
**/
SqlObject * sql_object_get (SqlObject * obj, const gchar * property)
{
SqlObject * value;
g_return_val_if_fail (SQL_IS_OBJECT (obj), NULL);
g_object_get (obj, property, &value, NULL);
return value;
}
void sql_object_add_child (SqlObject * obj, const gchar * property, SqlObject * child)
{
SqlList * list;
g_return_if_fail (SQL_IS_OBJECT (obj));
g_return_if_fail (SQL_IS_OBJECT (child));
g_object_get (obj, property, &list, NULL);
sql_list_add (list, child);
}
void sql_object_remove_child (SqlObject * obj, const gchar * property, guint n)
{
SqlList * list;
g_return_if_fail (SQL_IS_OBJECT (obj));
g_object_get (obj, property, &list, NULL);
sql_list_remove (list, n);
}
/**
* sql_object_get_holders:
* @obj: a #SqlObject
* @batch: an #SqlBatch
*
* Gets all identifiers of the contained holders.
**/
void sql_object_get_holders (SqlObject * obj, SqlBatch * batch)
{
g_return_if_fail (SQL_IS_OBJECT (obj));
g_return_if_fail (SQL_IS_BATCH (batch));
SQL_OBJECT_GET_CLASS (obj)->find_holders (obj, batch);
}
/**
* sql_object_changed:
* @obj: a #SqlObject
*
* Emits the changed signal on #SqlObject.
**/
void sql_object_changed (SqlObject * obj)
{
g_return_if_fail (SQL_IS_OBJECT (obj));
g_signal_emit (obj, signals[CHANGED], 0);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_object_init (SqlObject * obj)
{
obj->sql = NULL;
}
static void sql_object_init (SqlObject * obj) {}
static void sql_object_finalize (GObject * obj)
static void sql_object_finalize (SqlObject * obj)
{
g_free (SQL_OBJECT (obj)->sql);
G_OBJECT_CLASS (sql_object_parent_class)->finalize (obj);
G_OBJECT_CLASS (sql_object_parent_class)->finalize (G_OBJECT (obj));
}
static void sql_object_class_init (SqlObjectClass * klass)
{
G_OBJECT_CLASS (klass)->finalize = sql_object_finalize;
klass->is_ready = sql_object_is_ready_default;
G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) sql_object_finalize;
klass->find_holders = sql_object_find_holders;
klass->is_ready = NULL;
klass->render = NULL;
/**

View File

@ -19,6 +19,8 @@
#define SQL_OBJECT_H
#include <gvn/gvn.h>
#include "sql-param-object.h"
#include "sql-param-list.h"
#define SQL_TYPE_OBJECT (sql_object_get_type ())
#define SQL_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_OBJECT, SqlObject))
@ -29,14 +31,13 @@
typedef struct _SqlObject SqlObject;
typedef struct _SqlObjectClass SqlObjectClass;
#include "sql-render.h"
typedef gboolean (* SqlObjectIsReadyFunc) (SqlObject * obj);
typedef void (* SqlObjectFindHoldersFunc) (); // (SqlObject * obj, SqlBatch * holders);
typedef void (* SqlRenderFunc) (); // (SqlObject * obj, SqlRender * render, SqlBatch * batch);
struct _SqlObject
{
GInitiallyUnowned parent;
gchar * sql;
};
struct _SqlObjectClass
@ -45,12 +46,24 @@ struct _SqlObjectClass
GInitiallyUnownedClass parent;
SqlRenderFunc render;
SqlObjectIsReadyFunc is_ready;
SqlObjectFindHoldersFunc find_holders;
};
#include "sql-render.h"
#include "sql-batch.h"
GType sql_object_get_type ();
void sql_object_render (SqlObject * obj, SqlRender * render);
void sql_object_render (SqlObject * obj, SqlRender * render, SqlBatch * batch);
gboolean sql_object_is_ready (SqlObject * obj);
void sql_object_list_add (SqlObject * obj, GSList ** list, SqlObject * sub);
void sql_object_list_free (SqlObject * obj, GSList * list);
void sql_object_get_holders (SqlObject * obj, SqlBatch * batch);
void sql_object_set (SqlObject * obj, const gchar * property, SqlObject * set);
SqlObject * sql_object_get (SqlObject * obj, const gchar * property);
void sql_object_add_child (SqlObject * obj, const gchar * property, SqlObject * child);
void sql_object_remove_child (SqlObject * obj, const gchar * property, guint n);
void sql_object_changed (SqlObject * obj);
gpointer sql_object_add (gpointer obj, gpointer child);
void sql_object_remove (gpointer obj, gpointer child);
#endif

View File

@ -29,20 +29,23 @@
**/
G_DEFINE_TYPE (SqlOperation, sql_operation, SQL_TYPE_EXPR);
SqlOperation * 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
static const gchar * SQL_OPERATION_TYPE[] =
{
"*"
"NOT"
,"-"
,"+"
,"*"
,"/"
,"+"
,"-"
,"NOT"
,"IS"
,"="
,"!="
@ -54,43 +57,71 @@ static const gchar * SQL_OPERATION_TYPE[] =
,"AND"
,"OR"
,"XOR"
,"%"
,"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, T, NULL, obj->expr,
SQL_OPERATION_TYPE[obj->type]);
sql_render_add_list (render, TRUE, NULL, self->operands,
SQL_OPERATION_TYPE[self->type]);
sql_render_append (render, ")");
}
static gboolean sql_operation_is_ready (SqlOperation * obj)
{
GSList * n;
for (n = obj->expr; n; n = n->next)
if (!sql_object_is_ready (n->data))
return FALSE;
return TRUE;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
/**
* sql_operation_add_expr:
* @obj: an #SqlOperation.
* @expr: an #SqlExpr.
* sql_operation_get_operator:
* @self: a #SqlOperation
*
* Adds an expression to an existing operation.
* Return value: the operation type
**/
void sql_operation_add_expr (SqlOperation * obj, SqlExpr * expr)
SqlOperationType sql_operation_get_operator (SqlOperation * self)
{
g_return_if_fail (SQL_IS_OPERATION (obj));
g_return_if_fail (SQL_IS_EXPR (expr));
g_return_val_if_fail (SQL_IS_OPERATION (self), 0);
sql_object_list_add (SQL_OBJECT (obj), &obj->expr, SQL_OBJECT (expr));
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
* @operands: 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
@ -98,46 +129,52 @@ void sql_operation_add_expr (SqlOperation * obj, SqlExpr * expr)
enum
{
PROP_TYPE = 1
,PROP_COUNT
,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_int (value);
self->type = g_value_get_enum (value);
break;
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_int (value, obj->type);
g_value_set_enum (value, self->type);
break;
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->expr = NULL;
self->operands = NULL;
}
static void sql_operation_finalize (SqlOperation * obj)
static void sql_operation_finalize (SqlOperation * self)
{
sql_object_list_free (SQL_OBJECT (obj), obj->expr);
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)
@ -147,13 +184,58 @@ static void sql_operation_class_init (SqlOperationClass * klass)
k->set_property = (GObjectSetPropertyFunc) sql_operation_set_property;
k->get_property = (GObjectGetPropertyFunc) sql_operation_get_property;
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_operation_render;
SQL_OBJECT_CLASS (klass)->is_ready = (SqlObjectIsReadyFunc) sql_operation_is_ready;
g_object_class_install_property (k, PROP_TYPE,
g_param_spec_int ("type"
,"Type"
,"The type of the operation"
,0, SQL_OPERATION_TYPE_COUNT, 0
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_OPERANDS,
sql_param_list ("operands"
,("Operators")
,("The list of operands")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
}
GType sql_operation_type_get_type ()
{
static GType type = 0;
if (type == 0)
{
static const GEnumValue values[] =
{
{SQL_OPERATION_TYPE_NOT ,"SQL_OPERATION_TYPE_NOT" ,"not"
},{SQL_OPERATION_TYPE_MINUS ,"SQL_OPERATION_TYPE_MINUS" ,"minus"
},{SQL_OPERATION_TYPE_PLUS ,"SQL_OPERATION_TYPE_PLUS" ,"plus"
},{SQL_OPERATION_TYPE_MULTIPLICATION ,"SQL_OPERATION_TYPE_MULTIPLICATION" ,"multiplication"
},{SQL_OPERATION_TYPE_DIVISION ,"SQL_OPERATION_TYPE_DIVISION" ,"division"
},{SQL_OPERATION_TYPE_SUM ,"SQL_OPERATION_TYPE_SUM" ,"sum"
},{SQL_OPERATION_TYPE_SUBTRACTION ,"SQL_OPERATION_TYPE_SUBTRACTION" ,"subtraction"
},{SQL_OPERATION_TYPE_IS ,"SQL_OPERATION_TYPE_IS" ,"is"
},{SQL_OPERATION_TYPE_EQUAL ,"SQL_OPERATION_TYPE_EQUAL" ,"equal"
},{SQL_OPERATION_TYPE_NOT_EQUAL ,"SQL_OPERATION_TYPE_NOT_EQUAL" ,"not-equal"
},{SQL_OPERATION_TYPE_GREATER_EQUAL ,"SQL_OPERATION_TYPE_GREATER_EQUAL" ,"greater-equal"
},{SQL_OPERATION_TYPE_GREATER ,"SQL_OPERATION_TYPE_GREATER" ,"greater"
},{SQL_OPERATION_TYPE_LOWER_EQUAL ,"SQL_OPERATION_TYPE_LOWER_EQUAL" ,"lower-equal"
},{SQL_OPERATION_TYPE_LOWER ,"SQL_OPERATION_TYPE_LOWER" ,"lower"
},{SQL_OPERATION_TYPE_LIKE ,"SQL_OPERATION_TYPE_LIKE" ,"like"
},{SQL_OPERATION_TYPE_AND ,"SQL_OPERATION_TYPE_AND" ,"and"
},{SQL_OPERATION_TYPE_OR ,"SQL_OPERATION_TYPE_OR" ,"or"
},{SQL_OPERATION_TYPE_XOR ,"SQL_OPERATION_TYPE_XOR" ,"xor"
},{SQL_OPERATION_TYPE_MOD ,"SQL_OPERATION_TYPE_MOD" ,"mod"
},{SQL_OPERATION_TYPE_IN ,"SQL_OPERATION_TYPE_IN" ,"in"
},{0, NULL, NULL}
};
type = g_enum_register_static
(g_intern_static_string ("SqlOperationType"), values);
}
return type;
}

View File

@ -24,16 +24,23 @@
#define SQL_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_OPERATION, SqlOperation))
#define SQL_IS_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_OPERATION))
#define SQL_TYPE_OPERATION_TYPE (sql_operation_type_get_type ())
typedef struct _SqlOperation SqlOperation;
typedef struct _SqlOperationClass SqlOperationClass;
typedef enum
{
SQL_OPERATION_TYPE_MULTIPLICATION
// Unary
SQL_OPERATION_TYPE_NOT
,SQL_OPERATION_TYPE_MINUS
,SQL_OPERATION_TYPE_PLUS
// Binary
,SQL_OPERATION_TYPE_MULTIPLICATION
,SQL_OPERATION_TYPE_DIVISION
,SQL_OPERATION_TYPE_SUM
,SQL_OPERATION_TYPE_REST
,SQL_OPERATION_TYPE_NOT
,SQL_OPERATION_TYPE_SUBTRACTION
,SQL_OPERATION_TYPE_IS
,SQL_OPERATION_TYPE_EQUAL
,SQL_OPERATION_TYPE_NOT_EQUAL
@ -45,6 +52,8 @@ typedef enum
,SQL_OPERATION_TYPE_AND
,SQL_OPERATION_TYPE_OR
,SQL_OPERATION_TYPE_XOR
,SQL_OPERATION_TYPE_MOD
,SQL_OPERATION_TYPE_IN
,SQL_OPERATION_TYPE_COUNT
}
SqlOperationType;
@ -57,7 +66,7 @@ SqlOperationType;
struct _SqlOperation
{
SqlExpr parent;
GSList * expr; // List of SqlExpr pointers
SqlList * operands; // List of SqlExpr
SqlOperationType type;
};
@ -68,7 +77,12 @@ struct _SqlOperationClass
};
GType sql_operation_get_type ();
SqlOperation * sql_operation_new (SqlOperationType type);
void sql_operation_add_expr (SqlOperation * obj, SqlExpr * expr);
GType sql_operation_type_get_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

112
sql/sql-param-list.c Normal file
View File

@ -0,0 +1,112 @@
/*
* Copyright (C) 2013 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sql-param-list.h"
#include "sql-holder.h"
/**
* sql_param_list:
* Return value: (transfer full):
**/
GParamSpec *
sql_param_list (const gchar * name, const gchar * nick,
const gchar * blurb, GType items_type, GParamFlags flags)
{
SqlParamList * pspec;
g_return_val_if_fail (g_type_is_a (items_type, SQL_TYPE_OBJECT), NULL);
pspec = g_param_spec_internal (SQL_TYPE_PARAM_OBJECT
,name
,nick
,blurb
,flags
);
pspec->items_type = items_type;
return G_PARAM_SPEC (pspec);
}
static void
sql_param_list_init (GParamSpec * pspec) {}
static void
sql_param_list_set_default (GParamSpec * pspec, GValue * value)
{
SqlList * list = sql_list_new (SQL_PARAM_LIST (pspec)->items_type);
g_value_set_object (value, list);
}
static gboolean
sql_param_list_validate (GParamSpec * pspec, GValue * value)
{
GType type;
gboolean change;
gpointer object = g_value_get_object (value);
if (!object)
return FALSE;
type = G_OBJECT_TYPE (object);
change = !(
(g_value_type_compatible (type, SQL_TYPE_LIST)
&& SQL_PARAM_LIST (pspec)->items_type == sql_list_get_items_type (object))
|| g_value_type_compatible (type, SQL_TYPE_HOLDER)
);
if (change)
g_value_set_object (value, NULL);
return change;
}
static gint
sql_param_list_values_cmp (GParamSpec * pspec, const GValue * a, const GValue * b)
{
guint8 * pa = g_value_get_object (a);
guint8 * pb = g_value_get_object (b);
return pa < pb ? -1 : pa > pb;
}
GType
sql_param_list_get_type ()
{
static GType type = 0;
if (!type)
{
GParamSpecTypeInfo pspec_info =
{
sizeof (SqlParamList)
,16
,sql_param_list_init
,SQL_TYPE_LIST
,NULL
,sql_param_list_set_default
,sql_param_list_validate
,sql_param_list_values_cmp
};
type = g_param_type_register_static (
g_intern_static_string ("SqlParamList"), &pspec_info);
}
return type;
}

42
sql/sql-param-list.h Normal file
View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2013 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SQL_PARAM_LIST_H
#define SQL_PARAM_LIST_H
#include "sql-object.h"
#define SQL_TYPE_PARAM_LIST (sql_param_list_get_type ())
#define SQL_PARAM_LIST(pspec) (G_TYPE_CHECK_INSTANCE_CAST (pspec, SQL_TYPE_PARAM_LIST, SqlParamList))
#define SQL_IS_PARAM_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_PARAM_LIST))
typedef struct
{
GParamSpec parent;
GType items_type;
}
SqlParamList;
GType sql_param_list_get_type ();
GParamSpec * sql_param_list (const gchar * name
,const gchar * nick
,const gchar * blurb
,GType items_type
,GParamFlags flags);
#endif

108
sql/sql-param-object.c Normal file
View File

@ -0,0 +1,108 @@
/*
* Copyright (C) 2013 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sql-param-object.h"
#include "sql-holder.h"
/**
* sql_param_object:
* Return value: (transfer full):
**/
GParamSpec *
sql_param_object (const gchar * name, const gchar * nick,
const gchar * blurb, GType object_type, GParamFlags flags)
{
GParamSpec * pspec;
g_return_val_if_fail (g_type_is_a (object_type, SQL_TYPE_OBJECT), NULL);
pspec = g_param_spec_internal (SQL_TYPE_PARAM_OBJECT
,name
,nick
,blurb
,flags
);
return pspec;
}
static void
sql_param_object_init (GParamSpec * pspec) {}
static void
sql_param_object_set_default (GParamSpec * pspec, GValue * value)
{
g_value_set_object (value, NULL);
}
static gboolean
sql_param_object_validate (GParamSpec * pspec, GValue * value)
{
GType type;
gboolean change;
GObject * object = g_value_get_object (value);
if (!object)
return FALSE;
type = G_OBJECT_TYPE (object);
change = !(
g_value_type_compatible (type, G_PARAM_SPEC_VALUE_TYPE (pspec))
|| g_value_type_compatible (type, SQL_TYPE_HOLDER)
);
if (change)
g_value_set_object (value, NULL);
return change;
}
static gint
sql_param_object_values_cmp (GParamSpec * pspec, const GValue * a, const GValue * b)
{
guint8 * pa = g_value_get_object (a);
guint8 * pb = g_value_get_object (b);
return pa < pb ? -1 : pa > pb;
}
GType
sql_param_object_get_type ()
{
static GType type = 0;
if (!type)
{
GParamSpecTypeInfo pspec_info =
{
sizeof (SqlParamObject)
,16
,sql_param_object_init
,SQL_TYPE_OBJECT
,NULL
,sql_param_object_set_default
,sql_param_object_validate
,sql_param_object_values_cmp
};
type = g_param_type_register_static (
g_intern_static_string ("SqlParamObject"), &pspec_info);
}
return type;
}

40
sql/sql-param-object.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2013 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SQL_PARAM_OBJECT_H
#define SQL_PARAM_OBJECT_H
#include "sql-object.h"
#define SQL_TYPE_PARAM_OBJECT (sql_param_object_get_type ())
#define SQL_PARAM_OBJECT(pspec) (G_TYPE_CHECK_INSTANCE_CAST (pspec, SQL_TYPE_PARAM_OBJECT, SqlParamObject))
#define SQL_IS_PARAM_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_PARAM_OBJECT))
typedef struct
{
GParamSpec parent;
}
SqlParamObject;
GType sql_param_object_get_type ();
GParamSpec * sql_param_object (const gchar * name
,const gchar * nick
,const gchar * blurb
,GType object_type
,GParamFlags flags);
#endif

View File

@ -19,32 +19,18 @@
#define SQL_PARSER_H
#include "sql-object.h"
#include "sql-field.h"
#define SQL_PARSER_LOG_DOMAIN (g_quark_from_string ("SqlParser"))
/**
* sql_parser_parse:
* @sql: a string containing an SQL query
* @sql: An string containing an SQL query.
* @err: (out) (allow-none): a return location of a #GError or %NULL to ignore
* errors
*
* Parses @sql and makes an #SqlObject from the query on it.
*
* Return value: (transfer full): an #SqlObject
* Return value: (transfer full): an #SqlObject.
*/
SqlObject * sql_parser_parse (const gchar * sql, GError ** err) G_GNUC_WARN_UNUSED_RESULT;
/**
* sql_parser_parse_field:
* @field: a string containing a field name
*
* Parses a qualified or unqualified SQL field name to an #SqlField object. The
* field can be specified using both ` or " as quotes. This object must be
* unreferenced using g_object_unref().
*
* Return value: (transfer full): an #SqlField
**/
SqlField * sql_parser_parse_field (const gchar * field);
#endif

View File

@ -56,16 +56,19 @@ SqlRender * sql_render_new (gchar delimiter)
*
* Return value: a string with the rendered statement of %NULL if error.
**/
gchar * sql_render_get_string (SqlRender * obj, gpointer object, gpointer data, GError ** err)
gchar * sql_render_get_string (SqlRender * obj, gpointer object, SqlBatch * batch, gpointer data, GError ** err)
{
gchar * sql;
g_return_val_if_fail (SQL_IS_RENDER (obj), NULL);
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
g_return_val_if_fail (SQL_IS_BATCH (batch) || !batch, NULL);
obj->data = data;
obj->object = g_object_ref (object);
obj->batch = batch ? g_object_ref (batch) : NULL;
obj->buffer = g_string_sized_new (SQL_BUFFER_SIZE);
obj->ancestors = NULL;
sql_render_add_object (obj, object);
@ -83,6 +86,9 @@ gchar * sql_render_get_string (SqlRender * obj, gpointer object, gpointer data,
sql = g_string_free (obj->buffer, FALSE);
g_clear_object (&obj->object);
g_clear_object (&obj->batch);
g_slist_free (obj->ancestors);
obj->ancestors = NULL;
obj->buffer = NULL;
obj->data = NULL;
return sql;
@ -101,7 +107,23 @@ void sql_render_register_function (SqlRender * obj, GType type, SqlRenderFunc fu
{
g_return_if_fail (SQL_IS_RENDER (obj));
g_hash_table_insert (obj->symbol_table, GUINT_TO_POINTER (type), function);
g_hash_table_insert (obj->custom_renderers, GUINT_TO_POINTER (type), function);
}
/**
* sql_render_get_ancestors:
* @obj: the #SqlRender
*
* Obtains a list of parents of the currently rendered object, including it.
*
* Return value: (transfer none) (element-type GObject): the #GSList with the
* parents, the list should not be edited or freed.
**/
GSList * sql_render_get_ancestors (SqlRender * obj)
{
g_return_val_if_fail (SQL_IS_RENDER (obj), NULL);
return obj->ancestors;
}
/**
@ -120,13 +142,16 @@ void sql_render_add_object (SqlRender * obj, gpointer object)
if (object)
{
function = g_hash_table_lookup (obj->symbol_table,
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);
function (object, obj, obj->batch);
else
sql_object_render (object, obj);
sql_object_render (object, obj, obj->batch);
obj->ancestors = g_slist_delete_link (obj->ancestors, obj->ancestors);
}
}
@ -274,31 +299,18 @@ void sql_render_add_item (SqlRender * obj, gboolean required, const gchar * toke
* @obj: a #SqlRender
* @required:
* @token:
* @list: (element-type GObject.Object): a list of objects to add
* @list: a list of objects to add
* @separator:
*
*
**/
void sql_render_add_list (SqlRender * obj, gboolean required, const gchar * token,
GSList * list, const gchar * separator)
SqlList * list, const gchar * separator)
{
g_return_if_fail (SQL_IS_RENDER (obj));
g_return_if_fail (SQL_IS_LIST (list) || !list);
if (list)
{
GSList * n;
sql_render_add_token (obj, token);
for (n = list; n; n = n->next)
{
sql_render_add_object (obj, n->data);
if (n->next)
g_string_append_printf (obj->buffer, " %s", separator);
}
}
else if (required)
sql_render_set_error (obj);
sql_render_add_list_with_func (obj, required, token, list, separator, NULL);
}
/**
@ -306,27 +318,32 @@ void sql_render_add_list (SqlRender * obj, gboolean required, const gchar * toke
* @obj: a #SqlRender
* @required:
* @token:
* @list: (element-type GObject.Object):
* @list:
* @separator:
* @function: (scope call):
*
*
**/
void sql_render_add_list_with_func (SqlRender * obj, gboolean required, const gchar * token,
GSList * list, const gchar * separator, SqlRenderFunc function)
SqlList * list, const gchar * separator, SqlRenderFunc function)
{
g_return_if_fail (SQL_IS_RENDER (obj));
GList * i;
if (list)
g_return_if_fail (SQL_IS_RENDER (obj));
g_return_if_fail (SQL_IS_LIST (list) || !list);
if (list && (i = sql_list_get_items (list)))
{
GSList * n;
sql_render_add_token (obj, token);
for (n = list; n; n = n->next)
for (; i; i = i->next)
{
function (n->data, obj);
if (function)
function (i->data, obj, obj->batch);
else
sql_render_add_object (obj, i->data);
if (n->next)
if (i->next)
g_string_append_printf (obj->buffer, " %s", separator);
}
}
@ -389,7 +406,7 @@ static void sql_render_init (SqlRender * obj)
{
obj->buffer = NULL;
obj->error = NULL;
obj->symbol_table = g_hash_table_new (
obj->custom_renderers = g_hash_table_new (
g_direct_hash
,g_direct_equal
);
@ -397,7 +414,7 @@ static void sql_render_init (SqlRender * obj)
static void sql_render_finalize (SqlRender * obj)
{
g_hash_table_unref (obj->symbol_table);
g_hash_table_unref (obj->custom_renderers);
G_OBJECT_CLASS (sql_render_parent_class)->finalize (G_OBJECT (obj));
}

View File

@ -26,20 +26,16 @@
#define SQL_RENDER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_RENDER, SqlRender))
#define SQL_IS_RENDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_RENDER))
#define T TRUE
#define F FALSE
#define SQL_BUFFER_SIZE 500
typedef struct _SqlRender SqlRender;
typedef struct _SqlRenderClass SqlRenderClass;
typedef void (* SqlRenderFunc) (gpointer obj, SqlRender * render);
#include "sql-object.h"
#include "sql-batch.h"
/**
* SqlRender:
* @symbol_table: (element-type GType Sql.RenderFunc):
* @custom_renderers: (element-type GType Sql.RenderFunc):
**/
struct _SqlRender
{
@ -47,8 +43,10 @@ struct _SqlRender
GError * error;
GString * buffer;
gpointer object;
SqlBatch * batch;
GSList * ancestors;
gpointer data;
GHashTable * symbol_table;
GHashTable * custom_renderers;
gint8 delimiter;
};
@ -70,10 +68,14 @@ typedef enum
}
SqlRenderError;
#include "sql-object.h"
#include "sql-list.h"
GType sql_render_get_type ();
SqlRender * sql_render_new (gchar delimiter);
gchar * sql_render_get_string (SqlRender * obj, gpointer object, gpointer data, GError ** err);
gchar * sql_render_get_string (SqlRender * obj, gpointer object, SqlBatch * batch, gpointer data, GError ** err);
void sql_render_register_function (SqlRender * obj, GType type, SqlRenderFunc function);
GSList * sql_render_get_ancestors (SqlRender * obj);
void sql_render_add_espace (SqlRender * obj);
void sql_render_printf (SqlRender * obj, const gchar * string, ...);
void sql_render_append (SqlRender * obj, const gchar * string);
@ -82,8 +84,8 @@ void sql_render_add_token (SqlRender * obj, const gchar * token);
void sql_render_add_identifier (SqlRender * obj, const gchar * identifier);
void sql_render_add_object (SqlRender * obj, gpointer object);
void sql_render_add_item (SqlRender * obj, gboolean required, const gchar * token, gpointer item);
void sql_render_add_list (SqlRender * obj, gboolean required, const gchar * token, GSList * list, const gchar * separator);
void sql_render_add_list_with_func (SqlRender * obj, gboolean required, const gchar * token, GSList * list, const gchar * separator, SqlRenderFunc function);
void sql_render_add_list (SqlRender * obj, gboolean required, const gchar * token, SqlList * list, const gchar * separator);
void sql_render_add_list_with_func (SqlRender * obj, gboolean required, const gchar * token, SqlList * list, const gchar * separator, SqlRenderFunc function);
void sql_render_set_error (SqlRender * obj);
#endif

154
sql/sql-select-field.c Normal file
View File

@ -0,0 +1,154 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sql-select-field.h"
/**
* SECTION: sql-select_field
* @Short_description:
* @Title: SqlSelectField
**/
G_DEFINE_TYPE (SqlSelectField, sql_select_field, SQL_TYPE_OBJECT);
SqlObject * sql_select_field_new ()
{
return g_object_new (SQL_TYPE_SELECT_FIELD, NULL);
}
/**
* sql_select_field_get_alias:
* @self: an #SqlSelectField
*
* Gets the alias of @self.
*
* Return value: (transfer none): the field alias.
**/
const gchar * sql_select_field_get_alias (SqlSelectField * self)
{
g_return_val_if_fail (SQL_IS_SELECT_FIELD (self), NULL);
return self->alias;
}
/**
* sql_select_field_set_alias:
* @self: an #SqlSelectField
* @alias: (transfer none): new alias
*
* Sets the alias of @self to @alias.
**/
void sql_select_field_set_alias (SqlSelectField * self, const gchar * alias)
{
g_return_if_fail (SQL_IS_SELECT_FIELD (self));
g_free (self->alias);
self->alias = g_strdup (alias);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_select_field_render (SqlSelectField * self, SqlRender * render)
{
sql_render_add_object (render, self->expr);
if (self->alias)
{
sql_render_add_token (render, "AS");
sql_render_add_identifier (render, self->alias);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum
{
PROP_EXPR = 1
,PROP_ALIAS
};
static void sql_select_field_set_property (SqlSelectField * self, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_EXPR:
sql_object_remove (self, self->expr);
self->expr = sql_object_add (self, g_value_get_object (value));
break;
case PROP_ALIAS:
g_free (self->alias);
self->alias = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
static void sql_select_field_get_property (SqlSelectField * self, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_EXPR:
g_value_set_object (value, self->expr);
break;
case PROP_ALIAS:
g_value_set_string (value, self->alias);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_select_field_init (SqlSelectField * self)
{
self->expr = NULL;
self->alias = NULL;
}
static void sql_select_field_finalize (SqlSelectField * self)
{
g_free (self->alias);
sql_object_remove (self, self->expr);
G_OBJECT_CLASS (sql_select_field_parent_class)->finalize (G_OBJECT (self));
}
static void sql_select_field_class_init (SqlSelectFieldClass * klass)
{
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) sql_select_field_finalize;
k->set_property = (GObjectSetPropertyFunc) sql_select_field_set_property;
k->get_property = (GObjectGetPropertyFunc) sql_select_field_get_property;
SQL_OBJECT_CLASS (k)->render = (SqlRenderFunc) sql_select_field_render;
g_object_class_install_property (k, PROP_EXPR,
sql_param_object ("expr"
,("Expression")
,("The expression")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_ALIAS,
g_param_spec_string ("alias"
,("Alias")
,("The alias for the expression")
,NULL
,G_PARAM_READWRITE
));
}

49
sql/sql-select-field.h Normal file
View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SQL_SELECT_FIELD_H
#define SQL_SELECT_FIELD_H
#include "sql-object.h"
#include "sql-expr.h"
#define SQL_TYPE_SELECT_FIELD (sql_select_field_get_type ())
#define SQL_SELECT_FIELD(self) (G_TYPE_CHECK_INSTANCE_CAST (self, SQL_TYPE_SELECT_FIELD, SqlSelectField))
#define SQL_IS_SELECT_FIELD(self) (G_TYPE_CHECK_INSTANCE_TYPE (self, SQL_TYPE_SELECT_FIELD))
typedef struct _SqlSelectField SqlSelectField;
typedef struct _SqlSelectFieldClass SqlSelectFieldClass;
struct _SqlSelectField
{
SqlObject parent;
SqlExpr * expr;
gchar * alias;
};
struct _SqlSelectFieldClass
{
/* <private> */
SqlObjectClass parent;
};
GType sql_select_field_get_type ();
SqlObject * sql_select_field_new ();
const gchar * sql_select_field_get_alias (SqlSelectField * self);
void sql_select_field_set_alias (SqlSelectField * self, const gchar * alias);
#endif

139
sql/sql-select-order.c Normal file
View File

@ -0,0 +1,139 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sql-select-order.h"
/**
* SECTION: sql-select-order
* @Short_description:
* @Title: SqlSelectOrder
**/
G_DEFINE_TYPE (SqlSelectOrder, sql_select_order, SQL_TYPE_OBJECT);
SqlObject * sql_select_order_new ()
{
return g_object_new (SQL_TYPE_SELECT_ORDER, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_select_order_render (SqlSelectOrder * obj, SqlRender * render)
{
sql_render_add_object (render, obj->expr);
if (obj->way == SQL_SELECT_ORDER_DESC)
sql_render_add_token (render, "DESC");
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum
{
PROP_EXPR = 1
,PROP_WAY
};
static void sql_select_order_set_property (SqlSelectOrder * obj, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_EXPR:
sql_object_remove (obj, obj->expr);
obj->expr = sql_object_add (obj, g_value_get_object (value));
break;
case PROP_WAY:
obj->way = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
static void sql_select_order_get_property (SqlSelectOrder * obj, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_EXPR:
g_value_set_object (value, obj->expr);
break;
case PROP_WAY:
g_value_set_enum (value, obj->way);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_select_order_init (SqlSelectOrder * obj)
{
obj->expr = NULL;
}
static void sql_select_order_finalize (SqlSelectOrder * obj)
{
sql_object_remove (obj, obj->expr);
G_OBJECT_CLASS (sql_select_order_parent_class)->finalize (G_OBJECT (obj));
}
static void sql_select_order_class_init (SqlSelectOrderClass * klass)
{
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) sql_select_order_finalize;
k->set_property = (GObjectSetPropertyFunc) sql_select_order_set_property;
k->get_property = (GObjectGetPropertyFunc) sql_select_order_get_property;
SQL_OBJECT_CLASS (k)->render = (SqlRenderFunc) sql_select_order_render;
g_object_class_install_property (k, PROP_EXPR,
sql_param_object ("expr"
,("Expression")
,("The expression")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_WAY,
g_param_spec_enum ("way"
,("Way")
,("The order way")
,SQL_TYPE_SELECT_ORDER_WAY
,SQL_SELECT_ORDER_ASC
,G_PARAM_READWRITE
));
}
GType sql_select_order_way_get_type ()
{
static GType type = 0;
if (type == 0)
{
static const GEnumValue values[] =
{
{SQL_SELECT_ORDER_ASC ,"SQL_SELECT_ORDER_ASC" ,"asc"
},{SQL_SELECT_ORDER_DESC ,"SQL_SELECT_ORDER_DESC" ,"desc"
},{0, NULL, NULL}
};
type = g_enum_register_static
(g_intern_static_string ("SqlSelectOrderWay"), values);
}
return type;
}

63
sql/sql-select-order.h Normal file
View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SQL_SELECT_ORDER_H
#define SQL_SELECT_ORDER_H
#include "sql-object.h"
#include "sql-expr.h"
#define SQL_TYPE_SELECT_ORDER (sql_select_order_get_type ())
#define SQL_SELECT_ORDER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_SELECT_ORDER, SqlSelectOrder))
#define SQL_IS_SELECT_ORDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_SELECT_ORDER))
#define SQL_TYPE_SELECT_ORDER_WAY (sql_select_order_way_get_type ())
typedef struct _SqlSelectOrder SqlSelectOrder;
typedef struct _SqlSelectOrderClass SqlSelectOrderClass;
/**
* SqlSelectOrderWay:
* @SQL_SELECT_ORDER_ASC: ascendent order
* @SQL_SELECT_ORDER_DESC: descendent order
**/
typedef enum
{
SQL_SELECT_ORDER_ASC
,SQL_SELECT_ORDER_DESC
}
SqlSelectOrderWay;
struct _SqlSelectOrder
{
SqlObject parent;
SqlExpr * expr;
SqlSelectOrderWay way;
};
struct _SqlSelectOrderClass
{
/* <private> */
SqlObjectClass parent;
};
GType sql_select_order_get_type ();
GType sql_select_order_way_get_type ();
SqlObject * sql_select_order_new ();
#endif

View File

@ -16,7 +16,6 @@
*/
#include "sql-select.h"
#include "sql-field.h"
/**
* SECTION: sql-select
@ -25,84 +24,35 @@
*
* This object represents a SELECT SQL statement
**/
typedef struct
{
SqlExpr * expr;
gchar * alias;
}
SqlSelectAlias;
typedef struct
{
SqlExpr * expr;
SqlOrderWay way;
}
SqlOrder;
G_DEFINE_TYPE (SqlSelect, sql_select, SQL_TYPE_DML);
SqlSelect * sql_select_new ()
SqlObject * sql_select_new ()
{
return g_object_new (SQL_TYPE_SELECT, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
/*
static const char * SQL_SELECT_TYPE[] =
{
NULL
""
,"UNION ALL"
,"UNION ANY"
,"INTERSECT"
,"EXCEPT"
};
*/
static void sql_select_render_order (SqlOrder * order, SqlRender * render)
{
sql_render_add_object (render, order->expr);
if (order->way == SQL_ORDER_DESC)
sql_render_add_token (render, "DESC");
}
static void sql_select_render (SqlSelect * obj, SqlRender * render)
{
if (obj->alias)
sql_render_add_list (render, TRUE, "SELECT", obj->fields, ",");
sql_render_add_list (render, FALSE, "FROM", SQL_DML (obj)->targets, ",");
if (SQL_DML (obj)->targets)
{
GSList * n;
sql_render_add_token (render, "SELECT");
for (n = obj->expr; n; n = n->next)
{
GSList * l;
sql_render_add_object (render, n->data);
for (l = obj->alias; l; l = l->next)
if (((SqlSelectAlias *) l->data)->expr == n->data)
{
sql_render_add_identifier (render,
((SqlSelectAlias *) l->data)->alias);
}
if (n->next)
sql_render_append (render, " ,");
}
}
else
sql_render_add_list (render, T, "SELECT", obj->expr, ",");
sql_render_add_list (render, F, "FROM", SQL_DML (obj)->target, ",");
if (SQL_DML (obj)->target)
{
sql_render_add_item (render, F, "WHERE", SQL_DML (obj)->where);
sql_render_add_list (render, F, "GROUP BY", obj->group, ",");
sql_render_add_item (render, F, "HAVING", obj->having);
sql_render_add_list_with_func (render, F, "ORDER", obj->order, ",",
(SqlRenderFunc) sql_select_render_order);
sql_render_add_item (render, FALSE, "WHERE", SQL_DML (obj)->where);
sql_render_add_list (render, FALSE, "GROUP BY", obj->group, ",");
sql_render_add_item (render, FALSE, "HAVING", obj->having);
sql_render_add_list (render, FALSE, "ORDER", obj->order, ",");
if (obj->limit_count)
sql_render_printf (render, "LIMIT %u OFFSET %u"
@ -110,18 +60,9 @@ static void sql_select_render (SqlSelect * obj, SqlRender * render)
,obj->limit_offset
);
}
}
static void sql_order_free (SqlOrder * obj)
{
g_object_unref (obj->expr);
g_free (obj);
}
static void sql_select_alias_free (SqlSelectAlias * obj)
{
g_free (obj->alias);
g_free (obj);
if (obj->next)
sql_render_add_item (render, FALSE, SQL_SELECT_TYPE[obj->type], obj->next);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
@ -130,92 +71,27 @@ void sql_select_add_expr (SqlSelect * obj, SqlExpr * expr)
{
g_return_if_fail (SQL_IS_SELECT (obj));
g_return_if_fail (SQL_IS_EXPR (expr));
obj->expr = g_slist_append (obj->expr, g_object_ref_sink (expr));
}
void sql_select_set_alias (SqlSelect * obj, SqlExpr * expr, const gchar * alias)
{
GSList * list;
g_return_if_fail (SQL_IS_SELECT (obj));
list = g_slist_find (obj->expr, expr);
if (list)
{
SqlSelectAlias * as = g_new (SqlSelectAlias, 1);
as->alias = g_strdup (alias);
as->expr = expr;
obj->alias = g_slist_append (obj->alias, as);
}
}
/*
* Return the alias of a field and if it's an unaliased SqlField, its name,
* otherwise returns NULL (uses include of sql-field.h)
*/
gchar * sql_select_get_column_name (SqlSelect * obj, SqlExpr * expr)
{
gboolean listed = FALSE;
GSList * n;
g_return_val_if_fail (SQL_IS_SELECT (obj), NULL);
g_return_val_if_fail (SQL_IS_EXPR (expr), NULL);
for (n = obj->expr; n; n = n->next)
if (expr == n->data)
{
listed = TRUE;
break;
}
if (listed)
for (n = obj->alias; n; n = n->next)
{
SqlSelectAlias * as = n->data;
if (expr == as->expr)
return g_strdup (as->alias);
}
if (SQL_IS_FIELD (expr))
{
gchar * name;
g_object_get (expr, "name", &name, NULL);
return name;
}
return NULL;
}
void sql_select_add_group (SqlSelect * obj, SqlExpr * expr)
{
g_return_if_fail (SQL_IS_SELECT (obj));
g_return_if_fail (SQL_IS_EXPR (expr));
obj->group = g_slist_append (obj->group, g_object_ref_sink (expr));
}
void sql_select_set_having (SqlSelect * obj, SqlExpr * expr)
void sql_select_set_having (SqlSelect * obj, SqlExpr * having)
{
g_return_if_fail (SQL_IS_SELECT (obj));
g_return_if_fail (SQL_IS_EXPR (having) || having);
sql_object_remove (obj, obj->having);
obj->having = sql_object_add (obj, having);
}
void sql_select_add_order (SqlSelect * obj, SqlExpr * expr, SqlSelectOrderWay way)
{
g_return_if_fail (SQL_IS_SELECT (obj));
g_return_if_fail (SQL_IS_EXPR (expr));
g_clear_object (&obj->having);
obj->having = g_object_ref_sink (expr);
}
void sql_select_add_order (SqlSelect * obj, SqlExpr * expr, SqlOrderWay way)
{
g_return_if_fail (SQL_IS_SELECT (obj));
g_return_if_fail (SQL_IS_EXPR (expr));
SqlOrder * order = g_new (SqlOrder, 1);
order->expr = g_object_ref_sink (expr);
order->way = way;
obj->order = g_slist_append (obj->order, order);
}
void sql_select_set_distinct (SqlSelect * obj, gboolean distinct)
@ -238,15 +114,9 @@ void sql_select_set_next (SqlSelect * obj, SqlSelect * next, SqlSelectType type)
g_return_if_fail (SQL_IS_SELECT (obj));
g_return_if_fail (SQL_IS_SELECT (next) || !next);
g_clear_object (&obj->next);
if (next)
{
obj->next = g_object_ref (next);
obj->type = type;
}
else
obj->type = SQL_SELECT_NONE;
sql_object_remove (obj, obj->next);
obj->next = sql_object_add (obj, next);
obj->type = next ? type : SQL_SELECT_NONE;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@ -254,9 +124,12 @@ void sql_select_set_next (SqlSelect * obj, SqlSelect * next, SqlSelectType type)
enum
{
PROP_DISTINCT = 1
,PROP_FIELDS
,PROP_GROUP
,PROP_HAVING
,PROP_ORDER
,PROP_LIMIT_COUNT
,PROP_LIMIT_OFFSET
,PROP_HAVING
,PROP_TYPE
,PROP_NEXT
};
@ -269,21 +142,33 @@ static void sql_select_set_property (SqlSelect * obj, guint id,
case PROP_DISTINCT:
obj->distinct = g_value_get_boolean (value);
break;
case PROP_FIELDS:
sql_object_remove (obj, obj->fields);
obj->fields = sql_object_add (obj, g_value_get_object (value));
break;
case PROP_GROUP:
sql_object_remove (obj, obj->group);
obj->group = sql_object_add (obj, g_value_get_object (value));
break;
case PROP_HAVING:
sql_select_set_having (obj, g_value_get_object (value));
break;
case PROP_ORDER:
sql_object_remove (obj, obj->order);
obj->order = sql_object_add (obj, g_value_get_object (value));
break;
case PROP_LIMIT_COUNT:
obj->limit_count = g_value_get_uint (value);
break;
case PROP_LIMIT_OFFSET:
obj->limit_offset = g_value_get_uint (value);
break;
case PROP_HAVING:
sql_select_set_having (obj, g_value_get_object (value));
case PROP_NEXT:
sql_select_set_next (obj, g_value_get_object (value), obj->type);
break;
case PROP_TYPE:
obj->type = g_value_get_int (value);
break;
case PROP_NEXT:
sql_select_set_next (obj, g_value_get_object (value), obj->type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
@ -297,21 +182,30 @@ static void sql_select_get_property (SqlSelect * obj, guint id,
case PROP_DISTINCT:
g_value_set_boolean (value, obj->distinct);
break;
case PROP_FIELDS:
g_value_set_object (value, obj->fields);
break;
case PROP_GROUP:
g_value_set_object (value, obj->group);
break;
case PROP_HAVING:
g_value_set_object (value, obj->having);
break;
case PROP_ORDER:
g_value_set_object (value, obj->order);
break;
case PROP_LIMIT_COUNT:
g_value_set_uint (value, obj->limit_count);
break;
case PROP_LIMIT_OFFSET:
g_value_set_uint (value, obj->limit_offset);
break;
case PROP_HAVING:
g_value_set_object (value, obj->having);
case PROP_NEXT:
g_value_set_object (value, obj->next);
break;
case PROP_TYPE:
g_value_set_int (value, obj->type);
break;
case PROP_NEXT:
g_value_set_object (value, obj->next);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
@ -322,8 +216,7 @@ static void sql_select_get_property (SqlSelect * obj, guint id,
static void sql_select_init (SqlSelect * obj)
{
obj->distinct = FALSE;
obj->expr = NULL;
obj->alias = NULL;
obj->fields = NULL;
obj->group = NULL;
obj->having = NULL;
obj->order = NULL;
@ -333,62 +226,85 @@ static void sql_select_init (SqlSelect * obj)
static void sql_select_finalize (SqlSelect * obj)
{
g_clear_object (&obj->having);
g_clear_object (&obj->next);
g_slist_free_full (obj->expr, g_object_unref);
g_slist_free_full (obj->group, g_object_unref);
g_slist_free_full (obj->alias, (GFreeFunc) sql_select_alias_free);
g_slist_free_full (obj->order, (GFreeFunc) sql_order_free);
if (obj->group)
g_object_unref (obj->group);
if (obj->order)
g_object_unref (obj->order);
sql_object_remove (obj, obj->fields);
sql_object_remove (obj, obj->having);
sql_object_remove (obj, obj->next);
G_OBJECT_CLASS (sql_select_parent_class)->finalize (G_OBJECT (obj));
}
static void sql_select_class_init (SqlSelectClass * k)
static void sql_select_class_init (SqlSelectClass * klass)
{
GObjectClass * klass = G_OBJECT_CLASS (k);
klass->finalize = (GObjectFinalizeFunc) sql_select_finalize;
klass->set_property = (GObjectSetPropertyFunc) sql_select_set_property;
klass->get_property = (GObjectGetPropertyFunc) sql_select_get_property;
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_select_render;
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) sql_select_finalize;
k->set_property = (GObjectSetPropertyFunc) sql_select_set_property;
k->get_property = (GObjectGetPropertyFunc) sql_select_get_property;
SQL_OBJECT_CLASS (k)->render = (SqlRenderFunc) sql_select_render;
g_object_class_install_property (klass, PROP_LIMIT_COUNT,
g_object_class_install_property (k, PROP_DISTINCT,
g_param_spec_boolean ("distinct"
,"Distinct"
,"Determines if the #SqlSelect uses the DISTINCT clause"
,FALSE, G_PARAM_READWRITE
,_("Distinct")
,_("Determines if the #SqlSelect uses the DISTINCT clause")
,FALSE
,G_PARAM_READWRITE
));
g_object_class_install_property (klass, PROP_LIMIT_COUNT,
g_object_class_install_property (k, PROP_FIELDS,
sql_param_list ("fields"
,_("Fields")
,_("The list of fields")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
g_object_class_install_property (k, PROP_GROUP,
sql_param_list ("group"
,_("Group")
,_("The GROUP BY section")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
g_object_class_install_property (k, PROP_HAVING,
sql_param_object ("having"
,_("Having")
,_("The HAVING clause")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_ORDER,
sql_param_list ("order"
,_("Order")
,_("The ORDER BY section")
,SQL_TYPE_SELECT_ORDER
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
g_object_class_install_property (k, PROP_LIMIT_COUNT,
g_param_spec_uint ("limit-count"
,"Limit count"
,"The COUNT field of the LIMIT clause"
,0, G_MAXUINT, 0, G_PARAM_READWRITE
,_("Limit count")
,_("The COUNT field of the LIMIT clause")
,0, G_MAXUINT, 0
,G_PARAM_READWRITE
));
g_object_class_install_property (klass, PROP_LIMIT_OFFSET,
g_object_class_install_property (k, PROP_LIMIT_OFFSET,
g_param_spec_uint ("limit-offset"
,"Limit offset"
,"The OFFSET field of the LIMIT clause"
,0, G_MAXUINT, 0, G_PARAM_READWRITE
,_("Limit offset")
,_("The OFFSET field of the LIMIT clause")
,0, G_MAXUINT, 0
,G_PARAM_READWRITE
));
g_object_class_install_property (klass, PROP_HAVING,
g_param_spec_object ("having"
,"Having"
,"The HAVING clause"
,SQL_TYPE_EXPR, G_PARAM_READWRITE
g_object_class_install_property (k, PROP_NEXT,
sql_param_object ("next"
,_("Next")
,_("The next #SqlSelect in case of a statement with more than one")
,SQL_TYPE_SELECT
,G_PARAM_READWRITE
));
g_object_class_install_property (klass, PROP_TYPE,
g_object_class_install_property (k, PROP_TYPE,
g_param_spec_int ("type"
,"Type"
,"One of the possible options of #SqlSelectType"
,0, SQL_SELECT_COUNT - 1, 0, G_PARAM_READWRITE
));
g_object_class_install_property (klass, PROP_NEXT,
g_param_spec_object ("next"
,"Next"
,"The next #SqlSelect in case of a statement with more than one"
,SQL_TYPE_SELECT, G_PARAM_READWRITE
,_("Type")
,_("One of the possible options of #SqlSelectType")
,0, SQL_SELECT_COUNT - 1, 0
,G_PARAM_READWRITE
));
}

View File

@ -19,6 +19,8 @@
#define SQL_SELECT_H
#include "sql-dml.h"
#include "sql-select-field.h"
#include "sql-select-order.h"
#define SQL_TYPE_SELECT (sql_select_get_type ())
#define SQL_SELECT(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_SELECT, SqlSelect))
@ -38,38 +40,22 @@ typedef enum
}
SqlSelectType;
/**
* SqlOrderWay:
* @SQL_ORDER_ASC: ascendent order
* @SQL_ORDER_DESC: descendent order
**/
typedef enum
{
SQL_ORDER_ASC
,SQL_ORDER_DESC
}
SqlOrderWay;
/**
* SqlSelect:
* @expr: (element-type Sql.Expr):
* @group: (element-type Sql.Expr):
* @order: (element-type Sql.Expr):
**/
struct _SqlSelect
{
SqlDml parent;
gboolean distinct;
GSList * expr;
GSList * alias; // List of Sql.SelectAlias
GSList * group;
SqlList * fields; // List of SqlSelectField
SqlList * group; // List of SqlExpr
SqlExpr * having;
GSList * order;
SqlList * order; // List of SqlSelectOrder
guint limit_offset;
guint limit_count;
SqlSelectType type;
SqlSelect * next;
SqlSelectType type;
};
struct _SqlSelectClass
@ -79,14 +65,13 @@ struct _SqlSelectClass
};
GType sql_select_get_type ();
SqlSelect * sql_select_new ();
SqlObject * sql_select_new ();
void sql_select_set_distinct (SqlSelect * obj, gboolean distinct);
void sql_select_add_expr (SqlSelect * obj, SqlExpr * expr);
void sql_select_set_alias (SqlSelect * obj, SqlExpr * expr, const gchar * alias);
gchar * sql_select_get_column_name (SqlSelect * obj, SqlExpr * expr);
void sql_select_add_group (SqlSelect * obj, SqlExpr * expr);
void sql_select_set_having (SqlSelect * obj, SqlExpr * expr);
void sql_select_add_order (SqlSelect * obj, SqlExpr * expr, SqlOrderWay way);
void sql_select_add_order (SqlSelect * obj, SqlExpr * expr, SqlSelectOrderWay way);
void sql_select_set_limit (SqlSelect * obj, guint count, guint offset);
void sql_select_set_next (SqlSelect * obj, SqlSelect * next, SqlSelectType type);

103
sql/sql-set.c Normal file
View File

@ -0,0 +1,103 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sql-set.h"
/**
* SECTION: sql-set
* @Short_description: represents any set used in SQL.
* @Title: SqlSet
**/
G_DEFINE_TYPE (SqlSet, sql_set, SQL_TYPE_EXPR);
SqlObject * sql_set_new ()
{
return g_object_new (SQL_TYPE_SET, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_set_render (SqlSet * obj, SqlRender * render)
{
sql_render_append (render, "(");
sql_render_add_list (render, FALSE, NULL, obj->exprs, ",");
sql_render_append (render, ")");
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum
{
PROP_EXPRS = 1
};
static void sql_set_set_property (SqlSet * obj, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_EXPRS:
sql_object_remove (obj, obj->exprs);
obj->exprs = sql_object_add (obj, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
static void sql_set_get_property (SqlSet * obj, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_EXPRS:
g_value_set_object (value, obj->exprs);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_set_init (SqlSet * obj)
{
obj->exprs = NULL;
}
static void sql_set_finalize (SqlSet * obj)
{
sql_object_remove (obj, obj->exprs);
G_OBJECT_CLASS (sql_set_parent_class)->finalize (G_OBJECT (obj));
}
static void sql_set_class_init (SqlSetClass * klass)
{
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) sql_set_finalize;
k->set_property = (GObjectSetPropertyFunc) sql_set_set_property;
k->get_property = (GObjectGetPropertyFunc) sql_set_get_property;
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_set_render;
g_object_class_install_property (k, PROP_EXPRS,
sql_param_list ("exprs"
,("Expressions")
,("The list of expressions")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
}

45
sql/sql-set.h Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SQL_SET_H
#define SQL_SET_H
#include "sql-expr.h"
#define SQL_TYPE_SET (sql_set_get_type ())
#define SQL_SET(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_SET, SqlSet))
#define SQL_IS_SET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_SET))
typedef struct _SqlSet SqlSet;
typedef struct _SqlSetClass SqlSetClass;
struct _SqlSet
{
SqlExpr parent;
SqlList * exprs;
};
struct _SqlSetClass
{
/* <private> */
SqlObjectClass parent;
};
GType sql_set_get_type ();
SqlObject * sql_set_new ();
#endif

View File

@ -41,6 +41,5 @@ struct _SqlStmtClass
};
GType sql_stmt_get_type ();
gboolean sql_stmt_is_ready (SqlStmt * obj);
#endif

View File

@ -16,6 +16,15 @@
*/
#include "sql-string.h"
#include "sql-holder.h"
typedef struct
{
gchar * start;
gchar * end;
SqlObject * holder;
}
HolderData;
/**
* SECTION: sql-string
@ -26,7 +35,7 @@
**/
G_DEFINE_TYPE (SqlString, sql_string, SQL_TYPE_STMT);
SqlString * sql_string_new (const gchar * sql)
SqlObject * sql_string_new (const gchar * sql)
{
return g_object_new (SQL_TYPE_STRING, "sql", sql, NULL);
}
@ -35,81 +44,41 @@ SqlString * sql_string_new (const gchar * sql)
static void sql_string_render (SqlString * obj, SqlRender * render)
{
guint n;
gsize pos;
gchar * i = obj->sql;
GSList * p = obj->params;
GSList * i;
gchar * ptr = obj->sql;
for (n = 0; n < obj->positions->len && p; n++)
for (i = obj->holders; i; i = i->next)
{
pos = g_array_index (obj->positions, gsize, n);
g_string_append_len (render->buffer, i, (obj->sql + pos) - i);
i = obj->sql + pos + 2;
HolderData * holder_data = i->data;
g_string_append_len (render->buffer, ptr, holder_data->start - ptr - 1);
ptr = holder_data->end;
sql_render_add_object (render, p->data);
p = p->next;
sql_render_add_object (render, holder_data->holder);
}
sql_render_append (render, i);
sql_render_append (render, ptr);
}
static gboolean sql_string_is_ready (SqlString * obj)
static void sql_string_find_holders (SqlString * obj, SqlBatch * batch)
{
guint n;
GSList * p = obj->params;
GSList * i;
for (n = 0; n < obj->positions->len && p; n++)
{
if (!sql_object_is_ready (p->data))
return FALSE;
p = p->next;
}
return n == obj->positions->len;
for (i = obj->holders; i; i = i->next)
sql_object_get_holders (((HolderData *) i->data)->holder, batch);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
void sql_string_add_expr (SqlString * obj, SqlExpr * expr)
static void sql_string_free_holder_data (HolderData * holder_data)
{
g_return_if_fail (SQL_IS_STRING (obj));
g_return_if_fail (SQL_IS_EXPR (expr));
sql_object_list_add (SQL_OBJECT (obj), &obj->params, SQL_OBJECT (expr));
}
void sql_string_add_param (SqlString * obj, GvnParam * param)
{
g_return_if_fail (SQL_IS_STRING (obj));
g_return_if_fail (GVN_IS_PARAM (param));
SqlExpr * value = sql_value_new ();
sql_value_set_param (SQL_VALUE (value), param);
sql_object_list_add (SQL_OBJECT (obj), &obj->params, SQL_OBJECT (value));
}
void sql_string_add_value (SqlString * obj, GType type, gconstpointer content)
{
g_return_if_fail (SQL_IS_STRING (obj));
GValue value = G_VALUE_INIT;
SqlExpr * expr;
gvn_value_new_with_content (&value, type, (gpointer) content);
expr = sql_value_new ();
sql_value_set_value (SQL_VALUE (expr), &value);
sql_object_list_add (SQL_OBJECT (obj), &obj->params, SQL_OBJECT (expr));
g_value_unset (&value);
g_object_unref (holder_data->holder);
g_free (holder_data);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
typedef enum
enum
{
PROP_SQL = 1
}
SqlStringProp;
};
static void sql_string_set_property (SqlString * obj, guint id,
const GValue * value, GParamSpec * pspec)
@ -118,35 +87,58 @@ static void sql_string_set_property (SqlString * obj, guint id,
{
case PROP_SQL:
{
gchar * n;
gchar * i;
obj->sql = g_value_dup_string (value);
n = obj->sql;
for (; n && *n != '\0'; n++)
if (obj->sql)
for (i = obj->sql; TRUE; i++)
{
switch (*n)
switch (*i)
{
case '#':
if (*(n+1) == 'p')
{
gsize pos = n - obj->sql;
g_array_append_val (obj->positions, pos);
n++;
}
gchar * ptr = ++i;
gchar * holder_id;
HolderData * holder_data;
while (g_ascii_isalpha (*i))
i++;
holder_data = g_new (HolderData, 1);
holder_data->start = ptr;
holder_data->end = i;
obj->holders = g_slist_prepend (obj->holders, holder_data);
holder_id = g_strndup (ptr, i - ptr);
holder_data->holder = g_object_ref_sink (sql_holder_new (holder_id));
g_free (holder_id);
break;
}
case '\'':
do {
n = g_strstr_len (++n, -1, "'");
}
while (n && *(n-1) == '\\');
case '"':
case '`':
{
gchar delimiter = *i;
while (*(++i) != delimiter)
{
if (*i == '\\')
i++;
if (*i == '\0')
break;
}
if (!n || *n == '\0')
break;
}
}
if (*i == '\0')
break;
}
obj->holders = g_slist_reverse (obj->holders);
break;
}
default:
@ -171,16 +163,14 @@ static void sql_string_get_property (SqlString * obj, guint id,
static void sql_string_init (SqlString * obj)
{
obj->sql = NULL;
obj->params = NULL;
obj->positions = g_array_sized_new (FALSE, FALSE, sizeof (gsize), 5);
obj->holders = NULL;
}
static void sql_string_finalize (SqlString * obj)
{
g_free (obj->sql);
g_array_free (obj->positions, TRUE);
g_slist_free_full (obj->params, (GDestroyNotify) g_object_unref);
g_slist_free_full (obj->holders,
(GDestroyNotify) sql_string_free_holder_data);
G_OBJECT_CLASS (sql_string_parent_class)->finalize (G_OBJECT (obj));
}
@ -191,7 +181,7 @@ static void sql_string_class_init (SqlStringClass * k)
klass->set_property = (GObjectSetPropertyFunc) sql_string_set_property;
klass->get_property = (GObjectGetPropertyFunc) sql_string_get_property;
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_string_render;
SQL_OBJECT_CLASS (klass)->is_ready = (SqlObjectIsReadyFunc) sql_string_is_ready;
SQL_OBJECT_CLASS (klass)->find_holders = (SqlObjectFindHoldersFunc) sql_string_find_holders;
g_object_class_install_property (klass, PROP_SQL,
g_param_spec_string ("sql"

View File

@ -21,7 +21,6 @@
#include <gvn/gvn-param.h>
#include <gvn/gvn-value.h>
#include "sql-stmt.h"
#include "sql-value.h"
#define SQL_TYPE_STRING (sql_string_get_type ())
#define SQL_IS_STRING(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_STRING))
@ -32,15 +31,13 @@ typedef struct _SqlStringClass SqlStringClass;
/**
* SqlString:
* @params: (element-type GvnParam):
* @positions: (element-type gsize):
* @expr: (element-type Sql.Expr):
**/
struct _SqlString
{
SqlStmt parent;
gchar * sql;
GSList * params;
GArray * positions;
GSList * holders;
};
struct _SqlStringClass
@ -50,9 +47,6 @@ struct _SqlStringClass
};
GType sql_string_get_type ();
SqlString * sql_string_new (const gchar * sql);
void sql_string_add_expr (SqlString * obj, SqlExpr * expr);
void sql_string_add_param (SqlString * obj, GvnParam * param);
void sql_string_add_value (SqlString * obj, GType type, gconstpointer content);
SqlObject * sql_string_new (const gchar * sql);
#endif

View File

@ -27,7 +27,7 @@
**/
G_DEFINE_TYPE (SqlSubquery, sql_subquery, SQL_TYPE_TARGET);
SqlSubquery * sql_subquery_new (SqlSelect * select)
SqlObject * sql_subquery_new (SqlSelect * select)
{
return g_object_new (SQL_TYPE_SUBQUERY, "select", select, NULL);
}
@ -39,7 +39,7 @@ static void sql_subquery_render (SqlSubquery * obj, SqlRender * render)
if (obj->select)
{
sql_render_append (render, "(");
sql_render_add_item (render, T, NULL, obj->select);
sql_render_add_item (render, TRUE, NULL, obj->select);
sql_render_append (render, ")");
}
}
@ -49,10 +49,10 @@ static void sql_subquery_render (SqlSubquery * obj, SqlRender * render)
void sql_subquery_set_select (SqlSubquery * obj, SqlSelect * select)
{
g_return_if_fail (SQL_IS_SUBQUERY (obj));
g_return_if_fail (SQL_IS_SELECT (select));
g_return_if_fail (SQL_IS_SELECT (select) || !select);
g_clear_object (&obj->select);
obj->select = g_object_ref_sink (select);
sql_object_remove (obj, obj->select);
obj->select = sql_object_add (obj, select);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@ -97,7 +97,7 @@ static void sql_subquery_init (SqlSubquery * obj)
static void sql_subquery_finalize (SqlSubquery * obj)
{
g_clear_object (&obj->select);
sql_object_remove (obj, obj->select);
G_OBJECT_CLASS (sql_subquery_parent_class)->finalize (G_OBJECT (obj));
}
@ -110,9 +110,10 @@ static void sql_subquery_class_init (SqlSubqueryClass * klass)
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_subquery_render;
g_object_class_install_property (k, PROP_SELECT,
g_param_spec_object ("select"
, "Select"
, "An #SqlSelect"
, SQL_TYPE_SELECT, G_PARAM_READWRITE
sql_param_object ("select"
,("Select")
,("The SELECT statement")
,SQL_TYPE_SELECT
,G_PARAM_READWRITE
));
}

View File

@ -41,7 +41,7 @@ struct _SqlSubqueryClass
};
GType sql_subquery_get_type ();
SqlSubquery * sql_subquery_new (SqlSelect * select);
SqlObject * sql_subquery_new (SqlSelect * select);
void sql_subquery_set_select (SqlSubquery * obj, SqlSelect * select);
#endif

View File

@ -26,25 +26,75 @@
**/
G_DEFINE_TYPE (SqlTable, sql_table, SQL_TYPE_TARGET);
SqlTarget * sql_table_new (const gchar * name)
SqlObject * sql_table_new (const gchar * name, const gchar * schema)
{
return g_object_new (SQL_TYPE_TABLE, "name", name, NULL);
return g_object_new (SQL_TYPE_TABLE, "name", name, "schema", schema, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_table_render (SqlTable * obj, SqlRender * render)
static void sql_table_render (SqlTable * self, SqlRender * render)
{
if (obj->schema)
if (self->schema)
{
sql_render_add_identifier (render, obj->schema);
sql_render_add_identifier (render, self->schema);
sql_render_append (render, ".");
}
sql_render_add_identifier (render, obj->name);
sql_render_add_identifier (render, self->name);
if (g_strcmp0 (obj->name, SQL_TARGET (obj)->alias))
sql_render_add_identifier (render, SQL_TARGET (obj)->alias);
if (SQL_TARGET (self)->alias)
sql_render_add_identifier (render, SQL_TARGET (self)->alias);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
/**
* sql_table_get_name:
* @self: the #SqlTable
*
* Return value: the table name
**/
const gchar * sql_table_get_name (SqlTable * self)
{
return self->name;
}
/**
* sql_table_set_name:
* @self: the #SqlTable
* @name: the target name
**/
void sql_table_set_name (SqlTable * self, const gchar * name)
{
g_return_if_fail (SQL_IS_TABLE (self));
g_free (self->name);
self->name = g_strdup (name);
}
/**
* sql_table_get_schema:
* @self: the #SqlTable
*
* Return value: the schema name
**/
const gchar * sql_table_get_schema (SqlTable * self)
{
return self->schema;
}
/**
* sql_table_set_schema:
* @self: the #SqlTable
* @schema: the schema name
**/
void sql_table_set_schema (SqlTable * self, const gchar * schema)
{
g_return_if_fail (SQL_IS_TABLE (self));
g_free (self->schema);
self->schema = g_strdup (schema);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@ -55,76 +105,74 @@ enum
,PROP_SCHEMA
};
static void sql_table_set_property (SqlTable * obj, guint id,
static void sql_table_set_property (SqlTable * self, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_NAME:
g_free (obj->name);
obj->name = g_value_dup_string (value);
g_free (self->name);
self->name = g_value_dup_string (value);
break;
case PROP_SCHEMA:
g_free (obj->schema);
obj->schema = g_value_dup_string (value);
g_free (self->schema);
self->schema = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
static void sql_table_get_property (SqlTable * obj, guint id,
static void sql_table_get_property (SqlTable * self, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_NAME:
g_value_set_string (value, obj->name);
g_value_set_string (value, self->name);
break;
case PROP_SCHEMA:
g_value_set_string (value, obj->schema);
g_value_set_string (value, self->schema);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_table_init (SqlTable * obj)
static void sql_table_init (SqlTable * self)
{
obj->name = NULL;
obj->schema = NULL;
self->name = NULL;
self->schema = NULL;
}
static void sql_table_finalize (SqlTable * obj)
static void sql_table_finalize (SqlTable * self)
{
g_free (obj->name);
g_free (obj->schema);
obj->name = NULL;
obj->schema = NULL;
G_OBJECT_CLASS (sql_table_parent_class)->finalize (G_OBJECT (obj));
g_free (self->name);
g_free (self->schema);
G_OBJECT_CLASS (sql_table_parent_class)->finalize (G_OBJECT (self));
}
static void sql_table_class_init (SqlTableClass * k)
static void sql_table_class_init (SqlTableClass * klass)
{
GObjectClass * klass = G_OBJECT_CLASS (k);
klass->finalize = (GObjectFinalizeFunc) sql_table_finalize;
klass->set_property = (GObjectSetPropertyFunc) sql_table_set_property;
klass->get_property = (GObjectGetPropertyFunc) sql_table_get_property;
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) sql_table_finalize;
k->set_property = (GObjectSetPropertyFunc) sql_table_set_property;
k->get_property = (GObjectGetPropertyFunc) sql_table_get_property;
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_table_render;
g_object_class_install_property (klass, PROP_NAME,
g_object_class_install_property (k, PROP_NAME,
g_param_spec_string ("name"
, "Name"
, "The table name"
, NULL, G_PARAM_READWRITE
,("Name")
,("The table name")
,NULL, G_PARAM_READWRITE
));
g_object_class_install_property (klass, PROP_SCHEMA,
g_object_class_install_property (k, PROP_SCHEMA,
g_param_spec_string ("schema"
,"Schema"
,"The schema where the table is"
,("Schema")
,("The schema where the table is")
,NULL, G_PARAM_READWRITE
));
}

View File

@ -21,8 +21,8 @@
#include "sql-target.h"
#define SQL_TYPE_TABLE (sql_table_get_type ())
#define SQL_TABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_TABLE, SqlTable))
#define SQL_IS_TABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_TABLE))
#define SQL_TABLE(self) (G_TYPE_CHECK_INSTANCE_CAST (self, SQL_TYPE_TABLE, SqlTable))
#define SQL_IS_TABLE(self) (G_TYPE_CHECK_INSTANCE_TYPE (self, SQL_TYPE_TABLE))
typedef struct _SqlTable SqlTable;
typedef struct _SqlTableClass SqlTableClass;
@ -41,6 +41,10 @@ struct _SqlTableClass
};
GType sql_table_get_type ();
SqlTarget * sql_table_new (const gchar * name);
SqlObject * sql_table_new (const gchar * name, const gchar * schema);
const gchar * sql_table_get_name (SqlTable * self);
void sql_table_set_name (SqlTable * self, const gchar * name);
const gchar * sql_table_get_schema (SqlTable * self);
void sql_table_set_schema (SqlTable * self, const gchar * schema);
#endif

View File

@ -29,14 +29,28 @@ G_DEFINE_ABSTRACT_TYPE (SqlTarget, sql_target, SQL_TYPE_OBJECT);
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
void sql_target_set_alias (SqlTarget * obj, const gchar * alias)
/**
* sql_target_set_alias:
* @self: the #SqlTargetClass
* @alias: the target alias
**/
void sql_target_set_alias (SqlTarget * self, const gchar * alias)
{
g_return_if_fail (SQL_IS_TARGET (obj));
g_return_if_fail (SQL_IS_TARGET (self));
g_free (obj->alias);
g_free (self->alias);
self->alias = g_strdup (alias);
}
if (alias)
obj->alias = g_strdup (alias);
/**
* sql_target_get_alias:
* @self: the #SqlTargetClass
**/
const gchar * sql_target_get_alias (SqlTarget * self)
{
g_return_if_fail (SQL_IS_TARGET (self));
return self->alias;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@ -46,44 +60,43 @@ enum
PROP_ALIAS = 1
};
static void sql_target_set_property (SqlTarget * obj, guint id,
static void sql_target_set_property (SqlTarget * self, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_ALIAS:
sql_target_set_alias (obj, g_value_get_string (value));
sql_target_set_alias (self, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
static void sql_target_get_property (SqlTarget * obj, guint id,
static void sql_target_get_property (SqlTarget * self, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_ALIAS:
g_value_set_string (value, obj->alias);
g_value_set_string (value, self->alias);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_target_finalize (SqlTarget * obj)
static void sql_target_init (SqlTarget * self)
{
g_free (obj->alias);
obj->alias = NULL;
G_OBJECT_CLASS (sql_target_parent_class)->finalize (G_OBJECT (obj));
self->alias = NULL;
}
static void sql_target_init (SqlTarget * obj)
static void sql_target_finalize (SqlTarget * self)
{
obj->alias = NULL;
g_free (self->alias);
G_OBJECT_CLASS (sql_target_parent_class)->finalize (G_OBJECT (self));
}
static void sql_target_class_init (SqlTargetClass * k)
@ -95,8 +108,9 @@ static void sql_target_class_init (SqlTargetClass * k)
g_object_class_install_property (klass, PROP_ALIAS,
g_param_spec_string ("alias"
, "Alias"
, "The alias for the target"
, NULL, G_PARAM_READWRITE
,("Alias")
,("The alias for the target")
,NULL
,G_PARAM_READWRITE
));
}

View File

@ -21,8 +21,8 @@
#include "sql-object.h"
#define SQL_TYPE_TARGET (sql_target_get_type ())
#define SQL_TARGET(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_TARGET, SqlTarget))
#define SQL_IS_TARGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_TARGET))
#define SQL_TARGET(self) (G_TYPE_CHECK_INSTANCE_CAST (self, SQL_TYPE_TARGET, SqlTarget))
#define SQL_IS_TARGET(self) (G_TYPE_CHECK_INSTANCE_TYPE (self, SQL_TYPE_TARGET))
typedef struct _SqlTarget SqlTarget;
typedef struct _SqlTargetClass SqlTargetClass;
@ -40,6 +40,7 @@ struct _SqlTargetClass
};
GType sql_target_get_type ();
void sql_target_set_alias (SqlTarget * obj, const gchar * alias);
void sql_target_set_alias (SqlTarget * self, const gchar * alias);
const gchar * sql_target_get_alias (SqlTarget * self);
#endif

120
sql/sql-update-set.c Normal file
View File

@ -0,0 +1,120 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sql-update-set.h"
/**
* SECTION: sql-update_set
* @Short_description: Defines a field for the SET clause for an #SqlUpdate.
* @Title: SqlUpdateSet
**/
G_DEFINE_TYPE (SqlUpdateSet, sql_update_set, SQL_TYPE_OBJECT);
SqlObject * sql_update_set_new ()
{
return g_object_new (SQL_TYPE_UPDATE_SET, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_update_set_render (SqlUpdateSet * set, SqlRender * render)
{
sql_render_add_object (render, set->field);
sql_render_add_token (render, "=");
sql_render_add_object (render, set->expr);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum
{
PROP_FIELD = 1
,PROP_EXPR
};
static void sql_update_set_set_property (SqlUpdateSet * obj, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_FIELD:
sql_object_remove (obj, obj->field);
obj->field = sql_object_add (obj, g_value_get_object (value));
break;
case PROP_EXPR:
sql_object_remove (obj, obj->expr);
obj->expr = sql_object_add (obj, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
static void sql_update_set_get_property (SqlUpdateSet * obj, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_FIELD:
g_value_set_object (value, obj->field);
break;
case PROP_EXPR:
g_value_set_object (value, obj->expr);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_update_set_init (SqlUpdateSet * obj)
{
obj->field = NULL;
obj->expr = NULL;
}
static void sql_update_set_finalize (SqlUpdateSet * obj)
{
sql_object_remove (obj, obj->field);
sql_object_remove (obj, obj->expr);
G_OBJECT_CLASS (sql_update_set_parent_class)->finalize (G_OBJECT (obj));
}
static void sql_update_set_class_init (SqlUpdateSetClass * klass)
{
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) sql_update_set_finalize;
k->set_property = (GObjectSetPropertyFunc) sql_update_set_set_property;
k->get_property = (GObjectGetPropertyFunc) sql_update_set_get_property;
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_update_set_render;
g_object_class_install_property (k, PROP_FIELD,
g_param_spec_object ("field"
,("Field")
,("The field")
,SQL_TYPE_FIELD
,G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_EXPR,
g_param_spec_object ("expr"
,("Expression")
,("The expression")
,SQL_TYPE_EXPR
,G_PARAM_READWRITE
));
}

48
sql/sql-update-set.h Normal file
View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SQL_UPDATE_SET_H
#define SQL_UPDATE_SET_H
#include "sql-object.h"
#include "sql-field.h"
#include "sql-expr.h"
#define SQL_TYPE_UPDATE_SET (sql_update_set_get_type ())
#define SQL_UPDATE_SET(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_UPDATE_SET, SqlUpdateSet))
#define SQL_IS_UPDATE_SET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_UPDATE_SET))
typedef struct _SqlUpdateSet SqlUpdateSet;
typedef struct _SqlUpdateSetClass SqlUpdateSetClass;
struct _SqlUpdateSet
{
SqlObject parent;
SqlField * field;
SqlExpr * expr;
};
struct _SqlUpdateSetClass
{
/* <private> */
SqlObjectClass parent;
};
GType sql_update_set_get_type ();
SqlObject * sql_update_set_new ();
#endif

View File

@ -26,67 +26,92 @@
**/
G_DEFINE_TYPE (SqlUpdate, sql_update, SQL_TYPE_DML);
SqlUpdate * sql_update_new ()
SqlObject * sql_update_new ()
{
return g_object_new (SQL_TYPE_UPDATE, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void sql_update_render_set (SqlUpdateSet * set, SqlRender * render)
{
sql_render_add_object (render, set->field);
sql_render_add_token (render, "=");
sql_render_add_object (render, set->expr);
}
static void sql_update_render (SqlUpdate * obj, SqlRender * render)
{
sql_render_add_list (render, T, "UPDATE", SQL_DML (obj)->target, ",");
sql_render_add_list (render, TRUE, "UPDATE", SQL_DML (obj)->targets, ",");
if (SQL_DML (obj)->target)
if (SQL_DML (obj)->targets)
{
sql_render_add_list_with_func (render, T, "SET", obj->set, ",",
(SqlRenderFunc) sql_update_render_set);
sql_render_add_item (render, F, "WHERE", SQL_DML (obj)->where);
sql_render_add_list (render, TRUE, "SET", obj->sets, ",");
sql_render_add_item (render, FALSE, "WHERE", SQL_DML (obj)->where);
}
}
static void sql_update_set_free (SqlUpdateSet * obj)
{
g_object_unref (obj->field);
g_object_unref (obj->expr);
g_free (obj);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
void sql_update_add_set (SqlUpdate * obj, SqlField * field, SqlExpr * expr)
{
g_return_if_fail (SQL_IS_UPDATE (obj));
g_return_if_fail (SQL_IS_FIELD (field) && SQL_IS_EXPR (expr));
}
SqlUpdateSet * set = g_new (SqlUpdateSet, 1);
set->field = g_object_ref_sink (field);
set->expr = g_object_ref_sink (expr);
obj->set = g_slist_append (obj->set, set);
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum
{
PROP_SETS = 1
};
static void sql_update_set_property (SqlUpdate * obj, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_SETS:
sql_object_remove (obj, obj->sets);
obj->sets = sql_object_add (obj, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
static void sql_update_get_property (SqlUpdate * obj, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_SETS:
g_value_set_object (value, obj->sets);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void sql_update_init (SqlUpdate * obj)
{
obj->set = NULL;
obj->sets = NULL;
}
static void sql_update_finalize (SqlUpdate * obj)
{
g_slist_free_full (obj->set, (GFreeFunc) sql_update_set_free);
sql_object_remove (obj, obj->sets);
G_OBJECT_CLASS (sql_update_parent_class)->finalize (G_OBJECT (obj));
}
static void sql_update_class_init (SqlUpdateClass * klass)
{
G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) sql_update_finalize;
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) sql_update_finalize;
k->set_property = (GObjectSetPropertyFunc) sql_update_set_property;
k->get_property = (GObjectGetPropertyFunc) sql_update_get_property;
SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_update_render;
g_object_class_install_property (k, PROP_SETS,
sql_param_list ("sets"
,("Sets")
,("A list of sets")
,SQL_TYPE_UPDATE_SET
,G_PARAM_READWRITE | G_PARAM_CONSTRUCT
));
}

View File

@ -20,6 +20,7 @@
#include "sql-dml.h"
#include "sql-field.h"
#include "sql-update-set.h"
#define SQL_TYPE_UPDATE (sql_update_get_type ())
#define SQL_UPDATE(object) (G_TYPE_CHECK_INSTANCE_CAST (object, SQL_TYPE_UPDATE, SqlUpdate))
@ -28,29 +29,13 @@
typedef struct _SqlUpdate SqlUpdate;
typedef struct _SqlUpdateClass SqlUpdateClass;
typedef struct _SqlUpdateSet SqlUpdateSet;
/**
* SqlUpdateSet:
* @field: an #SqlField
* @expr: an #SqlExpr
*
* Defines a field for the SET clause for an #SqlUpdate.
**/
struct _SqlUpdateSet
{
SqlField * field;
SqlExpr * expr;
};
/**
* SqlUpdate:
* @set: (element-type Sql.UpdateSet):
**/
struct _SqlUpdate
{
SqlDml parent;
GSList * set; // List of SqlUpdateSet
SqlList * sets; // List of SqlUpdateSet
};
struct _SqlUpdateClass
@ -61,7 +46,7 @@ struct _SqlUpdateClass
GType sql_update_get_type ();
SqlUpdate * sql_update_new ();
SqlObject * sql_update_new ();
void sql_update_add_set (SqlUpdate * obj, SqlField * field, SqlExpr * expr);
#endif

View File

@ -28,14 +28,20 @@
**/
G_DEFINE_TYPE (SqlValue, sql_value, SQL_TYPE_EXPR);
SqlExpr * sql_value_new ()
SqlObject * sql_value_new ()
{
return g_object_new (SQL_TYPE_VALUE, NULL);
}
SqlExpr * sql_value_new_with_value (const GValue * value)
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);
@ -111,7 +117,7 @@ static gboolean sql_value_is_ready (SqlValue * obj)
return !gvn_value_is_null (obj->value);
}
static void sql_value_set_real_value (SqlValue * obj, const GValue * value)
static void sql_value_put_value (SqlValue * obj, const GValue * value)
{
if (gvn_value_ccopy (value, obj->value))
g_signal_emit_by_name (obj, "changed");
@ -119,7 +125,7 @@ static void sql_value_set_real_value (SqlValue * obj, const GValue * value)
static void sql_value_cb_value_changed (GvnParam * param, const GValue * value, SqlValue * obj)
{
sql_value_set_real_value (obj, value);
sql_value_put_value (obj, value);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
@ -136,7 +142,7 @@ void sql_value_set_value (SqlValue * obj, const GValue * value)
g_return_if_fail (SQL_IS_VALUE (obj));
g_return_if_fail (!obj->param);
sql_value_set_real_value (obj, value);
sql_value_put_value (obj, value);
}
void sql_value_set_param (SqlValue * obj, GvnParam * param)
@ -155,10 +161,21 @@ void sql_value_set_param (SqlValue * obj, GvnParam * param)
obj->param = g_object_ref_sink (param);
g_signal_connect (param, "value-changed",
G_CALLBACK (sql_value_cb_value_changed), obj);
sql_value_set_real_value (obj, gvn_param_get_value (param));
sql_value_put_value (obj, gvn_param_get_value (param));
}
}
/**
* sql_value_get_param:
* Return value: (transfer none):
**/
GvnParam * sql_value_get_param (SqlValue * self)
{
g_return_if_fail (SQL_IS_VALUE (self));
return self->param;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum

View File

@ -42,10 +42,12 @@ struct _SqlValueClass
};
GType sql_value_get_type ();
SqlExpr * sql_value_new ();
SqlExpr * sql_value_new_with_value (const GValue * value);
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

@ -20,11 +20,18 @@
#include <gvn/gvn.h>
#include "sql-object.h"
#include "sql-holder.h"
#include "sql-list.h"
#include "sql-batch.h"
#include "sql-set.h"
#include "sql-string.h"
#include "sql-stmt.h"
#include "sql-multi-stmt.h"
#include "sql-select.h"
#include "sql-select-field.h"
#include "sql-select-order.h"
#include "sql-update.h"
#include "sql-update-set.h"
#include "sql-insert.h"
#include "sql-delete.h"
#include "sql-expr.h"

View File

@ -3,6 +3,5 @@ Sql cheader_filename="sql/sql.h"
Render.object type="GLib.Object"
Render.add_object.object#parameter type="GLib.Object"
Render.get_string.object#parameter type="GLib.Object"
RenderFunc.obj#parameter type="GLib.Object"
parser_parse name="parse"

View File

@ -193,25 +193,29 @@ static gboolean vn_completion_match_selected (GtkEntryCompletion * completion,
static void vn_completion_substitute (VnCompletion * obj)
{
SqlExpr * field;
SqlString * stmt;
SqlOperation * op;
SqlObject * field;
SqlObject * like;
SqlBatch * batch;
SqlList * operands;
if (!(obj->model && obj->field))
return;
g_object_get (obj->model, "stmt", &stmt, NULL);
like = sql_operation_new (SQL_OPERATION_TYPE_LIKE);
op = sql_operation_new (SQL_OPERATION_TYPE_LIKE);
operands = sql_list_new (SQL_TYPE_EXPR);
g_object_set (like, "operands", operands, NULL);
field = sql_field_new (obj->field, NULL, NULL);
sql_operation_add_expr (op, field);
field = sql_field_new (obj->field);
sql_list_add (operands, field);
obj->value = sql_value_new ();
sql_operation_add_expr (op, obj->value);
sql_list_add (operands, obj->value);
sql_string_add_expr (stmt, field);
sql_string_add_expr (stmt, SQL_EXPR (op));
batch = sql_batch_new ();
sql_batch_add (batch, "field", field);
sql_batch_add (batch, "filter", like);
db_model_set_batch (obj->model, batch);
}
static void vn_completion_set_field (VnCompletion * obj, gchar * field)

View File

@ -39,8 +39,8 @@ struct _VnCompletion
gboolean invalid;
guint column;
gchar * last_match;
SqlExpr * value;
DbModel * model;
SqlObject * value;
gchar * field;
};

View File

@ -16,6 +16,7 @@
*/
#include "vn-model.h"
#include <stdlib.h>
static void vn_model_buildable_init (GtkBuildableIface * iface);
@ -38,6 +39,7 @@ typedef struct
DbModel * model;
GSList * fields;
GSList * params;
GSList * linked;
}
VnModelData;
@ -55,42 +57,16 @@ static void vn_model_start_element (GMarkupParseContext * context,
d->fields = g_slist_prepend (d->fields, g_strdup (values[i]));
else if (!g_strcmp0 (names[i], "param"))
d->params = g_slist_prepend (d->params, g_strdup (values[i]));
}
static void vn_model_end_element (GMarkupParseContext * context,
const gchar * element, gpointer data, GError ** error)
{
GSList * f, * p;
VnModelData * d = data;
g_return_if_fail (d->builder);
if (g_strcmp0 (element, "links"))
return;
d->fields = g_slist_reverse (d->fields);
d->params = g_slist_reverse (d->params);
for (f = d->fields, p = d->params; f && p; f = f->next, p = p->next)
else if (!g_strcmp0 (names[i], "linked"))
{
gchar * field = f->data;
GvnParam * param = GVN_PARAM (gtk_builder_get_object (d->builder, p->data));
db_model_set_default_value_from_param (d->model, field, param);
g_free (f->data);
g_free (p->data);
gboolean b = values[i] && !g_strcmp0 (values[i], "True") ? TRUE : FALSE;
d->linked = g_slist_prepend (d->linked, GINT_TO_POINTER (b));
}
g_slist_free (d->fields);
g_slist_free (d->params);
g_slice_free (VnModelData, d);
}
static const GMarkupParser vn_model_parser =
{
vn_model_start_element
,vn_model_end_element
};
static gboolean vn_model_buildable_custom_tag_start (GtkBuildable * buildable,
@ -107,6 +83,7 @@ static gboolean vn_model_buildable_custom_tag_start (GtkBuildable * buildable,
data_ptr->model = DB_MODEL (buildable);
data_ptr->fields = NULL;
data_ptr->params = NULL;
data_ptr->linked = NULL;
*data = data_ptr;
*parser = vn_model_parser;
@ -118,6 +95,41 @@ static gboolean vn_model_buildable_custom_tag_start (GtkBuildable * buildable,
return FALSE;
}
static void vn_model_buildable_custom_finished (GtkBuildable * buildable,
GtkBuilder * builder, GObject * child, const gchar * tagname, gpointer data)
{
GSList * f, * p, * l;
VnModelData * d = data;
g_return_if_fail (d->builder);
if (g_strcmp0 (tagname, "links"))
return;
d->fields = g_slist_reverse (d->fields);
d->params = g_slist_reverse (d->params);
d->linked = g_slist_reverse (d->linked);
for (f = d->fields, p = d->params, l = d->linked;
f && p && l;
f = f->next, p = p->next, l = l->next)
{
gchar * field = f->data;
gboolean linked = GPOINTER_TO_INT (l->data);
GvnParam * param = GVN_PARAM (gtk_builder_get_object (d->builder, p->data));
db_model_set_default_value_from_param (d->model, field, param, linked);
g_free (f->data);
g_free (p->data);
}
g_slist_free (d->fields);
g_slist_free (d->params);
g_slist_free (d->linked);
g_slice_free (VnModelData, d);
}
static void vn_model_buildable_set_buildable_property (GtkBuildable * buildable,
GtkBuilder * builder, const gchar * name, const GValue * value)
{
@ -136,21 +148,15 @@ static void vn_model_buildable_set_buildable_property (GtkBuildable * buildable,
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void vn_model_finalize (VnModel * obj)
{
G_OBJECT_CLASS (vn_model_parent_class)->finalize (G_OBJECT (obj));
}
static void vn_model_class_init (VnModelClass * klass)
{
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) vn_model_finalize;
}
static void vn_model_buildable_init (GtkBuildableIface * iface)
{
iface->custom_tag_start = vn_model_buildable_custom_tag_start;
iface->set_buildable_property = vn_model_buildable_set_buildable_property;
iface->custom_finished = vn_model_buildable_custom_finished;
}
static void vn_model_init (VnModel * obj)

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.2 -->
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<!-- interface-local-resource-path ../image -->
@ -7,24 +7,14 @@
<property name="width_request">400</property>
<property name="height_request">300</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Hedera</property>
<property name="destroy_with_parent">True</property>
<property name="icon">../image/icon.svg</property>
<signal name="destroy" handler="vn_gui_on_child_destroyed" swapped="no"/>
<child>
<object class="GtkBox" id="box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkAlignment" id="alignment">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">4</property>
<child>
<object class="GtkNotebook" id="notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="show_border">False</property>
<property name="scrollable">True</property>
<signal name="create-window" handler="vn_gui_on_page_detached" swapped="no"/>
<signal name="page-added" handler="vn_gui_on_page_added" swapped="no"/>
@ -33,14 +23,4 @@
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@ -1,200 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<!-- interface-requires gtk+ 3.0 -->
<requires lib="gtk+" version="3.0"/>
<!-- interface-local-resource-path ../image -->
<object class="GtkDialog" id="settings-dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Configuration</property>
<property name="resizable">False</property>
<property name="destroy_with_parent">True</property>
<property name="icon">../image/icon.svg</property>
<property name="type_hint">dialog</property>
<property name="transient_for">window</property>
<signal name="delete-event" handler="vn_login_settings_on_delete_event" swapped="no"/>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">spread</property>
<child>
<object class="GtkButton" id="cancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="vn_login_cb_settings_cancel_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="apply">
<property name="label">gtk-apply</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<accelerator key="Return" signal="clicked"/>
<accelerator key="KP_Enter" signal="clicked"/>
<signal name="clicked" handler="vn_login_cb_settings_apply_clicked" swapped="no"/>
</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="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="grid2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkEntry" id="plugin">
<property name="visible">True</property>
<property name="can_focus">True</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="host">
<property name="visible">True</property>
<property name="can_focus">True</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>
<child>
<object class="GtkLabel" id="plugin-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Plugin:</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="host-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Host:</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="GtkLabel" id="schema-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Schema:</property>
</object>
<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="GtkEntry" id="schema">
<property name="visible">True</property>
<property name="can_focus">True</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">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="ca-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">SSL CA:</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>
<object class="GtkEntry" id="ssl-ca">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="secondary_icon_stock">gtk-info</property>
<property name="secondary_icon_activatable">False</property>
<property name="secondary_icon_sensitive">False</property>
<property name="secondary_icon_tooltip_text" translatable="yes">Path to the file containing the CA certificate, if this is empty SSL won't be used</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>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">cancel</action-widget>
<action-widget response="0">apply</action-widget>
</action-widgets>
</object>
<object class="GtkWindow" id="window">
<property name="can_focus">False</property>
<property name="border_width">15</property>
@ -259,13 +67,10 @@
<property name="visible">True</property>
<property name="can_focus">True</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>
@ -281,8 +86,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>
@ -298,8 +101,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>
@ -308,10 +109,7 @@
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="secondary_icon_stock">gtk-find</property>
<property name="secondary_icon_activatable">True</property>
<property name="secondary_icon_sensitive">True</property>
<property name="secondary_icon_name">edit-find-symbolic</property>
<property name="secondary_icon_tooltip_text" translatable="yes">Press here to see the password</property>
<signal name="icon-press" handler="vn_login_cb_pass_show" swapped="no"/>
<signal name="icon-release" handler="vn_login_cb_pass_hide" swapped="no"/>
@ -319,8 +117,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>
@ -335,8 +131,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>
@ -377,9 +171,9 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<accelerator key="Return" signal="clicked"/>
<accelerator key="KP_Enter" signal="clicked"/>
<signal name="clicked" handler="vn_login_cb_connect_clicked" swapped="no"/>
<accelerator key="KP_Enter" signal="clicked"/>
<accelerator key="Return" signal="clicked"/>
</object>
<packing>
<property name="expand">False</property>
@ -397,4 +191,178 @@
</object>
</child>
</object>
<object class="GtkDialog" id="settings-dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Configuration</property>
<property name="resizable">False</property>
<property name="destroy_with_parent">True</property>
<property name="icon">../image/icon.svg</property>
<property name="type_hint">dialog</property>
<property name="transient_for">window</property>
<signal name="delete-event" handler="vn_login_settings_on_delete_event" swapped="no"/>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">spread</property>
<child>
<object class="GtkButton" id="cancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="vn_login_cb_settings_cancel_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="apply">
<property name="label">gtk-apply</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="vn_login_cb_settings_apply_clicked" swapped="no"/>
<accelerator key="KP_Enter" signal="clicked"/>
<accelerator key="Return" signal="clicked"/>
</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="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="grid2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkEntry" id="plugin">
<property name="visible">True</property>
<property name="can_focus">True</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="host">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="plugin-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Plugin:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="host-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Host:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="schema-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Schema:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="schema">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="ca-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">SSL CA:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="ssl-ca">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="secondary_icon_name">dialog-information-symbolic</property>
<property name="secondary_icon_activatable">False</property>
<property name="secondary_icon_sensitive">False</property>
<property name="secondary_icon_tooltip_text" translatable="yes">Path to the file containing the CA certificate, if this is empty SSL won't be used</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">cancel</action-widget>
<action-widget response="0">apply</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -1,128 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.2 -->
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<!-- interface-local-resource-path ../image -->
<object class="GtkApplicationWindow" id="window">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Hedera</property>
<property name="window_position">center</property>
<property name="icon">../image/icon.svg</property>
<signal name="delete-event" handler="vn_gui_on_main_deleted" swapped="no"/>
<child>
<object class="GtkBox" id="box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">4</property>
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<child>
<object class="GtkNotebook" id="notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="scrollable">True</property>
<property name="group_name">vn-notebook</property>
<signal name="create-window" handler="vn_gui_on_page_detached" swapped="no"/>
<signal name="page-added" handler="vn_gui_on_page_added" swapped="no"/>
<signal name="page-removed" handler="vn_gui_on_main_page_removed" swapped="no"/>
<signal name="switch-page" handler="vn_gui_on_switch_page" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="status">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="spacing">6</property>
<child>
<object class="GtkSpinner" id="spinner">
<property name="width_request">18</property>
<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>
<child>
<object class="GtkLabel" id="status-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Ready</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">User:</property>
<attributes>
<attribute name="weight" value="normal"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="user-name">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">[user-name]</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</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">True</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkAboutDialog" id="about">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="destroy_with_parent">True</property>
<property name="icon">../image/icon.svg</property>
<property name="type_hint">dialog</property>
<property name="transient_for">window</property>
<property name="program_name">Hedera</property>
<property name="version">Versión 1.0</property>
<property name="copyright" translatable="yes">Copyright - Verdnatura Levante S. L.</property>
@ -177,4 +63,23 @@ Juan Ferrer Toribio</property>
</object>
</child>
</object>
<object class="GtkApplicationWindow" id="window">
<property name="can_focus">False</property>
<property name="window_position">center</property>
<property name="icon">../image/icon.svg</property>
<signal name="delete-event" handler="vn_gui_on_main_deleted" swapped="no"/>
<child>
<object class="GtkNotebook" id="notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="show_border">False</property>
<property name="scrollable">True</property>
<property name="group_name">vn-notebook</property>
<signal name="create-window" handler="vn_gui_on_page_detached" swapped="no"/>
<signal name="page-added" handler="vn_gui_on_page_added" swapped="no"/>
<signal name="page-removed" handler="vn_gui_on_main_page_removed" swapped="no"/>
<signal name="switch-page" handler="vn_gui_on_switch_page" swapped="no"/>
</object>
</child>
</object>
</interface>

View File

@ -32,8 +32,8 @@ typedef struct _VnFormClass VnFormClass;
typedef GType (* VnFormGetTypeFunc) ();
typedef void (* VnFormOpenFunc) (VnForm * obj, GtkBuilder * builder, gpointer user_data);
typedef void (* VnFormActivateFunc) (VnForm * obj);
typedef void (* VnFormDeactivateFunc) (VnForm * obj);
/*typedef void (* VnFormActivateFunc) (VnForm * obj);
typedef void (* VnFormDeactivateFunc) (VnForm * obj);*/
struct _VnForm
{
@ -46,13 +46,21 @@ struct _VnForm
GMenuModel * menu;
};
/**
* VnFormClass:
* @open: the entry point of the form, the first to be executed after opening
* the form.
* @get_actions: returns the #GActionEntry array containing the actions declared
* by the form to be shown in its menu.
**/
struct _VnFormClass
{
GtkAlignmentClass parent;
/*< public >*/
void (* open) (VnForm * obj, GtkBuilder * builder, gpointer user_data);
const GActionEntry * (* get_actions) (VnForm * obj, int * size);
void (* activate) (VnForm * obj);
void (* deactivate) (VnForm * obj);
/* void (* activate) (VnForm * obj);
void (* deactivate) (VnForm * obj);*/
};
GType vn_form_get_type ();

View File

@ -47,6 +47,7 @@ struct _VnWindow
GtkWindow * widget;
GtkHeaderBar * header;
GtkWidget * menu_button;
GtkWidget * spinner;
GtkNotebook * notebook;
VnForm * active_form;
guint merge_id;
@ -81,22 +82,8 @@ void vn_gui_on_logout_activated (GSimpleAction * a, GVariant * v, gpointer obj);
void vn_gui_on_open_activated (GSimpleAction * a, GVariant * v, gpointer obj);
void vn_gui_on_about_activated (GSimpleAction * a, GVariant * v, gpointer obj);
void vn_gui_on_exit_activated (GSimpleAction * a, GVariant * v, gpointer obj);
static const GActionEntry app_entries[] =
{
{"logout", vn_gui_on_logout_activated}
,{"connect", vn_gui_on_open_activated}
,{"about", vn_gui_on_about_activated}
,{"quit", vn_gui_on_exit_activated}
};
void vn_gui_on_close_tab_activated (GSimpleAction * a, GVariant * v, gpointer obj);
static const GActionEntry win_entries[] =
{
{"close", vn_gui_on_close_tab_activated}
};
static void vn_gui_reconnect (VnGui * obj);
static void vn_gui_on_conn_error (DbConn * conn, const GError * error, VnGui * obj);
static void vn_gui_on_conn_status_changed (DbConn * conn, DbConnStatus status, VnGui * obj);
@ -108,6 +95,19 @@ void vn_gui_on_main_page_removed (GtkNotebook * notebook, GtkWidget * page, gu
static guint signals[LAST_SIGNAL] = {0};
static const GActionEntry app_entries[] =
{
{"logout", vn_gui_on_logout_activated}
,{"connect", vn_gui_on_open_activated}
,{"about", vn_gui_on_about_activated}
,{"quit", vn_gui_on_exit_activated}
};
static const GActionEntry win_entries[] =
{
{"close", vn_gui_on_close_tab_activated}
};
/**
* vn_gui_new:
* @app: a #GtkApplication
@ -469,8 +469,8 @@ static VnWindow * vn_gui_add_window (VnGui * obj, GtkWindow * widget, GtkNoteboo
window->header = g_object_new (GTK_TYPE_HEADER_BAR
,"show-close-button", TRUE
,"has-subtitle", TRUE
,"title", gtk_window_get_title (widget)
,"title", obj->app_title
,"subtitle", db_conn_get_user (obj->conn)
,NULL);
gtk_window_set_titlebar (widget, GTK_WIDGET (window->header));
@ -488,6 +488,10 @@ static VnWindow * vn_gui_add_window (VnGui * obj, GtkWindow * widget, GtkNoteboo
gtk_header_bar_pack_start (window->header, button);
window->menu_button = button;
window->spinner = gtk_spinner_new ();
gtk_widget_set_opacity (window->spinner, 0);
gtk_header_bar_pack_end (window->header, window->spinner);
// Loading the modules actions
for (n = obj->modules; n; n = n->next)
@ -729,7 +733,7 @@ void vn_gui_on_switch_page (GtkNotebook * notebook, VnForm * form, guint num, Vn
gtk_tree_model_get (GTK_TREE_MODEL (obj->tree),
iter, COL_TITLE, &form_title, -1);
gtk_header_bar_set_subtitle (window->header, form_title);
gtk_header_bar_set_title (window->header, form_title);
g_free (form_title);
}
@ -761,7 +765,7 @@ void vn_gui_on_main_page_removed (GtkNotebook * notebook,
if (gtk_notebook_get_n_pages (notebook) < 1)
{
vn_gui_hide_form (window);
gtk_header_bar_set_subtitle (window->header, NULL);
gtk_header_bar_set_title (window->header, window->obj->app_title);
}
vn_gui_set_show_tabs (window);
@ -859,6 +863,7 @@ static void vn_gui_on_conn_error (DbConn * conn, const GError * error, VnGui * o
*/
static void vn_gui_on_conn_status_changed (DbConn * conn, DbConnStatus status, VnGui * obj)
{
GSList * l;
gchar * status_text;
if (status & DB_CONN_CLOSING)
@ -876,18 +881,24 @@ static void vn_gui_on_conn_status_changed (DbConn * conn, DbConnStatus status, V
else
status_text = _("Ready");
gtk_label_set_text (obj->status_label, status_text);
for (l = obj->windows; l; l = l->next)
{
VnWindow * win = l->data;
gtk_widget_set_tooltip_text (win->spinner, status_text);
if (status & DB_CONN_LOADING)
{
// XXX: Used to fix a bug that causes the GtkSpinner not spin.
gtk_widget_hide (GTK_WIDGET (obj->spinner));
gtk_widget_show (GTK_WIDGET (obj->spinner));
gtk_spinner_start (obj->spinner);
//gtk_widget_show (win->spinner);
gtk_widget_set_opacity (win->spinner, 1);
gtk_spinner_start (GTK_SPINNER (win->spinner));
}
else
gtk_spinner_stop (obj->spinner);
{
//gtk_widget_hide (win->spinner);
gtk_widget_set_opacity (win->spinner, 0);
gtk_spinner_stop (GTK_SPINNER (win->spinner));
}
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
@ -944,25 +955,11 @@ void vn_gui_open (VnGui * obj)
if (gtk_builder_add_from_file (builder, MAIN_UI, &err))
{
gchar * user;
GtkLabel * label;
GKeyFile * config;
GtkWindow * widget;
GtkNotebook * notebook;
GtkWindow * widget = gtk_builder_get (builder, "window");
GtkNotebook * notebook = gtk_builder_get (builder, "notebook");
obj->spinner = gtk_builder_get (builder, "spinner");
obj->about = gtk_builder_get (builder, "about");
obj->menu = gtk_builder_get (builder, "menu");
obj->status_label = gtk_builder_get (builder, "status-label");
user = db_conn_get_user (obj->conn);
label = gtk_builder_get (builder, "user-name");
gtk_label_set_text (label, user);
g_free (user);
widget = gtk_builder_get (builder, "window");
notebook = gtk_builder_get (builder, "notebook");
obj->main_window = vn_gui_add_window (obj, widget, notebook);
gtk_builder_connect_signals (GTK_BUILDER (builder), obj->main_window);

View File

@ -50,11 +50,7 @@ struct _VnGui
VnWindow * main_window;
VnWindow * active_window;
GtkTreeStore * tree;
GtkTreeView * menu;
GtkSpinner * spinner;
GtkDialog * about;
GtkLabel * status_label;
GtkHeaderBar * header;
GMenuModel * main_menu;
GHashTable * forms;

View File

@ -80,9 +80,10 @@ static void vn_login_show (VnLogin * obj)
{
gchar * user;
gchar * pass;
GError * err = NULL;
GtkBuilder * builder = gtk_builder_new ();
if (gtk_builder_add_from_file (builder, LOGIN_UI, NULL))
if (gtk_builder_add_from_file (builder, LOGIN_UI, &err))
{
obj->window = BUILDER_GET (builder, "window");
obj->user = BUILDER_GET (builder, "user");
@ -117,11 +118,15 @@ static void vn_login_show (VnLogin * obj)
g_free (user);
g_free (pass);
}
else if (err)
{
g_warning ("VnLogin: %s", err->message);
g_clear_error (&err);
}
g_object_unref (builder);
}
// gtk_widget_show (GTK_WIDGET (obj->window));
gtk_widget_show_all (GTK_WIDGET (obj->window));
gtk_widget_grab_focus (GTK_WIDGET (obj->user));