/* * 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-join.h" #include "sql-field.h" /** * SECTION: sql-join * @Short_description: the equivalent of the SQL JOIN. * @Title: SqlJoin * * The #SqlJoin represents a joins between any targets. **/ G_DEFINE_TYPE (SqlJoin, sql_join, SQL_TYPE_TARGET); SqlObject * sql_join_new (SqlTarget * left, SqlTarget * right, SqlJoinType type) { return g_object_new (SQL_TYPE_JOIN ,"target-left" ,left ,"target-right" ,right ,"join-type" ,type ,NULL ); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private static const gchar * SQL_JOIN_TYPE[] = { "INNER" ,"LEFT" ,"RIGHT" }; static void sql_join_render (SqlJoin * obj, SqlRender * render) { sql_render_add_item (render, TRUE, 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); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public 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); sql_object_remove (obj, obj->target_left); obj->target_left = sql_object_add (obj, 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); sql_object_remove (obj, obj->target_right); obj->target_right = sql_object_add (obj, 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); sql_object_remove (obj, obj->condition); obj->condition = sql_object_add (obj, condition); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties enum { PROP_TARGET_LEFT = 1 ,PROP_TARGET_RIGHT ,PROP_TYPE ,PROP_CONDITION ,PROP_HAS_USING ,PROP_USING_FIELDS }; static void sql_join_set_property (SqlJoin * obj, guint id, const GValue * value, GParamSpec * pspec) { switch (id) { case PROP_TARGET_LEFT: sql_join_set_target_left (obj, g_value_get_object (value)); break; case PROP_TARGET_RIGHT: sql_join_set_target_right (obj, g_value_get_object (value)); break; case PROP_TYPE: obj->type = g_value_get_enum (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: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); } } static void sql_join_get_property (SqlJoin * obj, guint id, GValue * value, GParamSpec * pspec) { switch (id) { case PROP_TARGET_LEFT: g_value_set_object (value, obj->target_left); break; case PROP_TARGET_RIGHT: g_value_set_object (value, obj->target_right); break; case PROP_TYPE: g_value_set_enum (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); } } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class 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_OBJECT_CLASS (sql_join_parent_class)->finalize (G_OBJECT (obj)); } static void sql_join_class_init (SqlJoinClass * klass) { GObjectClass * k = G_OBJECT_CLASS (klass); k->finalize = (GObjectFinalizeFunc) sql_join_finalize; k->set_property = (GObjectSetPropertyFunc) sql_join_set_property; k->get_property = (GObjectGetPropertyFunc) sql_join_get_property; SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_join_render; g_object_class_install_property (k, PROP_TARGET_LEFT, sql_param_list ("target-left" ,"Left target" ,"The left target in the join" ,SQL_TYPE_TARGET ,G_PARAM_READWRITE )); g_object_class_install_property (k, PROP_TARGET_RIGHT, sql_param_list ("target-right" ,"Right target" ,"The right target in the join" ,SQL_TYPE_TARGET ,G_PARAM_READWRITE )); g_object_class_install_property (k, PROP_TYPE, g_param_spec_enum ("join-type" ,"Type" ,"The type of join" ,SQL_TYPE_JOIN_TYPE ,SQL_JOIN_TYPE_INNER ,G_PARAM_READWRITE )); g_object_class_install_property (k, PROP_CONDITION, sql_param_list ("condition" ,"Condition" ,"The condition used for the join" ,SQL_TYPE_EXPR ,G_PARAM_READWRITE )); g_object_class_install_property (k, PROP_HAS_USING, g_param_spec_boolean ("has-using" ,"Has using" ,"Wether the condition is a USING" ,FALSE ,G_PARAM_READWRITE | G_PARAM_CONSTRUCT )); g_object_class_install_property (k, PROP_CONDITION, sql_param_list ("using-fields" ,"Using fields" ,"The list of fields of the USING" ,SQL_TYPE_FIELD ,G_PARAM_READWRITE | G_PARAM_CONSTRUCT )); } GType sql_join_type_get_type () { static GType type = 0; if (type == 0) { static const GEnumValue values[] = { {SQL_JOIN_TYPE_INNER ,"SQL_JOIN_TYPE_INNER" ,"inner" },{SQL_JOIN_TYPE_LEFT ,"SQL_JOIN_TYPE_LEFT" ,"left" },{SQL_JOIN_TYPE_RIGHT ,"SQL_JOIN_TYPE_RIGHT" ,"right" },{0, NULL, NULL} }; type = g_enum_register_static (g_intern_static_string ("SqlJoinType"), values); } return type; }