/* * 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" #include "sql-holder.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 * self, SqlRender * render) { sql_render_add_item (render, TRUE, NULL, self->target_left); sql_render_add_token (render, SQL_JOIN_TYPE[self->type]); sql_render_add_token (render, "JOIN"); sql_render_add_item (render, TRUE, NULL, self->target_right); if (self->has_using) { sql_render_add_token (render, "USING"); sql_render_append (render, "("); sql_render_add_list (render, TRUE, NULL, self->using_fields, ","); sql_render_append (render, ")"); } else sql_render_add_item (render, FALSE, "ON", self->condition); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public SqlJoinType sql_join_get_join_type (SqlJoin * self) { g_return_if_fail (SQL_IS_JOIN (self)); return self->type; } void sql_join_set_target_left (SqlJoin * self, SqlTarget * target) { g_return_if_fail (SQL_IS_JOIN (self)); g_return_if_fail (SQL_IS_TARGET (target) || SQL_IS_HOLDER (target) || !target); sql_object_remove (self, self->target_left); self->target_left = sql_object_add (self, target); } void sql_join_set_target_right (SqlJoin * self, SqlTarget * target) { g_return_if_fail (SQL_IS_JOIN (self)); g_return_if_fail (SQL_IS_TARGET (target) || SQL_IS_HOLDER (target) || !target); sql_object_remove (self, self->target_right); self->target_right = sql_object_add (self, target); } void sql_join_set_condition (SqlJoin * self, SqlExpr * condition) { g_return_if_fail (SQL_IS_JOIN (self)); g_return_if_fail (SQL_IS_EXPR (condition) || SQL_IS_HOLDER (condition) || !condition); sql_object_remove (self, self->condition); self->condition = sql_object_add (self, condition); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties 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 * self, guint id, const GValue * value, GParamSpec * pspec) { switch (id) { case PROP_TARGET_LEFT: sql_join_set_target_left (self, g_value_get_object (value)); break; case PROP_TARGET_RIGHT: sql_join_set_target_right (self, g_value_get_object (value)); break; case PROP_TYPE: self->type = g_value_get_enum (value); break; case PROP_CONDITION: sql_join_set_condition (self, g_value_get_object (value)); break; case PROP_HAS_USING: self->has_using = g_value_get_boolean (value); break; case PROP_USING_FIELDS: sql_object_remove (self, self->using_fields); self->using_fields = sql_object_add (self, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec); } } static void sql_join_get_property (SqlJoin * self, guint id, GValue * value, GParamSpec * pspec) { switch (id) { case PROP_TARGET_LEFT: g_value_set_object (value, self->target_left); break; case PROP_TARGET_RIGHT: g_value_set_object (value, self->target_right); break; case PROP_TYPE: g_value_set_enum (value, self->type); break; case PROP_CONDITION: g_value_set_object (value, self->condition); break; case PROP_HAS_USING: g_value_set_boolean (value, self->has_using); break; case PROP_USING_FIELDS: g_value_set_object (value, self->using_fields); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec); } } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class static void sql_join_init (SqlJoin * self) { self->target_left = NULL; self->target_right = NULL; self->condition = NULL; self->using_fields = NULL; } static void sql_join_finalize (SqlJoin * self) { sql_object_remove (self, self->target_left); sql_object_remove (self, self->target_right); sql_object_remove (self, self->condition); sql_object_remove (self, self->using_fields); G_OBJECT_CLASS (sql_join_parent_class)->finalize (G_OBJECT (self)); } static void sql_join_class_init (SqlJoinClass * klass) { 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; }