/* * Copyright (C) 2012 - Juan Ferrer Toribio * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "sql-object.h" #include "sql-value.h" /** * SECTION: sql-object * @Short_description: represents an SQL statement or a part of it * @Title: SqlObject * * The #SqlObject is the base class for all objects in SqlLib. **/ G_DEFINE_ABSTRACT_TYPE (SqlObject, sql_object, G_TYPE_INITIALLY_UNOWNED); enum { CHANGED ,LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = {0}; //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private static void sql_object_child_changed (SqlObject * child, SqlObject * obj) { sql_object_changed (obj); } static void sql_object_find_holders (SqlObject * obj, SqlBatch * batch) { guint i; guint nparams; GParamSpec ** params; params = g_object_class_list_properties (G_OBJECT_GET_CLASS (obj), &nparams); for (i = 0; i < nparams; i++) if (SQL_IS_PARAM_OBJECT (params[i]) || SQL_IS_PARAM_LIST (params[i])) { SqlObject * child; g_object_get (obj, params[i]->name, &child, NULL); if (child) sql_object_get_holders (child, batch); } g_free (params); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Protected /** * sql_object_add: * @obj: #SqlObject where the new item will be added * @child: #SqlObject the object is added * * Note that this function is considered a protected method and should only * be used in classes that inherit from #SqlObjectClass. * * Return value: (transfer full): **/ gpointer sql_object_add (gpointer obj, gpointer child) { if (child) { g_object_ref_sink (child); g_signal_connect (child, "changed", G_CALLBACK (sql_object_child_changed), obj); } return child; } /** * sql_object_remove: * @obj: #SqlObject where the new item will be added * @child: #SqlObject the object is added * * Note that this function is considered a protected method and should only * be used in classes that inherit from #SqlObjectClass. **/ void sql_object_remove (gpointer obj, gpointer child) { if (child) { g_signal_handlers_disconnect_by_func (child, sql_object_child_changed, obj); g_object_unref (child); } } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public /** * sql_object_render: * @obj: a #SqlObject * @render: an #SqlRender * * Renders the object into a SQL string and stores it into the renderer. **/ void sql_object_render (SqlObject * obj, SqlRender * render, SqlBatch * batch) { g_return_if_fail (SQL_IS_OBJECT (obj)); g_return_if_fail (SQL_IS_RENDER (render)); g_return_if_fail (SQL_IS_BATCH (batch) || !batch); SQL_OBJECT_GET_CLASS (obj)->render (obj, render, batch); } /** * sql_object_is_ready: * @obj: a #SqlObject * * Checks if @obj and all of its elemens are ready to be rendered. * * Return value: %TRUE if ready, %FALSE otherwise. **/ gboolean sql_object_is_ready (SqlObject * obj) { guint i; guint nparams; GParamSpec ** params; gboolean is_ready = TRUE; SqlObjectClass * klass; g_return_val_if_fail (SQL_IS_OBJECT (obj), FALSE); klass = SQL_OBJECT_GET_CLASS (obj); params = g_object_class_list_properties (G_OBJECT_CLASS (klass), &nparams); for (i = 0; i < nparams && is_ready; i++) if (SQL_IS_PARAM_OBJECT (params[i]) || SQL_IS_PARAM_LIST (params[i])) { SqlObject * child; g_object_get (obj, params[i]->name, &child, NULL); is_ready = !child || sql_object_is_ready (child); } g_free (params); if (klass->is_ready) return klass->is_ready (obj); else return is_ready; } void sql_object_set (SqlObject * obj, const gchar * property, SqlObject * value) { g_return_if_fail (SQL_IS_OBJECT (obj)); g_return_if_fail (SQL_IS_OBJECT (value)); g_object_set (obj, property, value, NULL); } /** * sql_object_get: * Return value: (transfer none): **/ SqlObject * sql_object_get (SqlObject * obj, const gchar * property) { SqlObject * value; g_return_val_if_fail (SQL_IS_OBJECT (obj), NULL); g_object_get (obj, property, &value, NULL); return value; } void sql_object_add_child (SqlObject * obj, const gchar * property, SqlObject * child) { SqlList * list; g_return_if_fail (SQL_IS_OBJECT (obj)); g_return_if_fail (SQL_IS_OBJECT (child)); g_object_get (obj, property, &list, NULL); sql_list_add (list, child); } void sql_object_remove_child (SqlObject * obj, const gchar * property, guint n) { SqlList * list; g_return_if_fail (SQL_IS_OBJECT (obj)); g_object_get (obj, property, &list, NULL); sql_list_remove (list, n); } /** * sql_object_get_holders: * @obj: a #SqlObject * @batch: an #SqlBatch * * Gets all identifiers of the contained holders. **/ void sql_object_get_holders (SqlObject * obj, SqlBatch * batch) { g_return_if_fail (SQL_IS_OBJECT (obj)); g_return_if_fail (SQL_IS_BATCH (batch)); SQL_OBJECT_GET_CLASS (obj)->find_holders (obj, batch); } /** * sql_object_changed: * @obj: a #SqlObject * * Emits the changed signal on #SqlObject. **/ void sql_object_changed (SqlObject * obj) { g_return_if_fail (SQL_IS_OBJECT (obj)); g_signal_emit (obj, signals[CHANGED], 0); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class static void sql_object_init (SqlObject * obj) {} static void sql_object_finalize (SqlObject * obj) { G_OBJECT_CLASS (sql_object_parent_class)->finalize (G_OBJECT (obj)); } static void sql_object_class_init (SqlObjectClass * klass) { G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) sql_object_finalize; klass->find_holders = sql_object_find_holders; klass->is_ready = NULL; klass->render = NULL; /** * SqlObject::changed: * @obj: the object which emit the signal. * * This signal is emitted every time the statement or one of its attributes * is modified. */ signals[CHANGED] = g_signal_new ("changed", SQL_TYPE_OBJECT, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 ); }