diff --git a/AUTHORS b/AUTHORS index 8efb161..3374dca 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,3 @@ Alejandro Tomas Colombini Gomez Juan Ferrer Toribio Javier Gallego Ferris -Jordi Cuquerella diff --git a/Makefile.decl b/Makefile.decl index 850631c..b801e0e 100644 --- a/Makefile.decl +++ b/Makefile.decl @@ -57,13 +57,13 @@ vn_datadir = $(hedera_datadir)/vn vn_imagedir = $(vn_datadir)/image vn_guidir = $(vn_datadir)/gui +module_querydir = $(hedera_datadir)/module/sql + if ENABLE_INSTALL vn_xmldir = $(datadir)/xml/$(PACKAGE) - module_querydir = $(hedera_datadir)/module/sql module_datadir = $(hedera_datadir)/module else vn_xmldir = $(vn_datadir)/schema - module_querydir = $(hedera_datadir)/module/sql module_datadir = $(hedera_datadir)/module/data endif diff --git a/build/m4/vn-dev.m4 b/build/m4/vn-dev.m4 new file mode 100644 index 0000000..abc1825 --- /dev/null +++ b/build/m4/vn-dev.m4 @@ -0,0 +1,68 @@ +dnl +dnl Copyright (C) 2012 - Juan Ferrer Toribio +dnl +dnl This program is free software: you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation, either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program. If not, see . +dnl + +# serial 2 vn-dev + +AC_DEFUN([VN_BUILD_OPTIONS], +[ + case $CFLAGS in + *-W*) ;; + *)CFLAGS+=" -Wall ";; + esac + + # Check for debug mode + AC_MSG_CHECKING([whether to build with debug information...]) + AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], + [Enable debug data generation [default = no]])], + [ENABLE_DEBUG="$enableval"], + [ENABLE_DEBUG=no]) + AC_MSG_RESULT([$ENABLE_DEBUG]) + + case $CFLAGS in + *-g*) ;; + *) + if test x"$ENABLE_DEBUG" = x"yes"; then + CFLAGS+=" -ggdb " + fi + ;; + esac + + # Check if the package must be configured to be installed + AC_MSG_CHECKING([whether to configure to install...]) + AC_ARG_ENABLE([install], + [AS_HELP_STRING([--enable-install], + [Enable install configuration [default = yes]])], + [ENABLE_INSTALL="$enableval"], + [ENABLE_INSTALL=yes]) + AC_MSG_RESULT([$installit]) + AM_CONDITIONAL(ENABLE_INSTALL, [test x"$ENABLE_INSTALL" = x"yes"]) + + case $CFLAGS in + *-O*) ;; + *) + if test x"$ENABLE_INSTALL" = x"yes"; then + CFLAGS+=" -O3" + fi + ;; + esac + + AC_SUBST([ENABLE_DEBUG]) + AC_SUBST([ENABLE_INSTALL]) + AC_SUBST([CFLAGS]) +]) + diff --git a/configure.ac b/configure.ac index d3454e2..5df77c7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,7 @@ AC_INIT([hedera], [1.0]) +dnl Set compiler flags empty by default +: ${CFLAGS=''} AC_CONFIG_AUX_DIR([build]) AC_CONFIG_MACRO_DIR([build/m4]) @@ -8,17 +10,32 @@ LT_INIT([dlopen]) AC_PREREQ([2.69]) AM_SILENT_RULES([yes]) -# Checks for programs +# Checks for the C compiler AC_PROG_CC +# Check for additional packages PKG_CHECK_MODULES([glib], [glib-2.0]) PKG_CHECK_MODULES([gdome], [gdome2]) PKG_CHECK_MODULES([gtk], [gtk+-3.0]) -PKG_CHECK_MODULES([gladeui], gladeui-2.0) +PKG_CHECK_MODULES([gladeui], [gladeui-2.0]) +PKG_CHECK_MODULES([gtksourceview], [gtksourceview-3.0] + ,[SOURCEVIEW=yes] + ,[echo $gtksourceview_PKG_ERRORS]) + +AM_CONDITIONAL(HAVE_SOURCEVIEW, [test -n $SOURCEVIEW]) GTK_DOC_CHECK([1.14],[--flavour no-tmpl]) + +# Internationalization IT_PROG_INTLTOOL([0.40.1], [no-xml]) +GETTEXT_PACKAGE=hedera +AC_SUBST([GETTEXT_PACKAGE]) +AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [GETTEXT package name]) +ALL_LINGUAS="es ca nl" +AM_GLIB_GNU_GETTEXT +AM_XGETTEXT_OPTION([-k_ -kQ_:1g -kN_ -kC_:1c,2 -kNC_:1c,2]) + # Checks for Ragel State Machine Compiler AC_PATH_PROG(RAGEL, [ragel], [no]) if test x"$RAGEL" = x"no" ; then @@ -49,51 +66,11 @@ fi AM_CONDITIONAL(ENABLE_VALA, [test x"$ENABLE_VALA" = x"yes" -a x"$VAPIGEN" != x"no"]) -# Internationalization -GETTEXT_PACKAGE=hedera -AC_SUBST([GETTEXT_PACKAGE]) -AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [GETTEXT package name]) -ALL_LINGUAS="es ca nl" -AM_GLIB_GNU_GETTEXT -AM_XGETTEXT_OPTION([-k_ -kQ_:1g -kN_ -kC_:1c,2 -kNC_:1c,2]) - # GSettings configuration GLIB_GSETTINGS -CFLAGS=" -Wall" - -# Check for debug mode -AC_MSG_CHECKING([whether to build with debug information...]) -AC_ARG_ENABLE([debug], - [AS_HELP_STRING([--enable-debug], - [Enable debug data generation [default = no]])], - [ENABLE_DEBUG="$enableval"], - [ENABLE_DEBUG=no]) -AC_MSG_RESULT([$ENABLE_DEBUG]) - -if test x"$ENABLE_DEBUG" = x"yes"; then - CFLAGS+=" -ggdb" -fi - -# Check if it will be installed -AC_MSG_CHECKING([whether to configure to install...]) -AC_ARG_ENABLE([install], - [AS_HELP_STRING([--enable-install], - [Enable install configuration [default = yes]])], - [ENABLE_INSTALL="$enableval"], - [ENABLE_INSTALL=yes]) -AC_MSG_RESULT([$installit]) -AM_CONDITIONAL(ENABLE_INSTALL, [test x"$ENABLE_INSTALL" = x"yes"]) - -if test x"$ENABLE_INSTALL" = x"yes"; then - CFLAGS+=" -O3" -else - CFLAGS+=" -O0" -fi - -AC_SUBST([CPPFLAGS]) -AC_SUBST([CFLAGS]) -AC_SUBST([LDFLAGS]) +# Sets the default build options for Vn projects +VN_BUILD_OPTIONS # Portability check disabled for GTK-DOC (can be changed if needed) AM_INIT_AUTOMAKE([-Wno-portability]) @@ -117,9 +94,9 @@ AC_CONFIG_FILES([ module/Makefile module/src/Makefile module/data/Makefile - module/sql/Makefile main/Makefile main/vn-hedera.desktop + main/vn-hedera-debug.desktop vapi/Makefile glade/Makefile docs/Makefile diff --git a/db/db-conn.c b/db/db-conn.c index cd9126e..b481f1a 100644 --- a/db/db-conn.c +++ b/db/db-conn.c @@ -239,7 +239,7 @@ static void db_conn_add_request (DbConn * obj, DbRequest * request) * @plugin: the plugin name * @err: return address of a #GError or #NULL * - * Tryes to load a plugin. + * Tries to load a plugin. * * Return vale: %TRUE if plugin was loaded successfully, %FALSE ortherwise **/ @@ -892,14 +892,15 @@ SqlString * db_conn_create_stmt_from_file (DbConn * obj, const gchar * query_fil g_return_val_if_fail (DB_IS_CONN (obj), NULL); g_return_val_if_fail (query_file, NULL); - + file = g_strconcat (query_file, ".sql", NULL); - - for (i = 0; obj->query_dirs &&obj->query_dirs[i] && !stmt; i++) + + if (obj->query_dirs) + for (i = 0; obj->query_dirs[i] && !stmt; i++) { gchar * buffer; gchar * path = g_build_filename (obj->query_dirs[i], file, NULL); - + if (g_file_get_contents (path, &buffer, NULL, NULL)) { stmt = sql_string_new (buffer); @@ -908,9 +909,9 @@ SqlString * db_conn_create_stmt_from_file (DbConn * obj, const gchar * query_fil g_free (path); } - + if (!stmt) - g_warning ("DbConn: Can't create statement from file: %s", query_file); + g_warning ("DbConn: Can't create statement from file: %s", file); g_free (file); return stmt; diff --git a/db/db-file-loader.c b/db/db-file-loader.c index e2f62eb..0bf4cf3 100644 --- a/db/db-file-loader.c +++ b/db/db-file-loader.c @@ -565,7 +565,7 @@ static void db_file_loader_cancel (DbFileLoader * obj, const gchar * name) g_hash_table_iter_init (&iter, obj->priv->downloading); - while (g_hash_table_iter_next (&iter, (gpointer*) &file, NULL)) + while (g_hash_table_iter_next (&iter, (gpointer *) &file, NULL)) if (!name || !g_strcmp0 (file->name, name)) { g_cancellable_cancel (file->cancel); diff --git a/db/db-iterator.c b/db/db-iterator.c index 8585dbf..d984a93 100644 --- a/db/db-iterator.c +++ b/db/db-iterator.c @@ -16,6 +16,7 @@ */ #include "db-iterator.h" +#include "db-model-holder.h" #define IS_READY(obj) (obj->model && db_model_get_status (obj->model) == DB_MODEL_STATUS_READY) @@ -24,29 +25,16 @@ * @short_description: manages a iterator with its events * @title: DbIterator * - * The DbIterator manages a connection with a data base. - * There are different ways to create an DbIterator: - * - * - * - * db_iterator_new(): This constructor just needs a #DbModel object - * - * - * - * - * db_iterator_new_with_stmt(): This one needs a #DbConn with the connection and - * a #SqlStmt object - * - * - * - * - * db_iterator_new_with_sql(): This one needs a #DbConn with the connection and - * the sql string - * - * - * + * The #DbIterator manages a connection with a data base. The function + * db_iterator_new() creates a new #DbIterator. */ -G_DEFINE_TYPE (DbIterator, db_iterator, G_TYPE_OBJECT); + +static void db_iterator_model_holder_interface_init (DbModelHolderInterface * iface); + +G_DEFINE_TYPE_WITH_CODE (DbIterator, db_iterator, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (DB_TYPE_MODEL_HOLDER, + db_iterator_model_holder_interface_init) +); enum { ITER_CHANGED @@ -72,48 +60,6 @@ DbIterator * db_iterator_new (DbModel * model) return g_object_new (DB_TYPE_ITERATOR, "model", model, NULL); } -/** - * db_iterator_new_with_stmt: - * @conn: the connection used to create the model. - * @stmt: the #SqlStmt statement used to create the model. - * - * Creates a new #DbIterator. #SqlStmt must be a #SqlSelect or a #SqlString - * object with a valid SELECT statement. - * - * Return value: a #DbIterator. - **/ -DbIterator * db_iterator_new_with_stmt (DbConn * conn, SqlStmt * stmt) -{ - DbIterator * obj; - DbModel * model; - - g_return_val_if_fail (DB_IS_CONN (conn) || !conn, NULL); - g_return_val_if_fail (SQL_IS_STMT (stmt) || !stmt, NULL); - - model = db_model_new (conn, stmt); - obj = g_object_new (DB_TYPE_ITERATOR, "model", model, NULL); - g_object_unref (model); - - return obj; -} - -/** - * db_iterator_new_with_sql: - * @conn: the connection used to create the model. - * @sql: the sql string used to create the model. - * - * Creates a new #DbIterator. sql must be a valid SELECT statement. - * - * Return value: a #DbIterator. - **/ -DbIterator * db_iterator_new_with_sql (DbConn * conn, const gchar * sql) -{ - g_return_val_if_fail (sql, NULL); - g_return_val_if_fail (DB_IS_CONN (conn) || !conn, NULL); - - return g_object_new (DB_TYPE_ITERATOR, "sql", sql, "conn", conn, NULL); -} - //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private static void db_iterator_unref_param (DbIterator * obj, DbParam * param) @@ -183,7 +129,7 @@ static void db_iterator_on_model_line_updated_after (DbModel * model, DbIter * i * Function called when row is deleted on the model. */ static void db_iterator_on_model_line_deleted (DbModel * model, gint row, DbIterator * obj) -{ +{ if (obj->row_selected && row == obj->row) { DbIter iter; @@ -296,31 +242,6 @@ static gboolean db_iterator_check_row_selected (DbIterator * obj) return FALSE; } -/* - * Attempts to create a model, if have enough information, and assigns it to - * the iterator. - */ -static void db_iterator_try_create_model (DbIterator * obj) -{ - DbModel * new_model = NULL; - - if (obj->conn) - { - if (obj->sql) - { - if (obj->use_file) - new_model = db_model_new_with_file (obj->conn, obj->sql); - else - new_model = db_model_new_with_sql (obj->conn, obj->sql); - } - if (obj->stmt) - new_model = db_model_new (obj->conn, obj->stmt); - } - - if (new_model) - db_iterator_set_model (obj, new_model); -} - //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public /** @@ -356,40 +277,6 @@ DbModel * db_iterator_get_model (DbIterator * obj) return obj->model; } -/** - * db_iterator_get_conn: - * @obj: a #DbIterator - * - * Gets connection used by the @obj model. - * - * Return value: (transfer none): the #DbConn - **/ -DbConn * db_iterator_get_conn (DbIterator * obj) -{ - g_return_val_if_fail (DB_IS_ITERATOR (obj), NULL); - - if (obj->model) - db_model_get_conn (obj->model); - - return NULL; -} - -/** - * db_iterator_set_conn: - * @obj: a #DbIterator - * @conn: the #DbConn - * - * Sets the connection used by the @obj model. - **/ -void db_iterator_set_conn (DbIterator * obj, DbConn * conn) -{ - g_return_if_fail (DB_IS_ITERATOR (obj)); - g_return_if_fail (DB_IS_CONN (conn)); - g_return_if_fail (obj->model); - - db_model_set_conn (obj->model, conn); -} - /** * db_iterator_is_ready: * @obj: a #DbIterator @@ -948,10 +835,6 @@ enum PROP_MODEL = 1 ,PROP_MODE ,PROP_REMEMBER_SELECTION - ,PROP_CONN - ,PROP_STMT - ,PROP_SQL - ,PROP_USE_FILE }; static void db_iterator_set_property (DbIterator * obj, guint id, @@ -968,25 +851,6 @@ static void db_iterator_set_property (DbIterator * obj, guint id, case PROP_REMEMBER_SELECTION: obj->remember_selection = g_value_get_boolean (value); break; - case PROP_CONN: - g_clear_object (&obj->conn); - obj->conn = g_value_dup_object (value); - db_iterator_try_create_model (obj); - break; - case PROP_STMT: - g_clear_object (&obj->stmt); - obj->stmt = g_value_dup_object (value); - db_iterator_try_create_model (obj); - break; - case PROP_SQL: - g_free (obj->sql); - obj->sql = g_value_dup_string (value); - db_iterator_try_create_model (obj); - break; - case PROP_USE_FILE: - obj->use_file = g_value_get_boolean (value); - db_iterator_try_create_model (obj); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); } @@ -1019,10 +883,6 @@ static void db_iterator_init (DbIterator * obj) obj->params = NULL; obj->row = 0; obj->row_selected = FALSE; - obj->conn = NULL; - obj->stmt = NULL; - obj->sql = NULL; - obj->use_file = FALSE; } static void db_iterator_finalize (DbIterator * obj) @@ -1049,10 +909,6 @@ static void db_iterator_finalize (DbIterator * obj) ); g_object_unref (obj->model); } - - g_clear_object (&obj->conn); - g_clear_object (&obj->stmt); - g_free (obj->sql); G_OBJECT_CLASS (db_iterator_parent_class)->finalize (G_OBJECT (obj)); } @@ -1064,34 +920,66 @@ static void db_iterator_class_init (DbIteratorClass * klass) k->get_property = (GObjectGetPropertyFunc) db_iterator_get_property; k->finalize = (GObjectFinalizeFunc) db_iterator_finalize; + /** + * DbIterator::iter-changed: + * @iterator: the object on which the signal is emitted + * @iter: a #DbIter + * + * This signal is emitted when @iter moves over the @iterator model + */ signals[ITER_CHANGED] = g_signal_new ("iter-changed", DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 ); + + /** + * DbIterator::data-changed: + * @iterator: the object on which the signal is emitted + * + * This signal is emitted when the model changes its data + */ signals[DATA_CHANGED] = g_signal_new ("data-changed", DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 ); + + /** + * DbIterator::row-num-changed: + * @iterator: the object on which the signal is emitted + * + * This signal is emitted when the selected row changes + */ signals[ROW_NUM_CHANGED] = g_signal_new ("row-num-changed", DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 ); + + /** + * DbIterator::status-changed: + * @iterator: the object on which the signal is emitted + * @ready: #TRUE if @iterator is ready, #FALSE otherwise + * + * This signal is emitted when the status of the iterator changes + */ signals[STATUS_CHANGED] = g_signal_new ("status-changed", DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN ); + + /** + * DbIterator::operations-done: + * @iterator: the object on which the signal is emitted + * + * This signal is emitted when all pending operations are performed over the + * model of @iterator + */ signals[OPERATIONS_DONE] = g_signal_new ("operations-done", DB_TYPE_ITERATOR, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 ); - g_object_class_install_property (k, PROP_MODEL, - g_param_spec_object ("model" - ,_("Model") - ,_("The DbModel handled by the iterator") - ,DB_TYPE_MODEL - ,G_PARAM_READWRITE - )); + g_object_class_override_property (k, PROP_MODEL, "model"); + g_object_class_install_property (k, PROP_MODE, g_param_spec_enum ("mode" ,_("Mode") @@ -1107,34 +995,12 @@ static void db_iterator_class_init (DbIteratorClass * klass) ,TRUE ,G_PARAM_CONSTRUCT | G_PARAM_READWRITE )); - g_object_class_install_property (k, PROP_CONN, - g_param_spec_object ("conn" - ,_("Connection") - ,_("The connection used by the model") - ,DB_TYPE_CONN - ,G_PARAM_WRITABLE - )); - g_object_class_install_property (k, PROP_STMT, - g_param_spec_object ("stmt" - ,_("Statement") - ,_("The statement used to create the model") - ,SQL_TYPE_STMT - ,G_PARAM_WRITABLE - )); - g_object_class_install_property (k, PROP_SQL, - g_param_spec_string ("sql" - ,_("SQL") - ,_("The SQL query used to create the model") - , NULL - ,G_PARAM_WRITABLE - )); - g_object_class_install_property (k, PROP_USE_FILE, - g_param_spec_boolean ("use-file" - ,_("Use file") - ,_("Wether to interpret the sql property as query file") - ,FALSE - ,G_PARAM_CONSTRUCT | G_PARAM_WRITABLE - )); +} + +static void db_iterator_model_holder_interface_init (DbModelHolderInterface * iface) +{ + iface->get_model = (DbModelHolderGetModelFunc) db_iterator_get_model; + iface->set_model = (DbModelHolderSetModelFunc) db_iterator_set_model; } GType db_iterator_mode_get_type () diff --git a/db/db-iterator.h b/db/db-iterator.h index d17a0ce..f39e963 100644 --- a/db/db-iterator.h +++ b/db/db-iterator.h @@ -81,11 +81,6 @@ struct _DbIterator gint row; gboolean row_selected; gboolean remember_selection; - - DbConn * conn; - SqlStmt * stmt; - gchar * sql; - gboolean use_file; }; struct _DbIteratorClass @@ -98,11 +93,6 @@ GType db_iterator_get_type (); GType db_iterator_mode_get_type () G_GNUC_CONST; DbIterator * db_iterator_new (DbModel * model); -DbIterator * db_iterator_new_with_stmt (DbConn * conn, SqlStmt * stmt); -DbIterator * db_iterator_new_with_sql (DbConn * conn, const gchar * sql); -DbModel * db_iterator_get_model (DbIterator * obj); -DbConn * db_iterator_get_conn (DbIterator * obj); -void db_iterator_set_conn (DbIterator * obj, DbConn * conn); gboolean db_iterator_is_ready (DbIterator * obj); DbIteratorMode db_iterator_get_mode (DbIterator * obj); void db_iterator_set_mode (DbIterator * obj, DbIteratorMode mode); diff --git a/db/db-model-holder.c b/db/db-model-holder.c index ef7db6e..bfc759f 100644 --- a/db/db-model-holder.c +++ b/db/db-model-holder.c @@ -19,15 +19,17 @@ /** * SECTION: db-model-holder - * @Short_description: + * @Short_description: interface for objects that use a model * @Title: DbModelHolder * @See_also: #DbModel * * This interface should be implemented from any class that uses a #DbModel as - * datasource. + * data source. This interface offers a #DbModel as a virtual property that has + * to be overwritten by the classes implementing it, as well as the + * db_model_holder_get_model() and db_model_holder_set_model() methods. **/ -G_DEFINE_INTERFACE (DbModelHolder, db_model_holder, G_TYPE_INTERFACE); +G_DEFINE_INTERFACE (DbModelHolder, db_model_holder, G_TYPE_INVALID); /** * db_model_holder_get_model: @@ -35,7 +37,7 @@ G_DEFINE_INTERFACE (DbModelHolder, db_model_holder, G_TYPE_INTERFACE); * * Gets the model used by holder. * - * Return value: the #DbModel + * Return value:(transfer none): the #DbModel **/ DbModel * db_model_holder_get_model (DbModelHolder * obj) { @@ -45,7 +47,7 @@ DbModel * db_model_holder_get_model (DbModelHolder * obj) } /** - * db_model_holder_get_model: + * db_model_holder_set_model: * @obj: a #DbModelHolder * @model: the #DbModel * @@ -54,18 +56,19 @@ DbModel * db_model_holder_get_model (DbModelHolder * obj) void db_model_holder_set_model (DbModelHolder * obj, DbModel * model) { g_return_if_fail (DB_IS_MODEL_HOLDER (obj)); + g_return_if_fail (DB_IS_MODEL (obj)); DB_MODEL_HOLDER_GET_INTERFACE (obj)->set_model (obj, model); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class -static void db_model_holder_default_init (DbModelHolderInterface * klass) -{ - g_object_interface_install_property (klass, +static void db_model_holder_default_init (DbModelHolderInterface * iface) +{ + g_object_interface_install_property (iface, g_param_spec_object ("model" - ,"Model" - ,"The model used by the holder" + ,_("Model") + ,_("The model used by the holder") ,DB_TYPE_MODEL ,G_PARAM_READWRITE )); diff --git a/db/db-model-holder.h b/db/db-model-holder.h index 1a475ea..99a5dba 100644 --- a/db/db-model-holder.h +++ b/db/db-model-holder.h @@ -15,34 +15,34 @@ * along with this program. If not, see . */ -#ifndef DB_MODEL_HOLDER_H -#define DB_MODEL_HOLDER_H +#ifndef DB_MODEL_HOLDER_H +#define DB_MODEL_HOLDER_H #include "db-model.h" - -#define DB_TYPE_MODEL_HOLDER (db_model_holder_get_type ()) -#define DB_MODEL_HOLDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DB_TYPE_MODEL_HOLDER, DbModelHolder)) -#define DB_IS_MODEL_HOLDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DB_TYPE_MODEL_HOLDER)) + +#define DB_TYPE_MODEL_HOLDER (db_model_holder_get_type ()) +#define DB_MODEL_HOLDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DB_TYPE_MODEL_HOLDER, DbModelHolder)) +#define DB_IS_MODEL_HOLDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DB_TYPE_MODEL_HOLDER)) #define DB_MODEL_HOLDER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), DB_TYPE_MODEL_HOLDER, DbModelHolderInterface)) - -typedef struct _DbModelHolder DbModelHolder; + +typedef struct _DbModelHolder DbModelHolder; typedef struct _DbModelHolderInterface DbModelHolderInterface; typedef DbModel * (* DbModelHolderGetModelFunc) (DbModelHolder * obj); typedef void (* DbModelHolderSetModelFunc) (DbModelHolder * obj, DbModel * sql); -struct _DbModelHolder {}; - -struct _DbModelHolderInterface +struct _DbModelHolder; + +struct _DbModelHolderInterface { - /* */ + /* */ GTypeInterface parent; DbModelHolderGetModelFunc get_model; DbModelHolderSetModelFunc set_model; -}; - +}; + GType db_model_holder_get_type (); DbModel * db_model_holder_get_model (DbModelHolder * obj); void db_model_holder_set_model (DbModelHolder * obj, DbModel * model); - -#endif \ No newline at end of file + +#endif diff --git a/db/db-model.c b/db/db-model.c index 912eb4d..f8a4c3a 100644 --- a/db/db-model.c +++ b/db/db-model.c @@ -25,11 +25,11 @@ * SECTION: db-model * @Short_description: data vinculed to a SELECT query sent to the database * @Title: DbModel - * @See_also: #DbIterator, #DbConn + * @See_also: #DbConn, #DbModelHolder * * The #DbModel class gets an SQL query statement to retrieve the data from the - * database connected by a #DbConn. It is normally used undirectly, using instead - * #DbForm. + * database connected by a #DbConn. It is normally used undirectly, using + * a #DbIterator or another #DbModelHolder instead. **/ /* @@ -60,6 +60,7 @@ struct _DbModelPrivate GHashTable * row_ops; gint updated_col; GValue * updated_value; + DbRow * null_row; GHashTable * column_index; GSList * pending_request; @@ -93,8 +94,8 @@ G_DEFINE_TYPE (DbModel, db_model, G_TYPE_OBJECT) /** * db_model_new: - * @conn: a #DbConn - * @stmt: an #SqlStmt + * @conn:(allow-none): a #DbConn + * @stmt:(allow-none): an #SqlStmt * * Returns the newly created #DbModel, filled with the data retrieved from the * database with @stmt and through @conn. @@ -108,7 +109,7 @@ DbModel * db_model_new (DbConn * conn, SqlStmt * stmt) /** * db_model_new_with_sql: - * @conn: a #DbConn + * @conn:(allow-none): a #DbConn * @sql: a string containing an SQL statement * * Returns the newly created #DbModel, filled with the data retrieved from the @@ -124,7 +125,7 @@ DbModel * db_model_new_with_sql (DbConn * conn, const gchar * sql) /** * db_model_new_with_file: - * @conn: a #DbConn + * @conn:(allow-none): a #DbConn * @file: the path to the file containing the SQL query to fill the model * * Returns a newly created #DbModel, filled with the data retrieved from @file. @@ -238,6 +239,14 @@ typedef struct } DbModelPKey; +typedef struct +{ + gint col; + gint order; + DbRow * null_row; +} +SortInfo; + enum { DB_MODEL_UNSORTED_SORT_COLUMN_ID = -2, @@ -387,7 +396,7 @@ static void db_model_on_data_ready (DbRequest * request, DbModel * obj) for (i = 0; i < priv->result->ncols; i++) { - // Set fields editable if *all* primary keys are selected FIXME + //FIXME Set fields editable iff ALL primary keys are selected if (priv->column[i].info & DB_COLUMN_PRI_KEY && !g_slist_find_custom (t, priv->column[i].table, (GCompareFunc) g_strcmp0)) for (j = 0; j < priv->result->ncols; j++) @@ -709,7 +718,7 @@ static gboolean db_model_set_row_operation (DbModel * obj, // if (!db_operation_add_updated (op, col)) // return FALSE; } - else + else return FALSE; return TRUE; @@ -940,7 +949,7 @@ static void db_model_set_join_fields (DbModel * obj, SqlJoin * join, static void db_model_post_process_query (DbModel * obj) { // TODO When parser gets fully functional, these 3 lines won't be needed, -// because obj->stmt will be a parsed stmt: +// because obj>priv->stmt will be a parsed stmt: gchar * rend = db_conn_render (obj->priv->conn, obj->priv->stmt, NULL); SqlObject * stmt = sql_parser_parse (rend); /*gchar * rend2 = NULL; @@ -953,11 +962,11 @@ g_free (rend2);*/ { DbModelField * lfield, * rfield; SqlJoin * join; - GList * n; + GSList * n; SqlSelect * select = SQL_SELECT (stmt); gboolean calculate_join = FALSE; - for (n = sql_list_get_items (SQL_DML (select)->targets); n; n = n->next) + for (n = SQL_DML (select)->target; n; n = n->next) if ((join = n->data) && SQL_IS_JOIN (join) && SQL_IS_TABLE (join->target_left) @@ -965,7 +974,6 @@ g_free (rend2);*/ && SQL_IS_OPERATION (join->condition)) { // DbJoin and ColDef creation - GList * operators; SqlOperation * op = SQL_OPERATION (join->condition); SqlField * lsql_field = NULL, * rsql_field = NULL; @@ -979,20 +987,19 @@ g_free (rend2);*/ if (op->type == SQL_OPERATION_TYPE_AND) { - GList * l; + GSList * l; - for (l = sql_list_get_items (op->operators); l; l = l->next) + for (l = op->expr; l; l = l->next) { SqlOperation * subop; - operators = sql_list_get_items (subop->operators); if (SQL_IS_OPERATION (subop = l->data) && subop->type == SQL_OPERATION_TYPE_EQUAL - && operators->data // Left Field - && operators->next && operators->next->data) // Right Field + && subop->expr->data // Left Field + && subop->expr->next && subop->expr->next->data) // Right Field { - lsql_field = SQL_FIELD (operators->data); - rsql_field = SQL_FIELD (operators->next->data); + lsql_field = SQL_FIELD (subop->expr->data); + rsql_field = SQL_FIELD (subop->expr->next->data); db_model_set_join_fields (obj, join, lsql_field, rsql_field, lfield, rfield); @@ -1010,25 +1017,20 @@ g_free (rend2);*/ } } } - else + else if (op->type == SQL_OPERATION_TYPE_EQUAL && op->expr->data + && op->expr->next && op->expr->next->data) { - operators = sql_list_get_items (op->operators); + lsql_field = SQL_FIELD (op->expr->data); + rsql_field = SQL_FIELD (op->expr->next->data); - if (op->type == SQL_OPERATION_TYPE_EQUAL && operators->data - && operators->next && operators->next->data) - { - lsql_field = SQL_FIELD (operators->data); - rsql_field = SQL_FIELD (operators->next->data); + db_model_set_join_fields (obj, join, + lsql_field, rsql_field, lfield, rfield); - db_model_set_join_fields (obj, join, - lsql_field, rsql_field, lfield, rfield); + calculate_join = TRUE; - calculate_join = TRUE; - - if (join->type != SQL_JOIN_TYPE_INNER) - db_model_calculate_col_def - (obj, join ,lsql_field, rsql_field); - } + if (join->type != SQL_JOIN_TYPE_INNER) + db_model_calculate_col_def + (obj, join ,lsql_field, rsql_field); } if (calculate_join) @@ -1140,7 +1142,10 @@ static gint db_model_value_compare0 (const GValue * a, const GValue * b) { gchar * a_str = g_utf8_casefold (g_value_get_string (a), -1); gchar * b_str = g_utf8_casefold (g_value_get_string (b), -1); - return g_utf8_collate (a_str, b_str); + gint res = g_utf8_collate (a_str, b_str); + g_free (a_str); + g_free (b_str); + return res; } default: if (a_type == G_TYPE_DATE) @@ -1164,21 +1169,24 @@ static gint db_model_value_compare0 (const GValue * a, const GValue * b) return 1; } -static gint db_model_valcmp_asc (gpointer * a, gpointer * b, gpointer col) +static inline gint db_model_valcmp (gpointer * a, gpointer * b, SortInfo * info) { + gint order; DbRow * first = *a; DbRow * second = *b; - return db_model_value_compare0 (&first->value[GPOINTER_TO_INT (col)] - ,&second->value[GPOINTER_TO_INT (col)]); -} -static gint db_model_valcmp_desc (gpointer * a, gpointer * b, gpointer col) -{ - DbRow * first = *a; - DbRow * second = *b; - return -db_model_value_compare0 (&(first->value)[GPOINTER_TO_INT (col)] - ,&(second->value)[GPOINTER_TO_INT (col)]); + if (first == info->null_row) + order = -1; + else if (second == info->null_row) + order = 1; + else + { + gint dir = info->order == DB_SORT_ASCENDING ? 1 : -1; + order = dir * db_model_value_compare0 (&first->value[info->col] + ,&second->value[info->col]); + } + return order; } static void db_model_set_status (DbModel * obj, DbModelStatus status) @@ -1206,19 +1214,19 @@ static void db_model_manage_join (DbModel * obj, DbIter * iter, gint col) DbModelPrivate * priv = obj->priv; if (priv->join - && gvn_param_spec_get_editable (priv->column[col].spec) - && !gvn_value_is_null (DB_ROW_FIELD (iter->data, col))) + && gvn_param_spec_get_editable (priv->column[col].spec)) +// && !gvn_value_is_null (DB_ROW_FIELD (iter->data, col))))XXX WHY WAS THIS HERE? it IS tested in set_value { gint i; GSList * n; gboolean send_request = FALSE, end = FALSE; - SqlList * stmts = g_object_ref_sink (sql_list_new (SQL_TYPE_MULTI_STMT)); - + SqlMultiStmt * multi_stmt = sql_multi_stmt_new (); /*FIXME for (i = 0; i < obj->ncols; i++) // Check for multi-field pkeys to be fully set // need to know the total number of pkey fields - if (i != col && obj->column[i].info & DB_COLUMN_PRI_KEY + if (i != col + && obj->column[i].info & DB_COLUMN_PRI_KEY && gvn_value_is_null (DB_ROW_FIELD (iter->data, i)) && !g_strcmp0 (obj->column[i].table, obj->column[col].table)) { @@ -1230,9 +1238,10 @@ static void db_model_manage_join (DbModel * obj, DbIter * iter, gint col) for (n = priv->join; n; n = n->next) { gint j; - SqlObject * where, * select; + SqlSelect * select; + SqlOperation * where; DbModelField * main_field = NULL, * other_field = NULL; - DbJoin * join = n->data; + DbJoin * join = (DbJoin *) n->data; if (join->left->main) { @@ -1257,39 +1266,38 @@ static void db_model_manage_join (DbModel * obj, DbIter * iter, gint col) if (!send_request) continue; // Continue to the next DbJoin in the list - select = sql_select_new (); - - sql_object_add_child (select, "targets", sql_table_new (other_field->table)); - - where = sql_operation_new (SQL_OPERATION_TYPE_AND); + select = sql_select_new (); + sql_dml_add_target (SQL_DML (select), + sql_table_new (other_field->table)); + where = sql_operation_new (SQL_OPERATION_TYPE_AND); for (i = 0; i < priv->result->ncols; i++) if (!g_strcmp0 (priv->column[i].table, other_field->table)) - { - sql_object_add_child (select, "exprs", - sql_field_new (priv->column[i].name, other_field->table, NULL)); - } + sql_select_add_expr (select, sql_field_new + (priv->column[i].name, other_field->table, NULL)); else if (!g_strcmp0 (priv->column[i].table, main_field->table)) - { - for (j = 0; j < main_field->name->len; j++) + for (j = 0; j < main_field->name->len; j++) if (!g_strcmp0 (priv->column[i].name, - g_ptr_array_index (main_field->name, j))) + g_ptr_array_index (main_field->name, j))) { - SqlObject * equal = sql_operation_new (SQL_OPERATION_TYPE_EQUAL); + SqlOperation * equal = + sql_operation_new (SQL_OPERATION_TYPE_EQUAL); - sql_object_add_child (equal, "operators", - sql_field_new (g_ptr_array_index (other_field->name, j) - ,other_field->table, NULL)); + sql_operation_add_expr (equal, sql_field_new + (g_ptr_array_index (other_field->name, j) + ,other_field->table, NULL + )); - sql_object_add_child (equal, "operators", - sql_value_new_with_value (DB_ROW_FIELD (iter->data, i))); + sql_operation_add_expr (equal, + sql_value_new_with_value + (DB_ROW_FIELD (iter->data, i))); - sql_object_add_child (where, "operators", equal); + sql_operation_add_expr (where, SQL_EXPR (equal)); } - } - sql_object_set (select, "where", where); - sql_list_add (stmts, select); + sql_dml_set_where (SQL_DML (select), SQL_EXPR (where)); + + sql_multi_stmt_add_stmt (multi_stmt, SQL_STMT (select)); } if (send_request) @@ -1303,7 +1311,7 @@ static void db_model_manage_join (DbModel * obj, DbIter * iter, gint col) join_data->col = col; request = db_conn_query_with_stmt_async (priv->conn - ,g_object_new (SQL_TYPE_MULTI_STMT, "stmts", stmts, NULL) + ,SQL_STMT (multi_stmt) ,(DbRequestDoneCallback) db_model_on_join_query_done ,join_data ,(GDestroyNotify) join_data_free @@ -1311,7 +1319,7 @@ static void db_model_manage_join (DbModel * obj, DbIter * iter, gint col) db_model_add_pending_request (obj, request); } - g_object_unref (stmts); + g_object_unref (multi_stmt); } } @@ -1367,7 +1375,9 @@ static void db_model_clear (DbModel * obj) priv->result = NULL; priv->column = NULL; priv->data = NULL; - + + priv->null_row = NULL; + g_free (priv->main_table); priv->main_table = NULL; priv->update_flags = 0; @@ -1428,15 +1438,23 @@ static gboolean db_model_table_row_all_null (DbModel * obj, DbRow * row, gint co **/ void db_model_set_conn (DbModel * obj, DbConn * conn) { + DbModelPrivate * priv; + g_return_if_fail (DB_IS_MODEL (obj)); g_return_if_fail (DB_IS_CONN (conn) || !conn); + priv = obj->priv; + if (conn) { - if (!obj->priv->conn) + if (!priv->conn) { - obj->priv->conn = g_object_ref (conn); - db_model_on_stmt_changed (obj->priv->stmt, obj); + priv->conn = g_object_ref (conn); + + if (priv->use_file && priv->sql) + priv->stmt = SQL_STMT (db_conn_create_stmt_from_file (conn, priv->sql)); + + db_model_on_stmt_changed (priv->stmt, obj); } else g_warning ("DbModel: The connection can only be set once"); @@ -1459,6 +1477,71 @@ DbConn * db_model_get_conn (DbModel * obj) return obj->priv->conn; } +/** + * db_model_set_sql: + * @obj: a #DbModel + * @sql: a value for the "sql property + * + * Sets the "sql" property to @sql. + **/ +void db_model_set_sql (DbModel * obj, const gchar * sql) +{ + SqlString * string = NULL; + + if (!sql) + return; + + g_return_if_fail (DB_IS_MODEL (obj)); + + g_free (obj->priv->sql); + obj->priv->sql = g_strdup (sql); + + if (obj->priv->use_file) + { + if (obj->priv->conn) + string = db_conn_create_stmt_from_file (obj->priv->conn, sql); + } + else + string = sql_string_new (sql); + + db_model_set_stmt (obj, SQL_STMT (string)); +} + +/** + * db_model_set_stmt: + * @obj: a #DbModel + * @stmt: the #SqlStmt + * + * Sets the "stmt" property of the model. + **/ +void db_model_set_stmt (DbModel * obj, SqlStmt * stmt) +{ + if (!stmt) + return; + + g_return_if_fail (!obj->priv->stmt); + g_return_if_fail (SQL_IS_STRING (stmt) || SQL_IS_SELECT (stmt)); + + obj->priv->stmt = g_object_ref_sink (stmt); + g_signal_connect (stmt, "changed", G_CALLBACK (db_model_on_stmt_changed), obj); + db_model_on_stmt_changed (stmt, obj); +} + +/** + * db_model_get_stmt: + * @obj: a #DbModel + * + * Returns the #SqlStmt which queries to the database about the data of @obj. + * + * Return value: (transfer none): the #SqlStmt property of @obj + **/ +const SqlStmt * db_model_get_stmt (DbModel * obj) +{ + g_return_val_if_fail (DB_IS_MODEL (obj), NULL); + + return obj->priv->stmt; +} + /** * db_model_get_spec: * @obj: a #DbModel @@ -1713,27 +1796,27 @@ void db_model_set_default_value_from_column (DbModel * obj, * @obj: a #DbModel * @dst_field: the field to be set * @param: a #GvnParam - * @id: an identifier string for @param * - * Get the default value for @dst_field from @param. + * **/ void db_model_set_default_value_from_param (DbModel * obj, - const gchar * dst_field, GvnParam * param, const gchar * id) + const gchar * dst_field, GvnParam * param) { - SqlObject * op, * value; + SqlExpr * value; + SqlOperation * op; g_return_if_fail (DB_IS_MODEL (obj)); g_return_if_fail (GVN_IS_PARAM (param)); g_return_if_fail (dst_field); op = sql_operation_new (SQL_OPERATION_TYPE_EQUAL); - sql_object_add_child (op, "operators", sql_field_new (dst_field, NULL, NULL)); + sql_operation_add_expr (op, sql_field_new (dst_field, NULL, NULL)); value = sql_value_new (); sql_value_set_param (SQL_VALUE (value), param); - sql_object_add_child (op, "operators", value); + sql_operation_add_expr (op, value); - sql_object_add_held_object (SQL_OBJECT (obj->priv->stmt), id, op); + sql_string_add_expr (SQL_STRING (obj->priv->stmt), SQL_EXPR (op)); DbParamDef * def = g_new (DbParamDef, 1); def->dst = g_strdup (dst_field); @@ -1745,17 +1828,16 @@ void db_model_set_default_value_from_param (DbModel * obj, /** * db_model_add_param: * @obj: a #DbModel - * @id: an identifier string for @param * @param: the #GvnParam to add * * Links the statement in the model to @param. **/ -void db_model_add_param (DbModel * obj, const gchar * id, GvnParam * param) +void db_model_add_param (DbModel * obj, GvnParam * param) { g_return_if_fail (DB_IS_MODEL (obj)); g_return_if_fail (GVN_IS_PARAM (param)); - sql_string_add_param (SQL_STRING (obj->priv->stmt), id, param); + sql_string_add_param (SQL_STRING (obj->priv->stmt), param); } /** @@ -1795,68 +1877,6 @@ const gchar * db_model_get_main_table (DbModel * obj) return obj->priv->main_table; } -/** - * db_model_get_stmt: - * @obj: a #DbModel - * - * Returns the #SqlStmt which queries to the database about the data of @obj. - * - * Return value: (transfer none): the #SqlStmt property of @obj - **/ -const SqlStmt * db_model_get_stmt (DbModel * obj) -{ - g_return_val_if_fail (DB_IS_MODEL (obj), NULL); - - return obj->priv->stmt; -} - -/** - * db_model_set_stmt: - * @obj: a #DbModel - * @stmt: the #SqlStmt - * - * Sets the "stmt" property of the model. - **/ -void db_model_set_stmt (DbModel * obj, SqlStmt * stmt) -{ - if (!stmt) - return; - - g_return_if_fail (!obj->priv->stmt); - g_return_if_fail (SQL_IS_STRING (stmt) || SQL_IS_SELECT (stmt)); - - obj->priv->stmt = g_object_ref_sink (stmt); - g_signal_connect (stmt, "changed", G_CALLBACK (db_model_on_stmt_changed), obj); - db_model_on_stmt_changed (stmt, obj); -} - -/** - * db_model_set_sql: - * @obj: a #DbModel - * @sql: a value for the "sql property - * - * Sets the "sql" property to @sql. - **/ -void db_model_set_sql (DbModel * obj, const gchar * sql) -{ - SqlString * string; - - if (!sql) - return; - - g_return_if_fail (DB_IS_MODEL (obj)); - - g_free (obj->priv->sql); - obj->priv->sql = g_strdup (sql); - - if (obj->priv->use_file) - string = db_conn_create_stmt_from_file (obj->priv->conn, sql); - else - string = sql_string_new (sql); - - db_model_set_stmt (obj, SQL_STMT (string)); -} - /** * db_model_get: * @obj: a #DbModel @@ -1939,6 +1959,9 @@ void db_model_set (DbModel * obj, DbIter * iter, ...) g_return_if_fail (DB_IS_MODEL (obj)); g_return_if_fail (obj->priv->result); g_return_if_fail (iter != NULL); + + if (iter->data == obj->priv->null_row) + return; va_start (va, iter); @@ -2025,14 +2048,19 @@ gboolean db_model_set_value (DbModel * obj, DbIter * iter, gint col, const GValu } else { - g_return_val_if_fail (0 <= col && col < priv->result->ncols, FALSE); - GValue new_value = {0}; DbRow * row = iter->data; DbOperation * operation = g_hash_table_lookup (priv->row_ops, row); DbModelRowOp row_op = operation ? operation->type : 0; GvnParamSpec * spec = priv->column[col].spec; + g_return_val_if_fail (0 <= col && col < priv->result->ncols, FALSE); + + if (iter->data == obj->priv->null_row) + { + return FALSE; + } + if (!gvn_param_spec_validate (spec, value, err)) { return FALSE; @@ -2131,7 +2159,7 @@ gboolean db_model_insert (DbModel * obj, DbIter * iter) DbParamDef * param_def = p->data; if (!g_strcmp0 (param_def->dst, priv->column[i].name)) - { + { def = gvn_param_get_value (param_def->param); g_value_init (&row->value[i], G_VALUE_TYPE (def)); gvn_value_copy (def, &row->value[i]); @@ -2139,7 +2167,17 @@ gboolean db_model_insert (DbModel * obj, DbIter * iter) } if (!def) - g_value_init (&row->value[i], GVN_TYPE_NULL); + { + def = gvn_param_spec_get_default (priv->column[i].spec); + + if (def && G_VALUE_TYPE (def) != SQL_TYPE_FUNCTION) + { + g_value_init (&row->value[i], G_VALUE_TYPE (def)); + gvn_value_copy (def, &row->value[i]); + } + else + g_value_init (&row->value[i], GVN_TYPE_NULL); + } } g_ptr_array_add (priv->data, row); @@ -2183,8 +2221,11 @@ void db_model_delete (DbModel * obj, DbIter * iter) return; } - if (!db_model_set_row_operation - (obj, g_ptr_array_index (obj->priv->data, DB_ROW_POSITION (iter->data)), + if (iter->data == obj->priv->null_row) + return; + + if (!db_model_set_row_operation (obj, + g_ptr_array_index (obj->priv->data, DB_ROW_POSITION (iter->data)), DB_MODEL_ROW_OP_DELETE, 0)) return; @@ -2194,6 +2235,68 @@ void db_model_delete (DbModel * obj, DbIter * iter) db_model_perform_operations (obj, FALSE); } +/** + * db_model_use_null_row: + * @obj: a #DbModel + * @use: wether to use a null row + * + * Sets wether to use a null row at the end of the model. This row can't be + * modified by the methods @db_model_delete or @db_model_set_value, the only way + * to remove it is to call @db_model_use_null_row again passing #FALSE. + **/ +void db_model_use_null_row (DbModel * obj, gboolean use) +{ + DbModelPrivate * priv; + + g_return_if_fail (DB_IS_MODEL (obj)); + + priv = obj->priv; + + if (MODEL_NOT_READY(obj) || !priv->result + || ((priv->null_row != NULL) == use)) + return; + + if (use) + { + if (!priv->null_row) + { + gint i; + DbIter iter; + DbModelPrivate * priv = obj->priv; + DbRow * curr, * row = db_row_new (priv->result->ncols, 0); + gpointer * data = priv->data->pdata; + + for (i = 0; i < row->len; i++) + g_value_init (&row->value[i], GVN_TYPE_NULL); + + priv->null_row = row; + iter.data = row; + iter.stamp = priv->stamp; + + priv->result->nrows++; + g_ptr_array_set_size (priv->data, priv->result->nrows); + curr = data[0]; + data[0] = row; + + for (i = 1; i < priv->result->nrows; i++) + { + DbRow * next = data[i]; + DB_ROW_POSITION (curr)++; + data[i] = curr; + curr = next; + } + + g_signal_emit (obj, db_model_signal[LINE_INSERTED], 0, &iter); + } + } + else if (priv->null_row) + { + g_signal_emit (obj, db_model_signal[LINE_DELETED], 0, + DB_ROW_POSITION (priv->null_row)); + priv->null_row = NULL; + } +} + /** * db_model_order_by: * @obj: a #DbModel @@ -2206,6 +2309,7 @@ void db_model_delete (DbModel * obj, DbIter * iter) void db_model_order_by (DbModel * obj, gint col, DbSortType order) { DbModelPrivate * priv; + SortInfo info; g_return_if_fail (DB_IS_MODEL (obj)); priv = obj->priv; g_return_if_fail (priv->result && col >= -2 && col < priv->result->ncols); @@ -2217,8 +2321,8 @@ void db_model_order_by (DbModel * obj, gint col, DbSortType order) gint r_ind, i = 0; if ((priv->order == order && priv->sort_column_id == col) - || !priv->data - || col == DB_MODEL_UNSORTED_SORT_COLUMN_ID) + || !priv->data + || col == DB_MODEL_UNSORTED_SORT_COLUMN_ID) return; if (col == DB_MODEL_DEFAULT_SORT_COLUMN_ID @@ -2229,14 +2333,13 @@ void db_model_order_by (DbModel * obj, gint col, DbSortType order) priv->sort_column_id = col; g_signal_emit (obj, db_model_signal[SORT_CHANGED], 0, NULL); - if (order == DB_SORT_DESCENDING) - g_ptr_array_sort_with_data (priv->data - ,(GCompareDataFunc) db_model_valcmp_desc - ,GINT_TO_POINTER (col)); - else - g_ptr_array_sort_with_data (priv->data - ,(GCompareDataFunc) db_model_valcmp_asc - ,GINT_TO_POINTER (col)); + info.col = col; + info.null_row = priv->null_row; + info.order = order; + + g_ptr_array_sort_with_data (priv->data + ,(GCompareDataFunc) db_model_valcmp + ,&info); for (r_ind = 0; r_ind < priv->result->nrows; r_ind++) { @@ -2376,13 +2479,12 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) gint i; DbRow * row; DbOperation * op_elem; - GList * l = NULL; GSList * sl = NULL; - SqlObject * multi = NULL, - * equal_op, * val = NULL, - * insert, * set, - * select, * where = NULL; - SqlList * stmts; + SqlOperation * op = NULL, + * equal_op; + SqlExpr * val = NULL; + SqlSelect * select; + SqlMultiStmt * multi; DbRequest * request; GQueue * req_ops = NULL; @@ -2403,7 +2505,7 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) if (priv->operation->length > 1) transaction = TRUE; - stmts = sql_list_new (SQL_TYPE_STMT); + multi = sql_multi_stmt_new (); while ((op_elem = g_queue_pop_head (priv->operation))) { @@ -2423,65 +2525,66 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) if (!transaction) { - g_object_unref (stmts); - stmts = NULL; + g_object_unref (multi); + multi = NULL; } } else { - SqlObject * delete = sql_delete_new (); - sql_object_add_child (delete, "targets", - sql_table_new (priv->main_table, NULL)); + SqlDelete * delete = sql_delete_new (); - where = sql_operation_new (SQL_OPERATION_TYPE_AND); + sql_dml_add_target + (SQL_DML (delete), sql_table_new (priv->main_table)); + + op = sql_operation_new (SQL_OPERATION_TYPE_AND); DbModelPKey * pkey = db_model_get_primary_key (obj, priv->main_table); for (i = 0; i < pkey->count; i++) { - equal_op = sql_operation_new (SQL_OPERATION_TYPE_EQUAL); + equal_op = + SQL_OPERATION (sql_operation_new (SQL_OPERATION_TYPE_EQUAL)); - sql_object_add_child (equal_op, "operators", + sql_operation_add_expr (equal_op, sql_field_new (priv->column[pkey->index[i]].name, NULL, NULL)); - sql_object_add_child (equal_op, "operators", - sql_value_new_with_value (&row->value[pkey->index[i]])); - sql_object_add_child (where, "operators", equal_op); + sql_operation_add_expr (equal_op, + sql_value_new_with_value (&row->value[pkey->index[i]])); + sql_operation_add_expr (op, SQL_EXPR (equal_op)); } db_model_pkey_free (pkey); - sql_object_set (delete, "where", where); - - sql_list_add (stmts, delete); + sql_dml_set_where (SQL_DML (delete), SQL_EXPR (op)); + sql_multi_stmt_add_stmt (multi, SQL_STMT (delete)); render_ops = TRUE; } } else if (op_elem->type & DB_MODEL_ROW_OP_INSERT) // INSERT { - SqlObject * target = sql_table_new (priv->main_table); + SqlInsert * insert; + SqlTarget * table = sql_table_new (priv->main_table); - insert = g_object_new (SQL_TYPE_INSERT, "table", target, NULL); - set = g_object_new (SQL_TYPE_SET, NULL); - sql_object_add_child (insert, "values", set); + insert = sql_insert_new (); + sql_insert_add_row (insert); + sql_insert_set_table (insert, SQL_TABLE (table)); select = sql_select_new (); - sql_object_add_child (select, "targets", target); - where = sql_operation_new (SQL_OPERATION_TYPE_AND); + sql_dml_add_target (SQL_DML (select), table); + + op = sql_operation_new (SQL_OPERATION_TYPE_AND); for (i = 0; i < row->len; i++) if (!g_strcmp0 (priv->column[i].table, priv->main_table)) { gboolean cont = FALSE; - SqlObject * field = NULL; + SqlExpr * field; - l = sql_list_get_items (SQL_INSERT (insert)->fields); - - for (; l; l = l->next) - if (!g_strcmp0 (((SqlField*) l->data)->name, priv->column[i].name) - && ((!((SqlField*) l->data)->target) - || !g_strcmp0 (((SqlField*) l->data)->target, priv->column[i].table))) + for (sl = insert->field; sl; sl = sl->next) + if (!g_strcmp0 (((SqlField*) sl->data)->name, priv->column[i].name) + && ((!((SqlField*) sl->data)->target) + || !g_strcmp0 (((SqlField*) sl->data)->target, priv->column[i].table))) { cont = TRUE; break; @@ -2490,26 +2593,26 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) if (cont) continue; + field = sql_field_new (priv->column[i].name, NULL, NULL); + sql_insert_add_field (insert, SQL_FIELD (field)); + val = sql_value_new_with_value (&row->value[i]); + sql_insert_add_expr (insert, + gvn_value_is_null (&row->value[i]) ? NULL : val); - sql_object_add_child (insert, "fields", - sql_field_new (priv->column[i].name, NULL, NULL)); - sql_object_add_child (set, - "exprs", gvn_value_is_null (&row->value[i]) ? NULL : val); - - sql_object_add_child (select, "exprs", - sql_field_new (priv->column[i].name, - priv->column[i].table, NULL)); + sql_select_add_expr (select, + sql_field_new (priv->column[i].name, priv->column[i].table, NULL)); // Set the filter conditions if (priv->column[i].info & DB_COLUMN_PRI_KEY) { gboolean unset = FALSE; GValue value = {0}; - SqlObject * eq_value; + SqlExpr * eq_value; - equal_op = sql_operation_new (SQL_OPERATION_TYPE_EQUAL); - sql_object_add_child (equal_op, "operators", field); + equal_op = SQL_OPERATION + (sql_operation_new (SQL_OPERATION_TYPE_EQUAL)); + sql_operation_add_expr (equal_op, field); def = gvn_param_spec_get_default (priv->column[i].spec); @@ -2520,9 +2623,9 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) else if (def && G_IS_VALUE (def)) { if (G_VALUE_TYPE (def) == SQL_TYPE_FUNCTION) - eq_value = g_value_get_object (def); + eq_value = SQL_EXPR (g_value_get_object (def)); else - eq_value = sql_value_new_with_value (def); + eq_value = sql_value_new_with_value (def); } else { @@ -2531,26 +2634,26 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) unset = TRUE; } - sql_object_add_child (equal_op, "operators", eq_value); + sql_operation_add_expr (equal_op, eq_value); if (unset) g_value_unset (&value); - sql_object_add_child (where, "operators", equal_op); + sql_operation_add_expr (op, SQL_EXPR (equal_op)); } } - sql_object_set (select, "where", where); + sql_dml_set_where (SQL_DML (select), SQL_EXPR(op)); + if (priv->param_default) for (sl = priv->param_default; sl; sl = sl->next) { gboolean cont = FALSE; + GSList * m; DbParamDef * param_def = sl->data; - l = sql_list_get_items (SQL_INSERT (insert)->fields); - - for (; l; l = l->next) - if (!g_strcmp0 (((SqlField*) l->data)->name, param_def->dst)) + for (m = insert->field; m; m = m->next) + if (!g_strcmp0 (((SqlField*) m->data)->name, param_def->dst)) { cont = TRUE; break; @@ -2561,13 +2664,13 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) val = sql_value_new_with_value (gvn_param_get_value (param_def->param)); - sql_object_add_child (insert, "fields", - sql_field_new (param_def->dst, NULL, NULL)); - sql_object_add_child (set, "exprs", val); + sql_insert_add_field (insert, + SQL_FIELD (sql_field_new (param_def->dst, NULL, NULL))); + sql_insert_add_expr (insert, val); } - sql_list_add (stmts, insert); - sql_list_add (stmts, select); + sql_multi_stmt_add_stmt (multi, SQL_STMT (insert)); + sql_multi_stmt_add_stmt (multi, SQL_STMT (select)); render_ops = TRUE; } else if (op_elem->type & DB_MODEL_ROW_OP_UPDATE) // UPDATE @@ -2575,7 +2678,8 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) // Depending on the field, generate an UPDATE or INSERT+SELECT GSList * m; GValue * new_value; - SqlObject * update = NULL; + SqlUpdate * update = NULL; + SqlInsert * insert = NULL; GSList * prev_tables = NULL; GSList * prev_updates = NULL; gboolean insert_set = FALSE; @@ -2598,9 +2702,8 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) if (!is_added) { - where = sql_operation_new (SQL_OPERATION_TYPE_AND); - update = g_object_new (SQL_TYPE_UPDATE, - "where", where, NULL); + update = sql_update_new (); + op = sql_operation_new (SQL_OPERATION_TYPE_AND); } else { @@ -2609,19 +2712,17 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) for (l = prev_updates; l; l = l->next) if (SQL_IS_UPDATE (l->data) - && SQL_IS_TABLE (t = sql_list_get_items (SQL_DML (l->data)->targets)->data) + && SQL_IS_TABLE (t = SQL_DML (l->data)->target->data) && !g_strcmp0 (SQL_TABLE (t)->name, priv->column[i].table)) { - update = l->data; + update = SQL_UPDATE (l->data); break; } } - sql_object_add_child (update, "sets", - g_object_new (SQL_TYPE_UPDATE_SET, - "field", sql_field_new (priv->column[i].name, NULL, NULL), - "expr", sql_value_new_with_value (new_value), - NULL)); + sql_update_add_set (update, SQL_FIELD + (sql_field_new (priv->column[i].name, NULL, NULL)), + sql_value_new_with_value (new_value)); if (!is_added) { @@ -2629,8 +2730,8 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) DbModelPKey * pkey = db_model_get_primary_key (obj, priv->column[i].table); - sql_object_add_child (update, "targets", - sql_table_new (priv->column[i].table)); + sql_dml_add_target + (SQL_DML (update), sql_table_new (priv->column[i].table)); for (j = 0; j < pkey->count; j++) { @@ -2654,20 +2755,20 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) equal_op = sql_operation_new (SQL_OPERATION_TYPE_EQUAL); - sql_object_add_child (equal_op, "operators", - sql_field_new (priv->column[key_col].name, - priv->column[key_col].table, NULL)); + sql_operation_add_expr (SQL_OPERATION (equal_op) + ,sql_field_new (priv->column[key_col].name + ,priv->column[key_col].table, NULL)); val = sql_value_new_with_value (primary); - sql_object_add_child (equal_op, "operators", val); - if (where) - sql_object_add_child (where, "operators", equal_op); + sql_operation_add_expr (equal_op, val); + + if (op) + sql_operation_add_expr (op, SQL_EXPR (equal_op)); } - sql_object_set (update, "where", where); - - sql_list_add (stmts, update); + sql_dml_set_where (SQL_DML (update), SQL_EXPR (op)); + sql_multi_stmt_add_stmt (multi, SQL_STMT (update)); db_model_pkey_free (pkey); } @@ -2684,14 +2785,11 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) select = sql_select_new (); } - if (!SQL_INSERT (insert)->table) + if (!insert->table) { - SqlObject * table = sql_table_new (priv->column[i].table); - sql_object_set (insert, "table", table); - sql_object_add_child (select, "targets", table); - - set = g_object_new (SQL_TYPE_SET, NULL); - sql_object_add_child (insert, "values", set); + SqlTarget * table = sql_table_new (priv->column[i].table); + sql_insert_set_table (insert, SQL_TABLE (table)); + sql_dml_add_target (SQL_DML (select), table); insert_set = TRUE; @@ -2704,21 +2802,19 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) priv->column[col_def].table)) continue; - sql_object_add_child (insert, "fields", - sql_field_new (dst, NULL, NULL)); - - sql_object_add_child (set, "exprs" - ,sql_value_new_with_value (DB_ROW_FIELD (row, col_def))); + sql_insert_add_field (insert, SQL_FIELD + (sql_field_new (dst, NULL, NULL))); + sql_insert_add_expr (insert, + sql_value_new_with_value (DB_ROW_FIELD (row, col_def))); } } if (insert_set) { val = sql_value_new_with_value (new_value); - - sql_object_add_child (insert, "fields", - sql_field_new (priv->column[i].name, NULL, NULL)); - sql_object_add_child (set, "exprs", val); + sql_insert_add_field (insert, SQL_FIELD + (sql_field_new (priv->column[i].name, NULL, NULL))); + sql_insert_add_expr (insert, val); } } } @@ -2728,15 +2824,15 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) if (insert) { - where = sql_operation_new (SQL_OPERATION_TYPE_AND); + op = sql_operation_new (SQL_OPERATION_TYPE_AND); for (i = 0; i < row->len; i++) - if (!g_strcmp0 (SQL_TABLE (sql_list_get_items (SQL_DML (select)->targets)->data)->name + if (!g_strcmp0 (SQL_TABLE (SQL_DML (select)->target->data)->name ,priv->column[i].table)) { - SqlObject * field = SQL_OBJECT + SqlExpr * field = SQL_EXPR (sql_field_new (priv->column[i].name, NULL, NULL)); - sql_object_add_child (select, "fields", field); + sql_select_add_expr (select, field); if (priv->column[i].info & DB_COLUMN_PRI_KEY) { @@ -2746,27 +2842,26 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) || (def && G_VALUE_TYPE (def) == SQL_TYPE_FUNCTION)) { equal_op = sql_operation_new (SQL_OPERATION_TYPE_EQUAL); - - sql_object_add_child (equal_op, "operators", field); + sql_operation_add_expr (equal_op, field); if (gvn_value_is_null (&row->value[i])) { if (def && G_VALUE_TYPE (def) == SQL_TYPE_FUNCTION) - sql_object_add_child (equal_op, "operators", - g_value_get_object (def)); + sql_operation_add_expr (equal_op, + SQL_EXPR (g_value_get_object (def))); } else - sql_object_add_child (equal_op, "operators", val); + sql_operation_add_expr (equal_op, val); - sql_object_add_child (where, "operators", equal_op); + sql_operation_add_expr (op, SQL_EXPR (equal_op)); } } } - sql_object_set (select, "where", where); + sql_dml_set_where (SQL_DML (select), SQL_EXPR (op)); - sql_list_add (stmts, insert); - sql_list_add (stmts, select); + sql_multi_stmt_add_stmt (multi, SQL_STMT (insert)); + sql_multi_stmt_add_stmt (multi, SQL_STMT (select)); } render_ops = TRUE; @@ -2788,7 +2883,6 @@ void db_model_perform_operations (DbModel * obj, gboolean retry) DbModelRequest * data = g_new (DbModelRequest, 1); data->obj = g_object_ref (obj); data->operations = req_ops; - multi = g_object_new (SQL_TYPE_MULTI_STMT, "stmts", stmts, NULL); request = db_conn_query_with_stmt_async (priv->conn ,SQL_STMT (multi) @@ -2860,7 +2954,7 @@ gboolean db_model_iter_is_valid (DbIter * iter, DbModel * obj) { g_return_val_if_fail (DB_IS_MODEL (obj), FALSE); - return (iter && iter->data && obj->priv->stamp == iter->stamp); + return (iter && VALID_ITER (iter, obj)); } // GtkTreeModel implementation methods. @@ -2935,14 +3029,13 @@ gint db_model_get_path (DbModel * obj, DbIter * iter) gboolean db_model_get_iter (DbModel * obj, DbIter * iter, gint path) { g_return_val_if_fail (DB_IS_MODEL (obj), FALSE); - if ((0 > path || (obj->priv->result && path >= obj->priv->result->nrows)) || MODEL_NOT_READY (obj)) return FALSE; iter->stamp = obj->priv->stamp; - iter->data = g_ptr_array_index (obj->priv->data, (guint) path); + iter->data = g_ptr_array_index (obj->priv->data, path); if (iter->data) return TRUE; @@ -2965,14 +3058,8 @@ gboolean db_model_get_iter_first (DbModel * obj, DbIter * iter) || !obj->priv->result || !obj->priv->result->nrows) return FALSE; - if (obj->priv->data) - { - iter->stamp = obj->priv->stamp; - iter->data = g_ptr_array_index (obj->priv->data, 0); - } - else - return FALSE; - + iter->stamp = obj->priv->stamp; + iter->data = g_ptr_array_index (obj->priv->data, 0); return TRUE; } @@ -2987,15 +3074,20 @@ gboolean db_model_get_iter_first (DbModel * obj, DbIter * iter) **/ gboolean db_model_iter_prev (DbModel * obj, DbIter * iter) { + DbModelPrivate * priv; + g_return_val_if_fail (DB_IS_MODEL (obj), FALSE); - if (MODEL_NOT_READY(obj) - || !obj->priv->result || !obj->priv->result->nrows) + + priv = obj->priv; + + if (MODEL_NOT_READY(obj) + || !priv->result || !priv->result->nrows) return FALSE; g_return_val_if_fail (VALID_ITER (iter, obj), FALSE); if ((iter->data = g_ptr_array_index - (obj->priv->data, (guint) DB_ROW_POSITION (iter->data) - 1))) + (priv->data, (guint) DB_ROW_POSITION (iter->data) - 1))) return TRUE; return FALSE; } @@ -3011,6 +3103,7 @@ gboolean db_model_iter_prev (DbModel * obj, DbIter * iter) **/ gboolean db_model_iter_next (DbModel * obj, DbIter * iter) { + gint pos; g_return_val_if_fail (DB_IS_MODEL (obj), FALSE); if (MODEL_NOT_READY(obj) || !obj->priv->result || !obj->priv->result->nrows) @@ -3018,7 +3111,7 @@ gboolean db_model_iter_next (DbModel * obj, DbIter * iter) g_return_val_if_fail (VALID_ITER (iter, obj), FALSE); - gint pos = DB_ROW_POSITION (iter->data); + pos = DB_ROW_POSITION (iter->data); if (pos < obj->priv->result->nrows-1) { @@ -3026,7 +3119,7 @@ gboolean db_model_iter_next (DbModel * obj, DbIter * iter) return TRUE; } - iter->stamp = (iter->stamp)? 0 : 1; + iter->stamp = (iter->stamp) ? 0 : 1; iter->data = NULL; return FALSE; } @@ -3085,8 +3178,8 @@ typedef enum { PROP_CONN = 1 ,PROP_STMT - ,PROP_SQL ,PROP_USE_FILE + ,PROP_SQL ,PROP_MAIN_TABLE ,PROP_UPDATE_FLAGS ,PROP_RESULT_POS @@ -3104,12 +3197,12 @@ static void db_model_set_property (DbModel * obj, guint property_id, case PROP_STMT: db_model_set_stmt (obj, g_value_get_object (value)); break; - case PROP_SQL: - db_model_set_sql (obj, g_value_get_string (value)); - break; case PROP_USE_FILE: obj->priv->use_file = g_value_get_boolean (value); break; + case PROP_SQL: + db_model_set_sql (obj, g_value_get_string (value)); + break; case PROP_MAIN_TABLE: db_model_request_main_table (obj, g_value_get_string (value)); break; @@ -3135,12 +3228,12 @@ static void db_model_get_property (DbModel * obj, guint property_id, case PROP_STMT: g_value_set_object (value, obj->priv->stmt); break; - case PROP_SQL: - g_value_set_string (value, obj->priv->sql); - break; case PROP_USE_FILE: g_value_set_boolean (value, obj->priv->use_file); break; + case PROP_SQL: + g_value_set_string (value, obj->priv->sql); + break; case PROP_MAIN_TABLE: g_value_set_string (value, obj->priv->main_table); break; @@ -3181,7 +3274,7 @@ static void db_model_init (DbModel *obj) obj->priv->column_default = NULL; obj->priv->param_default = NULL; obj->priv->pending_request = NULL; - + obj->priv->null_row = NULL; obj->priv->stamp = g_random_int (); obj->priv->fresh = TRUE; @@ -3229,7 +3322,7 @@ static void db_model_finalize (DbModel * obj) g_free (((DbParamDef *) n->data)->dst); g_free (n->data); } - + g_slist_free (obj->priv->param_default); parent->finalize (G_OBJECT (obj)); @@ -3246,7 +3339,7 @@ static void db_model_class_init (DbModelClass *k) /** * DbModel::status-changed: - * @model: the object which received the signal + * @model: the object on which the signal is emitted * @status: the current status of @model * * This signal is emitted every time the status of @model changes. @@ -3259,7 +3352,7 @@ static void db_model_class_init (DbModelClass *k) /** * DbModel::line-inserted: - * @model: the object which received the signal + * @model: the object on which the signal is emitted * @iter: a #DbIter * * This signal is emitted when a new row is inserted into @model. The inserted @@ -3273,7 +3366,7 @@ static void db_model_class_init (DbModelClass *k) /** * DbModel::line-deleted: - * @model: the object which received the signal + * @model: the object on which the signal is emitted * @position: the position of the deleted line * * Every time a row of @model is deleted, this signal is emitted. @@ -3286,7 +3379,7 @@ static void db_model_class_init (DbModelClass *k) /** * DbModel::line-toggled: - * @model: the instance that received the signal + * @model: the object on which the signal is emitted * @iter: a #DbIter * * Emitted to tell that the line is going to be deleted, @@ -3300,7 +3393,7 @@ static void db_model_class_init (DbModelClass *k) /** * DbModel::line-updated: - * @model: the object which received the signal + * @model: the object on which the signal is emitted * @iter: a #DbIter * * This signal is emitted when any value in a row of @model is set. @@ -3313,7 +3406,7 @@ static void db_model_class_init (DbModelClass *k) /** * DbModel::lines-reordered: - * @model: the object which received the signal + * @model: the object on which the signal is emitted * @col: the sort column * @new_order: (array) (element-type gint): an array mapped with the new * positions over the old ones @@ -3332,7 +3425,7 @@ static void db_model_class_init (DbModelClass *k) /** * DbModel::sort-changed: - * @model: the object which received the signal + * @model: the object on which the signal is emitted * * This signal is emitted when a new column is selected as sort criteria for * @model. @@ -3345,7 +3438,7 @@ static void db_model_class_init (DbModelClass *k) /** * DbModel::operations-done: - * @model: the object which received the signal + * @model: the object on which the signal is emitted * @success: whether the operation has failed or succeded * * When an operation on the model is performed on the DB, this signal @@ -3359,66 +3452,66 @@ static void db_model_class_init (DbModelClass *k) g_object_class_install_property (klass, PROP_CONN, g_param_spec_object ("conn" - ,_("Connection") - ,_("The DbConn that manages the connection to the database") - ,DB_TYPE_CONN - ,G_PARAM_READWRITE + ,_("Connection") + ,_("The DbConn that manages the connection to the database") + ,DB_TYPE_CONN + ,G_PARAM_READWRITE )); g_object_class_install_property (klass, PROP_STMT, g_param_spec_object ("stmt" - ,_("Statement") - ,_("The statement which retrieves the data") - ,SQL_TYPE_STMT - ,G_PARAM_READWRITE - )); - - g_object_class_install_property (klass, PROP_SQL, - g_param_spec_string ("sql" - ,_("SQL") - ,_("Depending on the \"use-file\" property this will " - "be the path to a file with queries for the " - "model or a SQL string") - ,NULL - ,G_PARAM_READWRITE + ,_("Statement") + ,_("The statement which retrieves the data") + ,SQL_TYPE_STMT + ,G_PARAM_READWRITE )); g_object_class_install_property (klass, PROP_USE_FILE, g_param_spec_boolean ("use-file" - ,_("Use file") - ,_("If this is set to TRUE, the \"sql\" property will " - "hold the name of a file containing a query, if " - "set to FALSE, \"sql\" is used as an SQL string") - ,FALSE - ,G_PARAM_READWRITE + ,_("Use file") + ,_("If this is set to TRUE, the \"sql\" property will " + "hold the name of a file containing a query, if " + "set to FALSE, \"sql\" is used as an SQL string") + ,FALSE + ,G_PARAM_READWRITE + )); + + g_object_class_install_property (klass, PROP_SQL, + g_param_spec_string ("sql" + ,_("SQL") + ,_("Depending on the \"use-file\" property this will " + "be the path to a file with queries for the " + "model or a SQL string") + ,NULL + ,G_PARAM_READWRITE )); g_object_class_install_property (klass, PROP_MAIN_TABLE, g_param_spec_string ("main-table" - ,_("Main Table") - ,_("The main table of the model") - ,NULL - ,G_PARAM_READWRITE + ,_("Main Table") + ,_("The main table of the model") + ,NULL + ,G_PARAM_READWRITE )); g_object_class_install_property (klass, PROP_UPDATE_FLAGS, g_param_spec_flags ("update-flags" - ,_("Update flags") - ,_("The flags that indicate how a model can be modified") - ,DB_TYPE_MODEL_UPDATE_FLAGS - ,DB_MODEL_ALL - ,G_PARAM_READWRITE + ,_("Update flags") + ,_("The flags that indicate how a model can be modified") + ,DB_TYPE_MODEL_UPDATE_FLAGS + ,DB_MODEL_ALL + ,G_PARAM_READWRITE )); g_object_class_install_property (klass, PROP_RESULT_POS, g_param_spec_uint ("result-pos" - ,_("Result position") - ,_("The position where the query that will fill the " - "model will be placed in a multi-query") - ,0 - ,G_MAXUINT32 - ,0 - ,G_PARAM_READWRITE + ,_("Result position") + ,_("The position where the query that will fill the " + "model will be placed in a multi-query") + ,0 + ,G_MAXUINT32 + ,0 + ,G_PARAM_READWRITE )); } diff --git a/db/db-model.h b/db/db-model.h index 26385ee..506dffa 100644 --- a/db/db-model.h +++ b/db/db-model.h @@ -206,6 +206,7 @@ void db_model_unset_update_flags (DbModel * obj 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 ,DbIter * iter @@ -248,12 +249,11 @@ void db_model_add_join_columns (DbModel * obj void db_model_set_default_value_from_column (DbModel * obj ,const gchar * dst_field ,gint src_column); + void db_model_set_default_value_from_param (DbModel * obj ,const gchar * dst_field - ,GvnParam * param - ,const gchar * id); + ,GvnParam * param); void db_model_add_param (DbModel * obj - ,const gchar * id ,GvnParam * param); //GtkTreeModel-like methods diff --git a/db/db-param.c b/db/db-param.c index 4f2230a..9e90e47 100644 --- a/db/db-param.c +++ b/db/db-param.c @@ -17,6 +17,14 @@ #include "db-param.h" +/** + * SECTION: db-param + * @Short_description: representation of the value of a field + * @Title: DbParam + * + * This class represents the value of a field in a #DbIterator. + **/ + G_DEFINE_TYPE (DbParam, db_param, GVN_TYPE_PARAM); /** diff --git a/db/db-result.h b/db/db-result.h index 08643d5..0a1c7ab 100644 --- a/db/db-result.h +++ b/db/db-result.h @@ -30,7 +30,7 @@ typedef struct _DbColumn DbColumn; * DbResult: * @nrows: Number of rows. * @ncols: Number of columns. - * @data: Has a #GList. + * @data: (element-type DbRow): Has a #GList. * @column: Has a #DbColumn. * * Has the information of a row. diff --git a/db/db.h b/db/db.h index 4757877..a42ba00 100644 --- a/db/db.h +++ b/db/db.h @@ -20,6 +20,7 @@ #include #include "db-iter.h" +#include "db-model-holder.h" #include "db-model.h" #include "db-request.h" #include "db-conn.h" diff --git a/debian/changelog b/debian/changelog index 1cb12cd..f0e0d82 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -libhedera (1.0-1) stable; urgency=low +libhedera (1.0-6) stable; urgency=low * Initial Release. diff --git a/debian/control b/debian/control index fb0d285..30a76fc 100644 --- a/debian/control +++ b/debian/control @@ -20,23 +20,25 @@ Description: Database access and widget provider library (runtime) queries. . The library also has a modular system to add and remove the different widgets - in run time. + in run time. And includes Glade integration, to design the programs in an + easiest, graphical way. . This package contains the executable and data files. Package: libhedera-dev Section: libdevel Architecture: amd64 -Depends: ${shlibs:Depends}, ${misc:Depends}, libhedera1 (= ${binary:Version}) -Suggests: libgtk-3-doc, libgtk-3-dbg, devhelp, valac (>= 0.16) -Recommends: glade (>= 3.4), anjuta (>= 3.4) +Depends: ${shlibs:Depends}, ${misc:Depends}, libhedera1 (= ${binary:Version}), + libgtk-3-dev +Suggests: libgtk-3-doc, libgtk-3-0-dbg, devhelp, valac (>= 0.16) +Recommends: glade (>= 3.4), anjuta (>= 3.4), libgtksourceview-3.0-1 Description: Database access and widget provider library (development) The hedera library provides and lets you create widgets bound to SQL queries and manages the different operations made over the data retrieved from these queries. . The library also has a modular system to add and remove the different widgets - in run time. And it includes Glade integration, to design the programs in an + in run time. And includes Glade integration, to design the programs in an easiest, graphical way. . This package contains development files to compile C and Vala programs that @@ -46,14 +48,15 @@ Description: Database access and widget provider library (development) Package: libhedera1 Section: libs Architecture: amd64 -Depends: ${shlibs:Depends}, ${misc:Depends}, libgtk-3-0, libgtk-3-dev +Depends: ${shlibs:Depends}, ${misc:Depends}, libgtk-3-0 Description: Database access and widget provider library (core) The hedera library provides and lets you create widgets bound to SQL queries and manages the different operations made over the data retrieved from these queries. . The library also has a modular system to add and remove the different widgets - in run time. + in run time. And includes Glade integration, to design the programs in an + easiest, graphical way. . This package contains the core of the library. It also provides the plugins to connect a PostgreSQL or MySQL database. @@ -68,6 +71,7 @@ Description: Database access and widget provider library (debug) queries. . The library also has a modular system to add and remove the different widgets - in run time. + in run time. And includes Glade integration, to design the programs in an + easiest, graphical way. . This package contains the debugging symbols for hedera. diff --git a/debian/hedera.dirs b/debian/hedera.dirs index cd6f5f3..f2e7c37 100644 --- a/debian/hedera.dirs +++ b/debian/hedera.dirs @@ -1,8 +1,8 @@ usr/bin usr/lib/hedera/module -usr/share/hedera/vn/image usr/share/hedera/vn +usr/share/hedera/vn/image usr/share/hedera/module usr/share/hedera/module/sql -usr/share/applications -usr/share/ca-certificates/verdnatura.es \ No newline at end of file +usr/share/hedera/module/sql/example +usr/share/applications \ No newline at end of file diff --git a/debian/hedera.install b/debian/hedera.install index baa912c..d83224a 100644 --- a/debian/hedera.install +++ b/debian/hedera.install @@ -1,7 +1,8 @@ usr/bin/* usr/lib/hedera/module/*.so -usr/share/hedera/vn/image/* usr/share/hedera/vn/* +usr/share/hedera/vn/image/* usr/share/hedera/module/* -usr/share/applications/* -usr/share/ca-certificates/verdnatura.es/* \ No newline at end of file +usr/share/hedera/module/sql/* +usr/share/hedera/module/sql/example/* +usr/share/applications/* \ No newline at end of file diff --git a/debian/libhedera-dev.dirs b/debian/libhedera-dev.dirs index 8ee5a77..4317d72 100644 --- a/debian/libhedera-dev.dirs +++ b/debian/libhedera-dev.dirs @@ -7,7 +7,7 @@ usr/include/hedera/vn/field usr/include/hedera/vn/column usr/lib/hedera usr/lib/glade/modules -usr/lib/girepository-1.0 +#usr/lib/girepository-1.0 usr/share/gir-1.0 usr/share/glade/catalogs usr/share/pkgconfig diff --git a/debian/libhedera-dev.install b/debian/libhedera-dev.install index 4938212..54beaff 100644 --- a/debian/libhedera-dev.install +++ b/debian/libhedera-dev.install @@ -17,7 +17,7 @@ usr/lib/hedera/libvnfield.so usr/lib/hedera/libvncolumn.a usr/lib/hedera/libvncolumn.so usr/lib/glade/modules/libgladevn.so -usr/lib/girepository-1.0/* +#usr/lib/girepository-1.0/* usr/share/gir-1.0/* usr/share/glade/catalogs/* usr/share/pkgconfig/* diff --git a/docs/reference/hedera/hedera-docs.sgml b/docs/reference/hedera/hedera-docs.sgml index 7c596be..9af016d 100644 --- a/docs/reference/hedera/hedera-docs.sgml +++ b/docs/reference/hedera/hedera-docs.sgml @@ -95,6 +95,7 @@ DbLib + diff --git a/glade/Makefile.am b/glade/Makefile.am index 56b9ac0..37540dd 100644 --- a/glade/Makefile.am +++ b/glade/Makefile.am @@ -4,20 +4,31 @@ gladevn_lib_LTLIBRARIES = libgladevn.la AM_CPPFLAGS = \ -I$(top_srcdir) \ - $(gladeui_CFLAGS) + $(gladeui_CFLAGS) \ + $(DEFINES) \ + $(gtksourceview_CFLAGS) libgladevn_la_LIBADD = \ $(top_builddir)/vn/libvn.la \ - $(gladeui_LIBS) + $(gladeui_LIBS) \ + $(gtksourceview_LIBS) libgladevn_la_LDFLAGS = -avoid-version libgladevn_la_SOURCES = \ glade-vn.h \ glade-vn.c \ - glade-vn-batch.c + glade-vn-batch.c \ + glade-db-sql.c \ + glade-db-model.c gladevn_data_DATA = vn.xml +if HAVE_SOURCEVIEW +DEFINES = -D_HAVE_GTKSOURCEVIEW +else +DEFINES = +endif + EXTRA_DIST = $(gladevn_data_DATA) install-data-hook: rm -f $(DESTDIR)$(gladevn_libdir)/libgladevn.la - rm -f $(DESTDIR)$(gladevn_libdir)/libgladevn.a \ No newline at end of file + rm -f $(DESTDIR)$(gladevn_libdir)/libgladevn.a diff --git a/glade/glade-db-model.c b/glade/glade-db-model.c new file mode 100644 index 0000000..e223c5d --- /dev/null +++ b/glade/glade-db-model.c @@ -0,0 +1,364 @@ +/* + * 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 . + */ + +#include "glade-vn.h" + +//+++++++++++++++++++++++++++++++++++++++++++++++++ DbModel GladeEditorProperty + +typedef struct +{ + GladeEditorProperty parent; + + GtkWidget * button; + GtkWidget * entry; + gboolean connected; + GladeWidget * widget; +} +GladeEPropModel; + +GLADE_MAKE_EPROP (GladeEPropModel, glade_eprop_model) +#define GLADE_TYPE_EPROP_MODEL (glade_eprop_model_get_type()) +#define GLADE_EPROP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_EPROP_MODEL, GladeEPropModel)) +#define GLADE_EPROP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_EPROP_MODEL, GladeEPropModelClass)) +#define GLADE_IS_EPROP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_EPROP_MODEL)) +#define GLADE_IS_EPROP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_EPROP_MODEL)) +#define GLADE_EPROP_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_EPROP_MODEL, GladeEPropModelClass)) + +static void glade_eprop_model_name_changed (GladeProject * project, + GladeWidget * widget, GladeEPropModel * obj) +{ + if (widget && obj->widget) + { + gtk_entry_set_text (GTK_ENTRY (obj->entry), + glade_widget_get_name (widget)); + } +} + +static GladeWidget * glade_model_create (GladeProperty * prop) +{ + gboolean use = FALSE; + VnBatch * batch; + GladeWidget * batch_w; + GladeProject * project = glade_widget_get_project (glade_property_get_widget (prop)); + const GList * l, * n, * objects = glade_project_get_objects (project); + + for (n = objects; n; n = n->next) + if (VN_IS_BATCH (n->data)) + { + batch = n->data; + use = TRUE; + + for (l = vn_batch_get_objects (batch); l; l = l->next) + if (!DB_IS_MODEL (l->data)) + { + use = FALSE; + break; + } + + if (use) + break; + } + + if (!use) + batch_w = glade_command_create + (glade_widget_adaptor_get_by_type (VN_TYPE_BATCH), NULL, NULL, project); + else + batch_w = glade_widget_get_from_gobject (batch); + + return glade_command_create + (glade_widget_adaptor_get_by_type (DB_TYPE_MODEL), batch_w, NULL, project); +} + +/* + * glade_eprop_model_show_dialog: + * @button:(allow-none): a #GtkButton or @NULL + * @object: a #GladeEditorPropery or a #GladeWidget + * + * Opens a dialog to edit a #DbModel. + * Can be called by a #GladeEditorProperty or by the "edit" action of a + * #GladeWidgetAdaptor directly (in which case @button is %NULL and @obj is a + * #GladeWidget). + **/ +static void glade_eprop_model_show_dialog (GtkButton * button, GObject * object) +{ + gboolean created = FALSE; + GObject * o; + GtkWidget * box; + GtkDialog * dialog; + GladeWidget * widget; + GladeWidgetAdaptor * adaptor; + GladeEditable * editor; + GladeProperty * p = NULL; + GladeEditorProperty * eprop = NULL; + + if (GLADE_IS_EDITOR_PROPERTY (object)) + { + eprop = GLADE_EDITOR_PROPERTY (object); + p = glade_editor_property_get_property (eprop); + o = g_value_get_object (glade_property_inline_value (p)); + + if (o && DB_IS_MODEL (o)) + widget = glade_widget_get_from_gobject (o); + else + { + GValue val = G_VALUE_INIT; + + glade_command_push_group + (_("Create and set a model for a DbModelHolder")); + + widget = glade_model_create (p); + created = TRUE; + g_value_init (&val, DB_TYPE_MODEL); + g_value_set_object (&val, glade_widget_get_object (widget)); + glade_command_set_property_value (p, &val); + g_value_unset (&val); + + glade_command_pop_group (); + + glade_project_selection_set (glade_widget_get_project (widget), + glade_widget_get_object (glade_property_get_widget (p)), + TRUE); + + if (!GLADE_EPROP_MODEL (eprop)->connected) + { + g_signal_connect (glade_widget_get_project + (glade_property_get_widget (p)), "widget-name-changed", + G_CALLBACK (glade_eprop_model_name_changed), eprop); + GLADE_EPROP_MODEL (eprop)->connected = TRUE; + } + } + } + else + widget = GLADE_WIDGET (object); + + adaptor = glade_widget_get_adaptor (widget); + editor = glade_widget_adaptor_create_editable (adaptor, GLADE_PAGE_GENERAL); + glade_editable_load (editor, widget); + + dialog = GTK_DIALOG (gtk_dialog_new_with_buttons + (eprop ? _("Model configuration") : _("DbModel properties configuration") + ,GTK_WINDOW (glade_app_get_window ()) + ,GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT + ,GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL + ,GTK_STOCK_CLEAR, GTK_RESPONSE_REJECT + ,GTK_STOCK_OK, GTK_RESPONSE_OK + ,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), 400, 300); + + if (!eprop) + gtk_widget_hide (gtk_dialog_get_widget_for_response + (dialog, GTK_RESPONSE_REJECT)); + + box = gtk_alignment_new (0,0,1,1); + gtk_alignment_set_padding (GTK_ALIGNMENT (box), 8, 8, 8, 8); + gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (editor)); + gtk_widget_show_all (box); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (dialog)), + box, TRUE, TRUE, 0); + + switch (gtk_dialog_run (dialog)) + { + case GTK_RESPONSE_OK: + { + if (eprop) + { + gtk_entry_set_text (GTK_ENTRY (GLADE_EPROP_MODEL (eprop)->entry), + glade_widget_get_name (widget)); + GLADE_EPROP_MODEL (eprop)->widget = widget; + } + + break; + } + case GTK_RESPONSE_REJECT: + { + if (eprop) + { + glade_command_set_property (p, NULL); + GLADE_EPROP_MODEL (eprop)->widget = NULL; + } + + break; + } + case GTK_RESPONSE_CANCEL: + { + if (created) + { + GList * list = g_list_append (NULL, widget); + GladeWidget * batch = glade_widget_get_parent (widget); + + if (vn_batch_get_length + VN_BATCH (glade_widget_get_object (batch)) == 1) + list = g_list_prepend (list, batch); + + glade_command_delete (list); + g_list_free (list); + GLADE_EPROP_MODEL (eprop)->widget = NULL; + } + + break; + } + default: + break; + } + + gtk_widget_destroy (GTK_WIDGET (dialog)); +} + +static void glade_eprop_model_show_object_dialog (GtkButton * button, + GladeEditorProperty * eprop) +{ + GladeProperty * p = glade_editor_property_get_property (eprop); + // Widget to which the property belongs (e.g. Model Holder) + GladeWidget * widget = glade_property_get_widget (p); + GladeProject * project = glade_widget_get_project (widget); + GObject * object = g_value_get_object (glade_property_inline_value (p)); + // Widget representing the property itself (i.e. DbModel) + widget = object ? glade_widget_get_from_gobject (object) : NULL; + GLADE_EPROP_MODEL (eprop)->widget = widget; + + if (glade_editor_property_show_object_dialog (project, + _("Select a DbModel for the property"), NULL, + DB_TYPE_MODEL, NULL, &widget)) + { + if (widget) + { + GValue val = G_VALUE_INIT; + g_value_init (&val, DB_TYPE_MODEL); + g_value_set_object (&val, glade_widget_get_object (widget)); + glade_command_set_property_value (p, &val); + g_value_unset (&val); + } + else + glade_command_set_property (p, NULL); + } +} + +static GtkWidget * glade_eprop_model_create_input (GladeEditorProperty * eprop) +{ + GtkWidget * hbox, * box, * object_button; + GladeEPropModel * obj = GLADE_EPROP_MODEL (eprop); + + obj->button = gtk_button_new_with_label (_("New Model")); + g_signal_connect (G_OBJECT (obj->button), "clicked", + G_CALLBACK (glade_eprop_model_show_dialog), eprop); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + obj->entry = gtk_entry_new (); + gtk_editable_set_editable (GTK_EDITABLE (obj->entry), FALSE); + gtk_widget_set_hexpand (obj->entry, TRUE); + gtk_container_add (GTK_CONTAINER (hbox), obj->entry); + + object_button = gtk_button_new_with_label ("..."); + gtk_container_add (GTK_CONTAINER (hbox), object_button); + g_signal_connect (G_OBJECT (object_button), "clicked", + G_CALLBACK (glade_eprop_model_show_object_dialog), eprop); + + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add (GTK_CONTAINER (box), hbox); + gtk_container_add (GTK_CONTAINER (box), obj->button); + gtk_widget_show_all (box); + + obj->widget = NULL; +/* project = glade_widget_get_project (glade_property_get_widget + (glade_editor_property_get_property (eprop))); + */ + + return box; +} + +static void glade_eprop_model_load (GladeEditorProperty * eprop, GladeProperty * property) +{ + gchar * label; + const gchar * text; + GObject * object; + GladeEditorPropertyClass * parent_class = + g_type_class_peek_parent (GLADE_EDITOR_PROPERTY_GET_CLASS (eprop)); + parent_class->load (eprop, property); + + if (property == NULL) + return; + + if ((object = g_value_get_object (glade_property_inline_value (property)))) + { + label = _("Edit Model"); + text = glade_widget_get_name (glade_widget_get_from_gobject (object)); + } + else + { + label = _("New Model"); + text = ""; + } + + gtk_button_set_label (GTK_BUTTON (GLADE_EPROP_MODEL (eprop)->button), label); + gtk_entry_set_text (GTK_ENTRY (GLADE_EPROP_MODEL (eprop)->entry), text); +} + +static void glade_eprop_model_finalize (GObject * object) +{ + GObjectClass * parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (object)); + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++++ DbModel Action Callback + +void glade_db_model_action_activate (GladeWidgetAdaptor * adaptor, + DbModel * model, const gchar * path) +{ + glade_eprop_model_show_dialog (NULL, + (GObject *) glade_widget_get_from_gobject (model)); +} + +//++++++++++++++++++++++++++++++++++++++++++++ DbModelHolder GladeWidgetAdaptor + +GladeEditorProperty * glade_db_model_holder_create_eprop (GladeWidgetAdaptor * adaptor, + GladePropertyClass * klass, gboolean use_command) +{ + GladeEditorProperty * eprop; + GParamSpec * pspec = glade_property_class_get_pspec (klass); + + if (pspec->value_type == DB_TYPE_MODEL) + { + eprop = g_object_new (GLADE_TYPE_EPROP_MODEL, + "property-class", klass, + "use-command", use_command, NULL); + } + else + eprop = GWA_GET_CLASS (G_TYPE_OBJECT)->create_eprop (adaptor, klass, use_command); + + return eprop; +} + +void glade_db_model_write_widget (GladeWidgetAdaptor * adaptor, + GladeWidget * widget, GladeXmlContext * context, GladeXmlNode * node) +{ + GladeProperty * prop; + + if (!glade_xml_node_verify (node, GLADE_XML_TAG_WIDGET)) + return; + + prop = glade_widget_get_property (widget, "use-file"); + glade_property_write (prop, context, node); + + prop = glade_widget_get_property (widget, "sql"); + glade_property_write (prop, context, node); + + GWA_GET_CLASS (G_TYPE_OBJECT)->write_widget (adaptor, widget, context, node); +} diff --git a/glade/glade-db-sql.c b/glade/glade-db-sql.c new file mode 100644 index 0000000..e65d2d2 --- /dev/null +++ b/glade/glade-db-sql.c @@ -0,0 +1,231 @@ +/* + * 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 . + */ + +#include "glade-vn.h" + +#ifdef _HAVE_GTKSOURCEVIEW +#include +#include +#include +#include +#endif + +#define NEW_SQL _("New SQL statement") + +//+++++++++++++++++++++++++++++++++++++++++++++++++++ GladeEPropSql + +typedef struct +{ + GladeEditorProperty parent; + + GtkWidget * button; + GtkWidget * entry; + gint width; + gint height; +} +GladeEPropSql; + +GLADE_MAKE_EPROP (GladeEPropSql, glade_eprop_sql) +#define GLADE_TYPE_EPROP_SQL (glade_eprop_sql_get_type()) +#define GLADE_EPROP_SQL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_EPROP_SQL, GladeEPropSql)) +#define GLADE_EPROP_SQL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_EPROP_SQL, GladeEPropSqlClass)) +#define GLADE_IS_EPROP_SQL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_EPROP_SQL)) +#define GLADE_IS_EPROP_SQL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_EPROP_SQL)) +#define GLADE_EPROP_SQL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_EPROP_SQL, GladeEPropSqlClass)) + +static void glade_eprop_sql_show_dialog (GtkButton * button, GladeEditorProperty * eprop) +{ + gpointer text, buffer; + const gchar * sql; + GladeEPropSql * obj = GLADE_EPROP_SQL (eprop); + PangoFontDescription * font; + GtkWidget * scroll; + GladeProperty * p = glade_editor_property_get_property (eprop); + GtkDialog * dialog = GTK_DIALOG (gtk_dialog_new_with_buttons + (_("SQL Editor") + ,GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (eprop))) + ,GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT + ,GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL + ,GTK_STOCK_CLEAR, GTK_RESPONSE_REJECT + ,GTK_STOCK_OK, GTK_RESPONSE_OK + ,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); + + scroll = gtk_scrolled_window_new (gtk_adjustment_new (0,0,0,0,0,0), + gtk_adjustment_new (0,0,0,0,0,0)); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); + gtk_widget_set_margin_top (scroll, 6); + gtk_widget_set_margin_right (scroll, 6); + gtk_widget_set_margin_bottom (scroll, 6); + gtk_widget_set_margin_left (scroll, 6); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (dialog)), + scroll, TRUE, TRUE, 6); + +#ifdef _HAVE_GTKSOURCEVIEW + GtkSourceLanguageManager * lm = gtk_source_language_manager_new (); + GtkSourceLanguage * lang = gtk_source_language_manager_get_language (lm, "sql"); + text = gtk_source_view_new (); + gtk_source_view_set_tab_width (text, 4); + gtk_source_view_set_show_line_numbers (text, TRUE); + gtk_source_view_set_highlight_current_line (text, TRUE); + buffer = gtk_text_view_get_buffer (text); + gtk_source_buffer_set_language (buffer, lang); + gtk_source_buffer_set_highlight_matching_brackets (buffer, TRUE); +#else + text = gtk_text_view_new (); + buffer = gtk_text_view_get_buffer (text); +#endif + + font = pango_font_description_from_string ("Monospace"); + gtk_widget_override_font (text, font); + pango_font_description_free (font); + + sql = g_value_get_string (glade_property_inline_value (p)); + + if (sql) + gtk_text_buffer_set_text (buffer, sql, -1); + + gtk_container_add (GTK_CONTAINER (scroll), text); + gtk_widget_show_all (scroll); + + switch (gtk_dialog_run (dialog)) + { + case GTK_RESPONSE_OK: + { + GValue val = G_VALUE_INIT; + GtkTextIter * start = g_new (GtkTextIter, 1), + * end = g_new (GtkTextIter, 1); + g_value_init (&val, G_TYPE_STRING); + gtk_text_buffer_get_bounds (buffer, start, end); + + sql = gtk_text_buffer_get_text (buffer, start, end, TRUE); + g_value_set_string (&val, sql); + glade_command_set_property_value (p, &val); + + g_value_unset (&val); + g_free (start); + g_free (end); + break; + } + case GTK_RESPONSE_REJECT: + { + GValue val = G_VALUE_INIT; + g_value_init (&val, G_TYPE_STRING); + g_value_set_string (&val, ""); + glade_command_set_property_value (p, &val); + g_value_unset (&val); + break; + } + case GTK_RESPONSE_CANCEL: + default: + break; + } + + obj->width = gtk_widget_get_allocated_width (GTK_WIDGET (dialog)); + obj->height = gtk_widget_get_allocated_height (GTK_WIDGET (dialog)); + gtk_widget_destroy (GTK_WIDGET (dialog)); +} + +static void glade_eprop_sql_entry_text_changed (GtkEntry * entry, + GladeEditorProperty * eprop) +{ + const gchar * text = gtk_entry_get_text (entry); + GladeProperty * p = glade_editor_property_get_property (eprop); + + if (text) + { + GValue val = G_VALUE_INIT; + g_value_init (&val, G_TYPE_STRING); + g_value_set_string (&val, text); + + glade_command_set_property_value (p, &val); + + g_value_unset (&val); + } +} + +static GtkWidget * glade_eprop_sql_create_input (GladeEditorProperty * eprop) +{ + GladeEPropSql * obj = GLADE_EPROP_SQL (eprop); + GtkWidget * box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + + obj->entry = gtk_entry_new (); + gtk_widget_set_hexpand (obj->entry, TRUE); + g_signal_connect (obj->entry, "changed", + G_CALLBACK (glade_eprop_sql_entry_text_changed), obj); + gtk_container_add (GTK_CONTAINER (box), obj->entry); + + obj->button = gtk_button_new_with_label ("..."); + g_signal_connect (obj->button, "clicked", + G_CALLBACK (glade_eprop_sql_show_dialog), obj); + gtk_widget_set_tooltip_text (obj->button, _("Open the SQL Editor")); + gtk_container_add (GTK_CONTAINER (box), obj->button); + + gtk_widget_show_all (box); + + obj->width = 750; + obj->height = 550; + + return box; +} + +static void glade_eprop_sql_load (GladeEditorProperty * eprop, GladeProperty * property) +{ + const gchar * sql; + GladeEPropSql * obj = GLADE_EPROP_SQL (eprop); + + GladeEditorPropertyClass * parent_class = + g_type_class_peek_parent (GLADE_EDITOR_PROPERTY_GET_CLASS (eprop)); + parent_class->load (eprop, property); + + if (!property) + return; + + if ((sql = g_value_get_string (glade_property_inline_value (property)))) + gtk_entry_set_text (GTK_ENTRY (obj->entry), sql); +} + +static void glade_eprop_sql_finalize (GObject * object) +{ + GObjectClass * parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (object)); + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++ DbModel GladeWidgetAdaptor + +GladeEditorProperty * glade_db_sql_create_eprop (GladeWidgetAdaptor * adaptor, + GladePropertyClass * klass, gboolean use_command) +{ + GladeEditorProperty * eprop; + GParamSpec * pspec = glade_property_class_get_pspec (klass); + + if (!g_strcmp0 (pspec->name, "sql")) + { + eprop = g_object_new (GLADE_TYPE_EPROP_SQL, + "property-class", klass, + "use-command", use_command, NULL); + } + else + eprop = GWA_GET_CLASS (G_TYPE_OBJECT)->create_eprop (adaptor, klass, use_command); + + return eprop; +} diff --git a/glade/glade-vn-batch.c b/glade/glade-vn-batch.c index 409e8f3..25f82a3 100644 --- a/glade/glade-vn-batch.c +++ b/glade/glade-vn-batch.c @@ -65,5 +65,5 @@ void glade_vn_batch_replace_child (GladeWidgetAdaptor * adaptor, GList * glade_vn_batch_get_children (GladeWidgetAdaptor * adaptor, VnBatch * group) { - return vn_batch_get_objects (group); + return vn_batch_get_objects_list (group); } diff --git a/glade/vn.xml b/glade/vn.xml index cffdac7..11186c6 100644 --- a/glade/vn.xml +++ b/glade/vn.xml @@ -16,15 +16,28 @@ - + + + + + + + glade_db_model_action_activate + glade_db_sql_create_eprop + glade_db_model_write_widget - + - - + + + GParamObject + DbModel + + + glade_db_model_holder_create_eprop @@ -47,27 +60,32 @@ - - + + - + - + - - + + + GParamObject + DbModel + + + glade_db_model_holder_create_eprop - + - - + + @@ -79,17 +97,31 @@ - - + + + GParamObject + DbModel + + + + + glade_db_model_holder_create_eprop - - + + + GParamObject + DbModel + + + + + glade_db_model_holder_create_eprop @@ -105,7 +137,7 @@ - + glade_vn_batch_add_verify glade_vn_batch_add_child @@ -117,7 +149,6 @@ - @@ -125,7 +156,7 @@ - + @@ -134,7 +165,8 @@ - + + diff --git a/main/Makefile.am b/main/Makefile.am index c60c904..064198b 100644 --- a/main/Makefile.am +++ b/main/Makefile.am @@ -9,6 +9,7 @@ AM_CPPFLAGS = \ hedera_bin_LDFLAGS = -Wl,--export-dynamic hedera_bin_SOURCES = main.c hedera_bin_LDADD = \ + $(gtk_LIBS) \ $(top_builddir)/gvn/libgvn.la \ $(top_builddir)/db/libdb.la \ $(top_builddir)/vn/libvn.la @@ -21,12 +22,9 @@ $(hedera_bin_SCRIPTS): $(SCRIPT) pkgconfig_DATA = hedera.pc -desktop_DATA = vn-hedera.desktop - -HOST=verdnatura.es -certdir = $(datadir)/ca-certificates/$(HOST) -cert_DATA = cacert.pem -syscertdir = $(sysconfdir)/ssl/certs +desktop_DATA = \ + vn-hedera.desktop \ + vn-hedera-debug.desktop man_MANS = hedera.1 @@ -37,9 +35,5 @@ EXTRA_DIST = \ DISTCLEANFILES = \ $(hedera_bin_SCRIPTS) \ hedera.pc \ - vn-hedera.desktop - -install-data-hook: - mkdir -p $(DESTDIR)$(syscertdir) - (cd $(DESTDIR)$(syscertdir) && \ - $(LN_S) -f $(DESTDIR)$(certdir)/$(cert_DATA) $(HOST).pem) + vn-hedera.desktop \ + vn-hedera-debug.desktop diff --git a/main/hedera.1 b/main/hedera.1 index bbf6193..085dbdb 100644 --- a/main/hedera.1 +++ b/main/hedera.1 @@ -7,9 +7,13 @@ hedera \- modular management system .SH SYNOPSIS .B hedera -.\"RI [ options ] +.RB [\-\-lib-dir|\-l +.IR path \|] +.RB [\-\-data-dir|\-l +.IR path \|] +.RB [\-\-query-dir|\-l +.IR path \|] .br - .SH DESCRIPTION .B hedera is an enterprise management and administration application. It features modular @@ -26,9 +30,12 @@ will look for the modules in /usr/lib/hedera/module and for its corresponding data (GUI files, configuration...) in /usr/share/hedera/module but more directories can be added by setting .B VN_MODULE_LIB_PATH -(for the binaries) and +(for the binaries), .B VN_MODULE_DATA_PATH -(for the additional data). These environment variables are intended for testing +(for the additional data) and +.B VN_MODULE_QUERY_PATH +(for SQL query files) that can also be set automatically passing the +corresponding options. These environment variables are intended for testing during the developement and the expected is to use the modules installed. .PP The format for the configuration files for the modules and some information on @@ -37,7 +44,25 @@ for .B hedera. .SH OPTIONS - +.TP +.BI \-l\ path ,\ \-\-lib-dir\ path +Sets the value of the +.B VN_MODULE_LIB_PATH +variable. This option can be used mutiple times to specify more than one search +path for the module libraries. +.TP +.BI \-d\ path ,\ \-\-data-dir\ path +Sets the value of the +.B VN_MODULE_DATA_PATH +variable. This option can be used mutiple times to specify more than one search +path for the module data files. +.TP +.BI \-q\ path ,\ \-\-query-dir\ path +Sets the value of the +.B VN_MODULE_QUERY_PATH +variable. This option can be used mutiple times to specify more than one search +path for the module query files. +.br .SH EXAMPLE Given a module project in the home directory, .B hedera @@ -47,4 +72,4 @@ should be called like this to load the module without installing it: .SH AUTHORS Copyright (C) 2012 Juan Ferrer Toribio . .PP -Manual page written by Alejandro T. Colombini. \ No newline at end of file +Manual page written by Alejandro T. Colombini. diff --git a/main/hedera.sh.in b/main/hedera.sh.in index b7acf53..f645026 100644 --- a/main/hedera.sh.in +++ b/main/hedera.sh.in @@ -1,10 +1,26 @@ #!/bin/bash -if [ -x @bindir@/vn-updater-gui ] +UPDATE=1 + +while getopts ":u" OPTION +do + case $OPTION in + u) + UPDATE=0 + ;; + \?|:) + echo "Usage: $0 [-u]" + exit 1 + ;; + esac +done + +if [ "$UPDATE" -eq "1" -a -x @bindir@/vn-updater-gui ] then echo "Running updater..." @bindir@/vn-updater-gui fi export LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN=1 -exec @bindir@/hedera-bin + +exec hedera-bin diff --git a/main/vn-hedera-debug.desktop.in b/main/vn-hedera-debug.desktop.in new file mode 100644 index 0000000..6cd7923 --- /dev/null +++ b/main/vn-hedera-debug.desktop.in @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Hedera (Development) +GenericName=Office Tool +Comment=Runtime for the Hedera system (Development) +Exec=hedera -u +Icon=@prefix@/share/@PACKAGE@/vn/image/icon-debug.svg +Terminal=true +Type=Application +Categories=GNOME;GTK;Development; +StartupNotify=true +Version=@VERSION@ diff --git a/main/vn-hedera.desktop.in b/main/vn-hedera.desktop.in index e949638..c88b49a 100644 --- a/main/vn-hedera.desktop.in +++ b/main/vn-hedera.desktop.in @@ -3,7 +3,7 @@ Name=Hedera GenericName=Office Tool Comment=Runtime for the Hedera system Exec=hedera -Icon=@prefix@/share/hedera/vn/image/icon.svg +Icon=@prefix@/share/@PACKAGE@/vn/image/icon.svg Terminal=false Type=Application Categories=GNOME;GTK;Office; diff --git a/module/Makefile.am b/module/Makefile.am index b2980bc..b1c3b83 100644 --- a/module/Makefile.am +++ b/module/Makefile.am @@ -1,5 +1,5 @@ +include $(top_srcdir)/Makefile.decl SUBDIRS = \ src \ - data \ - sql + data \ No newline at end of file diff --git a/module/data/consulter.glade b/module/data/consulter.glade index 34a0453..b2638a9 100644 --- a/module/data/consulter.glade +++ b/module/data/consulter.glade @@ -1,7 +1,7 @@ - + diff --git a/module/data/customer.glade b/module/data/customer.glade index d34db37..0c0cb4c 100644 --- a/module/data/customer.glade +++ b/module/data/customer.glade @@ -1,7 +1,7 @@ - + SELECT id, street, pc, city, province, ok FROM user_address WHERE #p ORDER BY id @@ -19,7 +19,6 @@ True False 0 - none True @@ -308,7 +307,6 @@ True False 0 - none True diff --git a/module/data/users.glade b/module/data/users.glade index 400bf00..8b7e8aa 100644 --- a/module/data/users.glade +++ b/module/data/users.glade @@ -1,13 +1,30 @@ - - - SELECT user_id, group_id, uid, last_change, expire FROM account WHERE #p - on-iter - - - SELECT mail_alias_id, user_id FROM mail_alias_account WHERE #p + + + + + account-model + on-iter + + + + + alias-model + + + + + sip-model + on-iter + + + + + users-model + + True @@ -15,66 +32,6 @@ 6 vertical 6 - - - True - False - 0 - none - - - True - False - 30 - - - True - False - 6 - - - True - False - 1 - User name: - - - False - True - 0 - - - - - True - False - search-user - - - False - True - 1 - - - - - - - - - True - False - <b>Search</b> - True - - - - - False - True - 0 - - True @@ -277,9 +234,9 @@ True False + user-combo-model users mysql_user_id - SELECT id, user FROM mysql_user 1 @@ -344,9 +301,9 @@ True False + account-combo-model account group_id - SELECT id, name FROM `group` 1 @@ -518,9 +475,9 @@ Alias + alias-combo-model mail_alias_id True - SELECT id, alias FROM mail_alias @@ -739,6 +696,54 @@ + + + + SELECT u.id, u.name, u.mysql_user_id, m.user, u.active +FROM `user` u + JOIN mysql_user m ON u.mysql_user_id = m.id + + + + + SELECT user_id, extension, secret, callerid, callgroup +FROM account_sip +WHERE #p + + + + + SELECT id, alias FROM mail_alias + + + + + + SELECT id, user FROM mysql_user + + + + + + SELECT mail_alias_id, user_id +FROM mail_alias_account +WHERE #p + + + + + SELECT user_id, group_id, uid, last_change, expire +FROM account +WHERE #p + + + + + SELECT id, name FROM `group` + + + + False 5 @@ -898,11 +903,4 @@ - - SELECT user_id, extension, secret, callerid, callgroup FROM account_sip WHERE #p - on-iter - - - SELECT u.id, u.name, u.mysql_user_id, m.user, u.active FROM `user` u JOIN mysql_user m ON u.mysql_user_id = m.id - diff --git a/module/sql/.svn/entries b/module/sql/.svn/entries new file mode 100644 index 0000000..a51bd79 --- /dev/null +++ b/module/sql/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +309 +svn://www.verdnatura.es/hedera/trunk/module/sql +svn://www.verdnatura.es/hedera + + + +2013-07-05T08:50:39.387803Z +307 +juan + + + + + + + + + + + + + + +d9127786-647a-4bcf-81f6-65b2d4e6f3ab + diff --git a/module/sql/example/consulter.sql b/module/sql/example/consulter.sql new file mode 100644 index 0000000..b217bda --- /dev/null +++ b/module/sql/example/consulter.sql @@ -0,0 +1 @@ +SELECT name, color, id FROM item; \ No newline at end of file diff --git a/module/src/Makefile.am b/module/src/Makefile.am index aed27ca..7106c57 100644 --- a/module/src/Makefile.am +++ b/module/src/Makefile.am @@ -5,7 +5,8 @@ example_lib_LTLIBRARIES = libexample.la AM_CPPFLAGS = \ -I$(top_srcdir) \ - $(gtk_CFLAGS) + $(gtk_CFLAGS) \ + $(DEFINES) libexample_la_LDFLAGS = -avoid-version libexample_la_LIBADD = $(top_builddir)/vn/libvn.la libexample_la_SOURCES = \ @@ -16,6 +17,11 @@ libexample_la_SOURCES = \ vn-customer.h \ vn-customer.c +example_querydir = $(module_querydir)/example +example_query_DATA = ../sql/example/consulter.sql + +DEFINES = -D_QUERY_PATH=\"$(module_querydir)\" + install-data-hook: rm -f $(DESTDIR)$(module_libdir)/libexample.la rm -f $(DESTDIR)$(module_libdir)/libexample.a \ No newline at end of file diff --git a/module/src/vn-consulter.c b/module/src/vn-consulter.c index 8698c61..3697c6f 100644 --- a/module/src/vn-consulter.c +++ b/module/src/vn-consulter.c @@ -20,6 +20,8 @@ G_DEFINE_TYPE (VnConsulter, vn_consulter, VN_TYPE_FORM); +#define FILE_KW "sql://" + //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private void vn_consulter_clean_clicked (GtkButton * button, VnConsulter * obj) @@ -63,11 +65,14 @@ static void vn_consulter_model_status_changed (DbModel * model, DbModelStatus status, VnConsulter * obj) { GList * n; - GtkTreeView * tv = GTK_TREE_VIEW (obj->tree); + GtkTreeView * tv = GTK_TREE_VIEW (obj->grid); GList * cols = gtk_tree_view_get_columns (tv); for (n = cols; n; n = n->next) - gtk_tree_view_remove_column (tv, n->data); + { + GtkTreeViewColumn * col = n->data; + gtk_tree_view_remove_column (tv, col); + } g_list_free (cols); @@ -76,9 +81,8 @@ static void vn_consulter_model_status_changed (DbModel * model, case DB_MODEL_STATUS_READY: { gint i; - gint cols = db_model_get_ncols (model); - for (i = 0; i < cols; i++) + for (i = 0; i < db_model_get_ncols (model); i++) { VnColumn * column; GType col_type, type = db_model_get_column_type (model, i); @@ -92,7 +96,7 @@ static void vn_consulter_model_status_changed (DbModel * model, if (i == 7) col_type = VN_TYPE_COLUMN_IMAGE; - column = vn_grid_append_column (obj->tree, i + column = vn_grid_append_column (obj->grid, i ,db_model_get_column_name (model, i) ,col_type ,TRUE, FALSE @@ -135,14 +139,23 @@ void vn_consulter_send (GtkButton * button, VnConsulter * obj) vn_consulter_set_message (obj, sql); - model = db_model_new_with_sql (VN_FORM (obj)->conn, sql); + if (g_str_has_prefix (sql, FILE_KW)) + { + const gchar * filename = sql + g_utf8_strlen (FILE_KW, -1); + db_conn_set_query_path (VN_FORM (obj)->conn, _QUERY_PATH); + model = db_model_new_with_file (VN_FORM (obj)->conn, filename); + g_message ("VnConsulter: query loaded from \"%s/%s.sql\"", _QUERY_PATH, filename); + } + else + model = db_model_new_with_sql (VN_FORM (obj)->conn, sql); + g_signal_connect (model, "status-changed", G_CALLBACK (vn_consulter_model_status_changed), obj); iterator = db_iterator_new (model); iterator->mode = DB_ITERATOR_MODE_ON_DEMAND; vn_handler_set_iterator (obj->handler, iterator); - vn_grid_set_iterator (obj->tree, iterator); + vn_grid_set_iterator (obj->grid, iterator); vn_consulter_mode_toggled (GTK_TOGGLE_BUTTON (obj->mode), obj); @@ -159,7 +172,7 @@ static void vn_consulter_open (VnConsulter * obj) gchar * queries[] = { //MySQL (kk schema) - "/*my*/SELECT id, name, item_id, item_id2, amount, item.price " + "/*my*/SELECT id, name, item_id, item_id2, amount, item.price " "FROM movement JOIN item USING (item_id, item_id2)" ,"/*my*/SELECT item_id,item_id2, i.name, m.id, m.amount, m.price " "FROM item i LEFT JOIN movement m USING (item_id, item_id2)" @@ -170,7 +183,7 @@ static void vn_consulter_open (VnConsulter * obj) "FROM item i LEFT JOIN movement m ON i.id = m.item_id" ,"/*pg*/SELECT m.id, amount, item_id, name, color " "FROM movement m JOIN item ON m.item_id = item.id" - ,"/*pg*/SELECT * FROM item" + ,FILE_KW"example/consulter" ,"/*pg*/ SELECT id1, id2, name, ok, date, number, floating, image " "FROM prueben" ,NULL @@ -180,10 +193,10 @@ static void vn_consulter_open (VnConsulter * obj) obj->combo = vn_form_get (form, "query"); obj->tv = vn_form_get (form, "treeview"); obj->mode = vn_form_get (form, "mode"); - obj->tree = vn_form_get (form, "consulter"); + obj->grid = vn_form_get (form, "consulter"); obj->handler = vn_form_get (form, "handler"); gtk_entry_set_placeholder_text (vn_form_get (form, "combo-entry"), - _("Write your query here or select one from the list")); + _("Type or select a query")); gtk_tree_view_insert_column_with_attributes (obj->tv, -1, "Mensaje", gtk_cell_renderer_text_new (), "text", 0, NULL); diff --git a/module/src/vn-consulter.h b/module/src/vn-consulter.h index 9873519..5bcf5c1 100644 --- a/module/src/vn-consulter.h +++ b/module/src/vn-consulter.h @@ -30,13 +30,11 @@ typedef struct _VnConsulterClass VnConsulterClass; struct _VnConsulter { VnForm parent; - GtkButton * connect; GtkListStore * model; GtkCheckButton * mode; GtkComboBoxText * combo; GtkTreeView * tv; - GtkContainer * box; - VnGrid * tree; + VnGrid * grid; VnHandler * handler; }; diff --git a/module/src/vn-users.c b/module/src/vn-users.c index 8c008ae..0f16dff 100644 --- a/module/src/vn-users.c +++ b/module/src/vn-users.c @@ -57,7 +57,7 @@ static void vn_users_on_password_changed (DbRequest * request, VnUsers * obj) if (g_value_get_int (&value) != -1) gtk_widget_hide (GTK_WIDGET (obj->password_dialog)); else - vn_users_reset_dialog (obj, _("The password is too week.")); + vn_users_reset_dialog (obj, _("The password is too weak.")); g_value_unset (&value); } @@ -78,12 +78,10 @@ void vn_users_on_dialog_response (GtkDialog * dialog, gint response_id, VnUsers else { SqlString * query; - - query = sql_string_new ("SELECT user_set_password (#user, #password)" - ,"user", GVN_TYPE_PARAM, obj->user_id - ,"password", G_TYPE_STRING, password - ,NULL - ); + + query = sql_string_new ("SELECT user_set_password (#p, #p)"); + sql_string_add_param (query, obj->user_id); + sql_string_add_value (query, G_TYPE_STRING, password); db_conn_query_with_stmt_async (VN_FORM (obj)->conn ,SQL_STMT (query) diff --git a/plugin/pg/db-pg.c b/plugin/pg/db-pg.c index ad060e6..1cdc67c 100644 --- a/plugin/pg/db-pg.c +++ b/plugin/pg/db-pg.c @@ -16,7 +16,16 @@ */ #include -#include +//#include + +// Replaces postgres_fe.h until it gets fixed +#ifndef FRONTEND +#define FRONTEND 1 +#endif + +#include "c.h" +// end of the "fix" + #include // Macros to avoid redefinition warnings for constants #undef PACKAGE_BUGREPORT @@ -332,6 +341,7 @@ static DbResultSet * __db_pg_query switch (PQresultStatus (res)) { case PGRES_COMMAND_OK: + case PGRES_SINGLE_TUPLE: case PGRES_TUPLES_OK: { gchar ** q_t = NULL; @@ -674,9 +684,9 @@ static DbResultSet * __db_pg_query {// Serial fields GValue * v = g_new0 (GValue, 1); gchar ** split = g_strsplit_set (pg_val, "(':)", G_MAXINT8); - SqlObject * function = sql_function_new ("currval", NULL); + SqlFunction * function = sql_function_new ("currval", NULL); g_value_set_string (g_value_init (v, G_TYPE_STRING), split[2]); - sql_object_add_child (function, "params", sql_value_new_with_value (v)); + sql_function_add_param (function, sql_value_new_with_value (v)); g_value_unset (v); g_free (v); g_value_take_object (g_value_init (&def[j], SQL_TYPE_FUNCTION), diff --git a/po/POTFILES.in b/po/POTFILES.in index fe62387..7dcccd5 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -13,6 +13,7 @@ plugin/pg/db-pg.c db/db-iterator.c db/db-model.c +db/db-model-holder.c db/db-calc.c db/db-param.c db/db-conn.c @@ -44,4 +45,11 @@ vn/gui/main.glade vn/gui/child-window.glade vn/gui/actions.glade +glade/glade-db-model.c +glade/glade-db-sql.c + +module/data/example.xml module/data/users.glade +module/src/vn-users.c +module/data/consulter.glade +module/src/vn-consulter.c \ No newline at end of file diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 926cfab..d7f13f8 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -1,11 +1,9 @@ -module/data/example.xml module/data/consulter.glade module/data/customer.glade module/data/signer.glade module/src/vn-consulter.c module/src/vn-customer.c module/src/vn-signer.c -module/src/vn-users.c template/lib-object.c diff --git a/po/ca.po b/po/ca.po index b1e1b14..66117bd 100644 --- a/po/ca.po +++ b/po/ca.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: hedera 1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-07-10 11:56+0200\n" +"POT-Creation-Date: 2013-10-08 09:59+0200\n" "PO-Revision-Date: 2013-06-04 13:38+0200\n" "Last-Translator: Alejandro T. Colombini Gómez \n" "Language-Team: Catalan\n" @@ -132,7 +132,7 @@ msgstr "" msgid "The master GvnParam of this parameter" msgstr "" -#: ../gvn/gvn-param.c:457 ../db/db-iterator.c:1070 +#: ../gvn/gvn-param.c:457 ../db/db-iterator.c:985 msgid "Mode" msgstr "" @@ -164,7 +164,7 @@ msgstr "" msgid "The type of the value" msgstr "" -#: ../gvn/gvn-param.c:485 ../vn/vn-field.c:553 ../vn/vn-column.c:354 +#: ../gvn/gvn-param.c:485 ../vn/vn-field.c:553 ../vn/vn-column.c:401 msgid "Editable" msgstr "" @@ -172,7 +172,7 @@ msgstr "" msgid "Whether the param value can be modified" msgstr "" -#: ../gvn/gvn-param.c:492 ../vn/vn-field.c:560 +#: ../gvn/gvn-param.c:492 ../vn/vn-field.c:560 ../vn/vn-column.c:408 msgid "Null" msgstr "" @@ -213,9 +213,7 @@ msgstr "" msgid "The value" msgstr "" -#: ../sql/sql-string.c:198 ../db/db-iterator.c:1063 ../db/db-model.c:3411 -#: ../db/db-request.c:466 ../vn/field/vn-combo.c:356 -#: ../vn/field/vn-completion.c:315 ../vn/column/vn-column-combo.c:297 +#: ../sql/sql-string.c:198 ../db/db-model.c:3459 ../db/db-request.c:461 msgid "SQL" msgstr "" @@ -223,111 +221,91 @@ msgstr "" msgid "An arbitrary SQL string" msgstr "" -#: ../plugin/mysql/db-mysql.c:68 ../plugin/pg/db-pg.c:76 +#: ../plugin/mysql/db-mysql.c:68 ../plugin/pg/db-pg.c:85 #, c-format msgid "Can't allocate the needed memory" msgstr "" -#: ../db/db-iterator.c:284 -msgid "DbIterator: Can't reassign the 'model' property" -msgstr "" - -#: ../db/db-iterator.c:942 -msgid "DbIterator: Can't set the 'conn' property because model isn't set" -msgstr "" - -#: ../db/db-iterator.c:1049 ../db/db-calc.c:329 ../vn/field/vn-combo.c:342 -#: ../vn/column/vn-column-combo.c:283 -msgid "Model" -msgstr "" - -#: ../db/db-iterator.c:1050 -msgid "The DbModel handled by the iterator" -msgstr "" - -#: ../db/db-iterator.c:1056 ../db/db-model.c:3395 ../db/db-request.c:459 -#: ../vn/vn-gui.c:1531 ../vn/vn-form.c:241 ../vn/field/vn-combo.c:349 -#: ../vn/field/vn-completion.c:308 ../vn/column/vn-column-combo.c:290 -msgid "Connection" -msgstr "" - -#: ../db/db-iterator.c:1057 ../vn/field/vn-combo.c:350 -#: ../vn/field/vn-completion.c:309 ../vn/column/vn-column-combo.c:291 -msgid "The connection used by the model" -msgstr "" - -#: ../db/db-iterator.c:1064 ../vn/field/vn-combo.c:357 -#: ../vn/field/vn-completion.c:316 ../vn/column/vn-column-combo.c:298 -msgid "The SQL query used to create the model" -msgstr "" - -#: ../db/db-iterator.c:1071 +#: ../db/db-iterator.c:986 msgid "The mode in which the iterator is working" msgstr "" -#: ../db/db-iterator.c:1078 +#: ../db/db-iterator.c:993 #, fuzzy msgid "Remember selection" msgstr "Recordar" -#: ../db/db-iterator.c:1079 +#: ../db/db-iterator.c:994 msgid "Wether to rememeber the selection when model is refreshed" msgstr "" -#: ../db/db-model.c:3396 +#: ../db/db-model.c:3443 ../db/db-request.c:454 ../vn/vn-gui.c:1531 +#: ../vn/vn-form.c:235 +msgid "Connection" +msgstr "" + +#: ../db/db-model.c:3444 msgid "The DbConn that manages the connection to the database" msgstr "" -#: ../db/db-model.c:3403 ../db/db-request.c:473 +#: ../db/db-model.c:3451 ../db/db-request.c:468 msgid "Statement" msgstr "" -#: ../db/db-model.c:3404 +#: ../db/db-model.c:3452 msgid "The statement which retrieves the data" msgstr "" -#: ../db/db-model.c:3412 +#: ../db/db-model.c:3460 msgid "" "Depending on the \"use-file\" property this will be the path to a file with " "queries for the model or a SQL string" msgstr "" -#: ../db/db-model.c:3421 +#: ../db/db-model.c:3469 msgid "Use file" msgstr "" -#: ../db/db-model.c:3422 +#: ../db/db-model.c:3470 msgid "" "If this is set to TRUE, the \"sql\" property will hold the name of a file " "containing a query, if set to FALSE, \"sql\" is used as an SQL string" msgstr "" -#: ../db/db-model.c:3431 +#: ../db/db-model.c:3479 msgid "Main Table" msgstr "" -#: ../db/db-model.c:3432 +#: ../db/db-model.c:3480 msgid "The main table of the model" msgstr "" -#: ../db/db-model.c:3439 +#: ../db/db-model.c:3487 msgid "Update flags" msgstr "" -#: ../db/db-model.c:3440 +#: ../db/db-model.c:3488 msgid "The flags that indicate how a model can be modified" msgstr "" -#: ../db/db-model.c:3448 +#: ../db/db-model.c:3496 msgid "Result position" msgstr "" -#: ../db/db-model.c:3449 +#: ../db/db-model.c:3497 msgid "" "The position where the query that will fill the model will be placed in a " "multi-query" msgstr "" +#: ../db/db-model-holder.c:70 ../db/db-calc.c:329 +msgid "Model" +msgstr "" + +#: ../db/db-model-holder.c:71 +msgid "The model used by the holder" +msgstr "" + #: ../db/db-calc.c:330 msgid "The model where the operations will be applied" msgstr "" @@ -364,121 +342,121 @@ msgstr "" msgid "A column to apply the operations over it" msgstr "" -#: ../db/db-param.c:243 ../vn/vn-grid.c:349 ../vn/vn-field.c:532 +#: ../db/db-param.c:251 ../vn/vn-grid.c:357 ../vn/vn-field.c:532 msgid "Iterator" msgstr "" -#: ../db/db-param.c:244 +#: ../db/db-param.c:252 msgid "The iterator owner of param" msgstr "" -#: ../db/db-param.c:250 ../vn/vn-column.c:340 +#: ../db/db-param.c:258 ../vn/vn-column.c:387 msgid "Column index" msgstr "" -#: ../db/db-param.c:251 +#: ../db/db-param.c:259 msgid "The referenced column index" msgstr "" -#: ../db/db-param.c:257 ../vn/vn-field.c:539 ../vn/vn-column.c:347 +#: ../db/db-param.c:265 ../vn/vn-field.c:539 ../vn/vn-column.c:394 msgid "Column name" msgstr "Nom de la columna" -#: ../db/db-param.c:258 ../vn/vn-column.c:348 +#: ../db/db-param.c:266 ../vn/vn-column.c:395 msgid "The referenced column name" msgstr "Nom de la columna referenciada" -#: ../db/db-conn.c:279 ../db/db-conn.c:284 +#: ../db/db-conn.c:282 ../db/db-conn.c:287 #, c-format msgid "Can't load DbPlugin '%s': %s" msgstr "" -#: ../db/db-conn.c:297 +#: ../db/db-conn.c:300 #, c-format msgid "Plugin can't be loaded" msgstr "" -#: ../db/db-conn.c:413 +#: ../db/db-conn.c:416 #, c-format msgid "Can't open a new connection, it's already open." msgstr "" -#: ../db/db-conn.c:555 +#: ../db/db-conn.c:558 #, c-format msgid "The query is empty." msgstr "" -#: ../db/db-conn.c:1060 +#: ../db/db-conn.c:1037 msgid "Plugin" msgstr "" -#: ../db/db-conn.c:1061 +#: ../db/db-conn.c:1038 msgid "The name of the plugin" msgstr "" -#: ../db/db-conn.c:1067 +#: ../db/db-conn.c:1044 msgid "Query path" msgstr "" -#: ../db/db-conn.c:1068 +#: ../db/db-conn.c:1045 msgid "The path where query files are located" msgstr "" -#: ../db/db-conn.c:1074 ../db/db-file-loader.c:724 -#: ../vn/column/vn-column-image.c:475 +#: ../db/db-conn.c:1051 ../db/db-file-loader.c:724 +#: ../vn/column/vn-column-image.c:477 msgid "Host" msgstr "" -#: ../db/db-conn.c:1075 +#: ../db/db-conn.c:1052 msgid "The host name to connect to" msgstr "" -#: ../db/db-conn.c:1081 ../module/data/users.glade.h:4 +#: ../db/db-conn.c:1058 ../module/data/users.glade.h:2 msgid "User" msgstr "Usuari" -#: ../db/db-conn.c:1082 +#: ../db/db-conn.c:1059 msgid "The user name" msgstr "Nom d'usuari" -#: ../db/db-conn.c:1088 +#: ../db/db-conn.c:1065 msgid "DB name" msgstr "" -#: ../db/db-conn.c:1089 +#: ../db/db-conn.c:1066 msgid "The default schema" msgstr "" -#: ../db/db-request.c:315 +#: ../db/db-request.c:311 #, c-format msgid "The request was canceled" msgstr "" -#: ../db/db-request.c:460 +#: ../db/db-request.c:455 msgid "The connection used to render and execute the query" msgstr "" -#: ../db/db-request.c:467 +#: ../db/db-request.c:462 msgid "The SQL query to execute" msgstr "" -#: ../db/db-request.c:474 +#: ../db/db-request.c:469 msgid "The statement to execute" msgstr "" -#: ../db/db-request.c:480 +#: ../db/db-request.c:475 msgid "Result" msgstr "" -#: ../db/db-request.c:481 +#: ../db/db-request.c:476 msgid "The result data of the query" msgstr "" -#: ../db/db-request.c:487 +#: ../db/db-request.c:482 msgid "Error" msgstr "" -#: ../db/db-request.c:488 +#: ../db/db-request.c:483 msgid "The GError, if an error ocurred" msgstr "" @@ -492,11 +470,11 @@ msgstr "" msgid "Unknown content length of file %s" msgstr "" -#: ../db/db-file-loader.c:725 ../vn/column/vn-column-image.c:476 +#: ../db/db-file-loader.c:725 ../vn/column/vn-column-image.c:478 msgid "The host web server name to get the images" msgstr "" -#: ../db/db-file-loader.c:732 ../vn/column/vn-column-image.c:483 +#: ../db/db-file-loader.c:732 ../vn/column/vn-column-image.c:485 msgid "Path" msgstr "" @@ -558,7 +536,7 @@ msgstr "" msgid "Connection closed" msgstr "" -#: ../vn/vn-gui.c:987 ../vn/field/vn-http-image.c:118 +#: ../vn/vn-gui.c:987 ../vn/field/vn-http-image.c:116 msgid "Loading" msgstr "" @@ -578,17 +556,17 @@ msgstr "" msgid "The application handler for the entire program" msgstr "" -#: ../vn/vn-model.c:303 +#: ../vn/vn-model.c:317 #, c-format msgid "Function vn_model_set_sort_func not implemented" msgstr "Funció vn_model_set_sort_func no implementada" -#: ../vn/vn-model.c:310 +#: ../vn/vn-model.c:324 #, c-format msgid "Function vn_model_set_default_sort_func not implemented" msgstr "Funció vn_model_set_default_sort_func no implementada" -#: ../vn/vn-grid.c:350 +#: ../vn/vn-grid.c:358 msgid "The iterator used by VnGrid" msgstr "" @@ -652,48 +630,48 @@ msgstr "" msgid "Sets if it is used to handle a iterator with a single record" msgstr "" -#: ../vn/vn-form.c:227 +#: ../vn/vn-form.c:221 msgid "Name" msgstr "" -#: ../vn/vn-form.c:228 +#: ../vn/vn-form.c:222 msgid "The form name" msgstr "" -#: ../vn/vn-form.c:234 +#: ../vn/vn-form.c:228 msgid "Gui" msgstr "" -#: ../vn/vn-form.c:235 +#: ../vn/vn-form.c:229 msgid "The Gui object" msgstr "" -#: ../vn/vn-form.c:242 +#: ../vn/vn-form.c:236 msgid "The connection used by the module" msgstr "" -#: ../vn/vn-form.c:248 +#: ../vn/vn-form.c:242 msgid "Module" msgstr "" -#: ../vn/vn-form.c:249 +#: ../vn/vn-form.c:243 msgid "The module" msgstr "" -#: ../vn/vn-login.c:276 ../vn/vn-login.c:278 +#: ../vn/vn-login.c:290 ../vn/vn-login.c:292 msgid "Login error" msgstr "" -#: ../vn/vn-login.c:336 +#: ../vn/vn-login.c:348 #, c-format msgid "Bad connection settings, please check it." msgstr "" -#: ../vn/vn-login.c:457 +#: ../vn/vn-login.c:477 msgid "Application id" msgstr "" -#: ../vn/vn-login.c:458 +#: ../vn/vn-login.c:478 msgid "The application identifier" msgstr "" @@ -721,7 +699,7 @@ msgstr "" msgid "Whether the field value is user editable" msgstr "" -#: ../vn/vn-field.c:561 +#: ../vn/vn-field.c:561 ../vn/vn-column.c:409 msgid "Whether the field value can be of type GVN_TYPE_NULL" msgstr "" @@ -735,31 +713,27 @@ msgstr "" msgid "The number of decimal places to display." msgstr "" -#: ../vn/field/vn-combo.c:328 ../vn/column/vn-column-combo.c:269 +#: ../vn/field/vn-combo.c:286 ../vn/column/vn-column-combo.c:300 msgid "Index column" msgstr "" -#: ../vn/field/vn-combo.c:329 ../vn/column/vn-column-combo.c:270 +#: ../vn/field/vn-combo.c:287 ../vn/column/vn-column-combo.c:301 msgid "The column index of the model" msgstr "" -#: ../vn/field/vn-combo.c:335 ../vn/column/vn-column-combo.c:276 +#: ../vn/field/vn-combo.c:293 ../vn/column/vn-column-combo.c:307 msgid "Show column" msgstr "" -#: ../vn/field/vn-combo.c:336 ../vn/column/vn-column-combo.c:277 +#: ../vn/field/vn-combo.c:294 ../vn/column/vn-column-combo.c:308 msgid "The column of the model shown by combo" msgstr "" -#: ../vn/field/vn-combo.c:343 ../vn/column/vn-column-combo.c:284 -msgid "The model from which the combo takes the values shown in the list" -msgstr "" - -#: ../vn/field/vn-completion.c:322 +#: ../vn/field/vn-completion.c:325 msgid "Field" msgstr "" -#: ../vn/field/vn-completion.c:323 +#: ../vn/field/vn-completion.c:326 msgid "The name of the field used for the search" msgstr "" @@ -776,49 +750,49 @@ msgstr "" msgid "Select the image" msgstr "" -#: ../vn/field/vn-http-image.c:69 +#: ../vn/field/vn-http-image.c:70 msgid "Undefined error" msgstr "" -#: ../vn/field/vn-http-image.c:145 +#: ../vn/field/vn-http-image.c:142 msgid "File loader already set" msgstr "" #. Se usará para subir imagenes y cambiar nombres, o abrir un menu contextual #. g_signal_connect (obj, "event", G_CALLBACK (vn_http_image_cb_event), obj); -#: ../vn/field/vn-http-image.c:184 +#: ../vn/field/vn-http-image.c:181 msgid "No image set" msgstr "" -#: ../vn/field/vn-http-image.c:210 +#: ../vn/field/vn-http-image.c:207 msgid "File loader" msgstr "" -#: ../vn/field/vn-http-image.c:211 +#: ../vn/field/vn-http-image.c:208 msgid "A DbFileLoader, used to download the files" msgstr "" -#: ../vn/field/vn-http-image.c:218 +#: ../vn/field/vn-http-image.c:215 msgid "File path" msgstr "" -#: ../vn/field/vn-http-image.c:219 +#: ../vn/field/vn-http-image.c:216 msgid "The relative path to the image from file loader path" msgstr "" -#: ../vn/field/vn-http-image.c:226 +#: ../vn/field/vn-http-image.c:223 msgid "Image bytes" msgstr "" -#: ../vn/field/vn-http-image.c:227 +#: ../vn/field/vn-http-image.c:224 msgid "A GBytes structure with the image data" msgstr "" -#: ../vn/vn-column.c:341 +#: ../vn/vn-column.c:388 msgid "The column index in the model" msgstr "" -#: ../vn/vn-column.c:355 +#: ../vn/vn-column.c:402 msgid "Whether the column values are editable" msgstr "" @@ -830,25 +804,25 @@ msgstr "" msgid "The acceleration rate when you hold down a button." msgstr "" -#: ../vn/column/vn-column-image.c:484 +#: ../vn/column/vn-column-image.c:486 msgid "Base path from the host where the images will be downloaded" msgstr "" -#: ../vn/column/vn-column-image.c:491 +#: ../vn/column/vn-column-image.c:493 msgid "Tooltip path" msgstr "" -#: ../vn/column/vn-column-image.c:492 +#: ../vn/column/vn-column-image.c:494 msgid "" "Prefix for the path of the images to be shown in the tooltip. Starting after " "the path of the column and appending the name on each cell" msgstr "" -#: ../vn/column/vn-column-image.c:501 +#: ../vn/column/vn-column-image.c:503 msgid "Tooltip size" msgstr "" -#: ../vn/column/vn-column-image.c:502 +#: ../vn/column/vn-column-image.c:504 msgid "" "Size of the bigger side of the tooltip images, the another side will be " "scaled accordingly and smaller images won't be scaled" @@ -889,7 +863,7 @@ msgstr "Accés" msgid "User:" msgstr "Usuari:" -#: ../vn/gui/login.glade.h:9 ../module/data/users.glade.h:8 +#: ../vn/gui/login.glade.h:9 ../module/data/users.glade.h:6 msgid "Password:" msgstr "Contrasenya:" @@ -989,87 +963,179 @@ msgctxt "View menu option" msgid "Tool_bar" msgstr "" -#: ../module/data/users.glade.h:1 -#, fuzzy -msgid "User name:" -msgstr "Nom d'usuari" - -#: ../module/data/users.glade.h:2 -msgid "Search" +#: ../glade/glade-db-model.c:121 +msgid "Create and set a model for a DbModelHolder" msgstr "" -#: ../module/data/users.glade.h:3 +#: ../glade/glade-db-model.c:153 +msgid "Model configuration" +msgstr "" + +#: ../glade/glade-db-model.c:153 +msgid "DbModel properties configuration" +msgstr "" + +#: ../glade/glade-db-model.c:238 +msgid "Select a DbModel for the property" +msgstr "" + +#: ../glade/glade-db-model.c:259 ../glade/glade-db-model.c:306 +msgid "New Model" +msgstr "" + +#: ../glade/glade-db-model.c:301 +msgid "Edit Model" +msgstr "" + +#: ../glade/glade-db-sql.c:27 +msgid "New SQL statement" +msgstr "" + +#: ../glade/glade-db-sql.c:59 +msgid "SQL Editor" +msgstr "" + +#: ../glade/glade-db-sql.c:174 +msgid "Open the SQL Editor" +msgstr "" + +#: ../module/data/users.glade.h:1 msgid "Identifier" msgstr "" -#: ../module/data/users.glade.h:5 +#: ../module/data/users.glade.h:3 msgid "MySQL User" msgstr "" -#: ../module/data/users.glade.h:6 +#: ../module/data/users.glade.h:4 msgid "Enabled" msgstr "" -#: ../module/data/users.glade.h:7 +#: ../module/data/users.glade.h:5 msgid "Name:" msgstr "" -#: ../module/data/users.glade.h:9 +#: ../module/data/users.glade.h:7 msgid "MySQL user:" msgstr "" -#: ../module/data/users.glade.h:10 +#: ../module/data/users.glade.h:8 msgid "Enabled:" msgstr "" -#: ../module/data/users.glade.h:11 +#: ../module/data/users.glade.h:9 msgid "Identifier:" msgstr "" -#: ../module/data/users.glade.h:12 +#: ../module/data/users.glade.h:10 msgid "UID:" msgstr "" -#: ../module/data/users.glade.h:13 +#: ../module/data/users.glade.h:11 msgid "Main group:" msgstr "" -#: ../module/data/users.glade.h:14 +#: ../module/data/users.glade.h:12 msgid "Last change:" msgstr "" -#: ../module/data/users.glade.h:15 +#: ../module/data/users.glade.h:13 msgid "Expires:" msgstr "" -#: ../module/data/users.glade.h:16 +#: ../module/data/users.glade.h:14 msgid "Account" msgstr "" -#: ../module/data/users.glade.h:17 +#: ../module/data/users.glade.h:15 msgid "Alias" msgstr "" -#: ../module/data/users.glade.h:18 +#: ../module/data/users.glade.h:16 msgid "Mail alias" msgstr "" -#: ../module/data/users.glade.h:19 +#: ../module/data/users.glade.h:17 msgid "Extension:" msgstr "" -#: ../module/data/users.glade.h:20 +#: ../module/data/users.glade.h:18 msgid "Secret:" msgstr "" -#: ../module/data/users.glade.h:21 +#: ../module/data/users.glade.h:19 msgid "Call group:" msgstr "" -#: ../module/data/users.glade.h:22 +#: ../module/data/users.glade.h:20 msgid "SIP" msgstr "" -#: ../module/data/users.glade.h:23 +#: ../module/data/users.glade.h:21 +#, fuzzy +msgid "Change password" +msgstr "Repetir contrasenya:" + +#: ../module/data/users.glade.h:22 msgid "Repeat password:" msgstr "Repetir contrasenya:" + +#: ../module/src/vn-users.c:60 +msgid "The password is too weak." +msgstr "" + +#: ../module/src/vn-users.c:75 +msgid "The password can't be empty." +msgstr "" + +#: ../module/src/vn-users.c:77 +msgid "Passwords do not match." +msgstr "" + +#: ../module/data/consulter.glade.h:1 +msgid "Send" +msgstr "" + +#: ../module/data/consulter.glade.h:2 +msgid "Send the current query" +msgstr "" + +#: ../module/data/consulter.glade.h:3 +msgid "Clean" +msgstr "" + +#: ../module/data/consulter.glade.h:4 +msgid "Clean the messages" +msgstr "" + +#: ../module/data/consulter.glade.h:5 +msgid "_Consulter" +msgstr "" + +#: ../module/data/consulter.glade.h:6 +msgid "Query:" +msgstr "" + +#: ../module/data/consulter.glade.h:7 +msgid "Immediate changes" +msgstr "" + +#: ../module/data/consulter.glade.h:8 +msgid "Start" +msgstr "" + +#: ../module/data/consulter.glade.h:9 +msgid "Commit" +msgstr "" + +#: ../module/data/consulter.glade.h:10 +msgid "Rollback" +msgstr "" + +#: ../module/src/vn-consulter.c:199 +msgid "Type or select a query" +msgstr "" + +#, fuzzy +#~ msgid "User name:" +#~ msgstr "Nom d'usuari" diff --git a/po/es.po b/po/es.po index 1536d26..b92ddbd 100644 --- a/po/es.po +++ b/po/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: hedera 1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-07-10 11:56+0200\n" +"POT-Creation-Date: 2013-10-08 09:59+0200\n" "PO-Revision-Date: 2013-06-04 13:36+0200\n" "Last-Translator: Alejandro T. Colombini Gómez \n" "Language-Team: Spanish\n" @@ -134,7 +134,7 @@ msgstr "Maestro" msgid "The master GvnParam of this parameter" msgstr "El GvnParam maestro de este parámetro" -#: ../gvn/gvn-param.c:457 ../db/db-iterator.c:1070 +#: ../gvn/gvn-param.c:457 ../db/db-iterator.c:985 msgid "Mode" msgstr "Modo" @@ -166,7 +166,7 @@ msgstr "Tipo Glib" msgid "The type of the value" msgstr "El tipo del valor" -#: ../gvn/gvn-param.c:485 ../vn/vn-field.c:553 ../vn/vn-column.c:354 +#: ../gvn/gvn-param.c:485 ../vn/vn-field.c:553 ../vn/vn-column.c:401 msgid "Editable" msgstr "Editable" @@ -174,7 +174,7 @@ msgstr "Editable" msgid "Whether the param value can be modified" msgstr "Indica si el parámetro puede modificarse" -#: ../gvn/gvn-param.c:492 ../vn/vn-field.c:560 +#: ../gvn/gvn-param.c:492 ../vn/vn-field.c:560 ../vn/vn-column.c:408 msgid "Null" msgstr "Nulo" @@ -215,9 +215,7 @@ msgstr "El parametro al cual está vinculado" msgid "The value" msgstr "Valor" -#: ../sql/sql-string.c:198 ../db/db-iterator.c:1063 ../db/db-model.c:3411 -#: ../db/db-request.c:466 ../vn/field/vn-combo.c:356 -#: ../vn/field/vn-completion.c:315 ../vn/column/vn-column-combo.c:297 +#: ../sql/sql-string.c:198 ../db/db-model.c:3459 ../db/db-request.c:461 msgid "SQL" msgstr "SQL" @@ -225,72 +223,42 @@ msgstr "SQL" msgid "An arbitrary SQL string" msgstr "Una cadena SQL arbitraria" -#: ../plugin/mysql/db-mysql.c:68 ../plugin/pg/db-pg.c:76 +#: ../plugin/mysql/db-mysql.c:68 ../plugin/pg/db-pg.c:85 #, c-format msgid "Can't allocate the needed memory" msgstr "No es posible asignar la memoria necesaria" -#: ../db/db-iterator.c:284 -msgid "DbIterator: Can't reassign the 'model' property" -msgstr "DbIterator: No puedo reasignarse la propiedad 'model'" - -#: ../db/db-iterator.c:942 -msgid "DbIterator: Can't set the 'conn' property because model isn't set" -msgstr "" -"DbIterator: No se pudo configurar la propiedad porque 'model' no está " -"configurado" - -#: ../db/db-iterator.c:1049 ../db/db-calc.c:329 ../vn/field/vn-combo.c:342 -#: ../vn/column/vn-column-combo.c:283 -msgid "Model" -msgstr "Modelo" - -#: ../db/db-iterator.c:1050 -msgid "The DbModel handled by the iterator" -msgstr "El DbModel manejado por el iterador" - -#: ../db/db-iterator.c:1056 ../db/db-model.c:3395 ../db/db-request.c:459 -#: ../vn/vn-gui.c:1531 ../vn/vn-form.c:241 ../vn/field/vn-combo.c:349 -#: ../vn/field/vn-completion.c:308 ../vn/column/vn-column-combo.c:290 -msgid "Connection" -msgstr "Conexión" - -#: ../db/db-iterator.c:1057 ../vn/field/vn-combo.c:350 -#: ../vn/field/vn-completion.c:309 ../vn/column/vn-column-combo.c:291 -msgid "The connection used by the model" -msgstr "La conexión empleada por el modelo" - -#: ../db/db-iterator.c:1064 ../vn/field/vn-combo.c:357 -#: ../vn/field/vn-completion.c:316 ../vn/column/vn-column-combo.c:298 -msgid "The SQL query used to create the model" -msgstr "La consulta SQL usada para crear el modelo" - -#: ../db/db-iterator.c:1071 +#: ../db/db-iterator.c:986 msgid "The mode in which the iterator is working" -msgstr "El modo en el que está trabajando el iterador" +msgstr "El modo en el que está trabajando el Iterator" -#: ../db/db-iterator.c:1078 +#: ../db/db-iterator.c:993 msgid "Remember selection" msgstr "Recordar fila seleccionada" -#: ../db/db-iterator.c:1079 +#: ../db/db-iterator.c:994 msgid "Wether to rememeber the selection when model is refreshed" msgstr "" "Si se recordará o no la fila seleccionado cuando se refresque el modelo" -#: ../db/db-model.c:3396 +#: ../db/db-model.c:3443 ../db/db-request.c:454 ../vn/vn-gui.c:1531 +#: ../vn/vn-form.c:235 +msgid "Connection" +msgstr "Conexión" + +#: ../db/db-model.c:3444 msgid "The DbConn that manages the connection to the database" msgstr "La DbConn que controla la conexión a la base de datos" -#: ../db/db-model.c:3403 ../db/db-request.c:473 +#: ../db/db-model.c:3451 ../db/db-request.c:468 msgid "Statement" msgstr "Consulta" -#: ../db/db-model.c:3404 +#: ../db/db-model.c:3452 msgid "The statement which retrieves the data" msgstr "La consulta que recupera los datos" -#: ../db/db-model.c:3412 +#: ../db/db-model.c:3460 msgid "" "Depending on the \"use-file\" property this will be the path to a file with " "queries for the model or a SQL string" @@ -298,39 +266,39 @@ msgstr "" "Dependiendo de la propiedad \"use-file\", esta propiedad será la ruta a un " "fichero con consultas para el modelo o una cadena SQL" -#: ../db/db-model.c:3421 +#: ../db/db-model.c:3469 msgid "Use file" msgstr "Usa fichero" -#: ../db/db-model.c:3422 +#: ../db/db-model.c:3470 msgid "" "If this is set to TRUE, the \"sql\" property will hold the name of a file " "containing a query, if set to FALSE, \"sql\" is used as an SQL string" msgstr "" -"Si está puesto a TRUE, la propiedad \"sql\" contiene el nombre de un " -"archivo, si es falso, \"sql\" se usa como una cadena SQL" +"Si es TRUE, la propiedad \"sql\" contiene el nombre de un archivo, si es " +"falso, \"sql\" se usa como una cadena SQL" -#: ../db/db-model.c:3431 +#: ../db/db-model.c:3479 msgid "Main Table" msgstr "Tabla principal" -#: ../db/db-model.c:3432 +#: ../db/db-model.c:3480 msgid "The main table of the model" msgstr "La tabla principal del modelo" -#: ../db/db-model.c:3439 +#: ../db/db-model.c:3487 msgid "Update flags" msgstr "Flags de actualización" -#: ../db/db-model.c:3440 +#: ../db/db-model.c:3488 msgid "The flags that indicate how a model can be modified" msgstr "Indican como se puede modificar el modelo" -#: ../db/db-model.c:3448 +#: ../db/db-model.c:3496 msgid "Result position" msgstr "Posición del resultado" -#: ../db/db-model.c:3449 +#: ../db/db-model.c:3497 msgid "" "The position where the query that will fill the model will be placed in a " "multi-query" @@ -338,6 +306,14 @@ msgstr "" "La posición en la que se situa la consulta que pone datos en el modelo en " "una consulta múltiple" +#: ../db/db-model-holder.c:70 ../db/db-calc.c:329 +msgid "Model" +msgstr "Modelo" + +#: ../db/db-model-holder.c:71 +msgid "The model used by the holder" +msgstr "La conexión empleada por el objeto" + #: ../db/db-calc.c:330 msgid "The model where the operations will be applied" msgstr "El modelo en el que se aplicarán las operaciones" @@ -374,123 +350,123 @@ msgstr "Columna" msgid "A column to apply the operations over it" msgstr "Una columna sobre la que se aplicarán las operaciones" -#: ../db/db-param.c:243 ../vn/vn-grid.c:349 ../vn/vn-field.c:532 +#: ../db/db-param.c:251 ../vn/vn-grid.c:357 ../vn/vn-field.c:532 msgid "Iterator" msgstr "Iterator" -#: ../db/db-param.c:244 +#: ../db/db-param.c:252 msgid "The iterator owner of param" -msgstr "El iterador dueño del parámetro" +msgstr "El Iterator dueño del parámetro" -#: ../db/db-param.c:250 ../vn/vn-column.c:340 +#: ../db/db-param.c:258 ../vn/vn-column.c:387 msgid "Column index" -msgstr "Columna usada como índice" +msgstr "Posición" -#: ../db/db-param.c:251 +#: ../db/db-param.c:259 msgid "The referenced column index" -msgstr "El índice de la columna referenciada" +msgstr "La posición de la columna en el Grid" -#: ../db/db-param.c:257 ../vn/vn-field.c:539 ../vn/vn-column.c:347 +#: ../db/db-param.c:265 ../vn/vn-field.c:539 ../vn/vn-column.c:394 msgid "Column name" msgstr "Nombre de la columna" -#: ../db/db-param.c:258 ../vn/vn-column.c:348 +#: ../db/db-param.c:266 ../vn/vn-column.c:395 msgid "The referenced column name" msgstr "" "El nombre del campo en el Iterator vinculado al Grid al que pretenece la " "columna" -#: ../db/db-conn.c:279 ../db/db-conn.c:284 +#: ../db/db-conn.c:282 ../db/db-conn.c:287 #, c-format msgid "Can't load DbPlugin '%s': %s" msgstr "No se puede cargar el DbPlugin '%s': %s" -#: ../db/db-conn.c:297 +#: ../db/db-conn.c:300 #, c-format msgid "Plugin can't be loaded" msgstr "No se puede cargar el plug-in" -#: ../db/db-conn.c:413 +#: ../db/db-conn.c:416 #, c-format msgid "Can't open a new connection, it's already open." msgstr "No se puede abrir una nueva conexión, ya está abierta" -#: ../db/db-conn.c:555 +#: ../db/db-conn.c:558 #, c-format msgid "The query is empty." msgstr "La consulta está vacía." -#: ../db/db-conn.c:1060 +#: ../db/db-conn.c:1037 msgid "Plugin" msgstr "Plugin" -#: ../db/db-conn.c:1061 +#: ../db/db-conn.c:1038 msgid "The name of the plugin" msgstr "El nombre del plugin" -#: ../db/db-conn.c:1067 +#: ../db/db-conn.c:1044 msgid "Query path" msgstr "Ruta de consultas" -#: ../db/db-conn.c:1068 +#: ../db/db-conn.c:1045 msgid "The path where query files are located" msgstr "La ruta donde se encuentran los archivos de consultas" -#: ../db/db-conn.c:1074 ../db/db-file-loader.c:724 -#: ../vn/column/vn-column-image.c:475 +#: ../db/db-conn.c:1051 ../db/db-file-loader.c:724 +#: ../vn/column/vn-column-image.c:477 msgid "Host" msgstr "Host" -#: ../db/db-conn.c:1075 +#: ../db/db-conn.c:1052 msgid "The host name to connect to" msgstr "El nombre del host al que se conectará" -#: ../db/db-conn.c:1081 ../module/data/users.glade.h:4 +#: ../db/db-conn.c:1058 ../module/data/users.glade.h:2 msgid "User" msgstr "Usuario" -#: ../db/db-conn.c:1082 +#: ../db/db-conn.c:1059 msgid "The user name" msgstr "El nombre de usuario" -#: ../db/db-conn.c:1088 +#: ../db/db-conn.c:1065 msgid "DB name" msgstr "Nombre de la BD" -#: ../db/db-conn.c:1089 +#: ../db/db-conn.c:1066 msgid "The default schema" msgstr "El esquema por defecto" -#: ../db/db-request.c:315 +#: ../db/db-request.c:311 #, c-format msgid "The request was canceled" msgstr "Se ha cancelado la petición" -#: ../db/db-request.c:460 +#: ../db/db-request.c:455 msgid "The connection used to render and execute the query" msgstr "La conexión empleada por el módulo" -#: ../db/db-request.c:467 +#: ../db/db-request.c:462 msgid "The SQL query to execute" msgstr "La consulta SQL a ejecutar" -#: ../db/db-request.c:474 +#: ../db/db-request.c:469 msgid "The statement to execute" msgstr "La instrucción a ejecutar" -#: ../db/db-request.c:480 +#: ../db/db-request.c:475 msgid "Result" msgstr "Result" -#: ../db/db-request.c:481 +#: ../db/db-request.c:476 msgid "The result data of the query" msgstr "Los datos resultantes de la consulta" -#: ../db/db-request.c:487 +#: ../db/db-request.c:482 msgid "Error" msgstr "Error" -#: ../db/db-request.c:488 +#: ../db/db-request.c:483 msgid "The GError, if an error ocurred" msgstr "El GError, si ha habido algún error" @@ -504,11 +480,11 @@ msgstr "No se ha guardado %s en la cache" msgid "Unknown content length of file %s" msgstr "Longitud del contenido del archivo %s desconocida" -#: ../db/db-file-loader.c:725 ../vn/column/vn-column-image.c:476 +#: ../db/db-file-loader.c:725 ../vn/column/vn-column-image.c:478 msgid "The host web server name to get the images" msgstr "El nombre del servidor web al que se conectará" -#: ../db/db-file-loader.c:732 ../vn/column/vn-column-image.c:483 +#: ../db/db-file-loader.c:732 ../vn/column/vn-column-image.c:485 msgid "Path" msgstr "Ruta" @@ -572,7 +548,7 @@ msgstr "Conexión perdida" msgid "Connection closed" msgstr "Conexión cerrada" -#: ../vn/vn-gui.c:987 ../vn/field/vn-http-image.c:118 +#: ../vn/vn-gui.c:987 ../vn/field/vn-http-image.c:116 msgid "Loading" msgstr "Cargando" @@ -592,19 +568,19 @@ msgstr "Aplicación" msgid "The application handler for the entire program" msgstr "El manejador de la aplicación para todo el programa" -#: ../vn/vn-model.c:303 +#: ../vn/vn-model.c:317 #, c-format msgid "Function vn_model_set_sort_func not implemented" msgstr "Función vn_model_set_sort_func no implementada" -#: ../vn/vn-model.c:310 +#: ../vn/vn-model.c:324 #, c-format msgid "Function vn_model_set_default_sort_func not implemented" msgstr "Función vn_model_set_default_sort_func no implementada" -#: ../vn/vn-grid.c:350 +#: ../vn/vn-grid.c:358 msgid "The iterator used by VnGrid" -msgstr "El iterador empleado por VnGrid" +msgstr "El Iterator empleado por VnGrid" #: ../vn/vn-handler.c:65 msgid "Are you sure you want to delete the selected record?" @@ -666,48 +642,48 @@ msgstr "Registro simple" msgid "Sets if it is used to handle a iterator with a single record" msgstr "Indica si se utiliza para manejar solo un registro" -#: ../vn/vn-form.c:227 +#: ../vn/vn-form.c:221 msgid "Name" msgstr "Nombre" -#: ../vn/vn-form.c:228 +#: ../vn/vn-form.c:222 msgid "The form name" msgstr "El nombre del form" -#: ../vn/vn-form.c:234 +#: ../vn/vn-form.c:228 msgid "Gui" msgstr "Gui" -#: ../vn/vn-form.c:235 +#: ../vn/vn-form.c:229 msgid "The Gui object" msgstr "El objeto Gui" -#: ../vn/vn-form.c:242 +#: ../vn/vn-form.c:236 msgid "The connection used by the module" msgstr "La conexión empleada por el módulo" -#: ../vn/vn-form.c:248 +#: ../vn/vn-form.c:242 msgid "Module" msgstr "Módulo" -#: ../vn/vn-form.c:249 +#: ../vn/vn-form.c:243 msgid "The module" msgstr "El módulo" -#: ../vn/vn-login.c:276 ../vn/vn-login.c:278 +#: ../vn/vn-login.c:290 ../vn/vn-login.c:292 msgid "Login error" msgstr "Error de identificación" -#: ../vn/vn-login.c:336 +#: ../vn/vn-login.c:348 #, c-format msgid "Bad connection settings, please check it." msgstr "Conexión mal configurado, compruébelo por favor" -#: ../vn/vn-login.c:457 +#: ../vn/vn-login.c:477 msgid "Application id" msgstr "Id de la aplicación" -#: ../vn/vn-login.c:458 +#: ../vn/vn-login.c:478 msgid "The application identifier" msgstr "El identificador de la aplicación" @@ -725,17 +701,17 @@ msgstr "El parámetro en el que el campo escribe/lee su valor" #: ../vn/vn-field.c:533 msgid "The iterator used to get the field param" -msgstr "El iterador con el que se obtiene el parámetro" +msgstr "El Iterator con el que se obtiene el parámetro" #: ../vn/vn-field.c:540 msgid "The column name on the iterator" -msgstr "El nombre de la columna en el iterador" +msgstr "El nombre de la columna en el Iterator" #: ../vn/vn-field.c:554 msgid "Whether the field value is user editable" msgstr "Si el valor de campo puede ser editado por el usuario" -#: ../vn/vn-field.c:561 +#: ../vn/vn-field.c:561 ../vn/vn-column.c:409 msgid "Whether the field value can be of type GVN_TYPE_NULL" msgstr "Si el campo puede ser del tipo GVN_TYPE_NULL" @@ -749,31 +725,27 @@ msgstr "Dígitos" msgid "The number of decimal places to display." msgstr "El número de posiciones decimales que se muestran" -#: ../vn/field/vn-combo.c:328 ../vn/column/vn-column-combo.c:269 +#: ../vn/field/vn-combo.c:286 ../vn/column/vn-column-combo.c:300 msgid "Index column" msgstr "Columna índice" -#: ../vn/field/vn-combo.c:329 ../vn/column/vn-column-combo.c:270 +#: ../vn/field/vn-combo.c:287 ../vn/column/vn-column-combo.c:301 msgid "The column index of the model" msgstr "El índice de columna del modelo" -#: ../vn/field/vn-combo.c:335 ../vn/column/vn-column-combo.c:276 +#: ../vn/field/vn-combo.c:293 ../vn/column/vn-column-combo.c:307 msgid "Show column" msgstr "Mostrar columna" -#: ../vn/field/vn-combo.c:336 ../vn/column/vn-column-combo.c:277 +#: ../vn/field/vn-combo.c:294 ../vn/column/vn-column-combo.c:308 msgid "The column of the model shown by combo" msgstr "La columna del modelo que se mostrará en el combo" -#: ../vn/field/vn-combo.c:343 ../vn/column/vn-column-combo.c:284 -msgid "The model from which the combo takes the values shown in the list" -msgstr "El modelo del cual el combo tomará los valores mostrados en la lista" - -#: ../vn/field/vn-completion.c:322 +#: ../vn/field/vn-completion.c:325 msgid "Field" msgstr "Campo" -#: ../vn/field/vn-completion.c:323 +#: ../vn/field/vn-completion.c:326 msgid "The name of the field used for the search" msgstr "El nombre del campo usado para la búsqueda" @@ -790,49 +762,49 @@ msgstr "Cambiar fecha" msgid "Select the image" msgstr "Selecciona la imagen" -#: ../vn/field/vn-http-image.c:69 +#: ../vn/field/vn-http-image.c:70 msgid "Undefined error" msgstr "Error indefinido" -#: ../vn/field/vn-http-image.c:145 +#: ../vn/field/vn-http-image.c:142 msgid "File loader already set" msgstr "Ya se ha especificado un cargador de archivos" #. Se usará para subir imagenes y cambiar nombres, o abrir un menu contextual #. g_signal_connect (obj, "event", G_CALLBACK (vn_http_image_cb_event), obj); -#: ../vn/field/vn-http-image.c:184 +#: ../vn/field/vn-http-image.c:181 msgid "No image set" msgstr "Sin imagen" -#: ../vn/field/vn-http-image.c:210 +#: ../vn/field/vn-http-image.c:207 msgid "File loader" msgstr "Cargador de archivos" -#: ../vn/field/vn-http-image.c:211 +#: ../vn/field/vn-http-image.c:208 msgid "A DbFileLoader, used to download the files" msgstr "Un DbFileLoader que se usará para descargar los archivos" -#: ../vn/field/vn-http-image.c:218 +#: ../vn/field/vn-http-image.c:215 msgid "File path" msgstr "Ruta del archivo" -#: ../vn/field/vn-http-image.c:219 +#: ../vn/field/vn-http-image.c:216 msgid "The relative path to the image from file loader path" msgstr "La ruta relativa a la imagen desde la del cargador de archivos" -#: ../vn/field/vn-http-image.c:226 +#: ../vn/field/vn-http-image.c:223 msgid "Image bytes" msgstr "Bytes" -#: ../vn/field/vn-http-image.c:227 +#: ../vn/field/vn-http-image.c:224 msgid "A GBytes structure with the image data" msgstr "Una estructura GBytes con los datos de la imágen" -#: ../vn/vn-column.c:341 +#: ../vn/vn-column.c:388 msgid "The column index in the model" msgstr "El índice de la columna en el modelo" -#: ../vn/vn-column.c:355 +#: ../vn/vn-column.c:402 msgid "Whether the column values are editable" msgstr "Si el valor de campo puede ser editado por el usuario" @@ -844,15 +816,15 @@ msgstr "Tasa de subida" msgid "The acceleration rate when you hold down a button." msgstr "La tasa de aceleración cuando se mantiene apretado el botón." -#: ../vn/column/vn-column-image.c:484 +#: ../vn/column/vn-column-image.c:486 msgid "Base path from the host where the images will be downloaded" msgstr "La ruta base del servidor desde donde se descargarán las imágenes." -#: ../vn/column/vn-column-image.c:491 +#: ../vn/column/vn-column-image.c:493 msgid "Tooltip path" msgstr "Ruta del tooltip" -#: ../vn/column/vn-column-image.c:492 +#: ../vn/column/vn-column-image.c:494 msgid "" "Prefix for the path of the images to be shown in the tooltip. Starting after " "the path of the column and appending the name on each cell" @@ -861,11 +833,11 @@ msgstr "" "Empezando desde la ruta de la columna y añadiendo después el nombre de cada " "celda" -#: ../vn/column/vn-column-image.c:501 +#: ../vn/column/vn-column-image.c:503 msgid "Tooltip size" msgstr "Tamaño del tooltip" -#: ../vn/column/vn-column-image.c:502 +#: ../vn/column/vn-column-image.c:504 msgid "" "Size of the bigger side of the tooltip images, the another side will be " "scaled accordingly and smaller images won't be scaled" @@ -908,7 +880,7 @@ msgstr "Acceso" msgid "User:" msgstr "Usuario:" -#: ../vn/gui/login.glade.h:9 ../module/data/users.glade.h:8 +#: ../vn/gui/login.glade.h:9 ../module/data/users.glade.h:6 msgid "Password:" msgstr "Clave:" @@ -1022,86 +994,174 @@ msgctxt "View menu option" msgid "Tool_bar" msgstr "_Barra de herramientas" +#: ../glade/glade-db-model.c:121 +msgid "Create and set a model for a DbModelHolder" +msgstr "Crear y configurar un modelo para un DbModelHolder" + +#: ../glade/glade-db-model.c:153 +msgid "Model configuration" +msgstr "Configuración del Model" + +#: ../glade/glade-db-model.c:153 +msgid "DbModel properties configuration" +msgstr "Configuración de propiedades de DbModelo" + +#: ../glade/glade-db-model.c:238 +msgid "Select a DbModel for the property" +msgstr "Selecciona un DbModel para la propiedad" + +#: ../glade/glade-db-model.c:259 ../glade/glade-db-model.c:306 +msgid "New Model" +msgstr "Nuevo Modelo" + +#: ../glade/glade-db-model.c:301 +msgid "Edit Model" +msgstr "Editar Modelo" + +#: ../glade/glade-db-sql.c:27 +msgid "New SQL statement" +msgstr "Nueva consulta SQL" + +#: ../glade/glade-db-sql.c:59 +msgid "SQL Editor" +msgstr "Editor SQL" + +#: ../glade/glade-db-sql.c:174 +msgid "Open the SQL Editor" +msgstr "Abrir el Editor SQL" + #: ../module/data/users.glade.h:1 -msgid "User name:" -msgstr "Nombre de usuario:" - -#: ../module/data/users.glade.h:2 -msgid "Search" -msgstr "Buscar" - -#: ../module/data/users.glade.h:3 msgid "Identifier" msgstr "Identificador" -#: ../module/data/users.glade.h:5 +#: ../module/data/users.glade.h:3 msgid "MySQL User" msgstr "Usuario MySQL" -#: ../module/data/users.glade.h:6 +#: ../module/data/users.glade.h:4 msgid "Enabled" msgstr "Habilitado" -#: ../module/data/users.glade.h:7 +#: ../module/data/users.glade.h:5 msgid "Name:" msgstr "Nombre:" -#: ../module/data/users.glade.h:9 +#: ../module/data/users.glade.h:7 msgid "MySQL user:" msgstr "Usuario MySQL:" -#: ../module/data/users.glade.h:10 +#: ../module/data/users.glade.h:8 msgid "Enabled:" msgstr "Habilitado:" -#: ../module/data/users.glade.h:11 +#: ../module/data/users.glade.h:9 msgid "Identifier:" msgstr "Identificador:" -#: ../module/data/users.glade.h:12 +#: ../module/data/users.glade.h:10 msgid "UID:" msgstr "UID:" -#: ../module/data/users.glade.h:13 +#: ../module/data/users.glade.h:11 msgid "Main group:" msgstr "Grupo principal:" -#: ../module/data/users.glade.h:14 +#: ../module/data/users.glade.h:12 msgid "Last change:" msgstr "Último cambio:" -#: ../module/data/users.glade.h:15 +#: ../module/data/users.glade.h:13 msgid "Expires:" msgstr "Expira:" -#: ../module/data/users.glade.h:16 +#: ../module/data/users.glade.h:14 msgid "Account" msgstr "Cuenta" -#: ../module/data/users.glade.h:17 +#: ../module/data/users.glade.h:15 msgid "Alias" msgstr "Alias" -#: ../module/data/users.glade.h:18 +#: ../module/data/users.glade.h:16 msgid "Mail alias" msgstr "Alias de correo" -#: ../module/data/users.glade.h:19 +#: ../module/data/users.glade.h:17 msgid "Extension:" msgstr "Extensión:" -#: ../module/data/users.glade.h:20 +#: ../module/data/users.glade.h:18 msgid "Secret:" msgstr "Clave:" -#: ../module/data/users.glade.h:21 +#: ../module/data/users.glade.h:19 msgid "Call group:" msgstr "Call group:" -#: ../module/data/users.glade.h:22 +#: ../module/data/users.glade.h:20 msgid "SIP" msgstr "SIP" -#: ../module/data/users.glade.h:23 +#: ../module/data/users.glade.h:21 +msgid "Change password" +msgstr "Cambiar contraseña" + +#: ../module/data/users.glade.h:22 msgid "Repeat password:" msgstr "Repetir contraseña:" + +#: ../module/src/vn-users.c:60 +msgid "The password is too weak." +msgstr "La contraseña es demasiado débil." + +#: ../module/src/vn-users.c:75 +msgid "The password can't be empty." +msgstr "La contraseña no puede estar vacía." + +#: ../module/src/vn-users.c:77 +msgid "Passwords do not match." +msgstr "Las contraseñas no coinciden." + +#: ../module/data/consulter.glade.h:1 +msgid "Send" +msgstr "Enviar" + +#: ../module/data/consulter.glade.h:2 +msgid "Send the current query" +msgstr "Enviar la consulta actual" + +#: ../module/data/consulter.glade.h:3 +msgid "Clean" +msgstr "Limpiar" + +#: ../module/data/consulter.glade.h:4 +msgid "Clean the messages" +msgstr "Limpia los mensajes" + +#: ../module/data/consulter.glade.h:5 +msgid "_Consulter" +msgstr "_Consultor" + +#: ../module/data/consulter.glade.h:6 +msgid "Query:" +msgstr "Consulta:" + +#: ../module/data/consulter.glade.h:7 +msgid "Immediate changes" +msgstr "Cambios inmediatos" + +#: ../module/data/consulter.glade.h:8 +msgid "Start" +msgstr "Empezar" + +#: ../module/data/consulter.glade.h:9 +msgid "Commit" +msgstr "Efectuar" + +#: ../module/data/consulter.glade.h:10 +msgid "Rollback" +msgstr "Deshacer" + +#: ../module/src/vn-consulter.c:199 +msgid "Type or select a query" +msgstr "Escribe o selecciona la consulta" diff --git a/po/nl.po b/po/nl.po index 5985f0f..52a440e 100644 --- a/po/nl.po +++ b/po/nl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: hedera 1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-07-10 11:56+0200\n" +"POT-Creation-Date: 2013-10-08 09:59+0200\n" "PO-Revision-Date: 2012-10-09 11:38+0200\n" "Last-Translator: Alejandro T. Colombini Gómez \n" "Language-Team: Dutch\n" @@ -134,7 +134,7 @@ msgstr "" msgid "The master GvnParam of this parameter" msgstr "" -#: ../gvn/gvn-param.c:457 ../db/db-iterator.c:1070 +#: ../gvn/gvn-param.c:457 ../db/db-iterator.c:985 msgid "Mode" msgstr "" @@ -166,7 +166,7 @@ msgstr "" msgid "The type of the value" msgstr "" -#: ../gvn/gvn-param.c:485 ../vn/vn-field.c:553 ../vn/vn-column.c:354 +#: ../gvn/gvn-param.c:485 ../vn/vn-field.c:553 ../vn/vn-column.c:401 msgid "Editable" msgstr "" @@ -174,7 +174,7 @@ msgstr "" msgid "Whether the param value can be modified" msgstr "" -#: ../gvn/gvn-param.c:492 ../vn/vn-field.c:560 +#: ../gvn/gvn-param.c:492 ../vn/vn-field.c:560 ../vn/vn-column.c:408 msgid "Null" msgstr "" @@ -215,9 +215,7 @@ msgstr "" msgid "The value" msgstr "" -#: ../sql/sql-string.c:198 ../db/db-iterator.c:1063 ../db/db-model.c:3411 -#: ../db/db-request.c:466 ../vn/field/vn-combo.c:356 -#: ../vn/field/vn-completion.c:315 ../vn/column/vn-column-combo.c:297 +#: ../sql/sql-string.c:198 ../db/db-model.c:3459 ../db/db-request.c:461 msgid "SQL" msgstr "" @@ -225,110 +223,90 @@ msgstr "" msgid "An arbitrary SQL string" msgstr "" -#: ../plugin/mysql/db-mysql.c:68 ../plugin/pg/db-pg.c:76 +#: ../plugin/mysql/db-mysql.c:68 ../plugin/pg/db-pg.c:85 #, c-format msgid "Can't allocate the needed memory" msgstr "" -#: ../db/db-iterator.c:284 -msgid "DbIterator: Can't reassign the 'model' property" -msgstr "" - -#: ../db/db-iterator.c:942 -msgid "DbIterator: Can't set the 'conn' property because model isn't set" -msgstr "" - -#: ../db/db-iterator.c:1049 ../db/db-calc.c:329 ../vn/field/vn-combo.c:342 -#: ../vn/column/vn-column-combo.c:283 -msgid "Model" -msgstr "" - -#: ../db/db-iterator.c:1050 -msgid "The DbModel handled by the iterator" -msgstr "" - -#: ../db/db-iterator.c:1056 ../db/db-model.c:3395 ../db/db-request.c:459 -#: ../vn/vn-gui.c:1531 ../vn/vn-form.c:241 ../vn/field/vn-combo.c:349 -#: ../vn/field/vn-completion.c:308 ../vn/column/vn-column-combo.c:290 -msgid "Connection" -msgstr "" - -#: ../db/db-iterator.c:1057 ../vn/field/vn-combo.c:350 -#: ../vn/field/vn-completion.c:309 ../vn/column/vn-column-combo.c:291 -msgid "The connection used by the model" -msgstr "" - -#: ../db/db-iterator.c:1064 ../vn/field/vn-combo.c:357 -#: ../vn/field/vn-completion.c:316 ../vn/column/vn-column-combo.c:298 -msgid "The SQL query used to create the model" -msgstr "" - -#: ../db/db-iterator.c:1071 +#: ../db/db-iterator.c:986 msgid "The mode in which the iterator is working" msgstr "" -#: ../db/db-iterator.c:1078 +#: ../db/db-iterator.c:993 msgid "Remember selection" msgstr "" -#: ../db/db-iterator.c:1079 +#: ../db/db-iterator.c:994 msgid "Wether to rememeber the selection when model is refreshed" msgstr "" -#: ../db/db-model.c:3396 +#: ../db/db-model.c:3443 ../db/db-request.c:454 ../vn/vn-gui.c:1531 +#: ../vn/vn-form.c:235 +msgid "Connection" +msgstr "" + +#: ../db/db-model.c:3444 msgid "The DbConn that manages the connection to the database" msgstr "" -#: ../db/db-model.c:3403 ../db/db-request.c:473 +#: ../db/db-model.c:3451 ../db/db-request.c:468 msgid "Statement" msgstr "" -#: ../db/db-model.c:3404 +#: ../db/db-model.c:3452 msgid "The statement which retrieves the data" msgstr "" -#: ../db/db-model.c:3412 +#: ../db/db-model.c:3460 msgid "" "Depending on the \"use-file\" property this will be the path to a file with " "queries for the model or a SQL string" msgstr "" -#: ../db/db-model.c:3421 +#: ../db/db-model.c:3469 msgid "Use file" msgstr "" -#: ../db/db-model.c:3422 +#: ../db/db-model.c:3470 msgid "" "If this is set to TRUE, the \"sql\" property will hold the name of a file " "containing a query, if set to FALSE, \"sql\" is used as an SQL string" msgstr "" -#: ../db/db-model.c:3431 +#: ../db/db-model.c:3479 msgid "Main Table" msgstr "" -#: ../db/db-model.c:3432 +#: ../db/db-model.c:3480 msgid "The main table of the model" msgstr "" -#: ../db/db-model.c:3439 +#: ../db/db-model.c:3487 msgid "Update flags" msgstr "" -#: ../db/db-model.c:3440 +#: ../db/db-model.c:3488 msgid "The flags that indicate how a model can be modified" msgstr "" -#: ../db/db-model.c:3448 +#: ../db/db-model.c:3496 msgid "Result position" msgstr "" -#: ../db/db-model.c:3449 +#: ../db/db-model.c:3497 msgid "" "The position where the query that will fill the model will be placed in a " "multi-query" msgstr "" +#: ../db/db-model-holder.c:70 ../db/db-calc.c:329 +msgid "Model" +msgstr "" + +#: ../db/db-model-holder.c:71 +msgid "The model used by the holder" +msgstr "" + #: ../db/db-calc.c:330 msgid "The model where the operations will be applied" msgstr "" @@ -365,121 +343,121 @@ msgstr "" msgid "A column to apply the operations over it" msgstr "" -#: ../db/db-param.c:243 ../vn/vn-grid.c:349 ../vn/vn-field.c:532 +#: ../db/db-param.c:251 ../vn/vn-grid.c:357 ../vn/vn-field.c:532 msgid "Iterator" msgstr "" -#: ../db/db-param.c:244 +#: ../db/db-param.c:252 msgid "The iterator owner of param" msgstr "" -#: ../db/db-param.c:250 ../vn/vn-column.c:340 +#: ../db/db-param.c:258 ../vn/vn-column.c:387 msgid "Column index" msgstr "" -#: ../db/db-param.c:251 +#: ../db/db-param.c:259 msgid "The referenced column index" msgstr "" -#: ../db/db-param.c:257 ../vn/vn-field.c:539 ../vn/vn-column.c:347 +#: ../db/db-param.c:265 ../vn/vn-field.c:539 ../vn/vn-column.c:394 msgid "Column name" msgstr "" -#: ../db/db-param.c:258 ../vn/vn-column.c:348 +#: ../db/db-param.c:266 ../vn/vn-column.c:395 msgid "The referenced column name" msgstr "" -#: ../db/db-conn.c:279 ../db/db-conn.c:284 +#: ../db/db-conn.c:282 ../db/db-conn.c:287 #, c-format msgid "Can't load DbPlugin '%s': %s" msgstr "" -#: ../db/db-conn.c:297 +#: ../db/db-conn.c:300 #, c-format msgid "Plugin can't be loaded" msgstr "" -#: ../db/db-conn.c:413 +#: ../db/db-conn.c:416 #, c-format msgid "Can't open a new connection, it's already open." msgstr "" -#: ../db/db-conn.c:555 +#: ../db/db-conn.c:558 #, c-format msgid "The query is empty." msgstr "" -#: ../db/db-conn.c:1060 +#: ../db/db-conn.c:1037 msgid "Plugin" msgstr "" -#: ../db/db-conn.c:1061 +#: ../db/db-conn.c:1038 msgid "The name of the plugin" msgstr "" -#: ../db/db-conn.c:1067 +#: ../db/db-conn.c:1044 msgid "Query path" msgstr "" -#: ../db/db-conn.c:1068 +#: ../db/db-conn.c:1045 msgid "The path where query files are located" msgstr "" -#: ../db/db-conn.c:1074 ../db/db-file-loader.c:724 -#: ../vn/column/vn-column-image.c:475 +#: ../db/db-conn.c:1051 ../db/db-file-loader.c:724 +#: ../vn/column/vn-column-image.c:477 msgid "Host" msgstr "" -#: ../db/db-conn.c:1075 +#: ../db/db-conn.c:1052 msgid "The host name to connect to" msgstr "" -#: ../db/db-conn.c:1081 ../module/data/users.glade.h:4 +#: ../db/db-conn.c:1058 ../module/data/users.glade.h:2 msgid "User" msgstr "" -#: ../db/db-conn.c:1082 +#: ../db/db-conn.c:1059 msgid "The user name" msgstr "" -#: ../db/db-conn.c:1088 +#: ../db/db-conn.c:1065 msgid "DB name" msgstr "" -#: ../db/db-conn.c:1089 +#: ../db/db-conn.c:1066 msgid "The default schema" msgstr "" -#: ../db/db-request.c:315 +#: ../db/db-request.c:311 #, c-format msgid "The request was canceled" msgstr "" -#: ../db/db-request.c:460 +#: ../db/db-request.c:455 msgid "The connection used to render and execute the query" msgstr "" -#: ../db/db-request.c:467 +#: ../db/db-request.c:462 msgid "The SQL query to execute" msgstr "" -#: ../db/db-request.c:474 +#: ../db/db-request.c:469 msgid "The statement to execute" msgstr "" -#: ../db/db-request.c:480 +#: ../db/db-request.c:475 msgid "Result" msgstr "" -#: ../db/db-request.c:481 +#: ../db/db-request.c:476 msgid "The result data of the query" msgstr "" -#: ../db/db-request.c:487 +#: ../db/db-request.c:482 msgid "Error" msgstr "" -#: ../db/db-request.c:488 +#: ../db/db-request.c:483 msgid "The GError, if an error ocurred" msgstr "" @@ -493,11 +471,11 @@ msgstr "" msgid "Unknown content length of file %s" msgstr "" -#: ../db/db-file-loader.c:725 ../vn/column/vn-column-image.c:476 +#: ../db/db-file-loader.c:725 ../vn/column/vn-column-image.c:478 msgid "The host web server name to get the images" msgstr "" -#: ../db/db-file-loader.c:732 ../vn/column/vn-column-image.c:483 +#: ../db/db-file-loader.c:732 ../vn/column/vn-column-image.c:485 msgid "Path" msgstr "" @@ -559,7 +537,7 @@ msgstr "" msgid "Connection closed" msgstr "" -#: ../vn/vn-gui.c:987 ../vn/field/vn-http-image.c:118 +#: ../vn/vn-gui.c:987 ../vn/field/vn-http-image.c:116 msgid "Loading" msgstr "" @@ -579,17 +557,17 @@ msgstr "" msgid "The application handler for the entire program" msgstr "" -#: ../vn/vn-model.c:303 +#: ../vn/vn-model.c:317 #, c-format msgid "Function vn_model_set_sort_func not implemented" msgstr "" -#: ../vn/vn-model.c:310 +#: ../vn/vn-model.c:324 #, c-format msgid "Function vn_model_set_default_sort_func not implemented" msgstr "" -#: ../vn/vn-grid.c:350 +#: ../vn/vn-grid.c:358 msgid "The iterator used by VnGrid" msgstr "" @@ -653,48 +631,48 @@ msgstr "" msgid "Sets if it is used to handle a iterator with a single record" msgstr "" -#: ../vn/vn-form.c:227 +#: ../vn/vn-form.c:221 msgid "Name" msgstr "" -#: ../vn/vn-form.c:228 +#: ../vn/vn-form.c:222 msgid "The form name" msgstr "" -#: ../vn/vn-form.c:234 +#: ../vn/vn-form.c:228 msgid "Gui" msgstr "" -#: ../vn/vn-form.c:235 +#: ../vn/vn-form.c:229 msgid "The Gui object" msgstr "" -#: ../vn/vn-form.c:242 +#: ../vn/vn-form.c:236 msgid "The connection used by the module" msgstr "" -#: ../vn/vn-form.c:248 +#: ../vn/vn-form.c:242 msgid "Module" msgstr "" -#: ../vn/vn-form.c:249 +#: ../vn/vn-form.c:243 msgid "The module" msgstr "" -#: ../vn/vn-login.c:276 ../vn/vn-login.c:278 +#: ../vn/vn-login.c:290 ../vn/vn-login.c:292 msgid "Login error" msgstr "" -#: ../vn/vn-login.c:336 +#: ../vn/vn-login.c:348 #, c-format msgid "Bad connection settings, please check it." msgstr "" -#: ../vn/vn-login.c:457 +#: ../vn/vn-login.c:477 msgid "Application id" msgstr "" -#: ../vn/vn-login.c:458 +#: ../vn/vn-login.c:478 msgid "The application identifier" msgstr "" @@ -722,7 +700,7 @@ msgstr "" msgid "Whether the field value is user editable" msgstr "" -#: ../vn/vn-field.c:561 +#: ../vn/vn-field.c:561 ../vn/vn-column.c:409 msgid "Whether the field value can be of type GVN_TYPE_NULL" msgstr "" @@ -736,31 +714,27 @@ msgstr "" msgid "The number of decimal places to display." msgstr "" -#: ../vn/field/vn-combo.c:328 ../vn/column/vn-column-combo.c:269 +#: ../vn/field/vn-combo.c:286 ../vn/column/vn-column-combo.c:300 msgid "Index column" msgstr "" -#: ../vn/field/vn-combo.c:329 ../vn/column/vn-column-combo.c:270 +#: ../vn/field/vn-combo.c:287 ../vn/column/vn-column-combo.c:301 msgid "The column index of the model" msgstr "" -#: ../vn/field/vn-combo.c:335 ../vn/column/vn-column-combo.c:276 +#: ../vn/field/vn-combo.c:293 ../vn/column/vn-column-combo.c:307 msgid "Show column" msgstr "" -#: ../vn/field/vn-combo.c:336 ../vn/column/vn-column-combo.c:277 +#: ../vn/field/vn-combo.c:294 ../vn/column/vn-column-combo.c:308 msgid "The column of the model shown by combo" msgstr "" -#: ../vn/field/vn-combo.c:343 ../vn/column/vn-column-combo.c:284 -msgid "The model from which the combo takes the values shown in the list" -msgstr "" - -#: ../vn/field/vn-completion.c:322 +#: ../vn/field/vn-completion.c:325 msgid "Field" msgstr "" -#: ../vn/field/vn-completion.c:323 +#: ../vn/field/vn-completion.c:326 msgid "The name of the field used for the search" msgstr "" @@ -777,49 +751,49 @@ msgstr "" msgid "Select the image" msgstr "" -#: ../vn/field/vn-http-image.c:69 +#: ../vn/field/vn-http-image.c:70 msgid "Undefined error" msgstr "" -#: ../vn/field/vn-http-image.c:145 +#: ../vn/field/vn-http-image.c:142 msgid "File loader already set" msgstr "" #. Se usará para subir imagenes y cambiar nombres, o abrir un menu contextual #. g_signal_connect (obj, "event", G_CALLBACK (vn_http_image_cb_event), obj); -#: ../vn/field/vn-http-image.c:184 +#: ../vn/field/vn-http-image.c:181 msgid "No image set" msgstr "" -#: ../vn/field/vn-http-image.c:210 +#: ../vn/field/vn-http-image.c:207 msgid "File loader" msgstr "" -#: ../vn/field/vn-http-image.c:211 +#: ../vn/field/vn-http-image.c:208 msgid "A DbFileLoader, used to download the files" msgstr "" -#: ../vn/field/vn-http-image.c:218 +#: ../vn/field/vn-http-image.c:215 msgid "File path" msgstr "" -#: ../vn/field/vn-http-image.c:219 +#: ../vn/field/vn-http-image.c:216 msgid "The relative path to the image from file loader path" msgstr "" -#: ../vn/field/vn-http-image.c:226 +#: ../vn/field/vn-http-image.c:223 msgid "Image bytes" msgstr "" -#: ../vn/field/vn-http-image.c:227 +#: ../vn/field/vn-http-image.c:224 msgid "A GBytes structure with the image data" msgstr "" -#: ../vn/vn-column.c:341 +#: ../vn/vn-column.c:388 msgid "The column index in the model" msgstr "" -#: ../vn/vn-column.c:355 +#: ../vn/vn-column.c:402 msgid "Whether the column values are editable" msgstr "" @@ -831,25 +805,25 @@ msgstr "" msgid "The acceleration rate when you hold down a button." msgstr "" -#: ../vn/column/vn-column-image.c:484 +#: ../vn/column/vn-column-image.c:486 msgid "Base path from the host where the images will be downloaded" msgstr "" -#: ../vn/column/vn-column-image.c:491 +#: ../vn/column/vn-column-image.c:493 msgid "Tooltip path" msgstr "" -#: ../vn/column/vn-column-image.c:492 +#: ../vn/column/vn-column-image.c:494 msgid "" "Prefix for the path of the images to be shown in the tooltip. Starting after " "the path of the column and appending the name on each cell" msgstr "" -#: ../vn/column/vn-column-image.c:501 +#: ../vn/column/vn-column-image.c:503 msgid "Tooltip size" msgstr "" -#: ../vn/column/vn-column-image.c:502 +#: ../vn/column/vn-column-image.c:504 msgid "" "Size of the bigger side of the tooltip images, the another side will be " "scaled accordingly and smaller images won't be scaled" @@ -889,7 +863,7 @@ msgstr "" msgid "User:" msgstr "" -#: ../vn/gui/login.glade.h:9 ../module/data/users.glade.h:8 +#: ../vn/gui/login.glade.h:9 ../module/data/users.glade.h:6 msgid "Password:" msgstr "" @@ -989,86 +963,174 @@ msgctxt "View menu option" msgid "Tool_bar" msgstr "" +#: ../glade/glade-db-model.c:121 +msgid "Create and set a model for a DbModelHolder" +msgstr "" + +#: ../glade/glade-db-model.c:153 +msgid "Model configuration" +msgstr "" + +#: ../glade/glade-db-model.c:153 +msgid "DbModel properties configuration" +msgstr "" + +#: ../glade/glade-db-model.c:238 +msgid "Select a DbModel for the property" +msgstr "" + +#: ../glade/glade-db-model.c:259 ../glade/glade-db-model.c:306 +msgid "New Model" +msgstr "" + +#: ../glade/glade-db-model.c:301 +msgid "Edit Model" +msgstr "" + +#: ../glade/glade-db-sql.c:27 +msgid "New SQL statement" +msgstr "" + +#: ../glade/glade-db-sql.c:59 +msgid "SQL Editor" +msgstr "" + +#: ../glade/glade-db-sql.c:174 +msgid "Open the SQL Editor" +msgstr "" + #: ../module/data/users.glade.h:1 -msgid "User name:" -msgstr "" - -#: ../module/data/users.glade.h:2 -msgid "Search" -msgstr "" - -#: ../module/data/users.glade.h:3 msgid "Identifier" msgstr "" -#: ../module/data/users.glade.h:5 +#: ../module/data/users.glade.h:3 msgid "MySQL User" msgstr "" -#: ../module/data/users.glade.h:6 +#: ../module/data/users.glade.h:4 msgid "Enabled" msgstr "" -#: ../module/data/users.glade.h:7 +#: ../module/data/users.glade.h:5 msgid "Name:" msgstr "" -#: ../module/data/users.glade.h:9 +#: ../module/data/users.glade.h:7 msgid "MySQL user:" msgstr "" -#: ../module/data/users.glade.h:10 +#: ../module/data/users.glade.h:8 msgid "Enabled:" msgstr "" -#: ../module/data/users.glade.h:11 +#: ../module/data/users.glade.h:9 msgid "Identifier:" msgstr "" -#: ../module/data/users.glade.h:12 +#: ../module/data/users.glade.h:10 msgid "UID:" msgstr "" -#: ../module/data/users.glade.h:13 +#: ../module/data/users.glade.h:11 msgid "Main group:" msgstr "" -#: ../module/data/users.glade.h:14 +#: ../module/data/users.glade.h:12 msgid "Last change:" msgstr "" -#: ../module/data/users.glade.h:15 +#: ../module/data/users.glade.h:13 msgid "Expires:" msgstr "" -#: ../module/data/users.glade.h:16 +#: ../module/data/users.glade.h:14 msgid "Account" msgstr "" -#: ../module/data/users.glade.h:17 +#: ../module/data/users.glade.h:15 msgid "Alias" msgstr "" -#: ../module/data/users.glade.h:18 +#: ../module/data/users.glade.h:16 msgid "Mail alias" msgstr "" -#: ../module/data/users.glade.h:19 +#: ../module/data/users.glade.h:17 msgid "Extension:" msgstr "" -#: ../module/data/users.glade.h:20 +#: ../module/data/users.glade.h:18 msgid "Secret:" msgstr "" -#: ../module/data/users.glade.h:21 +#: ../module/data/users.glade.h:19 msgid "Call group:" msgstr "" -#: ../module/data/users.glade.h:22 +#: ../module/data/users.glade.h:20 msgid "SIP" msgstr "" -#: ../module/data/users.glade.h:23 +#: ../module/data/users.glade.h:21 +msgid "Change password" +msgstr "" + +#: ../module/data/users.glade.h:22 msgid "Repeat password:" msgstr "" + +#: ../module/src/vn-users.c:60 +msgid "The password is too weak." +msgstr "" + +#: ../module/src/vn-users.c:75 +msgid "The password can't be empty." +msgstr "" + +#: ../module/src/vn-users.c:77 +msgid "Passwords do not match." +msgstr "" + +#: ../module/data/consulter.glade.h:1 +msgid "Send" +msgstr "" + +#: ../module/data/consulter.glade.h:2 +msgid "Send the current query" +msgstr "" + +#: ../module/data/consulter.glade.h:3 +msgid "Clean" +msgstr "" + +#: ../module/data/consulter.glade.h:4 +msgid "Clean the messages" +msgstr "" + +#: ../module/data/consulter.glade.h:5 +msgid "_Consulter" +msgstr "" + +#: ../module/data/consulter.glade.h:6 +msgid "Query:" +msgstr "" + +#: ../module/data/consulter.glade.h:7 +msgid "Immediate changes" +msgstr "" + +#: ../module/data/consulter.glade.h:8 +msgid "Start" +msgstr "" + +#: ../module/data/consulter.glade.h:9 +msgid "Commit" +msgstr "" + +#: ../module/data/consulter.glade.h:10 +msgid "Rollback" +msgstr "" + +#: ../module/src/vn-consulter.c:199 +msgid "Type or select a query" +msgstr "" diff --git a/sql/Makefile.am b/sql/Makefile.am index 66d2c13..a859e79 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -5,23 +5,15 @@ 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-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 \ @@ -42,20 +34,12 @@ 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-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 \ @@ -69,7 +53,7 @@ libsql_la_SOURCES = \ sql-string.c \ sql-target.c \ sql-render.c \ - $(top_builddir)/sql/sql-parser.c + $(top_srcdir)/sql/sql-parser.c pkgconfig_DATA = sql.pc diff --git a/sql/parser/Makefile.am b/sql/parser/Makefile.am index da1df2b..917c924 100644 --- a/sql/parser/Makefile.am +++ b/sql/parser/Makefile.am @@ -1,6 +1,6 @@ include $(top_srcdir)/Makefile.decl -PARSER = $(top_builddir)/sql/sql-parser.c +PARSER = $(top_srcdir)/sql/sql-parser.c DIR = $(top_srcdir)/sql/parser TMPL = $(DIR)/lempar-tmpl.c diff --git a/sql/parser/gram.y b/sql/parser/gram.y index 07fac6e..87c9f26 100644 --- a/sql/parser/gram.y +++ b/sql/parser/gram.y @@ -17,35 +17,23 @@ * along with this program. If not, see . */ - #include - #include - #include - #include "gram.h" +#include +#include +#include +#include "gram.h" - typedef struct - { - SqlObject * object; - gchar * string; - gchar * current; - gboolean error; - } - ParseState; - - static inline SqlList * list_add (gpointer item, SqlList * list) - { - sql_list_add (list, item); - return list; - } - - static inline SqlList * list_new (gpointer item, GType gtype) - { - SqlList * list = sql_list_new (gtype); - return list_add (item, list); - } +typedef struct +{ + SqlObject * object; + gchar * string; + gchar * current; + gboolean error; +} +ParseState; } -%token_type {gchar *} -%token_destructor {g_free ($$);} +%token_type { gchar * } +%token_destructor { g_free ($$); } %token_prefix SQL_PARSER_ // Return pointer @@ -76,6 +64,8 @@ ,"Parser stack overflow. Parsing terminated.\n"); } +%parse_accept {} + // Operator precedence %left UNION EXCEPT. %left INSERSECT. @@ -100,44 +90,47 @@ start ::= multi_stmt (A). state->object = SQL_OBJECT (A); } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Multi statement - +// SqlMultiStmt %type multi_stmt {SqlStmt *} -multi_stmt(A) ::= stmt_list(stmts). -{ - guint len = sql_list_length (stmts); - if (len == 1) +multi_stmt(multi) ::= stmt_list(stmt). +{ + gint len = g_slist_length (stmt); + + if (len > 1) { - A = sql_list_get (stmts, 0); - g_object_unref (g_object_ref_sink (stmts)); + multi = SQL_STMT (sql_multi_stmt_new ()); + GSList * n; + for (n = stmt; n; n = n->next) + sql_multi_stmt_add_stmt (SQL_MULTI_STMT (multi), n->data); } + else if (len != 0) + multi = SQL_STMT (stmt->data); else - A = g_object_new (SQL_TYPE_MULTI_STMT, "stmts", stmts, NULL); + multi = NULL; + + g_slist_free (stmt); } -%type stmt_list {SqlList *} -stmt_list(A) ::= stmt(X). { A = list_new (X, SQL_TYPE_STMT); } -stmt_list(A) ::= stmt(X) SC. { A = list_new (X, SQL_TYPE_STMT); } -stmt_list(A) ::= stmt(X) SC stmt_list(B). { A = list_add (X, B); } - -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Statemet +%type stmt_list {GSList *} +%destructor stmt_list {g_slist_free ($$);} +stmt_list(A) ::= stmt(X) SC stmt_list(B). { A = g_slist_prepend (B, X); } +stmt_list(A) ::= stmt(X). { A = g_slist_prepend (A, X); } +stmt_list(A) ::= stmt(X) SC. { A = g_slist_prepend (A, X); } +// SqlStmt %type stmt {SqlStmt *} -stmt(A) ::= select_stmt(X). { A = X; } -stmt(A) ::= delete_stmt(X). { A = X; } -stmt(A) ::= update_stmt(X). { A = X; } -stmt(A) ::= insert_stmt(X). { A = X; } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Select +// SqlSelect +stmt(stmt) ::= multi_select(select). { stmt = SQL_STMT (select); } -%type select_stmt {SqlStmt *} -select_stmt(A) ::= select_stmt(B) set_op(type) simple_select(X). +%type multi_select {SqlSelect *} +multi_select(A) ::= multi_select(B) set_op(type) select_stmt(X). { - g_object_set (B, "type", type, "next", X, NULL); + sql_select_set_next (B, X, type); A = B; } -select_stmt(A) ::= simple_select(X). { A = X; } +multi_select(A) ::= select_stmt(X). { A = X; } %type set_op {SqlSelectType} set_op(A) ::= UNION ANY. { A = SQL_SELECT_UNION_ANY; } @@ -146,35 +139,73 @@ set_op(A) ::= UNION. { A = SQL_SELECT_UNION_ALL; } set_op(A) ::= INTERSECT. { A = SQL_SELECT_INTERSECT; } set_op(A) ::= EXCEPT. { A = SQL_SELECT_EXCEPT; } -%type simple_select {SqlStmt *} -simple_select(A) ::= LP simple_select(X) RP. { A = X; } -simple_select(A) ::= SELECT - distinct(distinct) - select_field_list(fields) - from(targets) - where(where) - group(group) having(having) - order(order) - limit(limit). +%type select_stmt {SqlSelect *} +select_stmt(A) ::= LP select_stmt(X) RP. { A = X; } +select_stmt(select) ::= SELECT distinct(distinct) select_expr(expr_l) + from(target_l) + where(where) + group(group_l) having(having) + order(order_l) orderway(way) + limit(limit). { - A = g_object_new (SQL_TYPE_SELECT - ,"distinct" ,distinct - ,"fields" ,fields - ,"targets" ,targets - ,"where" ,where - ,"group" ,group - ,"having" ,having - ,"having" ,having - ,"order" ,order - ,NULL - ); + GSList * n; + + select = sql_select_new (); + + sql_select_set_distinct (select, distinct); + + for (n = expr_l; n; n = n->next) + { + SelectExpr * se = n->data; + sql_select_add_expr (select, se->expr); + + if (se->alias) + { + sql_select_set_alias (select, se->expr, se->alias); + g_free (se->alias); + } + + g_free (se); + } + + g_slist_free (expr_l); + + for (n = target_l; n; n = n->next) + sql_dml_add_target (SQL_DML (select), n->data); + + g_slist_free (target_l); + + if (where) + sql_dml_set_where (SQL_DML (select), where); + + if (group_l) + { + for (n = group_l; n; n = n->next) + sql_select_add_group (select, n->data); + + g_slist_free (group_l); + + if (having) + sql_select_set_having (select, having); + } + + if (order_l) + { + for (n = order_l; n; n = n->next) + sql_select_add_order (select, n->data, way); + + g_slist_free (order_l); + } if (limit) - g_object_set (A - ,"limit-offset" ,limit->offset - ,"limit-count" ,limit->count - ,NULL + { + sql_select_set_limit (select + ,limit[0] ? (guint) atoi (limit[0]): 0 + ,limit[1] ? (guint) atoi (limit[1]): 0 ); + + g_strfreev (limit); + } } %type distinct {gboolean} @@ -182,21 +213,43 @@ distinct(A) ::= DISTINCT. { A = TRUE; } distinct(A) ::= ALL. { A = FALSE; } distinct(A) ::= . { A = FALSE; } -%type select_field {SqlSelectField *} -select_field(A) ::= expr(X). - { A = g_object_new (SQL_TYPE_SELECT_FIELD, "expr", X, NULL); } -select_field(A) ::= expr(X) alias(Y). - { A = g_object_new (SQL_TYPE_SELECT_FIELD, "expr", X, "alias", Y, NULL); } +// Expressions with optional alias, only found in the SELECT clause +%type select_expr {GSList *} +%include +{ +typedef struct +{ + SqlExpr * expr; + gchar * alias; +} +SelectExpr; -%type select_field_list {SqlList *} -select_field_list(A) ::= select_field(X). { A = list_new (X, SQL_TYPE_SELECT_FIELD); } -select_field_list(A) ::= select_field_list(B) CM select_field(X). { A = list_add (X, B); } +static inline GSList * sql_parser_alias_expr_add + (GSList * list, SqlExpr * expr, gchar * alias) +{ + SelectExpr * sexpr = g_new (SelectExpr, 1); + sexpr->expr = expr; + sexpr->alias = alias; + return g_slist_append (list, sexpr); +} +} +%destructor select_expr {g_slist_free_full ($$, (GDestroyNotify) g_free);} +select_expr(A) ::= select_expr(B) CM expr(X). + { A = sql_parser_alias_expr_add (B, X, NULL); } +select_expr(A) ::= select_expr(B) CM expr(X) alias(Y). + { A = sql_parser_alias_expr_add (B, X, Y); } +select_expr(A) ::= expr(X). + { A = sql_parser_alias_expr_add (A, X, NULL); } +select_expr(A) ::= expr(X) alias(Y). + { A = sql_parser_alias_expr_add (A, X, Y); } -%type from {SqlList *} +%type from {GSList *} +%destructor from {g_slist_free ($$);} from(A) ::= FROM target_list(X). { A = X; } from(A) ::= . { A = NULL; } -%type group {SqlList *} +%type group {GSList *} +%destructor group {g_slist_free ($$);} group(A) ::= GROUP expr_list(X). { A = X; } group(A) ::= . { A = NULL; } @@ -204,216 +257,235 @@ group(A) ::= . { A = NULL; } having(A) ::= HAVING expr(X). { A = X; } having(A) ::= . { A = NULL; } -%type order {SqlList *} -order(A) ::= ORDER order_list (X). { A = X; } +%type order {GSList *} +%destructor order {g_slist_free ($$);} +order(A) ::= ORDER expr_list (X). { A = X; } order(A) ::= . { A = NULL; } -%type order_list {SqlList *} -order_list(A) ::= order_expr(X). { A = list_new (X, SQL_TYPE_SELECT_ORDER); } -order_list(A) ::= order_list(B) CM order_expr(X). { A = list_add (X, B); } +%type orderway {SqlOrderWay} +orderway(A) ::= ASC. { A = SQL_ORDER_ASC; } +orderway(A) ::= DESC. { A = SQL_ORDER_DESC; } +orderway(A) ::= . { A = SQL_ORDER_ASC; } -%type order_expr {SqlSelectOrder *} -order_expr(A) ::= expr(X) order_way(Y). { A = g_object_new (SQL_TYPE_SELECT_ORDER, "expr", X, "way", Y, NULL); } - -%type order_way {SqlSelectOrderWay} -order_way(A) ::= ASC. { A = SQL_SELECT_ORDER_ASC; } -order_way(A) ::= DESC. { A = SQL_SELECT_ORDER_DESC; } -order_way(A) ::= . { A = SQL_SELECT_ORDER_ASC; } - -%type limit {SelectLimit *} -%destructor limit {g_free ($$);} +%type limit {gchar **} %include { - typedef struct - { - guint offset; - guint count; - } - SelectLimit; - - static inline SelectLimit * create_limit (gchar * offset, gchar * count) - { - SelectLimit * limit = g_new (SelectLimit, 1); - limit->offset = offset ? atoi (offset) : 0; - limit->count = count ? atoi (count) : 0; - return limit; - } -} -limit(A) ::= LIMIT INTEGER(X). { A = create_limit (NULL, X); } -limit(A) ::= OFFSET INTEGER(Y). { A = create_limit (Y, NULL); } -limit(A) ::= LIMIT INTEGER(X) OFFSET INTEGER(Y). { A = create_limit (Y, X); } -limit(A) ::= LIMIT INTEGER(X) CM INTEGER(Y). { A = create_limit (Y, X); } -limit(A) ::= . { A = NULL; } - -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Delete - -%type delete_stmt {SqlStmt *} -delete_stmt(A) ::= DELETE table_list(targets) del_using(tables) where(where). +gchar ** sql_parser_limit (gchar * limit, gchar * offset) { - A = g_object_new (SQL_TYPE_DELETE - ,"targets" ,targets - ,"tables" ,tables - ,"where" ,where - ,NULL - ); + gchar ** r = g_new (gchar *, 3); + r[0] = limit; + r[1] = offset; + r[2] = NULL; + return r; +} +} +limit(A) ::= LIMIT INTEGER(X). { A = sql_parser_limit (X, NULL); } +limit(A) ::= OFFSET INTEGER(Y). { A = sql_parser_limit (NULL, Y); } +limit(A) ::= LIMIT INTEGER(X) + OFFSET INTEGER(Y). { A = sql_parser_limit (X, Y); } +limit(A) ::= LIMIT INTEGER(X) + CM INTEGER(Y). { A = sql_parser_limit (Y, X); } +limit(A) ::= . { A = NULL; } + +// SqlDelete +stmt(stmt) ::= delete_stmt(delete). { stmt = SQL_STMT (delete); } + +%type delete_stmt {SqlDelete *} +delete_stmt(delete) ::= DELETE table_list(target) del_using(using) where(where). +{ + GSList * n; + delete = sql_delete_new (); + + for (n = target; n; n = n->next) + sql_dml_add_target (SQL_DML (delete), n->data); + g_slist_free (target); + + for (n = using; n; n = n->next) + sql_delete_add_table (delete, n->data); + g_slist_free (using); + + if (where) + sql_dml_set_where (SQL_DML (delete), where); } -%type table_list {SqlList *} -table_list(A) ::= table(X). { A = list_new (X, SQL_TYPE_TABLE); } -table_list(A) ::= table_list(B) CM table(X). { A = list_add (X, B); } +%type table_list {GSList *} +%destructor table_list {g_slist_free ($$);} +table_list(A) ::= table_list(B) CM table(X). { A = g_slist_append (B, X); } +table_list(A) ::= table(X). { A = g_slist_append (A, X); } -%type del_using {SqlList *} +%type del_using {GSList *} del_using(A) ::= USING target_list(X). { A = X; } del_using(A) ::= . { A = NULL; } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Update +// SqlUpdate +stmt(stmt) ::= update_stmt(update). { stmt = SQL_STMT (update); } -%type update_stmt {SqlStmt *} -update_stmt(A) ::= UPDATE table(table) SET update_list(sets) where(where). +%type update_stmt {SqlUpdate *} +update_stmt(update) ::= UPDATE table(table) SET update_list(u_list) where(where). { - A = g_object_new (SQL_TYPE_UPDATE - ,"targets" ,table - ,"sets" ,sets - ,"where" ,where - ,NULL - ); + GSList * n; + update = sql_update_new (); + + sql_dml_add_target (SQL_DML (update), table); + + for (n = u_list; n; n = n->next) + { + sql_update_add_set (update + ,((SqlUpdateSet *) n->data)->field + ,((SqlUpdateSet *) n->data)->expr + ); + g_free (n->data); + } + g_slist_free (u_list); + + if (where) + sql_dml_set_where (SQL_DML (update), where); } -%type update_list {SqlList *} -update_list(A) ::= update_set(X). { A = list_new (X, SQL_TYPE_UPDATE_SET); } -update_list(A) ::= update_list(B) CM update_set(X). { A = list_add (X, B); } +%type update_list {GSList *} +%destructor update_list {g_slist_free ($$);} +update_list(A) ::= update_list(B) CM update_set(X). { A = g_slist_append (B, X); } +update_list(A) ::= update_set(X). { A = g_slist_append (A, X); } %type update_set {SqlUpdateSet *} -update_set(A) ::= field(X) EQ def_expr(Y). +update_set(A) ::= field(X) EQ expr(Y). { - A = g_object_new (SQL_TYPE_UPDATE_SET - ,"field" ,X - ,"expr" ,Y - ,NULL - ); + A = g_new (SqlUpdateSet, 1); + A->field = SQL_FIELD (X); + A->expr = Y; +} +update_set(A) ::= field(X) EQ DEFAULT. +{ + A = g_new (SqlUpdateSet, 1); + A->field = SQL_FIELD (X); + A->expr = NULL; } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Insert - -%type insert_stmt {SqlStmt *} -insert_stmt(A) ::= INSERT table(table) insert_fields(fields) insert_values(values). -{ - A = g_object_new (SQL_TYPE_INSERT - ,"table" ,table - ,"fields" ,fields - ,NULL - ); - - if (SQL_IS_SELECT (values)) - g_object_set (A, "select", values, NULL); - else - g_object_set (A, "values", values, NULL); -} - -%type insert_fields {SqlList *} -insert_fields(A) ::= LP field_list(X) RP. { A = X; } -insert_fields(A) ::= . { A = NULL; } - -%type insert_values {gpointer} -insert_values(A) ::= DEFAULT VALUES. { A = NULL; } -insert_values(A) ::= VALUES set_list(X). { A = X; } -//insert_values(A) ::= select_stmt(X). { A = X; } - -%type set_list {SqlList *} -set_list(A) ::= set(X). { A = list_new (X, SQL_TYPE_SET); } -set_list(A) ::= set_list(B) CM set(X). { A = list_add (X, B); } - -%type set {SqlSet *} -set(A) ::= LP def_expr_list(X) RP. { A = g_object_new (SQL_TYPE_SET, "exprs", X, NULL); } - -%type def_expr_list {SqlList *} -def_expr_list(A) ::= def_expr(X). { A = list_new (X, SQL_TYPE_EXPR); } -def_expr_list(A) ::= def_expr_list(B) CM def_expr(X). { A = list_add (X, B); } - -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Common to statements - +// Common to SELECT, DELETE and UPDATE %type where {SqlExpr *} where(A) ::= WHERE expr(X). { A = SQL_EXPR (X); } where(A) ::= . { A = NULL; } -%type def_expr {SqlExpr *} -def_expr(A) ::= expr(X). { A = X; } -def_expr(A) ::= DEFAULT. { A = NULL; } +// SqlInsert +stmt(stmt) ::= insert_stmt(insert). { stmt = SQL_STMT (insert); } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Target - -%type target {SqlTarget *} -target(A) ::= unaliased_target(X). { A = X; } -target(A) ::= unaliased_target(X) alias(Y). +%type insert_stmt {SqlInsert *} +insert_stmt(insert) ::= INSERT table(table) ins_fields(field) ins_values(value). { - g_object_set (X, "alias", Y, NULL); - A = X; -} -//target(A) ::= LP target(X) RP. { A = X; } + GSList * ll, * n; + insert = sql_insert_new (); + sql_insert_set_table (insert, SQL_TABLE (table)); -%type target_list {SqlList *} -target_list(A) ::= target(X). { A = list_new (X, SQL_TYPE_TARGET); } -target_list(A) ::= target_list(B) CM target(X). { A = list_add (X, B); } + for (n = field; n; n = n->next) + sql_insert_add_field (insert, n->data); -%type unaliased_target {SqlTarget *} -unaliased_target(A) ::= join(X). { A = X; } -unaliased_target(A) ::= subquery(X). { A = X; } -unaliased_target(A) ::= table(X). { A = X; } + g_slist_free (field); -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Join - -%type join {SqlTarget *} -join(A) ::= target(left) join_type(type) target(right) join_cond(condition). -{ - A = g_object_new (SQL_TYPE_JOIN - ,"target-left" ,left - ,"target-right" ,right - ,"join-type" ,type - ,NULL - ); - - if (SQL_IS_LIST (condition)) // USING + for (ll = value; ll; ll = ll->next) { - GList * n; - SqlList * exprs = sql_list_new (SQL_TYPE_EXPR); - SqlOperation * op_and = g_object_new (SQL_TYPE_OPERATION - ,"type" ,SQL_OPERATION_TYPE_AND - ,"exprs" ,exprs - ,NULL - ); + sql_insert_add_row (insert); - for (n = sql_list_get_items (condition); n; n = n->next) - { - SqlList * equal = sql_list_new (SQL_TYPE_EXPR); - SqlOperation * op = g_object_new (SQL_TYPE_OPERATION - ,"type" ,SQL_OPERATION_TYPE_EQUAL - ,"exprs" ,equal - ,NULL - ); - - gchar * target = left->alias ? - left->alias : SQL_TABLE (left)->name; - gchar * schema = SQL_IS_TABLE(left) && SQL_TABLE (left)->schema ? - SQL_TABLE (left)->schema : NULL; - - g_object_set (n->data, "target", target, "schema", schema, NULL); - sql_list_add (equal, n->data); - - target = right->alias ? right->alias : SQL_TABLE (right)->name; - schema = SQL_IS_TABLE (right) && SQL_TABLE (right)->schema ? - SQL_TABLE (right)->schema : NULL; - - sql_list_add (equal, - sql_field_new (SQL_FIELD (n->data)->name, target, schema)); - - sql_list_add (exprs, op); - } - - g_object_set (A, "condition", op_and, NULL); - g_object_unref (g_object_ref_sink (condition)); + for (n = ll->data; n; n = n->next) + sql_insert_add_expr (insert, n->data); + g_slist_free (ll->data); + } + + g_slist_free (ll); +} + +%type ins_fields {GSList *} +%destructor ins_fields {g_slist_free ($$);} +ins_fields(A) ::= LP field_list(X) RP. { A = X; } +ins_fields(A) ::= . { A = NULL; } + +%type ins_values {GSList *} +ins_values ::= DEFAULT VALUES. +ins_values(A) ::= VALUES list_list(X). { A = X; } +//ins_values ::= multi_select.// not supported by the parsetree; + +%type list_list {GSList *} +%destructor list_list {g_slist_free ($$);} +list_list(A) ::= list_list(B) CM LP def_expr_list(X) RP. { A = g_slist_append (B, X); } +list_list(A) ::= LP def_expr_list(X) RP. { A = g_slist_append (A, X); } + +%type def_expr_list {GSList *} +%destructor def_expr_list {g_slist_free ($$);} +def_expr_list(A) ::= def_expr_list(B) CM def_expr(X). { A = g_slist_append (B, X); } +def_expr_list(A) ::= def_expr(X). { A = g_slist_append (A, X); } + +%type def_expr {SqlExpr *} +def_expr(A) ::= DEFAULT. { A = NULL; } +def_expr(A) ::= expr(X). { A = X; } + +// Common to all the statements + +// SqlTarget +%type target {SqlTarget *} +//target(A) ::= LP target(B) RP. { A = B; } +target(A) ::= target(B) alias(X). +{ + sql_target_set_alias (B, X); + g_free (X); + A = B; +} + +%type target_list {GSList *} +%destructor target_list {g_slist_free ($$);} +target_list(A) ::= target_list(B) CM target(X). { A = g_slist_append (B, X); } +target_list(A) ::= target(X). { A = g_slist_append (A, X); } + +target(A) ::= join(X). { A = X; } +target(A) ::= subquery(X). { A = X; } +target(A) ::= table(X). { A = X; } + +// SqlJoin +%type join {SqlTarget *} +join(join) ::= target(left) join_type(jtype) target(right) join_cond(condition). +{ + join = sql_join_new (left, right, jtype); + + if (condition) + { + if (SQL_IS_EXPR (condition)) + sql_join_set_condition (SQL_JOIN (join), condition); + else // USING list (GSList of SqlField) + { + SqlOperation * op = NULL; + GSList * n, * cond_list = condition; + gboolean use_cond = cond_list && cond_list->next ? TRUE : FALSE; + SqlOperation * cond = use_cond ? + sql_operation_new (SQL_OPERATION_TYPE_AND) : + NULL; + + for (n = condition; n; n = n->next) + { + gchar * target = left->alias ? + left->alias : SQL_TABLE (left)->name; + gchar * schema = SQL_IS_TABLE(left) && SQL_TABLE (left)->schema ? + SQL_TABLE (left)->schema : NULL; + op = sql_operation_new (SQL_OPERATION_TYPE_EQUAL); + + g_object_set (n->data, "target", target, "schema", schema, NULL); + + sql_operation_add_expr (op, n->data); + + target = right->alias ? right->alias : SQL_TABLE (right)->name; + schema = SQL_IS_TABLE (right) && SQL_TABLE (right)->schema ? + SQL_TABLE (right)->schema : NULL; + + sql_operation_add_expr (op, + sql_field_new (SQL_FIELD (n->data)->name, target, schema)); + + if (use_cond) + sql_operation_add_expr (cond, SQL_EXPR (op)); + } + + g_slist_free (condition); + + sql_join_set_condition (SQL_JOIN (join), + use_cond ? SQL_EXPR (cond) : SQL_EXPR (op)); + } } - else - g_object_set (A, "condition", condition, NULL); } %type join_type {SqlJoinType} @@ -423,109 +495,140 @@ join_type(A) ::= LEFT JOIN. { A = SQL_JOIN_TYPE_LEFT; } join_type(A) ::= RIGHT JOIN. { A = SQL_JOIN_TYPE_RIGHT; } %type join_cond {gpointer} -join_cond(A) ::= ON expr(X). { A = X; } -join_cond(A) ::= USING LP field_list(X) RP. { A = X; } - -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Subquery +join_cond(A) ::= ON expr(X). { A = X; }// A : SqlExpr +join_cond(A) ::= USING LP field_list(X) RP. { A = X; }// A : GSList +// SqlSubquery %type subquery {SqlTarget *} -subquery(A) ::= LP select_stmt(stmts) RP. -{ - A = g_object_new (SQL_TYPE_SUBQUERY, "stms", stmts, NULL); -} -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Table +subquery(sub) ::= LP multi_select(stmt) RP. + { sub = SQL_TARGET (sql_subquery_new (stmt)); } +//SqlTable %type table {SqlTarget *} + table(A) ::= identifier(X). { - A = g_object_new (SQL_TYPE_TABLE, "table", X, NULL); + A = sql_table_new (X); + g_free (X); } table(A) ::= identifier(Y) DOT identifier(X). { - A = g_object_new (SQL_TYPE_TABLE, "table", X, "schema", Y, NULL); + A = sql_table_new (X); + g_object_set (A, "schema", Y, NULL); + g_free (Y); + g_free (X); } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Expr - +// SqlExpr %type expr {SqlExpr *} expr(A) ::= LP expr(X) RP. { A = X; } -%type expr_list {SqlList *} -expr_list(A) ::= expr(X). { A = list_new (X, SQL_TYPE_EXPR); } -expr_list(A) ::= expr_list(B) CM expr(X). { A = list_add (X, B); } +%type expr_list {GSList *} +%destructor expr_list {g_slist_free ($$);} +expr_list(A) ::= expr_list(B) CM expr(X). { A = g_slist_append (B, X); } +expr_list(A) ::= expr(X). { A = g_slist_append (A, X); } expr(A) ::= field(X). { A = X; } expr(A) ::= function(X). { A = X; } -expr(A) ::= operation(X). { A = X; } +expr(A) ::= operation(X). { A = SQL_EXPR (X); } expr(A) ::= value(X). { A = X; } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Field - +// SqlField %type field {SqlExpr *} -field(A) ::= unqualified_field(X). { A = X; } -field(A) ::= identifier(Y) DOT unqualified_field(X). +field(A) ::= identifier(X). { - g_object_set (X, "target", Y, NULL); - A = X; + A = sql_field_new (X, NULL, NULL); + g_free (X); } -field(A) ::= identifier(Z) DOT identifier(Y) DOT unqualified_field(X). +field(A) ::= STAR. { - g_object_set (X, "target", Y, "schema", Z, NULL); - A = X; + A = sql_field_new ("*", NULL, NULL); +} +field(A) ::= identifier(Y) DOT identifier(X). +{ + A = sql_field_new (X, Y, NULL); + g_free (X); + g_free (Y); +} +field(A) ::= identifier(Y) DOT STAR. +{ + A = sql_field_new ("*", Y, NULL); + g_free (Y); +} +field(A) ::= identifier(Z) DOT identifier(Y) DOT identifier(X). +{ + A = sql_field_new (X, Y, Z); + g_free (X); + g_free (Y); + g_free (Z); +} +field(A) ::= identifier(Z) DOT identifier(Y) DOT STAR. +{ + A = sql_field_new ("*", Y, Z); + g_free (Y); + g_free (Z); } -%type unqualified_field {SqlExpr *} -unqualified_field(A) ::= identifier(X). -{ - A = g_object_new (SQL_TYPE_FIELD, "name", X, NULL); -} -unqualified_field(A) ::= STAR. -{ - A = g_object_new (SQL_TYPE_FIELD, "name", "*", NULL); -} - -%type field_list {SqlList *} -field_list(A) ::= field(X). { A = list_new (X, SQL_TYPE_FIELD); } -field_list(A) ::= field_list(B) CM field(X). { A = list_add (X, B); } - -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Function +%type field_list {GSList *} +%destructor field_list {g_slist_free ($$);} +field_list(A) ::= field_list(B) CM field(X). { A = g_slist_append (B, X); } +field_list(A) ::= field(X). { A = g_slist_append (A, X); } +// SqlFunction %type function {SqlExpr *} -function(A) ::= unqualified_function(X). { A = X; } -function(A) ::= identifier(Z) DOT unqualified_function(X). + +function(A) ::= identifier(Y) DOT identifier(X) LP RP. { - g_object_set (X, "schema", Z, NULL); - A = X; + A = SQL_EXPR (sql_function_new (X, Y)); + g_free (X); + g_free (Y); +} +function(A) ::= identifier(X) LP RP. +{ + A = SQL_EXPR (sql_function_new (X, NULL)); + g_free (X); +} +function(A) ::= identifier(Z) DOT identifier(X) LP expr_list(Y) RP. +{ + GSList * n = NULL; + A = SQL_EXPR (sql_function_new (X, Z)); + for ( n = Y; n; n = n->next) + sql_function_add_param (SQL_FUNCTION (A), n->data); + g_slist_free (Y); + g_free (X); +} +function(A) ::= identifier(X) LP expr_list(Y) RP. +{ + GSList * n = NULL; + A = SQL_EXPR (sql_function_new (X, NULL)); + for ( n = Y; n; n = n->next) + sql_function_add_param (SQL_FUNCTION (A), n->data); + g_slist_free (Y); + g_free (X); +} +function(A) ::= expr(X) MOD expr(Y). +{ + A = SQL_EXPR (sql_function_new ("MOD", NULL)); + sql_function_add_param (SQL_FUNCTION (A), SQL_EXPR (X)); + sql_function_add_param (SQL_FUNCTION (A), SQL_EXPR (Y)); } -%type unqualified_function {SqlExpr *} -unqualified_function(A) ::= identifier(X) LP function_expr_list(Y) RP. -{ - A = g_object_new (SQL_TYPE_FUNCTION, "name", X, "params", Y, NULL); -} - -%type function_expr_list {SqlList *} -function_expr_list(A) ::= . { A = NULL; } -function_expr_list(A) ::= expr_list(X). { A = X; } - -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Operation - -%type operation {SqlExpr *} +// SqlOperation +%type operation {SqlOperation *} %include { - static inline SqlExpr * create_operation - (const gpointer X, const gpointer Y, const SqlOperationType type) - { - SqlList * exprs = sql_list_new (SQL_TYPE_EXPR); - sql_list_add (exprs, X); - - if (Y) // Binary operation - sql_list_add (exprs, Y); - - return g_object_new (SQL_TYPE_OPERATION, "type", type, "exprs", exprs, NULL); - } +static inline SqlOperation * sql_parser_create_operation + (const gpointer X, const gpointer Y, const SqlOperationType type) +{ + SqlOperation * op = sql_operation_new (type); + sql_operation_add_expr (op, SQL_EXPR (X)); + if (Y) // Y == NULL for unary operations + sql_operation_add_expr (op, SQL_EXPR (Y)); + return op; } +} + operation(A) ::= MINUS expr(X). [SIGN] { GValue value = {0}; @@ -533,105 +636,108 @@ operation(A) ::= MINUS expr(X). [SIGN] g_value_init (&value, G_TYPE_INT); g_value_set_int (&value, -1); sql_value_set_value (SQL_VALUE (minus), &value); - A = create_operation (X, minus, SQL_OPERATION_TYPE_MULTIPLICATION); + A = sql_parser_create_operation (X, minus, SQL_OPERATION_TYPE_MULTIPLICATION); } -operation(A) ::= NOT expr(X). - { A = create_operation (X, NULL, SQL_OPERATION_TYPE_NOT); } - operation(A) ::= PLUS expr(X). [SIGN] - { A = create_operation (X, NULL, SQL_OPERATION_TYPE_SUM); } + { A = sql_parser_create_operation (X, NULL, SQL_OPERATION_TYPE_SUM); } operation(A) ::= expr(X) PLUS expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_SUM); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_SUM); } operation(A) ::= expr(X) MINUS expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_SUBTRACTION); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_REST); } operation(A) ::= expr(X) STAR expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_MULTIPLICATION); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_MULTIPLICATION); } operation(A) ::= expr(X) DIV expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_DIVISION); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_DIVISION); } operation(A) ::= expr(X) OR expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_OR); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_OR); } operation(A) ::= expr(X) XOR expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_XOR); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_XOR); } operation(A) ::= expr(X) AND expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_AND); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_AND); } + +operation(A) ::= NOT expr(X). + { A = sql_parser_create_operation (X, NULL, SQL_OPERATION_TYPE_NOT); } operation(A) ::= expr(X) EQ expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_EQUAL); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_EQUAL); } operation(A) ::= expr(X) NE expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_NOT_EQUAL); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_NOT_EQUAL); } //XXX the following should be %nonassoc operators but are %left to avoid // conflicts. The DB will warn about a bad use if used as %left. operation(A) ::= expr(X) GT expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_GREATER); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_GREATER); } operation(A) ::= expr(X) GE expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_GREATER_EQUAL); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_GREATER_EQUAL); } operation(A) ::= expr(X) LT expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_LOWER); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_LOWER); } operation(A) ::= expr(X) LE expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_LOWER_EQUAL); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_LOWER_EQUAL); } operation(A) ::= expr(X) LIKE expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_LIKE); } + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_LIKE); } operation(A) ::= expr(X) IS expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_IS); } - -operation(A) ::= expr(X) MOD expr(Y). - { A = create_operation (X, Y, SQL_OPERATION_TYPE_MOD); } - -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Value + { A = sql_parser_create_operation (X, Y, SQL_OPERATION_TYPE_IS); } +// SqlValue %type value {SqlExpr *} value(A) ::= INTEGER(X). { GValue value = {0}; + SqlExpr * v = sql_value_new (); g_value_set_int (g_value_init (&value, G_TYPE_INT), atoi (X)); - A = g_object_new (SQL_TYPE_VALUE, "value", &value, NULL); - g_value_unset (&value); + sql_value_set_value (SQL_VALUE (v), &value); + g_free (X); + A = v; } value(A) ::= FLOAT(X). { GValue value = {0}; + SqlExpr * v = sql_value_new (); g_value_set_double (g_value_init (&value, G_TYPE_DOUBLE), g_ascii_strtod (X, NULL)); - A = g_object_new (SQL_TYPE_VALUE, "value", &value, NULL); - g_value_unset (&value); + sql_value_set_value (SQL_VALUE (v), &value); + g_free (X); + A = v; } value(A) ::= STRING(X). { GValue value = {0}; + SqlExpr * v = sql_value_new (); g_value_set_string (g_value_init (&value, G_TYPE_STRING), X); - A = g_object_new (SQL_TYPE_VALUE, "value", &value, NULL); - g_value_unset (&value); + sql_value_set_value (SQL_VALUE (v), &value); + g_free (X); + A = v; } value(A) ::= BOOLEAN(X). { GValue value = {0}; + SqlExpr * v = sql_value_new (); g_value_set_boolean (g_value_init (&value, G_TYPE_BOOLEAN) ,(!g_strcmp0 (X, "TRUE") || !g_strcmp0 (X, "true")) ? TRUE : FALSE); - A = g_object_new (SQL_TYPE_VALUE, "value", &value, NULL); - g_value_unset (&value); + sql_value_set_value (SQL_VALUE (v), &value); + g_free (X); + A = v; } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Alias - +// Alias %type alias {gchar *} %destructor alias {g_free ($$);} alias(A) ::= AS identifier(X). { A = X; } @@ -639,8 +745,7 @@ alias(A) ::= identifier(X). { A = X; } identifier(A) ::= IDENTIFIER(X). { A = X; } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Placeholder - +// Placeholders %type placeholder {gchar *} %destructor expr {g_free ($$);} placeholder(A) ::= PLACEHOLDER(X). { A = X; } diff --git a/sql/parser/scan.rl b/sql/parser/scan.rl index 8b96bc1..57fb961 100644 --- a/sql/parser/scan.rl +++ b/sql/parser/scan.rl @@ -251,7 +251,7 @@ SqlObject * sql_parser_parse (gchar * sql) if (state->error) { if (state->object && G_IS_OBJECT (state->object)) - g_object_unref (g_object_ref_sink (state->object)); + g_object_unref (state->object); object = NULL; } else diff --git a/sql/sql-delete.c b/sql/sql-delete.c index 63dc205..3c9f570 100644 --- a/sql/sql-delete.c +++ b/sql/sql-delete.c @@ -26,7 +26,7 @@ **/ G_DEFINE_TYPE (SqlDelete, sql_delete, SQL_TYPE_DML); -SqlObject * sql_delete_new () +SqlDelete * sql_delete_new () { return g_object_new (SQL_TYPE_DELETE, NULL); } @@ -36,75 +36,40 @@ SqlObject * sql_delete_new () static void sql_delete_render (SqlDelete * obj, SqlRender * render) { sql_render_add_token (render, "DELETE"); - sql_render_add_list (render, TRUE, NULL, obj->tables, ","); + sql_render_add_object (render, obj->table); - if (SQL_DML (obj)->targets) + if (SQL_DML (obj)->target) { - sql_render_add_list (render, TRUE, "FROM", SQL_DML (obj)->targets, ","); - sql_render_add_item (render, FALSE, "WHERE", SQL_DML (obj)->where); + sql_render_add_list (render, T, "FROM", SQL_DML (obj)->target, ","); + sql_render_add_item (render, F, "WHERE", SQL_DML (obj)->where); } } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties +//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public -enum +void sql_delete_add_table (SqlDelete * obj, SqlTable * table) { - PROP_TABLES = 1 -}; - -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); - } + g_return_if_fail (SQL_IS_DELETE (obj)); + g_return_if_fail (SQL_IS_TABLE (table)); + + obj->table = g_slist_append (obj->table, g_object_ref_sink (table)); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class static void sql_delete_init (SqlDelete * obj) { - obj->tables = NULL; + obj->table = NULL; } static void sql_delete_finalize (SqlDelete * obj) { - sql_object_remove (obj, obj->tables); + g_slist_free_full (obj->table, g_object_unref); G_OBJECT_CLASS (sql_delete_parent_class)->finalize (G_OBJECT (obj)); } static void sql_delete_class_init (SqlDeleteClass * klass) { - 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; + G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) sql_delete_finalize; 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 - )); } diff --git a/sql/sql-delete.h b/sql/sql-delete.h index fcb0783..a398973 100644 --- a/sql/sql-delete.h +++ b/sql/sql-delete.h @@ -35,7 +35,7 @@ typedef struct _SqlDeleteClass SqlDeleteClass; struct _SqlDelete { SqlDml parent; - SqlList * tables; + GSList * table; }; struct _SqlDeleteClass @@ -45,6 +45,7 @@ struct _SqlDeleteClass }; GType sql_delete_get_type (); -SqlObject * sql_delete_new (); +SqlDelete * sql_delete_new (); +void sql_delete_add_table (SqlDelete * obj, SqlTable * table); #endif diff --git a/sql/sql-dml.c b/sql/sql-dml.c index 7d61719..7833af9 100644 --- a/sql/sql-dml.c +++ b/sql/sql-dml.c @@ -28,21 +28,42 @@ 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) +{ + g_return_if_fail (SQL_IS_DML (obj)); + g_return_if_fail (SQL_IS_TARGET (target)); + + 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) || SQL_IS_HOLDER (where) || !where); + g_return_if_fail (SQL_IS_EXPR (where)); - sql_object_remove (obj, obj->where); - obj->where = sql_object_add (obj, where); + g_clear_object (&obj->where); + obj->where = g_object_ref_sink (where); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties enum { - PROP_TARGETS = 1 - ,PROP_WHERE + PROP_WHERE = 1 }; static void sql_dml_set_property (SqlDml * obj, guint id, @@ -50,10 +71,6 @@ 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; @@ -67,9 +84,6 @@ 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; @@ -80,37 +94,30 @@ static void sql_dml_get_property (SqlDml * obj, guint id, //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class -static void sql_dml_init (SqlDml * obj) -{ - obj->targets = NULL; - obj->where = NULL; -} - static void sql_dml_finalize (SqlDml * obj) { - sql_object_remove (obj, obj->targets); - sql_object_remove (obj, obj->where); + 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_class_init (SqlDmlClass * klass) +static void sql_dml_init (SqlDml * obj) { - 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; + obj->target = NULL; + obj->where = NULL; +} - 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" +static void sql_dml_class_init (SqlDmlClass * k) +{ + 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; + + g_object_class_install_property (klass, PROP_WHERE, + g_param_spec_object ("where" ,"Where" - ,"The WHERE section of an statement" + ,"The expression used to filter rows, it's the WHERE section of an statement" ,SQL_TYPE_EXPR ,G_PARAM_READWRITE )); diff --git a/sql/sql-dml.h b/sql/sql-dml.h index d7c528f..6cc6d0b 100644 --- a/sql/sql-dml.h +++ b/sql/sql-dml.h @@ -37,7 +37,7 @@ typedef struct _SqlDmlClass SqlDmlClass; struct _SqlDml { SqlStmt parent; - SqlList * targets; + GSList * target; SqlExpr * where; }; @@ -48,6 +48,7 @@ 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); #endif diff --git a/sql/sql-expr.c b/sql/sql-expr.c index 00b9993..e31d6df 100644 --- a/sql/sql-expr.c +++ b/sql/sql-expr.c @@ -28,6 +28,11 @@ **/ 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) {} diff --git a/sql/sql-field.c b/sql/sql-field.c index 8511016..9002634 100644 --- a/sql/sql-field.c +++ b/sql/sql-field.c @@ -36,14 +36,13 @@ G_DEFINE_TYPE (SqlField, sql_field, SQL_TYPE_EXPR); * * Return value: an #SqlExpr */ -SqlObject * sql_field_new (const gchar * name, const gchar * target, const gchar * schema) +SqlExpr * sql_field_new (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 @@ -97,7 +96,8 @@ static void sql_field_set_property (SqlField * obj, guint id, switch (id) { case PROP_NAME: - sql_field_set_name (obj, g_value_get_string (value)); + g_free (obj->name); + obj->name = g_value_dup_string (value); break; case PROP_TARGET: g_free (obj->target); @@ -145,6 +145,7 @@ static void sql_field_finalize (SqlField * obj) g_free (obj->name); g_free (obj->target); g_free (obj->schema); + G_OBJECT_CLASS (sql_field_parent_class)->finalize (G_OBJECT (obj)); } diff --git a/sql/sql-field.h b/sql/sql-field.h index c33efe8..5ad5d40 100644 --- a/sql/sql-field.h +++ b/sql/sql-field.h @@ -43,7 +43,7 @@ struct _SqlFieldClass }; GType sql_field_get_type (); -SqlObject * sql_field_new (const gchar * name +SqlExpr * sql_field_new (const gchar * name ,const gchar * target ,const gchar * schema); void sql_field_set_name (SqlField * obj, const gchar * name); diff --git a/sql/sql-function.c b/sql/sql-function.c index d5c7249..187f63c 100644 --- a/sql/sql-function.c +++ b/sql/sql-function.c @@ -46,18 +46,27 @@ static void sql_function_render (SqlFunction * obj, SqlRender * render) if (obj->name) { sql_render_append (render, "("); - sql_render_add_list (render, FALSE, NULL, obj->params, ","); + sql_render_add_list (render, F, NULL, obj->param, ","); 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 enum { PROP_NAME = 1 ,PROP_SCHEMA - ,PROP_PARAMS }; static void sql_function_set_property (SqlFunction * obj, guint id, @@ -73,10 +82,6 @@ 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); } @@ -93,9 +98,6 @@ 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); } @@ -107,14 +109,14 @@ static void sql_function_init (SqlFunction * obj) { obj->name = NULL; obj->schema = NULL; - obj->params = NULL; + obj->param = NULL; } static void sql_function_finalize (SqlFunction * obj) { g_free (obj->name); g_free (obj->schema); - sql_object_remove (obj, obj->params); + g_slist_free_full (obj->param, g_object_unref); G_OBJECT_CLASS (sql_function_parent_class)->finalize (G_OBJECT (obj)); } @@ -133,6 +135,7 @@ static void sql_function_class_init (SqlFunctionClass * klass) ,NULL ,G_PARAM_READWRITE )); + g_object_class_install_property (k, PROP_SCHEMA, g_param_spec_string ("schema" ,"Schema" @@ -140,11 +143,4 @@ static void sql_function_class_init (SqlFunctionClass * klass) ,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 - )); } diff --git a/sql/sql-function.h b/sql/sql-function.h index ac4190c..6ffc283 100644 --- a/sql/sql-function.h +++ b/sql/sql-function.h @@ -37,7 +37,7 @@ struct _SqlFunction SqlExpr parent; gchar * schema; gchar * name; - SqlList * params; // List of SqlExpr + GSList * param; // Parameters for the function, list of SqlExpr }; struct _SqlFunctionClass @@ -48,5 +48,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); #endif diff --git a/sql/sql-insert.c b/sql/sql-insert.c index 6270dd0..697a861 100644 --- a/sql/sql-insert.c +++ b/sql/sql-insert.c @@ -26,27 +26,51 @@ **/ G_DEFINE_TYPE (SqlInsert, sql_insert, SQL_TYPE_STMT); -SqlObject * sql_insert_new () +SqlInsert * 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, TRUE, "INSERT INTO", obj->table); + sql_render_add_item (render, T, "INSERT INTO", obj->table); if (obj->table) { - if (obj->values) + if (obj->expr) { sql_render_add_espace (render); sql_render_append (render, "("); - sql_render_add_list (render, FALSE, NULL, obj->fields, ","); + sql_render_add_list (render, F, NULL, obj->field, ","); sql_render_append (render, ")"); sql_render_add_token (render, "VALUES"); - sql_render_add_list (render, FALSE, NULL, obj->values, ","); + sql_render_add_list_with_func (render, F, NULL, obj->expr, ",", + (SqlRenderFunc) sql_insert_render_row); } else sql_render_add_token (render, "DEFAULT VALUES"); @@ -55,19 +79,56 @@ static void sql_insert_render (SqlInsert * obj, SqlRender * render) //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public -void sql_insert_set_table_from_name (SqlInsert * obj, const gchar * table) +void sql_insert_set_table (SqlInsert * obj, SqlTable * table) { g_return_if_fail (SQL_IS_INSERT (obj)); - g_return_if_fail (table); - - sql_object_remove (obj, obj->table); - obj->table = sql_object_add (obj, sql_table_new (table)); + g_return_if_fail (SQL_IS_TABLE (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)); } 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 @@ -75,8 +136,6 @@ void sql_insert_add_expr (SqlInsert * obj, SqlExpr * expr) enum { PROP_TABLE = 1 - ,PROP_FIELDS - ,PROP_VALUES }; static void sql_insert_set_property (SqlInsert * obj, guint id, @@ -85,16 +144,7 @@ static void sql_insert_set_property (SqlInsert * obj, guint id, switch (id) { case PROP_TABLE: - 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)); + sql_insert_set_table (obj, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); @@ -109,12 +159,6 @@ 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); } @@ -125,15 +169,15 @@ static void sql_insert_get_property (SqlInsert * obj, guint id, static void sql_insert_init (SqlInsert * obj) { obj->table = NULL; - obj->fields = NULL; - obj->values = NULL; + obj->field = NULL; + obj->expr = NULL; + obj->iter = NULL; } static void sql_insert_finalize (SqlInsert * obj) { - sql_object_remove (obj, obj->table); - sql_object_remove (obj, obj->fields); - sql_object_remove (obj, obj->values); + sql_insert_clean (obj); + g_clear_object (&obj->table); G_OBJECT_CLASS (sql_insert_parent_class)->finalize (G_OBJECT (obj)); } @@ -146,24 +190,10 @@ 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, - sql_param_object ("table" + g_param_spec_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 - )); } diff --git a/sql/sql-insert.h b/sql/sql-insert.h index 3be108a..7fa3bd8 100644 --- a/sql/sql-insert.h +++ b/sql/sql-insert.h @@ -18,15 +18,14 @@ #ifndef SQL_INSERT_H #define SQL_INSERT_H -#define SQL_TYPE_INSERT (sql_insert_get_type ()) -#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)) +#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)) #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; @@ -41,8 +40,9 @@ struct _SqlInsert { SqlStmt parent; SqlTable * table; - SqlList * fields; // List of SqlField - SqlList * values; // List of SqlSet + GSList * field; // List of SqlField + GSList * expr; // List of GSList of SqlExpr + GSList * iter; }; struct _SqlInsertClass @@ -51,8 +51,12 @@ struct _SqlInsertClass SqlStmtClass parent; }; -GType sql_insert_get_type (); -SqlObject * sql_insert_new (); -void sql_insert_set_table_from_name (SqlInsert * obj, const gchar * table); +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); #endif \ No newline at end of file diff --git a/sql/sql-join.c b/sql/sql-join.c index 4836962..66b072d 100644 --- a/sql/sql-join.c +++ b/sql/sql-join.c @@ -16,7 +16,6 @@ */ #include "sql-join.h" -#include "sql-field.h" /** * SECTION: sql-join @@ -48,20 +47,11 @@ static const gchar * SQL_JOIN_TYPE[] = static void sql_join_render (SqlJoin * obj, SqlRender * render) { - sql_render_add_item (render, TRUE, NULL, obj->target_left); + sql_render_add_item (render, T, NULL, obj->target_left); sql_render_add_token (render, SQL_JOIN_TYPE[obj->type]); sql_render_add_token (render, "JOIN"); - sql_render_add_item (render, TRUE, NULL, obj->target_right); - - if (obj->has_using) - { - sql_render_add_token (render, "USING"); - sql_render_append (render, "("); - sql_render_add_list (render, TRUE, NULL, obj->using_fields, ","); - sql_render_append (render, ")"); - } - else - sql_render_add_item (render, FALSE, "ON", obj->condition); + sql_render_add_item (render, T, NULL, obj->target_right); + sql_render_add_item (render, F, "ON", obj->condition); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public @@ -69,28 +59,28 @@ static void sql_join_render (SqlJoin * obj, SqlRender * render) void sql_join_set_target_left (SqlJoin * obj, SqlTarget * target) { g_return_if_fail (SQL_IS_JOIN (obj)); - g_return_if_fail (SQL_IS_TARGET (target) || SQL_IS_HOLDER (target) || !target); + g_return_if_fail (SQL_IS_TARGET (target)); - sql_object_remove (obj, obj->target_left); - obj->target_left = sql_object_add (obj, target); + g_clear_object (&obj->target_left); + obj->target_left = g_object_ref_sink (target); } void sql_join_set_target_right (SqlJoin * obj, SqlTarget * target) { g_return_if_fail (SQL_IS_JOIN (obj)); - g_return_if_fail (SQL_IS_TARGET (target) || SQL_IS_HOLDER (target) || !target); + g_return_if_fail (SQL_IS_TARGET (target)); - sql_object_remove (obj, obj->target_right); - obj->target_right = sql_object_add (obj, target); + g_clear_object (&obj->target_right); + obj->target_right = g_object_ref_sink (target); } void sql_join_set_condition (SqlJoin * obj, SqlExpr * condition) { g_return_if_fail (SQL_IS_JOIN (obj)); - g_return_if_fail (SQL_IS_EXPR (condition) || SQL_IS_HOLDER (condition) || !condition); + g_return_if_fail (SQL_IS_EXPR (condition)); - sql_object_remove (obj, obj->condition); - obj->condition = sql_object_add (obj, condition); + g_clear_object (&obj->condition); + obj->condition = g_object_ref_sink (condition); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties @@ -101,8 +91,6 @@ enum ,PROP_TARGET_RIGHT ,PROP_TYPE ,PROP_CONDITION - ,PROP_HAS_USING - ,PROP_USING_FIELDS }; static void sql_join_set_property (SqlJoin * obj, guint id, @@ -117,19 +105,12 @@ static void sql_join_set_property (SqlJoin * obj, guint id, sql_join_set_target_right (obj, g_value_get_object (value)); break; case PROP_TYPE: - obj->type = g_value_get_enum (value); + obj->type = g_value_get_int (value); break; case PROP_CONDITION: sql_join_set_condition (obj, g_value_get_object (value)); break; - case PROP_HAS_USING: - obj->has_using = g_value_get_boolean (value); - break; - case PROP_USING_FIELDS: - sql_object_remove (obj, obj->using_fields); - obj->using_fields = sql_object_add (obj, g_value_get_object (value)); - break; - default: + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); } } @@ -146,17 +127,11 @@ static void sql_join_get_property (SqlJoin * obj, guint id, g_value_set_object (value, obj->target_right); break; case PROP_TYPE: - g_value_set_enum (value, obj->type); + g_value_set_int (value, obj->type); break; case PROP_CONDITION: g_value_set_object (value, obj->condition); break; - case PROP_HAS_USING: - g_value_set_boolean (value, obj->has_using); - break; - case PROP_USING_FIELDS: - g_value_set_object (value, obj->using_fields); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); } @@ -169,15 +144,13 @@ static void sql_join_init (SqlJoin * obj) obj->target_left = NULL; obj->target_right = NULL; obj->condition = NULL; - obj->using_fields = NULL; } static void sql_join_finalize (SqlJoin * obj) { - sql_object_remove (obj, obj->target_left); - sql_object_remove (obj, obj->target_right); - sql_object_remove (obj, obj->condition); - sql_object_remove (obj, obj->using_fields); + g_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)); } @@ -190,67 +163,31 @@ 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, - sql_param_list ("target-left" + g_param_spec_object ("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, - sql_param_list ("target-right" + g_param_spec_object ("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_enum ("join-type" + g_param_spec_int ("join-type" ,"Type" ,"The type of join" - ,SQL_TYPE_JOIN_TYPE - ,SQL_JOIN_TYPE_INNER + ,0, SQL_JOIN_TYPE_COUNT - 1, SQL_JOIN_TYPE_INNER ,G_PARAM_READWRITE )); g_object_class_install_property (k, PROP_CONDITION, - sql_param_list ("condition" + g_param_spec_object ("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; } diff --git a/sql/sql-join.h b/sql/sql-join.h index 91a929c..1e6e652 100644 --- a/sql/sql-join.h +++ b/sql/sql-join.h @@ -22,10 +22,8 @@ #include "sql-expr.h" #define SQL_TYPE_JOIN (sql_join_get_type ()) -#define SQL_IS_JOIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_JOIN)) -#define SQL_JOIN(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, SQL_TYPE_JOIN, SqlJoin)) - -#define SQL_TYPE_JOIN_TYPE (sql_join_type_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)) typedef struct _SqlJoin SqlJoin; typedef struct _SqlJoinClass SqlJoinClass; @@ -46,8 +44,6 @@ struct _SqlJoin SqlTarget * target_right; SqlJoinType type; SqlExpr * condition; - gboolean has_using; - SqlList * using_fields; }; struct _SqlJoinClass @@ -57,8 +53,6 @@ struct _SqlJoinClass }; GType sql_join_get_type (); -GType sql_join_type_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); diff --git a/sql/sql-multi-stmt.c b/sql/sql-multi-stmt.c index 2f7047e..501a4f5 100644 --- a/sql/sql-multi-stmt.c +++ b/sql/sql-multi-stmt.c @@ -35,69 +35,34 @@ SqlMultiStmt * sql_multi_stmt_new () static void sql_multi_stmt_render (SqlMultiStmt * obj, SqlRender * render) { - sql_render_add_list (render, TRUE, NULL, obj->stmts, ";"); + sql_render_add_list (render, T, NULL, obj->stmt, ";"); } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties +//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public -enum +void sql_multi_stmt_add_stmt (SqlMultiStmt * obj, SqlStmt * stmt) { - PROP_STMTS = 1 -}; + g_return_if_fail (SQL_IS_MULTI_STMT (obj)); + g_return_if_fail (SQL_IS_STMT (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); - } + obj->stmt = g_slist_append (obj->stmt, g_object_ref_sink (stmt)); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class static void sql_multi_stmt_init (SqlMultiStmt * obj) { - obj->stmts = NULL; + obj->stmt = NULL; } static void sql_multi_stmt_finalize (SqlMultiStmt * obj) { - sql_object_remove (obj, obj->stmts); + g_slist_free_full (obj->stmt, g_object_unref); G_OBJECT_CLASS (sql_multi_stmt_parent_class)->finalize (G_OBJECT (obj)); } static void sql_multi_stmt_class_init (SqlMultiStmtClass * klass) { - 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; + G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) sql_multi_stmt_finalize; 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 - )); } diff --git a/sql/sql-multi-stmt.h b/sql/sql-multi-stmt.h index 2b544be..9156f36 100644 --- a/sql/sql-multi-stmt.h +++ b/sql/sql-multi-stmt.h @@ -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(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, SQL_TYPE_MULTI_STMT)) +#define SQL_IS_MULTI_STMT(object) (G_TYPE_CHECK_INSTANCE_TYPE (object, SQL_TYPE_MULTI_STMT)) typedef struct _SqlMultiStmt SqlMultiStmt; typedef struct _SqlMultiStmtClass SqlMultiStmtClass; @@ -34,7 +34,7 @@ typedef struct _SqlMultiStmtClass SqlMultiStmtClass; struct _SqlMultiStmt { SqlStmt parent; - SqlList * stmts; + GSList * stmt; }; struct _SqlMultiStmtClass @@ -45,5 +45,6 @@ struct _SqlMultiStmtClass GType sql_multi_stmt_get_type (); SqlMultiStmt * sql_multi_stmt_new (); +void sql_multi_stmt_add_stmt (SqlMultiStmt * obj, SqlStmt * stmt); #endif diff --git a/sql/sql-object.c b/sql/sql-object.c index d3363b0..3eaf35e 100644 --- a/sql/sql-object.c +++ b/sql/sql-object.c @@ -35,49 +35,65 @@ static guint signals[LAST_SIGNAL] = {0}; //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private -static void sql_object_child_changed (SqlObject * child, SqlObject * obj) +static void sql_object_list_changed (SqlObject * sub, SqlObject * obj) { - sql_object_changed (obj); + g_signal_emit (obj, signals[CHANGED], 0); +} + +static gboolean sql_object_is_ready_default (SqlObject * obj) +{ + return TRUE; } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Protected /** - * sql_object_add: - * @obj: #SqlObject where the new item will be added - * @child: #SqlObject the object is added + * 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. * * Note that this function is considered a protected method and should only - * be used in classes that inherit from #SqlObjectClass. + * 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(). **/ -gpointer sql_object_add (gpointer obj, gpointer child) +void sql_object_list_add (SqlObject * obj, GSList ** list, SqlObject * sub) { - if (child) - { - g_object_ref_sink (child); - g_signal_connect (child, "changed", - G_CALLBACK (sql_object_child_changed), obj); - } - - return child; + *list = g_slist_append (*list, g_object_ref_sink (sub)); + g_signal_connect (sub, "changed", + G_CALLBACK (sql_object_list_changed), obj + ); } /** - * sql_object_remove: - * @obj: #SqlObject where the new item will be added - * @child: #SqlObject the object is added + * 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. * * Note that this function is considered a protected method and should only - * be used in classes that inherit from #SqlObjectClass. + * be used in classes that inherit from #SqlObjectClass and whose list has only + * been handled by the function sql_object_list_add(). **/ -void sql_object_remove (gpointer obj, gpointer child) +void sql_object_list_free (SqlObject * obj, GSList * list) { - if (child) + GSList * n; + + for (n = list; n; n = n->next) { - g_signal_handlers_disconnect_by_func (child, - sql_object_child_changed, obj); - g_object_unref (child); + g_signal_handlers_disconnect_by_func (n->data, + G_CALLBACK (sql_object_list_changed), obj + ); + g_object_unref (n->data); } + + g_slist_free (list); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public @@ -94,7 +110,7 @@ void sql_object_render (SqlObject * obj, SqlRender * render) g_return_if_fail (SQL_IS_OBJECT (obj)); g_return_if_fail (SQL_IS_RENDER (render)); -// SQL_OBJECT_GET_CLASS (obj)->render (obj, render); + return SQL_OBJECT_GET_CLASS (obj)->render (obj, render); } /** @@ -106,157 +122,29 @@ void sql_object_render (SqlObject * obj, SqlRender * render) * Return value: %TRUE if ready, %FALSE otherwise. **/ gboolean sql_object_is_ready (SqlObject * obj) -{ - SqlObjectClass * klass = SQL_OBJECT_GET_CLASS (obj); - +{ g_return_val_if_fail (SQL_IS_OBJECT (obj), FALSE); - if (obj->held_objects) - { - GList * i; - GList * held_objects = g_hash_table_get_values (obj->held_objects); - gboolean is_ready = TRUE; - - for (i = held_objects; i; i = i->next) - if (!sql_object_is_ready (i->data)) - { - is_ready = FALSE; - break; - } - - g_list_free (held_objects); - - if (!is_ready) - return FALSE; - } - - if (klass->is_ready) - return klass->is_ready (obj); - else - return TRUE; -} - -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); -} - - -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_add_held_object: - * @obj: a #SqlObject - * @id: the id of the #SqlHolder - * @held_object: the held object - * - * Adds a held object. - **/ -void sql_object_add_held_object (SqlObject * obj, const gchar * id, SqlObject * held_object) -{ - g_return_if_fail (SQL_IS_OBJECT (obj)); - g_return_if_fail (id); - - if (!obj->held_objects) - obj->held_objects = g_hash_table_new_full ( - g_str_hash - ,g_str_equal - ,g_free - ,g_object_unref - ); - - g_signal_connect (held_object, "changed", - G_CALLBACK (sql_object_child_changed), obj - ); - g_hash_table_replace (obj->held_objects, - g_strdup (id), g_object_ref_sink (held_object)); -} - -/** - * sql_object_get_held_object: - * @obj: a #SqlObject - * @id: the id of the #SqlHolder - * - * Gets a held object by its id. - * - * Return value: the #SqlObject if an object with that id exists, %NULL otherwise - **/ -SqlObject * sql_object_get_held_object (SqlObject * obj, const gchar * id) -{ - g_return_val_if_fail (SQL_IS_OBJECT (obj), NULL); - g_return_val_if_fail (id, NULL); - - if (obj->held_objects) - return g_hash_table_lookup (obj->held_objects, id); - - return NULL; -} - -/** - * sql_object_changed: - * @obj: a #SqlObject - * - * Emits the changed signal on #SqlObject. - **/ -void sql_object_changed (SqlObject * obj) -{ - g_signal_emit (obj, signals[CHANGED], 0); + return SQL_OBJECT_GET_CLASS (obj)->is_ready (obj); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class static void sql_object_init (SqlObject * obj) { - obj->child_groups = NULL; - obj->held_objects = NULL; + obj->sql = NULL; } -static void sql_object_finalize (SqlObject * obj) +static void sql_object_finalize (GObject * obj) { - if (obj->child_groups) - g_hash_table_destroy (obj->child_groups); - if (obj->held_objects) - g_hash_table_destroy (obj->held_objects); - - G_OBJECT_CLASS (sql_object_parent_class)->finalize (G_OBJECT (obj)); + g_free (SQL_OBJECT (obj)->sql); + G_OBJECT_CLASS (sql_object_parent_class)->finalize (obj); } static void sql_object_class_init (SqlObjectClass * klass) { - G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) sql_object_finalize; - klass->is_ready = NULL; + G_OBJECT_CLASS (klass)->finalize = sql_object_finalize; + klass->is_ready = sql_object_is_ready_default; klass->render = NULL; /** diff --git a/sql/sql-object.h b/sql/sql-object.h index fc81513..410135b 100644 --- a/sql/sql-object.h +++ b/sql/sql-object.h @@ -19,8 +19,6 @@ #define SQL_OBJECT_H #include -#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)) @@ -31,41 +29,28 @@ typedef struct _SqlObject SqlObject; typedef struct _SqlObjectClass SqlObjectClass; +#include "sql-render.h" + typedef gboolean (* SqlObjectIsReadyFunc) (SqlObject * obj); struct _SqlObject { GInitiallyUnowned parent; - GHashTable * child_groups; - GHashTable * held_objects; + gchar * sql; }; struct _SqlObjectClass { /* */ GInitiallyUnownedClass parent; - gpointer /* SqlRenderFunc */ render; + SqlRenderFunc render; SqlObjectIsReadyFunc is_ready; }; -#include "sql-holder.h" -#include "sql-list.h" -#include "sql-render.h" - -GType sql_object_get_type (); -void sql_object_render (SqlObject * obj, SqlRender * render); -gboolean sql_object_is_ready (SqlObject * obj); - -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_add_held_object (SqlObject * obj, const gchar * id, SqlObject * held_object); -SqlObject * sql_object_get_held_object (SqlObject * obj, const gchar * id); -void sql_object_changed (SqlObject * obj); - -gpointer sql_object_add (gpointer obj, gpointer child); -void sql_object_remove (gpointer obj, gpointer child); +GType sql_object_get_type (); +void sql_object_render (SqlObject * obj, SqlRender * render); +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); #endif diff --git a/sql/sql-operation.c b/sql/sql-operation.c index b0fa96f..b6a92ea 100644 --- a/sql/sql-operation.c +++ b/sql/sql-operation.c @@ -29,7 +29,7 @@ **/ G_DEFINE_TYPE (SqlOperation, sql_operation, SQL_TYPE_EXPR); -SqlObject * sql_operation_new (SqlOperationType type) +SqlOperation * sql_operation_new (SqlOperationType type) { return g_object_new (SQL_TYPE_OPERATION, "type", type, NULL); } @@ -38,14 +38,11 @@ SqlObject * sql_operation_new (SqlOperationType type) static const gchar * SQL_OPERATION_TYPE[] = { - "NOT" - ,"-" - ,"+" - - ,"*" + "*" ,"/" ,"+" ,"-" + ,"NOT" ,"IS" ,"=" ,"!=" @@ -57,25 +54,51 @@ static const gchar * SQL_OPERATION_TYPE[] = ,"AND" ,"OR" ,"XOR" - ,"%" - ,"IN" }; static void sql_operation_render (SqlOperation * obj, SqlRender * render) { sql_render_add_espace (render); sql_render_append (render, "("); - sql_render_add_list (render, TRUE, NULL, obj->operators, + sql_render_add_list (render, T, NULL, obj->expr, SQL_OPERATION_TYPE[obj->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. + * + * Adds an expression to an existing operation. + **/ +void sql_operation_add_expr (SqlOperation * obj, SqlExpr * expr) +{ + g_return_if_fail (SQL_IS_OPERATION (obj)); + g_return_if_fail (SQL_IS_EXPR (expr)); + + sql_object_list_add (SQL_OBJECT (obj), &obj->expr, SQL_OBJECT (expr)); +} + //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties enum { PROP_TYPE = 1 - ,PROP_OPERATORS + ,PROP_COUNT }; static void sql_operation_set_property (SqlOperation * obj, guint id, @@ -84,11 +107,7 @@ static void sql_operation_set_property (SqlOperation * obj, guint id, switch (id) { case PROP_TYPE: - obj->type = g_value_get_enum (value); - break; - case PROP_OPERATORS: - sql_object_remove (obj, obj->operators); - obj->operators = sql_object_add (obj, g_value_get_object (value)); + obj->type = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); @@ -101,10 +120,7 @@ static void sql_operation_get_property (SqlOperation * obj, guint id, switch (id) { case PROP_TYPE: - g_value_set_enum (value, obj->type); - break; - case PROP_OPERATORS: - g_value_set_object (value, obj->operators); + g_value_set_int (value, obj->type); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); @@ -115,12 +131,12 @@ static void sql_operation_get_property (SqlOperation * obj, guint id, static void sql_operation_init (SqlOperation * obj) { - obj->operators = NULL; + obj->expr = NULL; } static void sql_operation_finalize (SqlOperation * obj) { - sql_object_remove (obj, obj->operators); + sql_object_list_free (SQL_OBJECT (obj), obj->expr); G_OBJECT_CLASS (sql_operation_parent_class)->finalize (G_OBJECT (obj)); } @@ -131,58 +147,13 @@ 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_enum ("type" + g_param_spec_int ("type" ,"Type" ,"The type of the operation" - ,SQL_TYPE_OPERATION_TYPE - ,SQL_OPERATION_TYPE_AND - ,G_PARAM_READWRITE - )); - g_object_class_install_property (k, PROP_OPERATORS, - sql_param_list ("operators" - ,"Operators" - ,"The list of operators" - ,SQL_TYPE_EXPR + ,0, SQL_OPERATION_TYPE_COUNT, 0 ,G_PARAM_READWRITE )); } - -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; -} diff --git a/sql/sql-operation.h b/sql/sql-operation.h index 78da757..28716ca 100644 --- a/sql/sql-operation.h +++ b/sql/sql-operation.h @@ -24,23 +24,16 @@ #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 { - // Unary - SQL_OPERATION_TYPE_NOT - ,SQL_OPERATION_TYPE_MINUS - ,SQL_OPERATION_TYPE_PLUS - - // Binary - ,SQL_OPERATION_TYPE_MULTIPLICATION + SQL_OPERATION_TYPE_MULTIPLICATION ,SQL_OPERATION_TYPE_DIVISION ,SQL_OPERATION_TYPE_SUM - ,SQL_OPERATION_TYPE_SUBTRACTION + ,SQL_OPERATION_TYPE_REST + ,SQL_OPERATION_TYPE_NOT ,SQL_OPERATION_TYPE_IS ,SQL_OPERATION_TYPE_EQUAL ,SQL_OPERATION_TYPE_NOT_EQUAL @@ -52,8 +45,6 @@ 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; @@ -66,7 +57,7 @@ SqlOperationType; struct _SqlOperation { SqlExpr parent; - SqlList * operators; // List of SqlExpr + GSList * expr; // List of SqlExpr pointers SqlOperationType type; }; @@ -76,9 +67,8 @@ struct _SqlOperationClass SqlExprClass parent; }; -GType sql_operation_get_type (); -GType sql_operation_type_get_type (); - -SqlObject * sql_operation_new (SqlOperationType type); +GType sql_operation_get_type (); +SqlOperation * sql_operation_new (SqlOperationType type); +void sql_operation_add_expr (SqlOperation * obj, SqlExpr * expr); #endif diff --git a/sql/sql-render.c b/sql/sql-render.c index ce7dfa9..3ca14c7 100644 --- a/sql/sql-render.c +++ b/sql/sql-render.c @@ -66,7 +66,6 @@ gchar * sql_render_get_string (SqlRender * obj, gpointer object, gpointer data, obj->data = data; obj->object = g_object_ref (object); obj->buffer = g_string_sized_new (SQL_BUFFER_SIZE); - obj->ancestors = NULL; sql_render_add_object (obj, object); @@ -82,10 +81,8 @@ gchar * sql_render_get_string (SqlRender * obj, gpointer object, gpointer data, } else sql = g_string_free (obj->buffer, FALSE); - + g_clear_object (&obj->object); - g_slist_free (obj->ancestors); - obj->ancestors = NULL; obj->buffer = NULL; obj->data = NULL; return sql; @@ -104,23 +101,7 @@ void sql_render_register_function (SqlRender * obj, GType type, SqlRenderFunc fu { g_return_if_fail (SQL_IS_RENDER (obj)); - 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): 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; + g_hash_table_insert (obj->symbol_table, GUINT_TO_POINTER (type), function); } /** @@ -139,16 +120,13 @@ void sql_render_add_object (SqlRender * obj, gpointer object) if (object) { - function = g_hash_table_lookup (obj->custom_renderers, + function = g_hash_table_lookup (obj->symbol_table, GUINT_TO_POINTER (G_OBJECT_TYPE (object))); - obj->ancestors = g_slist_prepend (obj->ancestors, object); if (function) function (object, obj); else sql_object_render (object, obj); - - obj->ancestors = g_slist_delete_link (obj->ancestors, obj->ancestors); } } @@ -302,17 +280,16 @@ void sql_render_add_item (SqlRender * obj, gboolean required, const gchar * toke * **/ void sql_render_add_list (SqlRender * obj, gboolean required, const gchar * token, - SqlList * list, const gchar * separator) + GSList * list, const gchar * separator) { g_return_if_fail (SQL_IS_RENDER (obj)); - g_return_if_fail (SQL_IS_LIST (list)); if (list) { - GList * n; + GSList * n; sql_render_add_token (obj, token); - for (n = sql_list_get_items (list); n; n = n->next) + for (n = list; n; n = n->next) { sql_render_add_object (obj, n->data); @@ -336,17 +313,16 @@ void sql_render_add_list (SqlRender * obj, gboolean required, const gchar * toke * **/ void sql_render_add_list_with_func (SqlRender * obj, gboolean required, const gchar * token, - SqlList * list, const gchar * separator, SqlRenderFunc function) + GSList * list, const gchar * separator, SqlRenderFunc function) { g_return_if_fail (SQL_IS_RENDER (obj)); - g_return_if_fail (SQL_IS_LIST (list)); if (list) { - GList * n; + GSList * n; sql_render_add_token (obj, token); - for (n = sql_list_get_items (list); n; n = n->next) + for (n = list; n; n = n->next) { function (n->data, obj); @@ -413,7 +389,7 @@ static void sql_render_init (SqlRender * obj) { obj->buffer = NULL; obj->error = NULL; - obj->custom_renderers = g_hash_table_new ( + obj->symbol_table = g_hash_table_new ( g_direct_hash ,g_direct_equal ); @@ -421,7 +397,7 @@ static void sql_render_init (SqlRender * obj) static void sql_render_finalize (SqlRender * obj) { - g_hash_table_unref (obj->custom_renderers); + g_hash_table_unref (obj->symbol_table); G_OBJECT_CLASS (sql_render_parent_class)->finalize (G_OBJECT (obj)); } diff --git a/sql/sql-render.h b/sql/sql-render.h index da29abf..821bc82 100644 --- a/sql/sql-render.h +++ b/sql/sql-render.h @@ -26,6 +26,8 @@ #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; @@ -37,7 +39,7 @@ typedef void (* SqlRenderFunc) (gpointer obj, SqlRender * render); /** * SqlRender: - * @custom_renderers: (element-type GType Sql.RenderFunc): + * @symbol_table: (element-type GType Sql.RenderFunc): **/ struct _SqlRender { @@ -45,9 +47,8 @@ struct _SqlRender GError * error; GString * buffer; gpointer object; - GSList * ancestors; gpointer data; - GHashTable * custom_renderers; + GHashTable * symbol_table; gint8 delimiter; }; @@ -73,7 +74,6 @@ GType sql_render_get_type (); SqlRender * sql_render_new (gchar delimiter); gchar * sql_render_get_string (SqlRender * obj, gpointer object, 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 +82,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, 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_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_set_error (SqlRender * obj); #endif diff --git a/sql/sql-select.c b/sql/sql-select.c index dfc4179..7bd1719 100644 --- a/sql/sql-select.c +++ b/sql/sql-select.c @@ -24,35 +24,84 @@ * * 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); -SqlObject * sql_select_new () +SqlSelect * 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) { - 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) + if (obj->alias) { - 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, ","); + 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); if (obj->limit_count) sql_render_printf (render, "LIMIT %u OFFSET %u" @@ -60,9 +109,18 @@ static void sql_select_render (SqlSelect * obj, SqlRender * render) ,obj->limit_offset ); } - - if (obj->next) - sql_render_add_item (render, FALSE, SQL_SELECT_TYPE[obj->type], obj->next); +} + +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); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public @@ -71,27 +129,54 @@ 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); + } } 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 * 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) +void sql_select_set_having (SqlSelect * obj, SqlExpr * expr) { 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) @@ -114,9 +199,15 @@ 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); - sql_object_remove (obj, obj->next); - obj->next = sql_object_add (obj, next); - obj->type = next ? type : SQL_SELECT_NONE; + g_clear_object (&obj->next); + + if (next) + { + obj->next = g_object_ref (next); + obj->type = type; + } + else + obj->type = SQL_SELECT_NONE; } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties @@ -124,12 +215,9 @@ 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 }; @@ -142,33 +230,21 @@ 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_NEXT: - sql_select_set_next (obj, g_value_get_object (value), obj->type); + case PROP_HAVING: + sql_select_set_having (obj, g_value_get_object (value)); 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); } @@ -182,30 +258,21 @@ 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_NEXT: - g_value_set_object (value, obj->next); + case PROP_HAVING: + g_value_set_object (value, obj->having); 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); } @@ -216,7 +283,8 @@ static void sql_select_get_property (SqlSelect * obj, guint id, static void sql_select_init (SqlSelect * obj) { obj->distinct = FALSE; - obj->fields = NULL; + obj->expr = NULL; + obj->alias = NULL; obj->group = NULL; obj->having = NULL; obj->order = NULL; @@ -226,83 +294,62 @@ static void sql_select_init (SqlSelect * obj) static void sql_select_finalize (SqlSelect * obj) { - g_object_unref (obj->group); - g_object_unref (obj->order); - sql_object_remove (obj, obj->fields); - sql_object_remove (obj, obj->having); - sql_object_remove (obj, obj->next); + 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); G_OBJECT_CLASS (sql_select_parent_class)->finalize (G_OBJECT (obj)); } -static void sql_select_class_init (SqlSelectClass * klass) +static void sql_select_class_init (SqlSelectClass * k) { - 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; + 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; - g_object_class_install_property (k, PROP_LIMIT_COUNT, + g_object_class_install_property (klass, PROP_LIMIT_COUNT, g_param_spec_boolean ("distinct" ,"Distinct" ,"Determines if the #SqlSelect uses the DISTINCT clause" - ,FALSE - ,G_PARAM_READWRITE + ,FALSE, G_PARAM_READWRITE )); - g_object_class_install_property (k, PROP_FIELDS, - sql_param_list ("fields" - ,"Fields" - ,"The list of fields" - ,SQL_TYPE_EXPR - ,G_PARAM_READWRITE - )); - g_object_class_install_property (k, PROP_GROUP, - sql_param_object ("group" - ,"Group" - ,"The GROUP BY section" - ,SQL_TYPE_EXPR - ,G_PARAM_READWRITE - )); - 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_object_class_install_property (k, PROP_LIMIT_COUNT, + + g_object_class_install_property (klass, 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 + ,0, G_MAXUINT, 0, G_PARAM_READWRITE )); - g_object_class_install_property (k, PROP_LIMIT_OFFSET, + + g_object_class_install_property (klass, 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 + ,0, G_MAXUINT, 0, 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_HAVING, + g_param_spec_object ("having" + ,"Having" + ,"The HAVING clause" + ,SQL_TYPE_EXPR, G_PARAM_READWRITE )); - g_object_class_install_property (k, PROP_TYPE, + + g_object_class_install_property (klass, PROP_TYPE, g_param_spec_int ("type" ,"Type" ,"One of the possible options of #SqlSelectType" - ,0, SQL_SELECT_COUNT - 1, 0 - ,G_PARAM_READWRITE + ,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 )); } diff --git a/sql/sql-select.h b/sql/sql-select.h index 420deb3..55120fe 100644 --- a/sql/sql-select.h +++ b/sql/sql-select.h @@ -19,8 +19,6 @@ #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)) @@ -40,6 +38,18 @@ 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): @@ -50,15 +60,16 @@ struct _SqlSelect { SqlDml parent; gboolean distinct; - SqlList * fields; - SqlList * group; + GSList * expr; + GSList * alias; // List of Sql.SelectAlias + GSList * group; SqlExpr * having; - SqlList * order; + GSList * order; guint limit_offset; guint limit_count; - SqlSelect * next; SqlSelectType type; + SqlSelect * next; }; struct _SqlSelectClass @@ -68,13 +79,13 @@ struct _SqlSelectClass }; GType sql_select_get_type (); -SqlObject * sql_select_new (); +SqlSelect * 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); 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, SqlSelectOrderWay way); +void sql_select_add_order (SqlSelect * obj, SqlExpr * expr, SqlOrderWay way); void sql_select_set_limit (SqlSelect * obj, guint count, guint offset); void sql_select_set_next (SqlSelect * obj, SqlSelect * next, SqlSelectType type); diff --git a/sql/sql-stmt.h b/sql/sql-stmt.h index adaf930..3cffb1e 100644 --- a/sql/sql-stmt.h +++ b/sql/sql-stmt.h @@ -41,5 +41,6 @@ struct _SqlStmtClass }; GType sql_stmt_get_type (); +gboolean sql_stmt_is_ready (SqlStmt * obj); #endif diff --git a/sql/sql-string.c b/sql/sql-string.c index 8d119b1..90f4656 100644 --- a/sql/sql-string.c +++ b/sql/sql-string.c @@ -16,15 +16,6 @@ */ #include "sql-string.h" -#include "sql-holder.h" - -typedef struct -{ - gchar * start; - gchar * end; - SqlHolder * holder; -} -HolderData; /** * SECTION: sql-string @@ -44,71 +35,81 @@ SqlString * sql_string_new (const gchar * sql) static void sql_string_render (SqlString * obj, SqlRender * render) { - GSList * i; - gchar * ptr = obj->sql; - - for (i = obj->holders; i; i = i->next) + guint n; + gsize pos; + gchar * i = obj->sql; + GSList * p = obj->params; + + for (n = 0; n < obj->positions->len && p; n++) { - 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, holder_data->holder); + pos = g_array_index (obj->positions, gsize, n); + g_string_append_len (render->buffer, i, (obj->sql + pos) - i); + i = obj->sql + pos + 2; + + sql_render_add_object (render, p->data); + p = p->next; } - sql_render_append (render, ptr); + sql_render_append (render, i); } -static void sql_string_free_holder_data (HolderData * holder_data) +static gboolean sql_string_is_ready (SqlString * obj) { - g_object_unref (holder_data->holder); - g_free (holder_data); + guint n; + GSList * p = obj->params; + + 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; } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public -/** - * sql_string_add_param: - * @obj: the #SqlString - * @id: the id assigned to the item - **/ -void sql_string_add_param (SqlString * obj, const gchar * id, GvnParam * param) +void sql_string_add_expr (SqlString * obj, SqlExpr * expr) +{ + 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_add_held_object (SQL_OBJECT (obj), id, SQL_OBJECT (value)); - g_object_unref (value); + sql_object_list_add (SQL_OBJECT (obj), &obj->params, SQL_OBJECT (value)); } -/** - * sql_string_add_value: - * @obj: the #SqlString - * @id: the id assigned to the item - **/ -void sql_string_add_value (SqlString * obj, const gchar * id, GType type, gpointer content) +void sql_string_add_value (SqlString * obj, GType type, gconstpointer content) { g_return_if_fail (SQL_IS_STRING (obj)); - GValue gvalue = {0}; - SqlExpr * value; + GValue value = {0}; + SqlExpr * expr; - gvn_value_new_with_content (&gvalue, type, content); - value = sql_value_new (); - sql_value_set_value (SQL_VALUE (value), &gvalue); - sql_object_add_held_object (SQL_OBJECT (obj), id, SQL_OBJECT (value)); - g_object_unref (value); - g_value_unset (&gvalue); + gvn_value_new_with_content (&value, type, 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); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties -enum +typedef enum { PROP_SQL = 1 -}; +} +SqlStringProp; static void sql_string_set_property (SqlString * obj, guint id, const GValue * value, GParamSpec * pspec) @@ -117,54 +118,35 @@ static void sql_string_set_property (SqlString * obj, guint id, { case PROP_SQL: { - gchar * i; + gchar * n; obj->sql = g_value_dup_string (value); + n = obj->sql; - if (obj->sql) - for (i = obj->sql; ; i++) + for (; n && *n != '\0'; n++) { - switch (*i) + switch (*n) { case '#': - { - 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 = sql_holder_new (holder_id); - g_free (holder_id); - + if (*(n+1) == 'p') + { + gsize pos = n - obj->sql; + g_array_append_val (obj->positions, pos); + n++; + } break; - } case '\'': - case '"': - case '`': - { - gchar delimiter = *i; - - while (*(++i) != delimiter) - if (*i == '\\') - i++; - + do { + n = g_strstr_len (++n, -1, "'"); + } + while (n && *(n-1) == '\\'); break; - } } - if (*i == '\0') + if (!n || *n == '\0') break; } - - obj->holders = g_slist_reverse (obj->holders); + break; } default: @@ -189,14 +171,16 @@ static void sql_string_get_property (SqlString * obj, guint id, static void sql_string_init (SqlString * obj) { - obj->holders = NULL; + obj->sql = NULL; + obj->params = NULL; + obj->positions = g_array_sized_new (FALSE, FALSE, sizeof (gsize), 5); } static void sql_string_finalize (SqlString * obj) { g_free (obj->sql); - g_slist_free_full (obj->holders, - (GDestroyNotify) sql_string_free_holder_data); + g_array_free (obj->positions, TRUE); + g_slist_free_full (obj->params, (GDestroyNotify) g_object_unref); G_OBJECT_CLASS (sql_string_parent_class)->finalize (G_OBJECT (obj)); } @@ -207,6 +191,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; g_object_class_install_property (klass, PROP_SQL, g_param_spec_string ("sql" diff --git a/sql/sql-string.h b/sql/sql-string.h index 75193d5..d55265f 100644 --- a/sql/sql-string.h +++ b/sql/sql-string.h @@ -32,13 +32,15 @@ typedef struct _SqlStringClass SqlStringClass; /** * SqlString: - * @expr: (element-type Sql.Expr): + * @params: (element-type GvnParam): + * @positions: (element-type gsize): **/ struct _SqlString { SqlStmt parent; gchar * sql; - GSList * holders; + GSList * params; + GArray * positions; }; struct _SqlStringClass @@ -49,7 +51,8 @@ struct _SqlStringClass GType sql_string_get_type (); SqlString * sql_string_new (const gchar * sql); -void sql_string_add_param (SqlString * obj, const gchar * id, GvnParam * param); -void sql_string_add_value (SqlString * obj, const gchar * id, GType type, gpointer content); +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); #endif diff --git a/sql/sql-subquery.c b/sql/sql-subquery.c index c7cdbf0..a99b7f1 100644 --- a/sql/sql-subquery.c +++ b/sql/sql-subquery.c @@ -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, TRUE, NULL, obj->select); + sql_render_add_item (render, T, 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) || !select); + g_return_if_fail (SQL_IS_SELECT (select)); - sql_object_remove (obj, obj->select); - obj->select = sql_object_add (obj, select); + g_clear_object (&obj->select); + obj->select = g_object_ref_sink (select); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties @@ -97,7 +97,7 @@ static void sql_subquery_init (SqlSubquery * obj) static void sql_subquery_finalize (SqlSubquery * obj) { - sql_object_remove (obj, obj->select); + g_clear_object (&obj->select); G_OBJECT_CLASS (sql_subquery_parent_class)->finalize (G_OBJECT (obj)); } @@ -110,10 +110,9 @@ 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, - sql_param_object ("select" - ,"Select" - ,"The SELECT statement" - ,SQL_TYPE_SELECT - ,G_PARAM_READWRITE + g_param_spec_object ("select" + , "Select" + , "An #SqlSelect" + , SQL_TYPE_SELECT, G_PARAM_READWRITE )); } diff --git a/sql/sql-table.c b/sql/sql-table.c index 6ef7056..034a47b 100644 --- a/sql/sql-table.c +++ b/sql/sql-table.c @@ -26,7 +26,7 @@ **/ G_DEFINE_TYPE (SqlTable, sql_table, SQL_TYPE_TARGET); -SqlObject * sql_table_new (const gchar * name) +SqlTarget * sql_table_new (const gchar * name) { return g_object_new (SQL_TYPE_TABLE, "name", name, NULL); } @@ -101,25 +101,27 @@ static void sql_table_finalize (SqlTable * obj) { 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)); } -static void sql_table_class_init (SqlTableClass * klass) +static void sql_table_class_init (SqlTableClass * k) { - 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; + 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; SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_table_render; - g_object_class_install_property (k, PROP_NAME, + g_object_class_install_property (klass, PROP_NAME, g_param_spec_string ("name" , "Name" , "The table name" , NULL, G_PARAM_READWRITE )); - g_object_class_install_property (k, PROP_SCHEMA, + g_object_class_install_property (klass, PROP_SCHEMA, g_param_spec_string ("schema" ,"Schema" ,"The schema where the table is" diff --git a/sql/sql-table.h b/sql/sql-table.h index 9544872..3ae671f 100644 --- a/sql/sql-table.h +++ b/sql/sql-table.h @@ -41,6 +41,6 @@ struct _SqlTableClass }; GType sql_table_get_type (); -SqlObject * sql_table_new (const gchar * name); +SqlTarget * sql_table_new (const gchar * name); #endif diff --git a/sql/sql-target.c b/sql/sql-target.c index 2dd8ace..a0b87c5 100644 --- a/sql/sql-target.c +++ b/sql/sql-target.c @@ -34,7 +34,9 @@ void sql_target_set_alias (SqlTarget * obj, const gchar * alias) g_return_if_fail (SQL_IS_TARGET (obj)); g_free (obj->alias); - obj->alias = g_strdup (alias); + + if (alias) + obj->alias = g_strdup (alias); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties @@ -72,17 +74,18 @@ static void sql_target_get_property (SqlTarget * obj, guint id, //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class -static void sql_target_init (SqlTarget * obj) -{ - obj->alias = NULL; -} - static void sql_target_finalize (SqlTarget * obj) { g_free (obj->alias); + obj->alias = NULL; G_OBJECT_CLASS (sql_target_parent_class)->finalize (G_OBJECT (obj)); } +static void sql_target_init (SqlTarget * obj) +{ + obj->alias = NULL; +} + static void sql_target_class_init (SqlTargetClass * k) { GObjectClass * klass = G_OBJECT_CLASS (k); @@ -92,9 +95,8 @@ 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 )); } diff --git a/sql/sql-update.c b/sql/sql-update.c index b582722..c84df94 100644 --- a/sql/sql-update.c +++ b/sql/sql-update.c @@ -26,92 +26,67 @@ **/ G_DEFINE_TYPE (SqlUpdate, sql_update, SQL_TYPE_DML); -SqlObject * sql_update_new () +SqlUpdate * 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, TRUE, "UPDATE", SQL_DML (obj)->targets, ","); + sql_render_add_list (render, T, "UPDATE", SQL_DML (obj)->target, ","); - if (SQL_DML (obj)->targets) + if (SQL_DML (obj)->target) { - sql_render_add_list (render, TRUE, "SET", obj->sets, ","); - sql_render_add_item (render, FALSE, "WHERE", SQL_DML (obj)->where); + 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); } } +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)); -} - -//+++++++++++++++++++++++++++++++++++++++++++++++++++ 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); - } + + 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); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class static void sql_update_init (SqlUpdate * obj) { - obj->sets = NULL; + obj->set = NULL; } static void sql_update_finalize (SqlUpdate * obj) { - sql_object_remove (obj, obj->sets); + g_slist_free_full (obj->set, (GFreeFunc) sql_update_set_free); G_OBJECT_CLASS (sql_update_parent_class)->finalize (G_OBJECT (obj)); } static void sql_update_class_init (SqlUpdateClass * klass) { - 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; + G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) sql_update_finalize; 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 - )); } diff --git a/sql/sql-update.h b/sql/sql-update.h index cb2d472..d02704a 100644 --- a/sql/sql-update.h +++ b/sql/sql-update.h @@ -20,7 +20,6 @@ #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)) @@ -29,13 +28,29 @@ 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; - SqlList * sets; // List of SqlUpdateSet + GSList * set; // List of SqlUpdateSet }; struct _SqlUpdateClass @@ -46,7 +61,7 @@ struct _SqlUpdateClass GType sql_update_get_type (); -SqlObject * sql_update_new (); +SqlUpdate * sql_update_new (); void sql_update_add_set (SqlUpdate * obj, SqlField * field, SqlExpr * expr); #endif diff --git a/sql/sql-value.c b/sql/sql-value.c index 7940aa5..d3aab28 100644 --- a/sql/sql-value.c +++ b/sql/sql-value.c @@ -28,12 +28,12 @@ **/ G_DEFINE_TYPE (SqlValue, sql_value, SQL_TYPE_EXPR); -SqlObject * sql_value_new () +SqlExpr * sql_value_new () { return g_object_new (SQL_TYPE_VALUE, NULL); } -SqlObject * sql_value_new_with_value (const GValue * value) +SqlExpr * 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); diff --git a/sql/sql-value.h b/sql/sql-value.h index 6b75448..2d6c735 100644 --- a/sql/sql-value.h +++ b/sql/sql-value.h @@ -42,10 +42,10 @@ struct _SqlValueClass }; GType sql_value_get_type (); -SqlObject * sql_value_new (); -SqlObject * sql_value_new_with_value (const GValue * value); +SqlExpr * sql_value_new (); +SqlExpr * sql_value_new_with_value (const GValue * value); const GValue * sql_value_get_value (SqlValue * obj); void sql_value_set_value (SqlValue * obj, const GValue * value); void sql_value_set_param (SqlValue * obj, GvnParam * param); -#endif +#endif \ No newline at end of file diff --git a/sql/sql.h b/sql/sql.h index 91c5d28..d7616fd 100644 --- a/sql/sql.h +++ b/sql/sql.h @@ -20,17 +20,11 @@ #include #include "sql-object.h" -#include "sql-holder.h" -#include "sql-list.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" diff --git a/vapi/Db-1.0.metadata b/vapi/Db-1.0.metadata index e4c464e..26e0116 100644 --- a/vapi/Db-1.0.metadata +++ b/vapi/Db-1.0.metadata @@ -1,10 +1,20 @@ Db cheader_filename="db/db.h" +Calc.function#property type="Db.CalcFunc" + +Conn.render.object#parameter type="GLib.Object" + +Iterator.params type="Db.Param" + +Model.get skip=false name="get_values" +Model.set skip=false name="set_values" +Model.search skip=false +// This is to overwrite the property in a custom vala file +// Model.main_table skip + +Plugin.render.object#parameter type="GLib.Object" + Iter struct Iter.*#method skip Row struct - -Model.get skip=false -Model.set skip=false -Model.search skip=false \ No newline at end of file diff --git a/vapi/Gvn-1.0.metadata b/vapi/Gvn-1.0.metadata index 0c3e898..5b207da 100644 --- a/vapi/Gvn-1.0.metadata +++ b/vapi/Gvn-1.0.metadata @@ -6,4 +6,4 @@ value_get_valist skip=false Param.value_changed#method name="emit_value_changed" //FIXME -ParamSpec struct \ No newline at end of file +//ParamSpec struct \ No newline at end of file diff --git a/vapi/Sql-1.0.metadata b/vapi/Sql-1.0.metadata index aa7ddbf..10e0dde 100644 --- a/vapi/Sql-1.0.metadata +++ b/vapi/Sql-1.0.metadata @@ -1 +1,8 @@ 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" \ No newline at end of file diff --git a/vapi/Vn-1.0.metadata b/vapi/Vn-1.0.metadata index e931908..9cd7791 100644 --- a/vapi/Vn-1.0.metadata +++ b/vapi/Vn-1.0.metadata @@ -5,4 +5,4 @@ Builder.bind_columns skip=false Grid.append_columns skip=false -Batch.objects skip \ No newline at end of file +Form.@get type="unowned GLib.Object" diff --git a/vn/Makefile.am b/vn/Makefile.am index 909060e..f3dc62b 100644 --- a/vn/Makefile.am +++ b/vn/Makefile.am @@ -54,6 +54,7 @@ vn_image_DATA = \ image/hedera16x16.xpm \ image/hedera32x32.xpm \ image/icon.svg \ + image/icon-debug.svg \ image/logo.svg \ image/load.gif vn_gui_DATA = \ @@ -68,9 +69,9 @@ gsettings_SCHEMAS = $(top_srcdir)/vn/schema/$(PACKAGE).gschema.xml DEFINES = \ -D_GUI_DIR=\"$(vn_guidir)\" \ - -D_VN_MODULE_QUERY_DIR=\"$(module_querydir)/sql\" \ -D_VN_MODULE_LIB_DIR=\"$(module_libdir)\" \ -D_VN_MODULE_DATA_DIR=\"$(module_datadir)\" \ + -D_VN_MODULE_QUERY_DIR=\"$(module_querydir)\" \ -D_HEDERA_LOCALE_DIR=\"$(datadir)/locale\" \ -D_DTD_DIR=\"$(vn_xmldir)\" diff --git a/vn/column/vn-column-combo.c b/vn/column/vn-column-combo.c index ce17af7..b2ba478 100644 --- a/vn/column/vn-column-combo.c +++ b/vn/column/vn-column-combo.c @@ -18,15 +18,29 @@ #include "vn-column-combo.h" #include "../vn-model.h" -G_DEFINE_TYPE (VnColumnCombo, vn_column_combo, VN_TYPE_COLUMN); +static void vn_column_combo_model_holder_interface_init (DbModelHolderInterface * iface); + +G_DEFINE_TYPE_WITH_CODE (VnColumnCombo, vn_column_combo, VN_TYPE_COLUMN, + G_IMPLEMENT_INTERFACE (DB_TYPE_MODEL_HOLDER, + vn_column_combo_model_holder_interface_init) +); static void vn_column_combo_on_status_changed (DbModel * model, - DbModelStatus status, VnColumn * obj) + DbModelStatus status, VnColumnCombo * obj) { if (status == DB_MODEL_STATUS_READY) - g_object_set (obj->cell, "model", VN_COLUMN_COMBO (obj)->tree_model, NULL); + { + g_object_set (VN_COLUMN (obj)->cell, "model", obj->tree_model, NULL); + + db_model_use_null_row (obj->model, VN_COLUMN (obj)->null); + } else - g_object_set (obj->cell, "model", NULL, NULL); + g_object_set (VN_COLUMN (obj)->cell, "model", NULL, NULL); +} + +static DbModel * vn_column_combo_get_model (VnColumnCombo * obj) +{ + return obj->model; } static void vn_column_combo_set_model (VnColumnCombo * obj, DbModel * model) @@ -55,18 +69,13 @@ static void vn_column_combo_set_value (VnColumnCombo * obj, GtkTreeModel * model { if (obj->model && db_model_get_status (obj->model) == DB_MODEL_STATUS_READY) { - if (gvn_value_is_null (value)) - { - g_object_set_property (cell, "text", value); - } - else - { - DbIter iter; + DbIter iter; - if (db_model_search_value (obj->model, obj->index_column, &iter, value)) - g_object_set_property (cell, "text", - db_model_get_value (obj->model, &iter, obj->show_column, NULL)); - } + if (gvn_value_is_null (value)) + g_object_set_property (cell, "text", value); + else if (db_model_search_value (obj->model, obj->index_column, &iter, value)) + g_object_set_property (cell, "text", + db_model_get_value (obj->model, &iter, obj->show_column, NULL)); } } @@ -79,31 +88,54 @@ static void vn_column_combo_restore_focus (VnColumnCombo * obj) (gtk_tree_view_column_get_tree_view (GTK_TREE_VIEW_COLUMN (obj))); } +/* + * Sets the value of the entry to an empty string if a null value is selected. + */ +static gchar * vn_column_combo_on_format_entry_text (GtkComboBox * combo, + gchar * path, VnColumnCombo * obj) +{ + gchar * str; + GtkTreeIter iter; + + gtk_tree_model_get_iter_from_string (obj->tree_model, &iter, path); + gtk_tree_model_get (obj->tree_model, &iter, obj->show_column, &str, -1); + + return str ? str : g_strdup (""); +} + /* * Sets the autocompletion functionality to the cell being edited. */ static void vn_column_combo_on_editing_started (GtkCellRenderer * cell, - GtkCellEditable * editable, const gchar * path, VnColumnCombo * obj) + GtkCellEditable * cell_editable, const gchar * path, VnColumnCombo * obj) { GtkEntry * entry; - if (!GTK_IS_COMBO_BOX (editable) || !obj->tree_model) + if (!GTK_IS_COMBO_BOX (cell_editable) || !obj->tree_model) return; - entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (editable))); + entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (cell_editable))); if (!obj->completion_ready) { gtk_entry_completion_set_model (obj->completion, obj->tree_model); - g_object_set (obj->completion, "text-column", obj->show_column, NULL); + gtk_entry_completion_set_text_column (obj->completion, obj->show_column); obj->completion_ready = TRUE; - g_signal_connect_swapped (editable, "editing-done", + g_signal_connect_swapped (cell_editable, "editing-done", G_CALLBACK (vn_column_combo_restore_focus), obj); - obj->editable = editable; + obj->cell_editable = cell_editable; } gtk_entry_set_completion (entry, obj->completion); + + // Each edition uses a new cell_editable. + if (obj->cell_editable) + g_signal_handlers_disconnect_by_func (obj->cell_editable, + vn_column_combo_on_format_entry_text, obj); + + g_signal_connect (cell_editable, "format-entry-text", + G_CALLBACK (vn_column_combo_on_format_entry_text), obj); } /* @@ -115,14 +147,23 @@ static void vn_column_combo_on_edited (GtkCellRendererText *renderer, { DbIter iter; GValue value = {0}; - gvn_value_new_with_content (&value, G_TYPE_STRING, new_text); - if (db_model_search_value (obj->model, obj->show_column, &iter, &value)) + if (!g_strcmp0 (new_text, "")) { - const GValue * value; + g_value_init (&value, GVN_TYPE_NULL); + VN_COLUMN_GET_CLASS (obj)->value_changed (VN_COLUMN (obj), path, &value); + } + else + { + gvn_value_new_with_content (&value, G_TYPE_STRING, new_text); - if ((value = db_model_get_value (obj->model, &iter, obj->index_column, NULL))) - VN_COLUMN_GET_CLASS (obj)->value_changed (VN_COLUMN (obj), path, value); + if (db_model_search_value (obj->model, obj->show_column, &iter, &value)) + { + const GValue * val; + + if ((val = db_model_get_value (obj->model, &iter, obj->index_column, NULL))) + VN_COLUMN_GET_CLASS (obj)->value_changed (VN_COLUMN (obj), path, val); + } } g_value_unset (&value); @@ -133,7 +174,6 @@ static void vn_column_combo_on_edited (GtkCellRendererText *renderer, static void vn_column_combo_set_editable (VnColumnCombo * obj, gboolean editable) { VnColumn * parent = VN_COLUMN (obj); - g_object_set (parent->cell, "editable", editable, NULL); if (editable) { @@ -149,21 +189,29 @@ static void vn_column_combo_set_editable (VnColumnCombo * obj, gboolean editable } else { - g_signal_handlers_disconnect_by_func (parent->cell, - vn_column_combo_on_editing_started, obj); - g_signal_handlers_disconnect_by_func (parent->cell, - vn_column_combo_on_edited, obj); - g_signal_handlers_disconnect_by_func (parent->cell, - vn_column_combo_restore_focus, obj); + g_signal_handlers_disconnect_by_data (parent->cell, obj); - if (obj->editable) - g_signal_handlers_disconnect_by_func (obj->editable, - vn_column_combo_restore_focus, obj); + if (obj->cell_editable) + g_signal_handlers_disconnect_by_data (obj->cell_editable, obj); obj->completion = NULL; obj->completion_ready = FALSE; - obj->editable = NULL; + obj->cell_editable = NULL; } + + g_object_set (parent->cell, "editable", editable, NULL); +} + +static void vn_column_combo_set_null (VnColumnCombo * obj, gboolean null) +{ + if (vn_column_get_model (VN_COLUMN (obj)) && obj->model) + db_model_use_null_row (obj->model, null); +} + +static void vn_column_combo_model_changed (VnColumnCombo * obj) +{ + if (obj->model) + db_model_use_null_row (obj->model, VN_COLUMN (obj)->null); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties @@ -173,8 +221,6 @@ enum PROP_INDEX_COLUMN = 1 ,PROP_SHOW_COLUMN ,PROP_MODEL - ,PROP_CONN - ,PROP_SQL }; static void vn_column_combo_set_property (VnColumnCombo * obj, guint id, @@ -193,22 +239,6 @@ static void vn_column_combo_set_property (VnColumnCombo * obj, guint id, case PROP_MODEL: vn_column_combo_set_model (obj, g_value_get_object (value)); break; - case PROP_CONN: - db_model_set_conn (obj->model, g_value_get_object (value)); - break; - case PROP_SQL: - { - const gchar * sql = g_value_get_string (value); - - if (sql) - { - DbModel * model = db_model_new_with_sql (NULL, g_value_get_string (value)); - vn_column_combo_set_model (obj, model); - g_object_unref (model); - } - - break; - } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); } @@ -228,9 +258,6 @@ static void vn_column_combo_get_property (VnColumnCombo * obj, guint id, case PROP_MODEL: g_value_set_object (value, obj->model); break; - case PROP_CONN: - g_value_set_object (value, db_model_get_conn (obj->model)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); } @@ -245,7 +272,7 @@ static void vn_column_combo_init (VnColumnCombo * obj) obj->tree_model = NULL; obj->completion = NULL; obj->completion_ready = FALSE; - obj->editable = NULL; + obj->cell_editable = NULL; VN_COLUMN_GET_CLASS (obj)->set_renderer (VN_COLUMN (obj), cell); } @@ -263,6 +290,10 @@ static void vn_column_combo_class_init (VnColumnComboClass * klass) k->get_property = (GObjectGetPropertyFunc) vn_column_combo_get_property; VN_COLUMN_CLASS (klass)->set_value = (VnColumnSetValueFunc) vn_column_combo_set_value; VN_COLUMN_CLASS (klass)->set_editable = (VnColumnSetEditableFunc) vn_column_combo_set_editable; + VN_COLUMN_CLASS (klass)->set_null = (VnColumnSetNullFunc) vn_column_combo_set_null; + VN_COLUMN_CLASS (klass)->model_changed = (VnColumnModelChangedFunc) vn_column_combo_model_changed; + + g_object_class_override_property (k, PROP_MODEL, "model"); g_object_class_install_property (k, PROP_INDEX_COLUMN, g_param_spec_uint ("index-column" @@ -278,25 +309,10 @@ static void vn_column_combo_class_init (VnColumnComboClass * klass) ,0, 255, 1 ,G_PARAM_CONSTRUCT | G_PARAM_READWRITE )); - g_object_class_install_property (k, PROP_MODEL, - g_param_spec_object ("model" - ,_("Model") - ,_("The model from which the combo takes the values shown in the list") - ,DB_TYPE_MODEL - ,G_PARAM_READWRITE - )); - g_object_class_install_property (k, PROP_CONN, - g_param_spec_object ("conn" - ,_("Connection") - ,_("The connection used by the model") - ,DB_TYPE_CONN - ,G_PARAM_READWRITE - )); - g_object_class_install_property (k, PROP_SQL, - g_param_spec_string ("sql" - ,_("SQL") - ,_("The SQL query used to create the model") - , NULL - ,G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE - )); +} + +static void vn_column_combo_model_holder_interface_init (DbModelHolderInterface * iface) +{ + iface->get_model = (DbModelHolderGetModelFunc) vn_column_combo_get_model; + iface->set_model = (DbModelHolderSetModelFunc) vn_column_combo_set_model; } diff --git a/vn/column/vn-column-combo.h b/vn/column/vn-column-combo.h index 4ae712f..67f50d4 100644 --- a/vn/column/vn-column-combo.h +++ b/vn/column/vn-column-combo.h @@ -40,7 +40,7 @@ struct _VnColumnCombo guint show_column; GtkEntryCompletion * completion; gboolean completion_ready; - GtkCellEditable * editable; + GtkCellEditable * cell_editable; }; struct _VnColumnComboClass diff --git a/vn/column/vn-column-image.c b/vn/column/vn-column-image.c index 5177f6c..3657fd3 100644 --- a/vn/column/vn-column-image.c +++ b/vn/column/vn-column-image.c @@ -117,7 +117,7 @@ static void vn_column_image_on_download_tooltip (DbFileLoader * fl, { GdkPixbuf * pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - if (data->image) + if (data->image && G_IS_OBJECT (data->image)) g_object_unref (data->image); data->image = g_object_ref_sink (gtk_image_new_from_pixbuf (pixbuf)); @@ -293,7 +293,7 @@ static void vn_column_image_set_value (VnColumnImage * obj, GtkTreeModel * model return; } - else + else { gint view_x, view_y; GdkRectangle view_rect, cell_rect; @@ -325,12 +325,14 @@ static void vn_column_image_set_value (VnColumnImage * obj, GtkTreeModel * model obj->loader = db_file_loader_new (obj->host, obj->path); if (obj->tooltip_path && !obj->tooltips) + { obj->tooltips = g_hash_table_new_full ((GHashFunc) g_direct_hash, (GEqualFunc) g_direct_equal, (GDestroyNotify) NULL, (GDestroyNotify) free_tooltip_data); g_object_set (view, "has-tooltip", TRUE, NULL); g_signal_connect (view, "query-tooltip", G_CALLBACK (vn_column_image_on_query_tooltip), obj); + } data = g_new (DownloadData, 1); data->obj = g_object_ref (obj); @@ -344,8 +346,6 @@ static void vn_column_image_set_value (VnColumnImage * obj, GtkTreeModel * model } } -static void vn_column_image_set_editable (VnColumn * obj, gboolean editable){} - static void vn_column_image_on_model_changed (VnColumnImage * obj) { if (obj->loader) @@ -366,6 +366,8 @@ static void vn_column_image_on_model_changed (VnColumnImage * obj) obj->tooltips = NULL; } +static void vn_column_image_set_editable (VnColumn * obj, gboolean editable){} + //+++++++++++++++++++++++++++++++++++++++++++++++++++ Property enum @@ -447,7 +449,7 @@ static void vn_column_image_finalize (VnColumnImage * obj) if (obj->loader) { db_file_loader_cancel_all (obj->loader); - g_object_unref (obj->loader); + g_object_unref (obj->loader);//XXX } if (obj->loaded) diff --git a/vn/column/vn-column-image.h b/vn/column/vn-column-image.h index 6c12ac3..47ee0f8 100644 --- a/vn/column/vn-column-image.h +++ b/vn/column/vn-column-image.h @@ -39,11 +39,12 @@ struct _VnColumnImage VnColumn parent; gchar * host; gchar * path; - gchar * tooltip_path; - gint tooltip_size; DbFileLoader * loader; GHashTable * loaded; + gchar * tooltip_path; + gint tooltip_size; GHashTable * tooltips; + }; struct _VnColumnImageClass diff --git a/vn/column/vn-column-spin.c b/vn/column/vn-column-spin.c index 9145a4c..dcf05bf 100644 --- a/vn/column/vn-column-spin.c +++ b/vn/column/vn-column-spin.c @@ -19,12 +19,95 @@ G_DEFINE_TYPE (VnColumnSpin, vn_column_spin, VN_TYPE_COLUMN); +static void vn_column_entry_cb_edited (GtkCellRendererText * cell, + const gchar * path, gchar * text, VnColumnSpin * obj) +{ + GValue value = {0}; + + if (g_strcmp0 (text, "")) + { + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, text); + } + else + g_value_init (&value, GVN_TYPE_NULL); + + VN_COLUMN_GET_CLASS (obj)->value_changed (VN_COLUMN (obj), path, &value); + g_value_unset (&value); +} + +static void vn_column_spin_set_editable (VnColumn * obj, gboolean editable) +{ + g_object_set (obj->cell, "editable", editable, NULL); + + if (editable) + g_signal_connect (obj->cell, "edited", + G_CALLBACK (vn_column_entry_cb_edited), obj); + else + g_signal_handlers_disconnect_by_func (obj->cell, + vn_column_entry_cb_edited, obj); +} + +static void vn_column_spin_set_value (VnColumnSpin * obj, GtkTreeModel * model, + GtkTreeIter * iter, GtkCellRenderer * cell, const GValue * value) +{ +} + //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class +enum +{ + PROP_CLIMB_RATE = 1 + ,PROP_DIGITS + ,PROP_VALUE_TYPE +}; + +static void vn_column_spin_set_property (VnColumnSpin * obj, guint id, + const GValue * value, GParamSpec * pspec) +{ + switch (id) + { + case PROP_CLIMB_RATE: + g_object_set (VN_COLUMN (obj)->cell, + "climb-rate", g_value_get_double (value), NULL); + break; + case PROP_DIGITS: + g_object_set (VN_COLUMN (obj)->cell, + "digits", g_value_get_uint (value), NULL); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); + } +} +static void vn_column_spin_get_property (VnColumnSpin * obj, guint id, + GValue * value, GParamSpec * pspec) +{ + switch (id) + { + case PROP_CLIMB_RATE: + { + gdouble climb_rate; + g_object_get (value, "climb-rate", &climb_rate, NULL); + g_value_set_double (value, climb_rate); + break; + } + case PROP_DIGITS: + { + guint digits; + g_object_get (VN_COLUMN (obj)->cell, "digits", &digits, NULL); + g_value_set_uint (value, digits); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); + } +} + static void vn_column_spin_init (VnColumnSpin * obj) { GtkCellRenderer * cell = gtk_cell_renderer_spin_new (); VN_COLUMN_GET_CLASS (obj)->set_renderer (VN_COLUMN (obj), cell); +//??g_object_bind_property (obj, "digits", VN_COLUMN (obj)->cell, "digits"); } static void vn_column_spin_finalize (VnColumnSpin * obj) @@ -35,5 +118,26 @@ static void vn_column_spin_finalize (VnColumnSpin * obj) static void vn_column_spin_class_init (VnColumnSpinClass * klass) { GObjectClass * k = G_OBJECT_CLASS (klass); + VnColumnClass * col_k = VN_COLUMN_CLASS (klass); k->finalize = (GObjectFinalizeFunc) vn_column_spin_finalize; + k->set_property = (GObjectSetPropertyFunc) vn_column_spin_set_property; + k->get_property = (GObjectGetPropertyFunc) vn_column_spin_get_property; + col_k->set_value = (VnColumnSetValueFunc) vn_column_spin_set_value; + col_k->set_editable = (VnColumnSetEditableFunc) vn_column_spin_set_editable; + + g_object_class_install_property (k, PROP_CLIMB_RATE, + g_param_spec_double ("climb-rate" + ,_("Climb rate") + ,_("The acceleration rate when you hold down a button.") + ,0 ,0 ,0 + ,G_PARAM_CONSTRUCT | G_PARAM_READWRITE + )); + + g_object_class_install_property (k, PROP_DIGITS, + g_param_spec_uint ("digits" + ,_("Digits") + ,_("The number of decimal places to display.") + ,0 ,20 ,0 + ,G_PARAM_CONSTRUCT | G_PARAM_READWRITE + )); } diff --git a/vn/field/Makefile.am b/vn/field/Makefile.am index 10f75cd..580796f 100644 --- a/vn/field/Makefile.am +++ b/vn/field/Makefile.am @@ -14,6 +14,7 @@ field_include_HEADERS = \ vn-http-image.h AM_CPPFLAGS = \ + -D_IMAGE_DIR=\"$(vn_imagedir)\" \ -I$(top_srcdir) \ $(gtk_CFLAGS) libvnfield_la_LIBADD = $(gtk_LIBS) diff --git a/vn/field/vn-combo.c b/vn/field/vn-combo.c index 8d4d5a4..93b33e0 100644 --- a/vn/field/vn-combo.c +++ b/vn/field/vn-combo.c @@ -28,8 +28,14 @@ * * A combo box widget to select from a list of items, selected from a * database. - */ -G_DEFINE_TYPE (VnCombo, vn_combo, VN_TYPE_FIELD); + */ + +static void vn_combo_model_holder_interface_init (DbModelHolderInterface * iface); + +G_DEFINE_TYPE_WITH_CODE (VnCombo, vn_combo, VN_TYPE_FIELD, + G_IMPLEMENT_INTERFACE (DB_TYPE_MODEL_HOLDER, + vn_combo_model_holder_interface_init) +); /** * vn_combo_new: @@ -44,20 +50,6 @@ VnField * vn_combo_new (DbModel * model) return g_object_new (VN_TYPE_COMBO, "model", model, NULL); } -/** - * vn_combo_new_with_sql: - * @conn: the connection used to create the combo model - * @sql: the SQL query used to create the combo model - * - * Creates a new #VnCombo - * - * Return value: a #VnCombo - **/ -VnField * vn_combo_new_with_sql (DbConn * conn, const gchar * sql) -{ - return g_object_new (VN_TYPE_COMBO, "sql", sql, "conn", conn, NULL); -} - //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private static void vn_combo_cb_changed (GtkComboBox * combo, VnCombo * obj) @@ -108,37 +100,20 @@ static void vn_combo_cb_status_changed (DbModel * model, DbModelStatus status, V { gtk_combo_box_set_model (obj->combo, obj->tree); vn_combo_on_model_ready (obj, vn_field_get_value (VN_FIELD (obj))); + + db_model_use_null_row (model, vn_field_get_null (VN_FIELD (obj))); } else gtk_combo_box_set_model (obj->combo, NULL); } -//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public -/** - * vn_combo_set_conn: - * @obj: a #VnCombo - * @conn: the #DbConn - * - * Sets the connection used to create the combo model. - **/ -void vn_combo_set_conn (VnCombo * obj, DbConn * conn) +static DbModel * vn_combo_get_model (VnCombo * obj) { - g_return_if_fail (VN_IS_COMBO (obj)); - g_return_if_fail (DB_IS_CONN (conn)); - g_return_if_fail (obj->model); - - db_model_set_conn (obj->model, conn); + return obj->model; } -/** - * vn_combo_set_model: - * @obj: a #VnCombo - * @model: the #DbModel - * - * Sets the SQL query used to create the combo model. - **/ -void vn_combo_set_model (VnCombo * obj, DbModel * model) +static void vn_combo_set_model (VnCombo * obj, DbModel * model) { g_return_if_fail (VN_IS_COMBO (obj)); g_return_if_fail (DB_IS_MODEL (model) || !model); @@ -161,6 +136,8 @@ void vn_combo_set_model (VnCombo * obj, DbModel * model) } } +//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public + /** * vn_combo_get_index_column: * @obj: a #VnCombo @@ -230,8 +207,6 @@ enum PROP_INDEX_COLUMN = 1 ,PROP_SHOW_COLUMN ,PROP_MODEL - ,PROP_CONN - ,PROP_SQL }; static void vn_combo_set_property (VnCombo * obj, guint property_id, @@ -248,22 +223,6 @@ static void vn_combo_set_property (VnCombo * obj, guint property_id, case PROP_MODEL: vn_combo_set_model (obj, g_value_get_object (value)); break; - case PROP_CONN: - vn_combo_set_conn (obj, g_value_get_object (value)); - break; - case PROP_SQL: - { - const gchar * sql = g_value_get_string (value); - - if (sql) - { - DbModel * model = db_model_new_with_sql (NULL, g_value_get_string (value)); - vn_combo_set_model (obj, model); - g_object_unref (model); - } - - break; - } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); } @@ -283,9 +242,6 @@ static void vn_combo_get_property (VnCombo * obj, guint property_id, case PROP_MODEL: g_value_set_object (value, obj->model); break; - case PROP_CONN: - g_value_set_object (value, db_model_get_conn (obj->model)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); } @@ -323,6 +279,8 @@ static void vn_combo_class_init (VnComboClass * klass) k->get_property = (GObjectGetPropertyFunc) vn_combo_get_property; VN_FIELD_CLASS (klass)->set_value = (VnFieldSetValueFunc) vn_combo_set_value; + g_object_class_override_property (k, PROP_MODEL, "model"); + g_object_class_install_property (k, PROP_INDEX_COLUMN, g_param_spec_uint ("index-column" ,_("Index column") @@ -337,25 +295,10 @@ static void vn_combo_class_init (VnComboClass * klass) ,0, 255, 1 ,G_PARAM_CONSTRUCT | G_PARAM_READWRITE )); - g_object_class_install_property (k, PROP_MODEL, - g_param_spec_object ("model" - ,_("Model") - ,_("The model from which the combo takes the values shown in the list") - ,DB_TYPE_MODEL - ,G_PARAM_READWRITE - )); - g_object_class_install_property (k, PROP_CONN, - g_param_spec_object ("conn" - ,_("Connection") - ,_("The connection used by the model") - ,DB_TYPE_CONN - ,G_PARAM_READWRITE - )); - g_object_class_install_property (k, PROP_SQL, - g_param_spec_string ("sql" - ,_("SQL") - ,_("The SQL query used to create the model") - , NULL - ,G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE - )); +} + +static void vn_combo_model_holder_interface_init (DbModelHolderInterface * iface) +{ + iface->get_model = (DbModelHolderGetModelFunc) vn_combo_get_model; + iface->set_model = (DbModelHolderSetModelFunc) vn_combo_set_model; } diff --git a/vn/field/vn-combo.h b/vn/field/vn-combo.h index 34436a7..0cbdfba 100644 --- a/vn/field/vn-combo.h +++ b/vn/field/vn-combo.h @@ -33,6 +33,7 @@ typedef struct _VnComboClass VnComboClass; struct _VnCombo { VnField parent; +/* */ DbModel * model; GtkComboBox * combo; GtkCellRenderer * cell; @@ -49,9 +50,6 @@ struct _VnComboClass GType vn_combo_get_type (); VnField * vn_combo_new (DbModel * model); -VnField * vn_combo_new_with_sql (DbConn * conn, const gchar * sql); -void vn_combo_set_conn (VnCombo * obj, DbConn * conn); -void vn_combo_set_model (VnCombo * obj, DbModel * model); guint vn_combo_get_index_column (VnCombo * obj); void vn_combo_set_index_column (VnCombo * obj, guint column); guint vn_combo_get_show_column (VnCombo * obj); diff --git a/vn/field/vn-completion.c b/vn/field/vn-completion.c index 5e00843..6a7415e 100644 --- a/vn/field/vn-completion.c +++ b/vn/field/vn-completion.c @@ -31,21 +31,28 @@ * * A text box widget that auto-completes as the user writes using the data * retrieved from a database. - */ -G_DEFINE_TYPE (VnCompletion, vn_completion, VN_TYPE_FIELD); + */ + +static void vn_completion_model_holder_interface_init (DbModelHolderInterface * iface); + +G_DEFINE_TYPE_WITH_CODE (VnCompletion, vn_completion, VN_TYPE_FIELD, + G_IMPLEMENT_INTERFACE (DB_TYPE_MODEL_HOLDER, + vn_completion_model_holder_interface_init) +); /** * vn_completion_new: - * @sql: the SQL string used by completion. - * @field: the field where to search the values. + * @model: a #DbModel with the contents for the new completion. + * @field: the name of the field to search the values in. * - * Creates a new #VnCompletion. + * Creates a new #VnCompletion that will complete text with the data contained + * in the field named @field of @model. * * Return value: a #VnCompletion. **/ -VnField * vn_completion_new (const gchar * sql, const gchar * field) +VnField * vn_completion_new (DbModel * model, const gchar * field) { - return g_object_new (VN_TYPE_COMPLETION, "sql", sql, "field", field, NULL); + return g_object_new (VN_TYPE_COMPLETION, "model", model, "field", field, NULL); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private @@ -92,7 +99,7 @@ static void vn_completion_cb_changed (GtkEditable * entry, VnCompletion * obj) set_icon (obj, NULL); } - if (obj->sql && strlen (text) == 1 + if (obj->model && strlen (text) == 1 && (!obj->last_match || g_strcmp0 (text, obj->last_match))) { gchar * pattern; @@ -183,35 +190,54 @@ static gboolean vn_completion_match_selected (GtkEntryCompletion * completion, return FALSE; } -static void vn_completion_create_model (VnCompletion * obj) +static void vn_completion_substitute (VnCompletion * obj) { SqlExpr * field; SqlString * stmt; SqlOperation * op; - - if (!(obj->sql && obj->field)) + + if (!(obj->model && obj->field)) return; + g_object_get (obj->model, "stmt", &stmt, NULL); + op = sql_operation_new (SQL_OPERATION_TYPE_LIKE); - + field = sql_field_new (obj->field, NULL, NULL); sql_operation_add_expr (op, field); obj->value = sql_value_new (); sql_operation_add_expr (op, obj->value); - stmt = sql_string_new (obj->sql); sql_string_add_expr (stmt, field); sql_string_add_expr (stmt, SQL_EXPR (op)); - db_model_set_stmt (obj->model, SQL_STMT (stmt)); +} + +static void vn_completion_set_field (VnCompletion * obj, gchar * field) +{ + obj->field = field; + vn_completion_substitute (obj); +} + +static DbModel * vn_completion_get_model (VnCompletion * obj) +{ + return obj->model; +} + +static void vn_completion_set_model (VnCompletion * obj, DbModel * model) +{ + obj->model = model; + g_signal_connect (obj->model, "status-changed", + G_CALLBACK (vn_completion_cb_status_changed), obj); + + vn_completion_substitute (obj); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties enum { - PROP_CONN = 1 - ,PROP_SQL + PROP_MODEL = 1 ,PROP_FIELD }; @@ -220,16 +246,11 @@ static void vn_completion_set_property (VnCompletion * obj, guint property_id, { switch (property_id) { - case PROP_CONN: - db_model_set_conn (obj->model, g_value_get_object (value)); - break; - case PROP_SQL: - obj->sql = g_value_dup_string (value); - vn_completion_create_model (obj); + case PROP_MODEL: + vn_completion_set_model (obj, g_value_dup_object (value)); break; case PROP_FIELD: - obj->field = g_value_dup_string (value); - vn_completion_create_model (obj); + vn_completion_set_field (obj, g_value_dup_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); @@ -241,8 +262,8 @@ static void vn_completion_get_property (VnCompletion * obj, guint property_id, { switch (property_id) { - case PROP_CONN: - g_value_set_object (value, db_model_get_conn (obj->model)); + case PROP_MODEL: + g_value_set_object (value, obj->model); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); @@ -254,8 +275,7 @@ static void vn_completion_get_property (VnCompletion * obj, guint property_id, static void vn_completion_init (VnCompletion * obj) { GtkEntryCompletion * completion; - - obj->sql = NULL; + obj->field = NULL; obj->last_match = NULL; obj->invalid = FALSE; @@ -280,15 +300,10 @@ static void vn_completion_init (VnCompletion * obj) G_CALLBACK (vn_completion_match_selected), obj); gtk_entry_set_completion (obj->entry, completion); obj->completion = completion; - - obj->model = db_model_new (NULL, NULL); - g_signal_connect (obj->model, "status-changed", - G_CALLBACK (vn_completion_cb_status_changed), obj); } static void vn_completion_finalize (VnCompletion * obj) { - g_free (obj->sql); g_free (obj->field); g_free (obj->last_match); g_object_unref (obj->completion); @@ -303,20 +318,8 @@ static void vn_completion_class_init (VnCompletionClass * klass) k->set_property = (GObjectSetPropertyFunc) vn_completion_set_property; k->get_property = (GObjectGetPropertyFunc) vn_completion_get_property; - g_object_class_install_property (k, PROP_CONN, - g_param_spec_object ("conn" - ,_("Connection") - ,_("The connection used by the model") - ,DB_TYPE_CONN - ,G_PARAM_READWRITE - )); - g_object_class_install_property (k, PROP_SQL, - g_param_spec_string ("sql" - ,_("SQL") - ,_("The SQL query used to create the model") - ,NULL - ,G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY - )); + g_object_class_override_property (k, PROP_MODEL, "model"); + g_object_class_install_property (k, PROP_FIELD, g_param_spec_string ("field" ,_("Field") @@ -325,3 +328,9 @@ static void vn_completion_class_init (VnCompletionClass * klass) ,G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY )); } + +static void vn_completion_model_holder_interface_init (DbModelHolderInterface * iface) +{ + iface->get_model = (DbModelHolderGetModelFunc) vn_completion_get_model; + iface->set_model = (DbModelHolderSetModelFunc) vn_completion_set_model; +} \ No newline at end of file diff --git a/vn/field/vn-completion.h b/vn/field/vn-completion.h index 7bbac31..b3d3371 100644 --- a/vn/field/vn-completion.h +++ b/vn/field/vn-completion.h @@ -38,10 +38,9 @@ struct _VnCompletion gboolean invalid; guint column; gchar * last_match; - DbModel * model; SqlExpr * value; + DbModel * model; gchar * field; - gchar * sql; }; struct _VnCompletionClass @@ -51,6 +50,6 @@ struct _VnCompletionClass }; GType vn_completion_get_type (); -VnField * vn_completion_new (const gchar * sql, const gchar * field); +VnField * vn_completion_new (DbModel * model, const gchar * field); #endif \ No newline at end of file diff --git a/vn/field/vn-http-image.c b/vn/field/vn-http-image.c index ec5c6c0..06a1d1b 100644 --- a/vn/field/vn-http-image.c +++ b/vn/field/vn-http-image.c @@ -18,11 +18,12 @@ #include "vn-http-image.h" #include +#define LOAD_IMAGE _IMAGE_DIR"/load.gif" /* * img: an icon name * msg: text message or NULL */ -#define set_icon(img, msg) \ +#define SET_ICON(img, msg) \ g_object_set \ (obj->priv->image, "icon-name", img, \ "icon-size", GTK_ICON_SIZE_MENU, NULL); \ @@ -69,7 +70,7 @@ static void vn_http_image_cb_error (VnHttpImage * obj, const GError * error) gchar * e = error ? error->message : _("Undefined error"); const gchar * name = g_value_get_string (vn_field_get_value (VN_FIELD (obj))); g_warning ("VnHttpImage (%s%s): %s", obj->priv->path, name, e); - set_icon ("image-missing", e); + SET_ICON ("missing-image", e); } static void vn_http_image_cb_download @@ -78,12 +79,8 @@ static void vn_http_image_cb_download gtk_widget_set_tooltip_text (GTK_WIDGET (obj->priv->image), NULL); if (error) - { vn_http_image_cb_error (obj, error); - return; - } - - if (bytes) + else if (bytes) { gsize len; const gchar * data = g_bytes_get_data (bytes, &len); @@ -115,8 +112,8 @@ static void vn_http_image_set_value (VnHttpImage * obj, const GValue * value) { gchar * full_path = g_strconcat (obj->priv->path, "/", g_value_get_string (value), NULL); - set_icon ("view-refresh", _("Loading")); + SET_ICON ("view-refresh", _("Loading")); db_file_loader_download (obj->priv->loader, full_path, (DbFileLoaderCallbackFunc) vn_http_image_cb_download, obj); g_free (full_path); @@ -181,7 +178,7 @@ static void vn_http_image_init (VnHttpImage * obj) obj->priv->image = GTK_IMAGE (gtk_image_new ()); //Se usará para subir imagenes y cambiar nombres, o abrir un menu contextual // g_signal_connect (obj, "event", G_CALLBACK (vn_http_image_cb_event), obj); - set_icon ("image-missing", _("No image set")); + SET_ICON ("missing-image", _("No image set")); gtk_container_add (GTK_CONTAINER (obj), GTK_WIDGET (obj->priv->image)); VN_FIELD (obj)->field = GTK_WIDGET (obj->priv->image); diff --git a/vn/gui/login.glade b/vn/gui/login.glade index 017ff1d..d87d1fc 100644 --- a/vn/gui/login.glade +++ b/vn/gui/login.glade @@ -24,11 +24,9 @@ gtk-cancel - False True True True - False True @@ -41,14 +39,12 @@ gtk-apply - False True True True - False True - + @@ -323,11 +319,9 @@ Remember - False True True False - False 0 True @@ -357,11 +351,9 @@ gtk-edit - False True False True - False True @@ -374,14 +366,12 @@ gtk-connect - False True True True - False True - + @@ -390,6 +380,21 @@ 1 + + + gtk-cancel + True + True + True + True + + + + False + True + 2 + + False diff --git a/vn/image/icon-debug.svg b/vn/image/icon-debug.svg new file mode 100644 index 0000000..979f5ba --- /dev/null +++ b/vn/image/icon-debug.svg @@ -0,0 +1,419 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/vn/image/icon.svg b/vn/image/icon.svg index 010caec..6f0807d 100644 --- a/vn/image/icon.svg +++ b/vn/image/icon.svg @@ -18,541 +18,391 @@ viewBox="0 0 150.00001 116.64392" enable-background="new 0 0 272.352 211.738" xml:space="preserve" - inkscape:version="0.48.1 r9760" + inkscape:version="0.48.4 r9939" sodipodi:docname="icon.svg">image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + id="metadata262">image/svg+xml \ No newline at end of file diff --git a/vn/vn-batch.c b/vn/vn-batch.c index 1938ee6..95d621c 100644 --- a/vn/vn-batch.c +++ b/vn/vn-batch.c @@ -40,6 +40,7 @@ void vn_batch_add (VnBatch * obj, GObject * child) g_return_if_fail (G_IS_OBJECT (child)); obj->objects = g_list_prepend (obj->objects, child); + obj->count++; } /** @@ -54,6 +55,23 @@ void vn_batch_remove (VnBatch * obj, GObject * child) g_return_if_fail (VN_IS_BATCH (obj)); obj->objects = g_list_remove (obj->objects, child); + obj->count--; +} + +/** + * vn_batch_get_objects_list: + * @obj: a #VnBatch + * + * Returns all the #GObjects in @obj, copying the list. + * + * Return value: (transfer container) (element-type GObject): a #GList with all + * the objects, that must be freed with #g_list_free + **/ +GList * vn_batch_get_objects_list (VnBatch * obj) +{ + g_return_val_if_fail (VN_IS_BATCH (obj), NULL); + + return g_list_copy (obj->objects); } /** @@ -62,14 +80,29 @@ void vn_batch_remove (VnBatch * obj, GObject * child) * * Returns all the #GObjects in @obj. * - * Return value: (transfer container) (element-type GObject): a #GList with all - * the objects, that must be freed with #g_list_free + * Return value: (transfer none) (element-type GObject): a #GList with all + * the objects, that must not be freed **/ -GList * vn_batch_get_objects (VnBatch * obj) +const GList * vn_batch_get_objects (VnBatch * obj) { g_return_val_if_fail (VN_IS_BATCH (obj), NULL); - return g_list_copy (obj->objects); + return obj->objects; +} + +/** + * vn_batch_get_length: + * @obj: a #VnBatch + * + * Returns the number of childs currently contained in @obj. + * + * Return value: the number of childs + **/ +guint vn_batch_get_length (VnBatch * obj) +{ + g_return_val_if_fail (VN_IS_BATCH (obj), 0); + + return obj->count; } static void vn_batch_buildable_add_child (GtkBuildable * obj, @@ -83,6 +116,7 @@ static void vn_batch_buildable_add_child (GtkBuildable * obj, static void vn_batch_init (VnBatch * obj) { obj->objects = NULL; + obj->count = 0; } static void vn_batch_finalize (VnBatch * obj) diff --git a/vn/vn-batch.h b/vn/vn-batch.h index dd38fb6..7a6deae 100644 --- a/vn/vn-batch.h +++ b/vn/vn-batch.h @@ -31,10 +31,15 @@ typedef struct _VnBatch VnBatch; typedef struct _VnBatchClass VnBatchClass; +/** + * VnBatch: + * @objects: (element-type GObject): + **/ struct _VnBatch { GObject parent; GList * objects; + guint count; }; struct _VnBatchClass @@ -44,10 +49,12 @@ struct _VnBatchClass GType vn_batch_get_type (); -void vn_batch_add (VnBatch * obj - ,GObject * child); -void vn_batch_remove (VnBatch * obj - ,GObject * child); -GList * vn_batch_get_objects (VnBatch * obj); +void vn_batch_add (VnBatch * obj + ,GObject * child); +void vn_batch_remove (VnBatch * obj + ,GObject * child); +const GList * vn_batch_get_objects (VnBatch * obj); +GList * vn_batch_get_objects_list (VnBatch * obj); +guint vn_batch_get_length (VnBatch * obj); #endif \ No newline at end of file diff --git a/vn/vn-builder.c b/vn/vn-builder.c index 931cb63..99388eb 100644 --- a/vn/vn-builder.c +++ b/vn/vn-builder.c @@ -67,13 +67,9 @@ guint vn_builder_load_file (VnBuilder * obj, DbConn * conn, const gchar * filena GSList * objects = gtk_builder_get_objects (builder); for (n = objects; n; n = n->next) - if (VN_IS_COMBO (n->data) - || VN_IS_COMPLETION (n->data) - || VN_IS_COLUMN_COMBO (n->data) - || DB_IS_MODEL (n->data) - || DB_IS_ITERATOR (n->data)) - g_object_set (n->data, "conn", conn, NULL); - + if (DB_IS_MODEL (n->data)) + db_model_set_conn (n->data, conn); + g_slist_free (objects); } diff --git a/vn/vn-column.c b/vn/vn-column.c index 7a122e4..93e61b3 100644 --- a/vn/vn-column.c +++ b/vn/vn-column.c @@ -31,12 +31,12 @@ static void vn_column_value_changed (VnColumn * obj, const gchar * path, const G &iter, obj->column_index, value, NULL); } -static void vn_column_data_func (GtkTreeViewColumn * col, GtkCellRenderer * cell, +static void vn_column_data_func (GtkTreeViewColumn * col, GtkCellRenderer * cell, GtkTreeModel * model, GtkTreeIter * iter, VnColumn * obj) { - gchar * background; + GdkRGBA * background; DbIter dbiter; - DbModel * dbmodel; + DbModelRowOp ops; GValue value = {0}; gtk_tree_model_get_value (model, iter, obj->column_index, &value); @@ -44,18 +44,19 @@ static void vn_column_data_func (GtkTreeViewColumn * col, GtkCellRenderer * cell g_value_unset (&value); vn_gtk_tree_iter_to_db_iter (iter, &dbiter); - g_object_get (model, "model", &dbmodel, NULL); - DbModelRowOp ops = db_model_get_row_operations (dbmodel, &dbiter); - g_object_unref (dbmodel); + ops = db_model_get_row_operations ( + vn_model_get_model (VN_MODEL (model)) + ,&dbiter + ); if (ops & DB_MODEL_ROW_OP_DELETE) - background = "#fcc"; + background = obj->red; else if (ops & DB_MODEL_ROW_OP_INSERT || ops & DB_MODEL_ROW_OP_UPDATE) - background = "#cfc"; + background = obj->green; else background = NULL; - g_object_set (cell, "cell-background", background, NULL); + g_object_set (cell, "cell-background-rgba", background, NULL); } static void vn_column_set_renderer (VnColumn * obj, GtkCellRenderer * cell) @@ -86,7 +87,7 @@ static void vn_column_update_column_index (VnColumn * obj) gtk_tree_view_column_set_sort_column_id ( GTK_TREE_VIEW_COLUMN (obj), obj->column_index); } - } + } } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public @@ -163,7 +164,7 @@ void vn_column_set_column_index (VnColumn * obj, gint index) * * Gets if the column can be edited by the user. * - * Return value: %TRUE if its editable, %FALSE otherwhise + * Return value: %TRUE if it's editable, %FALSE otherwhise **/ gboolean vn_column_get_editable (VnColumn * obj) { @@ -177,7 +178,7 @@ gboolean vn_column_get_editable (VnColumn * obj) * @obj: the #VnColumn * @editable: a %gboolean indicating whether the column value is editable * - * Sets if the column could be edited by the user. + * Sets if the column can be edited by the user. **/ void vn_column_set_editable (VnColumn * obj, gboolean editable) { @@ -187,6 +188,38 @@ void vn_column_set_editable (VnColumn * obj, gboolean editable) VN_COLUMN_GET_CLASS (obj)->set_editable (obj, editable); } +/** + * vn_column_get_null: + * @obj: the #VnColumn + * + * Gets if the column can be set to null by the user. + * + * Return value: %TRUE if it can be, %FALSE otherwhise + **/ +gboolean vn_column_get_null (VnColumn * obj) +{ + g_return_val_if_fail (VN_IS_COLUMN (obj), FALSE); + + return obj->null; +} + +/** + * vn_column_set_null: + * @obj: the #VnColumn + * @null: a %gboolean indicating whether the column value can be null + * + * Sets if the column can be set to null by the user. + **/ +void vn_column_set_null (VnColumn * obj, gboolean null) +{ + g_return_if_fail (VN_IS_COLUMN (obj)); + + obj->null = null; + + if (VN_COLUMN_GET_CLASS (obj)->set_null) + VN_COLUMN_GET_CLASS (obj)->set_null (obj, null); +} + /** * vn_column_get_model: * @obj: the #VnColumn @@ -257,7 +290,7 @@ void vn_column_model_changed (VnColumn * obj) VnColumnClass * klass; g_return_if_fail (VN_IS_COLUMN (obj)); - + klass = VN_COLUMN_GET_CLASS (obj); vn_column_update_column_index (obj); @@ -272,6 +305,7 @@ enum PROP_COLUMN_INDEX = 1 ,PROP_COLUMN_NAME ,PROP_EDITABLE + ,PROP_NULL }; static void vn_column_set_property (VnColumn * obj, guint id, @@ -288,6 +322,9 @@ static void vn_column_set_property (VnColumn * obj, guint id, case PROP_EDITABLE: vn_column_set_editable (obj, g_value_get_boolean (value)); break; + case PROP_NULL: + vn_column_set_null (obj, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); } @@ -307,6 +344,9 @@ static void vn_column_get_property (VnColumn * obj, guint id, case PROP_EDITABLE: g_value_set_boolean (value, obj->editable); break; + case PROP_NULL: + g_value_set_boolean (value, obj->null); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); } @@ -318,10 +358,17 @@ static void vn_column_init (VnColumn * obj) { obj->column_index = -1; obj->column_name = NULL; + obj->red = g_new (GdkRGBA, 1); + gdk_rgba_parse (obj->red, "#fcc"); + obj->green = g_new (GdkRGBA, 1); + gdk_rgba_parse (obj->green, "#cfc"); } static void vn_column_finalize (VnColumn * obj) { + gdk_rgba_free (obj->red); + gdk_rgba_free (obj->green); + G_OBJECT_CLASS (vn_column_parent_class)->finalize (G_OBJECT (obj)); } @@ -356,4 +403,11 @@ static void vn_column_class_init (VnColumnClass * klass) ,FALSE ,G_PARAM_CONSTRUCT | G_PARAM_READWRITE )); + g_object_class_install_property (k, PROP_NULL, + g_param_spec_boolean ("null" + ,_("Null") + ,_("Whether the field value can be of type GVN_TYPE_NULL") + ,FALSE + ,G_PARAM_CONSTRUCT | G_PARAM_READWRITE + )); } diff --git a/vn/vn-column.h b/vn/vn-column.h index 09a3447..8431702 100644 --- a/vn/vn-column.h +++ b/vn/vn-column.h @@ -36,6 +36,7 @@ typedef void (*VnColumnSetValueFunc) (VnColumn * obj, GtkTreeModel * model, Gtk typedef void (*VnColumnValuechangedFunc) (VnColumn * obj, const gchar * path, const GValue * value); typedef void (*VnColumnSetRendererFunc) (VnColumn * obj, GtkCellRenderer * cell); typedef void (*VnColumnSetEditableFunc) (VnColumn * obj, gboolean editable); +typedef void (*VnColumnSetNullFunc) (VnColumn * obj, gboolean null); typedef void (*VnColumnModelChangedFunc) (VnColumn * obj); struct _VnColumn @@ -45,6 +46,9 @@ struct _VnColumn gint column_index; gchar * column_name; gboolean editable; + gboolean null; + GdkRGBA * red; + GdkRGBA * green; VnColumnSetValueFunc set_value; }; @@ -55,6 +59,7 @@ struct _VnColumnClass VnColumnValuechangedFunc value_changed; VnColumnSetRendererFunc set_renderer; VnColumnSetEditableFunc set_editable; + VnColumnSetNullFunc set_null; VnColumnModelChangedFunc model_changed; }; @@ -65,6 +70,8 @@ gint vn_column_get_column_index (VnColumn * obj); void vn_column_set_column_index (VnColumn * obj, gint index); gboolean vn_column_get_editable (VnColumn * obj); void vn_column_set_editable (VnColumn * obj, gboolean editable); +gboolean vn_column_get_null (VnColumn * obj); +void vn_column_set_null (VnColumn * obj, gboolean null); DbModel * vn_column_get_model (VnColumn * obj); gboolean vn_column_get_iter (VnColumn * obj, const gchar * path, DbIter * iter); void vn_column_model_changed (VnColumn * obj); diff --git a/vn/vn-form.c b/vn/vn-form.c index f83435e..4c70485 100644 --- a/vn/vn-form.c +++ b/vn/vn-form.c @@ -53,20 +53,14 @@ void vn_form_open (VnForm * obj) { gchar * buffer; gchar * ui_file = g_strdup_printf ("%s/%s.ui", dir, obj->name); - GError * err = NULL; - if (g_file_get_contents (ui_file, &buffer, NULL, &err)) + if (g_file_get_contents (ui_file, &buffer, NULL, NULL)) { obj->ui = buffer; g_object_ref (obj->actions); } else - { - g_warning ("VnForm: Actions were defined for %s but no UI " - "definition was found.", obj->name); - g_error_free (err); obj->actions = NULL; - } g_free (ui_file); } diff --git a/vn/vn-grid.c b/vn/vn-grid.c index 4e24e07..9ffa82e 100644 --- a/vn/vn-grid.c +++ b/vn/vn-grid.c @@ -91,19 +91,21 @@ static void vn_grid_on_iter_changed (DbIterator * iterator, GtkTreeView * obj) gtk_tree_selection_unselect_all (selection); } +static void vn_grid_on_model_changed (VnGrid * obj, GParamSpec * spec, gpointer data) +{ + GList * n, * columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (obj)); + + for (n = columns; n; n = n->next) + if (VN_IS_COLUMN (n->data)) + vn_column_model_changed (n->data); + + g_list_free (columns); +} + static void vn_grid_on_status_changed (DbIterator * iterator, gboolean ready, VnGrid * obj) { - GList * n; - GList * columns; - - obj->model = db_iterator_get_model (iterator); - columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (obj)); - - for (n = columns; n; n = n->next) - if (VN_IS_COLUMN (n->data)) - vn_column_model_changed (n->data); - - g_list_free (columns); + obj->model = db_model_holder_get_model (DB_MODEL_HOLDER (iterator)); + vn_grid_on_model_changed (obj, NULL, NULL); if (ready) { @@ -205,7 +207,7 @@ DbModel * vn_grid_get_model (VnGrid * obj) * Return value: (transfer none): the #VnColumn assigned to the new column. **/ VnColumn * vn_grid_insert_column (VnGrid * obj, gint position, gint column_index, - const gchar * title, GType column_type, gboolean editable, gboolean expand) + const gchar * title, GType column_type, gboolean editable, gboolean expand) { GtkTreeViewColumn * column; @@ -223,6 +225,7 @@ VnColumn * vn_grid_insert_column (VnGrid * obj, gint position, gint column_index ,"editable" ,editable ,NULL ); + gtk_tree_view_append_column (GTK_TREE_VIEW (obj), column); return VN_COLUMN (column); } @@ -295,7 +298,7 @@ VnGridProp; static void vn_grid_set_property (VnGrid * obj, guint id, const GValue * value, GParamSpec * pspec) -{ +{ switch (id) { case PROP_ITERATOR: @@ -329,11 +332,16 @@ static void vn_grid_init (VnGrid * obj) gtk_tree_view_get_selection (GTK_TREE_VIEW (obj)), GTK_SELECTION_SINGLE ); + + g_signal_connect (obj, "notify::model", + G_CALLBACK (vn_grid_on_model_changed), NULL); } static void vn_grid_finalize (VnGrid * obj) { vn_grid_set_iterator (obj, NULL); + g_signal_handlers_disconnect_by_func (obj, vn_grid_on_model_changed, NULL); + G_OBJECT_CLASS (vn_grid_parent_class)->finalize (G_OBJECT (obj)); } @@ -351,4 +359,4 @@ static void vn_grid_class_init (VnGridClass * k) ,DB_TYPE_ITERATOR ,G_PARAM_READWRITE )); -} +} \ No newline at end of file diff --git a/vn/vn-gui.c b/vn/vn-gui.c index f7cd705..402e041 100644 --- a/vn/vn-gui.c +++ b/vn/vn-gui.c @@ -1362,8 +1362,8 @@ static void vn_gui_set_property (VnGui * obj, guint id, switch (id) { case PROP_CONN: - { - gchar * query_path = g_build_path (G_SEARCHPATH_SEPARATOR_S + { + gchar * query_path = g_build_path (G_SEARCHPATH_SEPARATOR_S ,_VN_MODULE_QUERY_DIR ,g_getenv ("VN_MODULE_QUERY_PATH") ,NULL @@ -1392,7 +1392,7 @@ static void vn_gui_set_property (VnGui * obj, guint id, obj->app_title[0] = g_ascii_toupper (obj->app_title[0]); config_dir = g_build_filename (g_get_user_config_dir (), app_name, NULL); - g_mkdir_with_parents (config_dir, 0600); + g_mkdir_with_parents (config_dir, 0700); obj->config_file = g_build_filename (config_dir, "gui.ini", NULL); g_free (config_dir); diff --git a/vn/vn-login.c b/vn/vn-login.c index 520597b..d1536f8 100644 --- a/vn/vn-login.c +++ b/vn/vn-login.c @@ -88,6 +88,7 @@ static void vn_login_show (VnLogin * obj) obj->pass = vn_builder_get (builder, "password"); obj->remember = vn_builder_get (builder, "remember"); obj->connect = vn_builder_get (builder, "connect"); + obj->stop = vn_builder_get (builder, "stop"); obj->settings_button = vn_builder_get (builder, "settings"); obj->spinner = vn_builder_get (builder, "spinner"); obj->settings_dialog = vn_builder_get (builder, "settings-dialog"); @@ -123,6 +124,7 @@ static void vn_login_show (VnLogin * obj) gtk_widget_show_all (GTK_WIDGET (obj->window)); gtk_widget_grab_focus (GTK_WIDGET (obj->user)); gtk_widget_hide (obj->spinner); + gtk_widget_hide (obj->stop); if (autologin) gtk_button_clicked (obj->connect); @@ -140,9 +142,17 @@ static void vn_login_set_loading (VnLogin * obj, gboolean loading) gtk_widget_set_sensitive (GTK_WIDGET (obj->remember), !loading); if (loading) + { gtk_widget_show (obj->spinner); + gtk_widget_show (obj->stop); + gtk_widget_hide (GTK_WIDGET (obj->connect)); + } else + { gtk_widget_hide (obj->spinner); + gtk_widget_hide (obj->stop); + gtk_widget_show (GTK_WIDGET (obj->connect)); + } } /* @@ -367,6 +377,11 @@ void vn_login_cb_connect_clicked (GtkButton * button, VnLogin * obj) (GThreadFunc) vn_login_thread, connect_data); } +void vn_login_cb_stop_clicked (GtkButton * button, VnLogin * obj) +{ + +} + /* * Closes the application when login window is destroyed. */ diff --git a/vn/vn-login.h b/vn/vn-login.h index a40d813..8960a3a 100644 --- a/vn/vn-login.h +++ b/vn/vn-login.h @@ -46,6 +46,7 @@ struct _VnLogin GtkEntry * pass; GtkToggleButton * remember; GtkButton * connect; + GtkWidget * stop; GtkButton * settings_button; GtkWidget * spinner; diff --git a/vn/vn-model.c b/vn/vn-model.c index ff48c1f..debf93d 100644 --- a/vn/vn-model.c +++ b/vn/vn-model.c @@ -23,13 +23,27 @@ * * Creates a new #VnModel with @model as the data model. * - * Return value: (transfer full): a #VnModel. + * Return value: (transfer full): a #VnModel. **/ VnModel * vn_model_new (DbModel * model) { return g_object_new (VN_TYPE_MODEL, "model", model, NULL); } +/** + * vn_model_get_model: + * @obj: a #VnModel + * + * Passes the #DbModel used internally by @model. + * + * Return value: (transfer none): a #DbModel. + **/ +DbModel * vn_model_get_model (VnModel * obj) +{ + g_return_val_if_fail (VN_IS_MODEL (obj), NULL); + + return obj->model; +} /** * vn_gtk_tree_iter_from_db_iter: * @dest_iter: the #GtkTreeIter to set using the data on @src_iter diff --git a/vn/vn-model.h b/vn/vn-model.h index 1783fb8..0fa87cd 100644 --- a/vn/vn-model.h +++ b/vn/vn-model.h @@ -51,6 +51,7 @@ struct _VnModelClass GType vn_model_get_type (); VnModel * vn_model_new (DbModel * model); +DbModel * vn_model_get_model (VnModel * obj); gboolean vn_model_iter_is_valid (GtkTreeIter * iter, GtkTreeModel * model); void vn_gtk_tree_iter_from_db_iter (GtkTreeIter * dest_iter ,const DbIter * src_iter);