001package com.randomnoun.common.jexl.sql;
002
003/* (c) 2013 randomnoun. All Rights Reserved. This work is licensed under a
004 * BSD Simplified License. (http://www.randomnoun.com/bsd-simplified.html)
005 */
006
007import java.sql.Types;
008
009
010/**
011 * Objects of this type are used in the evaluation context passed into an SqlGenerator
012 * to define a database column used in a TopLevelExpression.
013 *
014 * <p>See the SqlGenerator class for detailed documentation.
015 *
016 * 
017 * @author knoxg
018 */
019public class SqlColumn
020{
021
022    /** These constants are copied directly from the java.sql.Types class;
023     *  note that we also add the new types MONEYVALUE, DATEVALUE, TIMEVALUE, FIXEDDATEVALUE and FIXEDTIMEVALUE */
024    public static final int ARRAY = Types.ARRAY;
025    public static final int BIGINT = Types.BIGINT;
026    public static final int BINARY = Types.BINARY;
027    public static final int BIT = Types.BIT;
028    public static final int BLOB = Types.BLOB;
029    public static final int BOOLEAN = Types.BOOLEAN;
030    public static final int CHAR = Types.CHAR;
031    public static final int CLOB = Types.CLOB;
032    public static final int DATALINK = Types.DATALINK;
033    public static final int DATE = Types.DATE;
034    public static final int DECIMAL = Types.DECIMAL;
035    public static final int DISTINCT = Types.DISTINCT;
036    public static final int DOUBLE = Types.DOUBLE;
037    public static final int FLOAT = Types.FLOAT;
038    public static final int INTEGER = Types.INTEGER;
039    public static final int JAVA_OBJECT = Types.JAVA_OBJECT;
040    public static final int LONGVARBINARY = Types.LONGVARBINARY;
041    public static final int LONGVARCHAR = Types.LONGVARCHAR;
042    public static final int NULL = Types.NULL;
043    public static final int NUMERIC = Types.NUMERIC;
044    public static final int OTHER = Types.OTHER;
045    public static final int REAL = Types.REAL;
046    public static final int REF = Types.REF;
047    public static final int SMALLINT = Types.SMALLINT;
048    public static final int STRUCT = Types.STRUCT;
049    public static final int TIME = Types.TIME;
050    public static final int TIMESTAMP = Types.TIMESTAMP;
051    public static final int TINYINT = Types.TINYINT;
052    public static final int VARBINARY = Types.VARBINARY;
053    public static final int VARCHAR = Types.VARCHAR;
054
055    /** The range 5000-6000 is currently unused in java.sql.Types;
056     * (and doesn't look like it will ever be used), so I'm going to use
057     * this for custom types. Anything in here is treated specially in SqlGenerator
058     * when converting to SQL.
059     *
060     */
061    public static final int MONEYVALUE = 5000; // perform currency matching
062    public static final int DATEVALUE = 5001; // perform conditional date ranges
063    public static final int TIMEVALUE = 5002; // perform conditional date ranges
064    public static final int FIXEDDATEVALUE = 5003; // as per DATEVALUE, stored as String (no TZ)
065    public static final int FIXEDTIMEVALUE = 5004; // as per TIMEVALUE, stored as String (no TZ)
066
067    /** The name of this database column */
068    private String name = null;
069
070    /** If this object describes a MONEYVALUE column, this field contains the name of the
071     *  currency code column (this.name contains the amount). */
072    private String currencyCodeName = null;
073
074    /** The name of the table this fields belongs to (or null if not specifying tables) */
075    private String table = null;
076
077    /** The type of this column. Corresponds to one of the public static final int constants
078     *  defined in this class. */
079    private int dataType = VARCHAR;
080
081    /** Create a new column, of type VARCHAR
082     *
083     * @param name     The name of the column in the database
084     */
085    public SqlColumn(String name)
086    {
087        this.name = name;
088    }
089
090    /** Create a new column, with the supplied datatype
091     *
092     * @param name     The name of the column in the database
093     * @param dataType The datatype of the column. Corresponds to one of the public static final
094     *   int constants defined in this class.
095     */
096    public SqlColumn(String name, int dataType)
097    {
098        this.name = name;
099        this.dataType = dataType;
100    }
101
102    /** Create a new column, in a specific table, of type VARCHAR
103     *
104     * @param name     The name of the column in the database
105     * @param table    The name of the table in the database this column is in
106     */
107    public SqlColumn(String name, String table)
108    {
109        this.name = name;
110        this.table = table;
111    }
112
113    /** Create a new column, in a specific table, with the supplied datatype
114     *
115     * @param name     The name of the column in the database
116     * @param table    The name of the table in the database this column is in
117     * @param dataType The datatype of the column. Corresponds to one of the public static final
118     *   int constants defined in this class.
119     */
120    public SqlColumn(String name, String table, int dataType)
121    {
122        this.name = name;
123        this.table = table;
124        this.dataType = dataType;
125    }
126
127    /** Sets the column name that contains the currency code, for a MONEYVALUE SqlColumn.
128     * If a table has been specified for this column, then the currency is <b>always</b>
129     * sourced from the same table.
130     *
131     * @param currencyCodeName the column name that contains the currency code
132     *
133     * @throws IllegalStateException if this method is called for a non-MONEYVALUE SqlColumn
134     */
135    public void setCurrencyCodeName(String currencyCodeName)
136    {
137        if (this.dataType != MONEYVALUE)
138        {
139            throw new IllegalStateException(
140                "A currencyColumnName may only be set for a MONEYVALUE type");
141        }
142
143        this.currencyCodeName = currencyCodeName;
144    }
145
146    /** Retrieves the name of this SqlColumn, as set by the constructor */
147    public String getName()
148    {
149        return name;
150    }
151
152    /** Retrieves the table of this SqlColumn, as set by the constructor */
153    public String getTable()
154    {
155        return table;
156    }
157
158    /** Retrieves the currency column of this SqlColumn, as supplied by setCurrencyCodeName */
159    public String getCurrencyCodeName()
160    {
161        return currencyCodeName;
162    }
163
164    /** Retrieves the data type of this SqlColumn */
165    public int getDataType()
166    {
167        return dataType;
168    }
169
170    /** Either returns the name of this column, or table + "." + name, if a table has been set */
171    public String getFullName()
172    {
173        if (table == null)
174        {
175            return name;
176        }
177        else
178        {
179            return table + "." + name;
180        }
181    }
182
183    /** Either returns the name of the currency column, or table + "." + currency name, if a table
184     *  has been set */
185    public String getFullCurrencyCodeName()
186    {
187        if (table == null)
188        {
189            return currencyCodeName;
190        }
191        else
192        {
193            return table + "." + currencyCodeName;
194        }
195    }
196
197    /** Retrieve a string representation of this column */
198    public String toString()
199    {
200        return getFullName();
201    }
202}