DBVIEW
src/org/dbview/db/structure/Table.java
00001 /*
00002         DbView - Graph Visualization
00003     Copyright (C) 2012  Denis BEURIVE
00004 
00005     This program is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017 */
00018 
00019 /**
00020  * @author Denis Beurive
00021  */
00022 
00023 package org.dbview.db.structure;
00024 
00025 import org.dbview.db.structure.Database;
00026 import org.dbview.db.structure.Field;
00027 import org.dbview.utils.Strings;
00028 import org.dbview.input_addons.DbIndex;
00029 
00030 import java.util.Enumeration;
00031 import java.util.Hashtable;
00032 import java.util.ArrayList;
00033 import java.util.Iterator;
00034 
00035 /**
00036  * This class represents a table.
00037  * @author Denis Beurive
00038  * @remark Adding a field to a table is done when a field is created.
00039  */
00040 public class Table
00041 {
00042     /**
00043      * The hash table lists all table's fields.
00044      * <ul>
00045      *      <li>Key: Name of the field.</li>
00046      *      <li>Value: The field.</li>
00047      * </ul>
00048      */
00049     private Hashtable<String, Field> __fields = new Hashtable<String, Field>();
00050 
00051     /**
00052      * The array contains the list of all fields listed in the order of declaration.
00053      */
00054     private ArrayList<String> __orderedFields = new ArrayList<String>();
00055 
00056     /** Name of the table. */
00057     private String __name = null;
00058 
00059     /** Database that contains this table. */
00060     private Database __db = null;
00061     
00062     /** List of all indexes for this table. */
00063     private Hashtable<String, DbIndex> __indexes = new Hashtable<String, DbIndex>();
00064     
00065     /** List of all indexes that are composed of one field. */
00066     private Hashtable<String, DbIndex> __simple_indexes = new Hashtable<String, DbIndex>();
00067     
00068     /** List of all indexes that are composed of more than one field. */
00069     private Hashtable<String, DbIndex> __composite_indexes = new Hashtable<String, DbIndex>();
00070 
00071     /** Number of indexes that are composed of more than one field. */
00072     private Integer __simple_indexes_count = -1;
00073     
00074     /** Number of indexes that are composed of one field. */
00075     private Integer __composite_indexes_count = -1;
00076     
00077     /** 
00078      * Set the list of indexes.
00079      * @param in_list The list of indexes to set.
00080      */
00081     public void setIndexes(Hashtable<String, DbIndex> in_list)
00082     {
00083         this.__indexes = in_list;
00084     }
00085     
00086     /**
00087      * This method returns the list of indexes that are defined by only one field.
00088      * @return The method returns the list of indexes that are defined by only one field.
00089      */
00090     public Hashtable<String, DbIndex> getSimpleIndexes()
00091     {
00092         if (-1 != this.__simple_indexes_count) { return this.__simple_indexes; }
00093         
00094         this.__simple_indexes_count = 0;
00095         for (Enumeration<String> e = this.__indexes.keys(); e.hasMoreElements(); )
00096         {
00097             String  index_name = e.nextElement();
00098             DbIndex index      = this.__indexes.get(index_name);
00099             if (index.fieldCount() > 1) { continue; }
00100             this.__simple_indexes.put(index_name, index);
00101             this.__simple_indexes_count++;
00102         }
00103         
00104         return this.__simple_indexes;
00105     }
00106     
00107     /**
00108      * This method returns the list of indexes that are defined by more than one field.
00109      * @return The method returns the list of indexes that are defined by more than one field.
00110      */
00111     public Hashtable<String, DbIndex> getCompositeIndexes()
00112     {
00113         if (-1 != this.__composite_indexes_count) { return this.__composite_indexes; }
00114         
00115         this.__composite_indexes_count = 0;
00116         for (Enumeration<String> e = this.__indexes.keys(); e.hasMoreElements(); )
00117         {
00118             String  index_name = e.nextElement();
00119             DbIndex index      = this.__indexes.get(index_name);
00120             if (1 == index.fieldCount()) { continue; }
00121             this.__composite_indexes.put(index_name, index);
00122             this.__composite_indexes_count++;
00123         }
00124         
00125         return this.__composite_indexes;
00126     }
00127     
00128     /**
00129      * This method returns the number of indexes composed by only one index.
00130      * @return The method returns the number of indexes composed by only one index.
00131      */
00132     public Integer compositeIndexCount()
00133     {
00134         if (-1 == this.__composite_indexes_count) { this.getCompositeIndexes(); }
00135         return this.__composite_indexes_count;
00136     }
00137 
00138     /**
00139      * This method returns the number of indexes composed by more than one index.
00140      * @return The method returns the number of indexes composed by more than one index.
00141      */
00142     public Integer simpleIndexCount()
00143     {
00144         if (-1 == this.__simple_indexes_count) { this.getSimpleIndexes(); }
00145         return this.__simple_indexes_count;
00146     }
00147     
00148     /**
00149      * This method returns the name of the table.
00150      * @return The method returns the name of the table.
00151      */
00152     public String getName()
00153     {
00154         return this.__name;
00155     }
00156 
00157     /**
00158      * Create a table.
00159      * @param in_db Database that contains the newly created table.
00160      * @param in_name Name of the table.
00161      * @throws org.dbview.db.structure.DatabaseException
00162      */
00163     public Table(Database in_db, String in_name) throws org.dbview.db.structure.DatabaseException
00164     {
00165         this.__name = in_name;
00166         this.__db   = in_db;
00167         in_db.addTable(this);
00168     }
00169 
00170     /**
00171      * Add a field to the table.
00172      * @param in_field Field to add.
00173      * @throws org.dbview.db.structure.TableException
00174      * @remark This method is accessible for package's members only.
00175      *         Adding a field to a table is done when a field is created.
00176      */
00177     void addField(Field in_field) throws org.dbview.db.structure.TableException
00178     {
00179 
00180         String field_name = in_field.getName();
00181         if (null != this.__fields.get(field_name))
00182         { throw new org.dbview.db.structure.TableException("Table " + this.__name + ": Field " + field_name + " already added!"); }
00183         this.__fields.put(in_field.getName(), in_field);
00184         __orderedFields.add(field_name);
00185     }
00186 
00187     /**
00188      * Returns a field.
00189      * @param in_name Name of the field to return
00190      * @return If the field, referenced by its name, exists, then the method returns it.
00191      *         Otherwise, the method returns the value null.
00192      */
00193     public Field getField(String in_name)
00194     {
00195         return this.__fields.get(in_name);
00196     }
00197 
00198     /**
00199      * Return the list of all fields in the table.
00200      * The returned list is ordered. The order is the order of the table's definition.
00201      * @return The method returns the list of all fields in the table.
00202      */
00203     public ArrayList<Field> getFields()
00204     {
00205         ArrayList<Field> result = new ArrayList<Field>();
00206         Iterator<String> i = this.__orderedFields.iterator();
00207         while (i.hasNext()) { result.add(this.__fields.get(i.next())); }
00208         return result;
00209     }
00210 
00211     /**
00212      * Return the database that contains this table.
00213      * @return The method returns the database that contains this table.
00214      */
00215     public Database getDatabase()
00216     {
00217         return this.__db;
00218     }
00219 
00220     /**
00221      * Return the name of the database that contains this table.
00222      * @return The method returns the name of the database that contains this table.
00223      */
00224     public String getDatabaseName()
00225     {
00226         return this.__db.getName();
00227     }
00228 
00229     /**
00230      * Return the list of foreign keys.
00231      * @return The method returns the list of foreign keys.
00232      */
00233     public ArrayList<Field> getForeignKeys()
00234     {
00235         ArrayList<Field> fks = new ArrayList<Field>();
00236         for (Field field: this.getFields()) { if (field.isForeignKey()) { fks.add(field); } }
00237         return fks;
00238     }
00239 
00240     /**
00241      * Produce a textual representation of the table.
00242      * @return The method returns a string that represents a textual representation of the table.
00243      */
00244     public String toString()
00245     {
00246         ArrayList<String> result = new ArrayList<String>();
00247         ArrayList<Field>  fields = this.getFields();
00248 
00249         result.add(this.getName());
00250         Iterator<Field> i = fields.iterator();
00251         while (i.hasNext())
00252         {
00253             Field f = i.next();
00254             result.add("\t" + f.toString());
00255         }
00256 
00257         return Strings.joinWithNewLines(result);
00258     }
00259 }