KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mckoi > database > SubsetColumnTable


1 /**
2  * com.mckoi.database.SubsetColumnTable 06 Apr 1998
3  *
4  * Mckoi SQL Database ( http://www.mckoi.com/database )
5  * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * Version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License Version 2 for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * Version 2 along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  * Change Log:
21  *
22  *
23  */

24
25 package com.mckoi.database;
26
27 import com.mckoi.util.IntegerVector;
28
29 /**
30  * This object is a filter that sits atop a Table object. Its purpose is to
31  * only provide a view of the columns that are required. In a Select
32  * query we may create a query with only the subset of columns that were
33  * originally in the table set. This object allows us to provide an
34  * interface to only the columns that the Table is allowed to access.
35  * <p>
36  * This method implements RootTable which means a union operation will not
37  * decend further past this table when searching for the roots.
38  *
39  * @author Tobias Downer
40  */

41
42 public final class SubsetColumnTable extends FilterTable
43                                      implements RootTable {
44
45   /**
46    * Maps from the column in this table to the column in the parent table.
47    * The number of entries of this should match the number of columns in this
48    * table.
49    */

50   private int[] column_map;
51
52   /**
53    * Maps from the column in the parent table, to the column in this table.
54    * The size of this should match the number of columns in the parent
55    * table.
56    */

57   private int[] reverse_column_map;
58
59   /**
60    * The DataTableDef object that describes the subset column of this
61    * table.
62    */

63   private DataTableDef subset_table_def;
64
65   /**
66    * The resolved Variable aliases for this subset. These are returned by
67    * getResolvedVariable and used in searches for findResolvedVariable. This
68    * can be used to remap the variable names used to match the columns.
69    */

70   private Variable[] aliases;
71
72
73   /**
74    * The Constructor.
75    */

76   public SubsetColumnTable(Table parent) {
77     super(parent);
78   }
79
80   /**
81    * Adds a column map into this table. The int array contains a map to the
82    * column in the parent object that we want the column number to reference.
83    * For example, to select columns 4, 8, 1, 2 into this new table, the
84    * array would be { 4, 8, 1, 2 }.
85    */

86   public void setColumnMap(int[] mapping, Variable[] aliases) {
87     reverse_column_map = new int[parent.getColumnCount()];
88     for (int i = 0; i < reverse_column_map.length; ++i) {
89       reverse_column_map[i] = -1;
90     }
91     column_map = mapping;
92
93     this.aliases = aliases;
94
95     subset_table_def = new DataTableDef();
96     DataTableDef parent_def = parent.getDataTableDef();
97     subset_table_def.setTableName(parent_def.getTableName());
98
99     for (int i = 0; i < mapping.length; ++i) {
100       int map_to = mapping[i];
101       DataTableColumnDef col_def =
102                         new DataTableColumnDef(parent.getColumnDefAt(map_to));
103       col_def.setName(aliases[i].getName());
104       subset_table_def.addVirtualColumn(col_def);
105       reverse_column_map[map_to] = i;
106     }
107     
108     subset_table_def.setImmutable();
109   }
110
111
112
113
114   /**
115    * Returns the number of columns in the table.
116    */

117   public int getColumnCount() {
118     return aliases.length;
119   }
120
121   /**
122    * Given a fully qualified variable field name, ie. 'APP.CUSTOMER.CUSTOMERID'
123    * this will return the column number the field is at. Returns -1 if the
124    * field does not exist in the table.
125    */

126   public int findFieldName(Variable v) {
127     for (int i = 0; i < aliases.length; ++i) {
128       if (v.equals(aliases[i])) {
129         return i;
130       }
131     }
132     return -1;
133   }
134
135   /**
136    * Returns the DataTableDef object that describes the columns and name
137    * of this table. For a SubsetColumnTable object, this returns the
138    * columns that were mapped via the 'setColumnMap' method.
139    */

140   public DataTableDef getDataTableDef() {
141     return subset_table_def;
142   }
143
144   /**
145    * Returns a fully qualified Variable object that represents the name of
146    * the column at the given index. For example,
147    * new Variable(new TableName("APP", "CUSTOMER"), "ID")
148    */

149   public Variable getResolvedVariable(int column) {
150     return aliases[column];
151   }
152
153   /**
154    * Returns a SelectableScheme for the given column in the given VirtualTable
155    * row domain.
156    */

157   final SelectableScheme getSelectableSchemeFor(int column,
158                                             int original_column, Table table) {
159
160     // We need to map the original_column if the original column is a reference
161
// in this subset column table. Otherwise we leave as is.
162
// The reason is because FilterTable pretends the call came from its
163
// parent if a request is made on this table.
164
int mapped_original_column = original_column;
165     if (table == this) {
166       mapped_original_column = column_map[original_column];
167     }
168
169     return super.getSelectableSchemeFor(column_map[column],
170                                         mapped_original_column, table);
171   }
172
173   /**
174    * Given a set, this trickles down through the Table hierarchy resolving
175    * the given row_set to a form that the given ancestor understands.
176    * Say you give the set { 0, 1, 2, 3, 4, 5, 6 }, this function may check
177    * down three levels and return a new 7 element set with the rows fully
178    * resolved to the given ancestors domain.
179    */

180   final void setToRowTableDomain(int column, IntegerVector row_set,
181                                  TableDataSource ancestor) {
182
183     super.setToRowTableDomain(column_map[column], row_set, ancestor);
184   }
185
186   /**
187    * Return the list of DataTable and row sets that make up the raw information
188    * in this table.
189    */

190   final RawTableInformation resolveToRawTable(RawTableInformation info) {
191     throw new Error JavaDoc("Tricky to implement this method!");
192     // ( for a SubsetColumnTable that is )
193
}
194
195   /**
196    * Returns an object that represents the information in the given cell
197    * in the table. This will generally be an expensive algorithm, so calls
198    * to it should be kept to a minimum. Note that the offset between two
199    * rows is not necessarily 1.
200    */

201   public final TObject getCellContents(int column, int row) {
202     return parent.getCellContents(column_map[column], row);
203   }
204
205   // ---------- Implemented from RootTable ----------
206

207   /**
208    * This function is used to check that two tables are identical. This
209    * is used in operations like 'union' that need to determine that the
210    * roots are infact of the same type.
211    */

212   public boolean typeEquals(RootTable table) {
213     return (this == table);
214   }
215
216
217   /**
218    * Returns a string that represents this table.
219    */

220   public String JavaDoc toString() {
221     String JavaDoc name = "SCT" + hashCode();
222     return name + "[" + getRowCount() + "]";
223   }
224
225 }
226
Popular Tags