KickJava   Java API By Example, From Geeks To Geeks.

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


1 /**
2  * com.mckoi.database.DefaultDataTable 11 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 import java.io.IOException JavaDoc;
29 import java.io.OutputStream JavaDoc;
30 import java.io.InputStream JavaDoc;
31
32 /**
33  * This represents a default implementation of a DataTable. It encapsulates
34  * information that is core to all DataTable objects. That is,
35  * <p>
36  * The table name,
37  * The description of the table fields,
38  * A set of SelectableScheme objects to describe row relations,
39  * A counter for the number of rows in the table.
40  * <p>
41  * There are two classes that extend this object. DataTable which is a
42  * DataTable that is a direct mapping to an internal table stored in the
43  * Database files. And TemporaryTable that contains information generated
44  * on the fly by the DBMS.
45  * <p>
46  * @author Tobias Downer
47  */

48
49 public abstract class DefaultDataTable extends AbstractDataTable {
50
51   /**
52    * The Database object that this table is a child of.
53    */

54   private Database database;
55
56   /**
57    * The number of rows in the table.
58    */

59   protected int row_count;
60
61   /**
62    * A list of schemes for managing the data relations of each column.
63    */

64   private SelectableScheme[] column_scheme;
65
66   /**
67    * The Constructor.
68    */

69   DefaultDataTable(Database database) {
70     super();
71     this.database = database;
72     this.row_count = 0;
73   }
74
75   /**
76    * Returns the Database object this table is part of.
77    */

78   public Database getDatabase() {
79     return database;
80   }
81
82   /**
83    * Returns the SelectableScheme for the given column. This is different from
84    * 'getColumnScheme(int column)' because this is designed to be overridden
85    * so derived classes can manage their own SelectableScheme sources.
86    */

87   protected SelectableScheme getRootColumnScheme(int column) {
88     return column_scheme[column];
89   }
90
91   /**
92    * Clears the SelectableScheme information for the given column.
93    */

94   protected void clearColumnScheme(int column) {
95     column_scheme[column] = null;
96   }
97
98   /**
99    * Blanks all the column schemes in the table to an initial state. This
100    * will make all schemes of type InsertSearch.
101    * <p>
102    * <strong>NOTE:</strong>
103    * The current default SelectableScheme type is InsertSearch. We may want
104    * to make this variable.
105    */

106   protected void blankSelectableSchemes() {
107     blankSelectableSchemes(0);
108   }
109
110   /**
111    * Blanks all the column schemes in this table to a specific type of
112    * scheme. If Type = 0 then InsertSearch (fast but takes up memory -
113    * requires each insert and delete from the table to be logged). If type
114    * = 1 then BlindSearch (slower but uses no memory and doesn't require
115    * insert and delete to be logged).
116    */

117   protected void blankSelectableSchemes(int type) {
118     column_scheme = new SelectableScheme[getColumnCount()];
119     for (int i = 0; i < column_scheme.length; ++i) {
120       if (type == 0) {
121         column_scheme[i] = new InsertSearch(this, i);
122       }
123       else if (type == 1) {
124         column_scheme[i] = new BlindSearch(this, i);
125       }
126     }
127   }
128
129   /**
130    * Returns the number of columns in the table.
131    */

132   public int getColumnCount() {
133     return getDataTableDef().columnCount();
134   }
135
136   /**
137    * Returns the number of rows stored in the table.
138    */

139   public int getRowCount() {
140     return row_count;
141   }
142
143 // /**
144
// * Returns a list of all the fields within the table. The list is ordered
145
// * the same way the fields were added in to the table. NOTE: if you use the
146
// * TableField.getName() method, it will not be fully resolved. There will
147
// * be no information about the table the field came from in the object.
148
// */
149
// public TableField[] getFields() {
150
// System.out.println("NOTE: Calls to DefaultDataTable.getFields() need to be deprecated.");
151
// return getDataTableDef().toTableFieldArray();
152
// }
153

154 // /**
155
// * Returns the field at the given column. Note the the name of the field
156
// * will not be fully resolved. It contains to information about the table
157
// * the field came from.
158
// */
159
// public TableField getFieldAt(int column) {
160
// System.out.println("NOTE: Calls to DefaultDataTable.getFieldAt() need to be deprecated.");
161
// return getDataTableDef().columnAt(column).tableFieldValue();
162
// }
163

164 // /**
165
// * Returns the fully resolved name of the given column in this table.
166
// *
167
// * @deprecated
168
// */
169
// public String getResolvedColumnName(int column) {
170
// StringBuffer out = new StringBuffer();
171
// out.append(getTableName().getName());
172
// out.append('.');
173
// out.append(getFieldAt(column).getName());
174
// return new String(out);
175
// }
176

177   /**
178    * Returns a fully qualified Variable object that represents the name of
179    * the column at the given index. For example,
180    * new Variable(new TableName("APP", "CUSTOMER"), "ID")
181    */

182   public Variable getResolvedVariable(int column) {
183     String JavaDoc col_name = getDataTableDef().columnAt(column).getName();
184     return new Variable(getTableName(), col_name);
185   }
186
187 // /**
188
// * Given a field name, ie. 'CUSTOMER.CUSTOMERID' this will return the
189
// * column number the field is at. Note that this method requires that the
190
// * type of the column (ie. the Table) be appended to the start. Returns
191
// * -1 if the field could not be found in the table.
192
// *
193
// * @deprecated
194
// */
195
// public int findFieldName(String name) {
196
// int point_index = name.indexOf('.');
197
// if (point_index == -1) {
198
// throw new Error("Can't find '.' deliminator in name: " + name);
199
// }
200
// String type = name.substring(0, point_index);
201
// String col_name = name.substring(point_index + 1);
202
//
203
// if (type.equals(getName())) {
204
// int size = getColumnCount();
205
// for (int i = 0; i < size; ++i) {
206
// TableField field = getFieldAt(i);
207
// if (field.getName().equals(col_name)) {
208
// return i;
209
// }
210
// }
211
// }
212
//
213
// return -1;
214
// }
215

216   /**
217    * Given a fully qualified variable field name, ie. 'APP.CUSTOMER.CUSTOMERID'
218    * this will return the column number the field is at. Returns -1 if the
219    * field does not exist in the table.
220    */

221   public int findFieldName(Variable v) {
222     // Check this is the correct table first...
223
TableName table_name = v.getTableName();
224     DataTableDef table_def = getDataTableDef();
225     if (table_name != null && table_name.equals(getTableName())) {
226       // Look for the column name
227
String JavaDoc col_name = v.getName();
228       int size = getColumnCount();
229       for (int i = 0; i < size; ++i) {
230         DataTableColumnDef col = table_def.columnAt(i);
231         if (col.getName().equals(col_name)) {
232           return i;
233         }
234       }
235     }
236     return -1;
237   }
238
239   /**
240    * Returns a SelectableScheme object for the given column of the
241    * VirtualTable. The Table parameter specifies the domain in which the
242    * scheme should be given. If table != this, we can safely assume it is a
243    * VirtualTable.
244    */

245   SelectableScheme getSelectableSchemeFor(int column, int original_column,
246                                           Table table) {
247     SelectableScheme scheme = getRootColumnScheme(column);
248
249 // System.out.println("DefaultDataTable.getSelectableSchemaFor(" +
250
// column + ", " + original_column + ", " + table);
251

252 // System.out.println(this);
253

254     // If we are getting a scheme for this table, simple return the information
255
// from the column_trees Vector.
256
if (table == this) {
257       return scheme;
258     }
259
260     // Otherwise, get the scheme to calculate a subset of the given scheme.
261
else {
262       return scheme.getSubsetScheme(table, original_column);
263     }
264
265   }
266
267   /**
268    * Given a set, this trickles down through the Table hierarchy resolving
269    * the given row_set to a form that the given ancestor understands.
270    * Say you give the set { 0, 1, 2, 3, 4, 5, 6 }, this function may check
271    * down three levels and return a new 7 element set with the rows fully
272    * resolved to the given ancestors domain.
273    */

274   void setToRowTableDomain(int column, IntegerVector row_set,
275                            TableDataSource ancestor) {
276     if (ancestor != this) {
277       throw new RuntimeException JavaDoc("Method routed to incorrect table ancestor.");
278     }
279   }
280
281   /**
282    * Return the list of DataTable and row sets that make up the raw information
283    * in this table. For a DataTable itselt, this is trivial.
284    * NOTE: Using this method is extremely inefficient, and should never be
285    * used. It is included only to complete feature set.
286    * IDEA: Put a warning to check if this method is ever used.
287    */

288   RawTableInformation resolveToRawTable(RawTableInformation info) {
289     System.err.println("Efficiency Warning in DataTable.resolveToRawTable.");
290     IntegerVector row_set = new IntegerVector();
291     RowEnumeration e = rowEnumeration();
292     while (e.hasMoreRows()) {
293       row_set.addInt(e.nextRowIndex());
294     }
295     info.add(this, row_set);
296     return info;
297   }
298
299 // /**
300
// * Returns a bit vector indicating the columns that are valid.
301
// */
302
// boolean[] validColumns() {
303
// int len = getColumnCount();
304
// boolean[] bit_vector = new boolean[len];
305
// for (int i = 0; i < len; ++i) {
306
// bit_vector[i] = true;
307
// }
308
// return bit_vector;
309
// }
310

311   /* ===== Convenience methods for updating internal information =====
312      =============== regarding the SelectableSchemes ================= */

313
314   /**
315    * Adds a single column of a row to the selectable scheme indexing.
316    */

317   void addCellToColumnSchemes(int row_number, int column_number) {
318     boolean indexable_type =
319                  getDataTableDef().columnAt(column_number).isIndexableType();
320     if (indexable_type) {
321       SelectableScheme ss = getRootColumnScheme(column_number);
322       ss.insert(row_number);
323     }
324   }
325
326   /**
327    * This is called when a row is in the table, and the SelectableScheme
328    * objects for each column need to be notified of the rows existance,
329    * therefore build up the relational model for the columns.
330    */

331   void addRowToColumnSchemes(int row_number) {
332     int col_count = getColumnCount();
333     DataTableDef table_def = getDataTableDef();
334     for (int i = 0; i < col_count; ++i) {
335       if (table_def.columnAt(i).isIndexableType()) {
336         SelectableScheme ss = getRootColumnScheme(i);
337         ss.insert(row_number);
338       }
339     }
340   }
341
342   /**
343    * This is called when an index to a row needs to be removed from the
344    * SelectableScheme objects. This occurs when we have a modification log
345    * of row removals that haven't actually happened to old backed up scheme.
346    */

347   void removeRowToColumnSchemes(int row_number) {
348     int col_count = getColumnCount();
349     DataTableDef table_def = getDataTableDef();
350     for (int i = 0; i < col_count; ++i) {
351       if (table_def.columnAt(i).isIndexableType()) {
352         SelectableScheme ss = getRootColumnScheme(i);
353         ss.remove(row_number);
354       }
355     }
356   }
357
358 }
359
Popular Tags