/*
 * Copyright (C) 2012 - Juan Ferrer Toribio
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "sql-field.h"

/**
 * SECTION: sql-field
 * @Short_description: a column of an SQL target.
 * @Title: SqlField
 * 
 * The #SqlField represents the column of an SQL target.
 **/
G_DEFINE_TYPE (SqlField, sql_field, SQL_TYPE_EXPR);

/**
 * sql_field_new:
 * @name: the name of the field
 * @target: (allow-none): the table from which the field is selected
 * @schema: (allow-none): the schema from which the table and field are selected
 * 
 * Creates a new #SqlField.
 * 
 * Return value: an #SqlExpr
 */
SqlObject * 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
	);
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private

static void sql_field_render (SqlField * obj, SqlRender * render)
{
	if (obj->target)
	{
		if (obj->schema)
		{
			sql_render_add_identifier (render, obj->schema);
			sql_render_append (render, ".");
		}

		sql_render_add_identifier (render, obj->target);
		sql_render_append (render, ".");
	}

	if (!g_strcmp0 (obj->name, "*"))
	{
		sql_render_add_espace (render);
		sql_render_append (render, "*");
	}
	else
		sql_render_add_identifier (render, obj->name);
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public

void sql_field_set_name (SqlField * obj, const gchar * name)
{
	g_return_if_fail (SQL_IS_FIELD (obj));
	g_return_if_fail (name);
	
	g_free (obj->name);
	obj->name = g_strdup (name);
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties

enum
{
	 PROP_NAME = 1
	,PROP_TARGET
	,PROP_SCHEMA
};

static void sql_field_set_property (SqlField * obj, guint id,
	const GValue * value, GParamSpec * pspec)
{
	switch (id)
	{
		case PROP_NAME:
			sql_field_set_name (obj, g_value_get_string (value));
			break;
		case PROP_TARGET:
			g_free (obj->target);
			obj->target = g_value_dup_string (value);
			break;
		case PROP_SCHEMA:
			g_free (obj->schema);
			obj->schema = g_value_dup_string (value);
			break;
		default:		
			G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
	}
}

static void sql_field_get_property (SqlField * obj, guint id,
	GValue * value, GParamSpec * pspec)
{	
	switch (id)
	{
		case PROP_NAME:
			g_value_set_string (value, obj->name);
			break;
		case PROP_TARGET:
			g_value_set_string (value, obj->target);
			break;
		case PROP_SCHEMA:
			g_value_set_string (value, obj->schema);
			break;
		default:		
			G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
	}
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class

static void sql_field_init (SqlField * obj)
{
	obj->name = NULL;
	obj->target = NULL;
	obj->schema = NULL;
}

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));
}

static void sql_field_class_init (SqlFieldClass * klass)
{
	GObjectClass * k = G_OBJECT_CLASS (klass);
	k->finalize = (GObjectFinalizeFunc) sql_field_finalize;
	k->set_property = (GObjectSetPropertyFunc) sql_field_set_property;
	k->get_property = (GObjectGetPropertyFunc) sql_field_get_property;
	SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_field_render;

	g_object_class_install_property (k, PROP_NAME,
		g_param_spec_string ("name"
			,"Name"
			,"The column name"
			,NULL
			,G_PARAM_READWRITE
	));
	g_object_class_install_property (k, PROP_TARGET,
		g_param_spec_string ("target"
			,"Target"
			,"The target name"
			,NULL
			,G_PARAM_READWRITE
	));
	g_object_class_install_property (k, PROP_SCHEMA,
		g_param_spec_string ("schema"
			,"Schema"
			,"The schema name"
			,NULL
			,G_PARAM_READWRITE
	));
}