KickJava   Java API By Example, From Geeks To Geeks.

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


1 /**
2  * com.mckoi.database.SimpleTableQuery 16 Oct 2001
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  * A simple convenience interface for querying a MutableTableDataSource
31  * instance. This is used as a very lightweight interface for changing a
32  * table. It is most useful for internal low level users of a database
33  * table which doesn't need the overhead of the Mckoi table hierarchy
34  * mechanism.
35  *
36  * @author Tobias Downer
37  */

38
39 public final class SimpleTableQuery {
40
41   /**
42    * The DataTableDef for this table.
43    */

44   private DataTableDef table_def;
45
46   /**
47    * The TableDataSource we are wrapping.
48    */

49   private TableDataSource table;
50
51   /**
52    * Constructs the SimpleTableQuery with the given MutableTableDataSource
53    * object.
54    */

55   public SimpleTableQuery(TableDataSource in_table) {
56 // in_table.addRootLock();
57
this.table = in_table;
58     this.table_def = table.getDataTableDef();
59   }
60
61   /**
62    * Returns a RowEnumeration that is used to iterate through the entire list
63    * of valid rows in the table.
64    */

65   public RowEnumeration rowEnumeration() {
66     return table.rowEnumeration();
67   }
68
69   /**
70    * Returns the total number of rows in this table.
71    */

72   public int getRowCount() {
73     return table.getRowCount();
74   }
75   
76   /**
77    * Gets the TObject at the given cell in the table.
78    * Note that the offset between one valid row and the next may not necessily
79    * be 1. It is possible for there to be gaps in the data. For an iterator
80    * that returns successive row indexes, use the 'rowEnumeration' method.
81    */

82   public TObject get(int column, int row) {
83     return table.getCellContents(column, row);
84   }
85
86   /**
87    * Finds the index of all the rows in the table where the given column is
88    * equal to the given object.
89    */

90   public IntegerVector selectIndexesEqual(int column, TObject cell) {
91     return table.getColumnScheme(column).selectEqual(cell);
92   }
93
94   /**
95    * Finds the index of all the rows in the table where the given column is
96    * equal to the given object.
97    * <p>
98    * We assume value is not null, and it is either a BigNumber to represent
99    * a number, a String, a java.util.Date or a ByteLongObject.
100    */

101   public IntegerVector selectIndexesEqual(int column, Object JavaDoc value) {
102     TType ttype = table_def.columnAt(column).getTType();
103     TObject cell = new TObject(ttype, value);
104     return selectIndexesEqual(column, cell);
105   }
106
107   /**
108    * Finds the index of all the rows in the table where the given column is
109    * equal to the given object for both of the clauses. This implies an
110    * AND for the two searches.
111    */

112   public IntegerVector selectIndexesEqual(int col1, TObject cell1,
113                                           int col2, TObject cell2) {
114
115     // All the indexes that equal the first clause
116
IntegerVector ivec = table.getColumnScheme(col1).selectEqual(cell1);
117
118     // From this, remove all the indexes that don't equals the second clause.
119
int index = ivec.size() - 1;
120     while (index >= 0) {
121       // If the value in column 2 at this index is not equal to value then
122
// remove it from the list and move to the next.
123
if (get(col2, ivec.intAt(index)).compareTo(cell2) != 0) {
124         ivec.removeIntAt(index);
125       }
126       --index;
127     }
128
129     return ivec;
130   }
131
132   /**
133    * Finds the index of all the rows in the table where the given column is
134    * equal to the given object for both of the clauses. This implies an
135    * AND for the two searches.
136    * <p>
137    * We assume value is not null, and it is either a BigNumber to represent
138    * a number, a String, a java.util.Date or a ByteLongObject.
139    */

140   public IntegerVector selectIndexesEqual(int col1, Object JavaDoc val1,
141                                           int col2, Object JavaDoc val2) {
142     TType t1 = table_def.columnAt(col1).getTType();
143     TType t2 = table_def.columnAt(col2).getTType();
144
145     TObject cell1 = new TObject(t1, val1);
146     TObject cell2 = new TObject(t2, val2);
147
148     return selectIndexesEqual(col1, cell1, col2, cell2);
149   }
150
151   /**
152    * Returns true if there is a single row in the table where the given column
153    * is equal to the given value, otherwise returns false. If there are 2 or
154    * more rows an assertion exception is thrown.
155    */

156   public boolean existsSingle(int col, Object JavaDoc val) {
157     IntegerVector ivec = selectIndexesEqual(col, val);
158     if (ivec.size() == 0) {
159       return false;
160     }
161     else if (ivec.size() == 1) {
162       return true;
163     }
164     else {
165       throw new Error JavaDoc("Assertion failed: existsSingle found multiple values.");
166     }
167   }
168
169   /**
170    * Assuming the table stores a key/value mapping, this returns the contents
171    * of value_column for any rows where key_column is equal to the key_value.
172    * An assertion exception is thrown if there is more than 2 rows that match
173    * the key. If no rows match the key then null is returned.
174    */

175   public Object JavaDoc getVar(int value_column, int key_column, Object JavaDoc key_value) {
176     // All indexes in the table where the key value is found.
177
IntegerVector ivec = selectIndexesEqual(key_column, key_value);
178     if (ivec.size() > 1) {
179       throw new Error JavaDoc("Assertion failed: getVar found multiple key values.");
180     }
181     else if (ivec.size() == 0) {
182       // Key found so return the value
183
return get(value_column, ivec.intAt(0));
184     }
185     else {
186       // Key not found so return null
187
return null;
188     }
189   }
190
191   // ---------- Table mutable methods ---------
192

193   /**
194    * Adds a new key/value mapping in this table. If the key already exists
195    * the old key/value row is deleted first. This method accepts two
196    * arguments, the column that contains the key value, and an Object[] array
197    * that is the list of cells to insert into the table. The Object[] array
198    * must be the size of the number of columns in this tbale.
199    * <p>
200    * NOTE: Change will come into effect globally at the next commit.
201    * <p>
202    * NOTE: This method must be assured of exlusive access to the table within
203    * the transaction.
204    * <p>
205    * NOTE: This only works if the given table implements MutableTableDataSource.
206    */

207   public void setVar(int key_column, Object JavaDoc[] vals) {
208     // Cast to a MutableTableDataSource
209
MutableTableDataSource mtable = (MutableTableDataSource) table;
210
211     // All indexes in the table where the key value is found.
212
IntegerVector ivec = selectIndexesEqual(key_column, vals[key_column]);
213     if (ivec.size() > 1) {
214       throw new Error JavaDoc("Assertion failed: setVar found multiple key values.");
215     }
216     else if (ivec.size() == 1) {
217       // Remove the current key
218
mtable.removeRow(ivec.intAt(0));
219     }
220     // Insert the new key
221
RowData row_data = new RowData(table);
222     for (int i = 0; i < table_def.columnCount(); ++i) {
223       row_data.setColumnDataFromObject(i, vals[i]);
224     }
225     mtable.addRow(row_data);
226   }
227
228   /**
229    * Deletes a single entry from the table where the given column equals the
230    * given value. If there are multiple values found an assertion exception
231    * is thrown. If a single value was found and deleted 'true' is returned
232    * otherwise false.
233    * <p>
234    * NOTE: This only works if the given table implements MutableTableDataSource.
235    */

236   public boolean deleteSingle(int col, Object JavaDoc val) {
237     // Cast to a MutableTableDataSource
238
MutableTableDataSource mtable = (MutableTableDataSource) table;
239
240     IntegerVector ivec = selectIndexesEqual(col, val);
241     if (ivec.size() == 0) {
242       return false;
243     }
244     else if (ivec.size() == 1) {
245       mtable.removeRow(ivec.intAt(0));
246       return true;
247     }
248     else {
249       throw new Error JavaDoc("Assertion failed: deleteSingle found multiple values.");
250     }
251   }
252
253   /**
254    * Deletes all the given indexes in this table.
255    * <p>
256    * NOTE: This only works if the given table implements MutableTableDataSource.
257    */

258   public void deleteRows(IntegerVector list) {
259     // Cast to a MutableTableDataSource
260
MutableTableDataSource mtable = (MutableTableDataSource) table;
261
262     for (int i = 0; i < list.size(); ++i) {
263       mtable.removeRow(list.intAt(i));
264     }
265   }
266
267
268
269
270
271
272   /**
273    * Disposes this object and frees any resources associated with it. This
274    * should be called when the query object is no longer being used.
275    */

276   public void dispose() {
277     if (table != null) {
278 // table.removeRootLock();
279
table = null;
280     }
281   }
282
283   /**
284    * To be save we call dispose from the finalize method.
285    */

286   public void finalize() {
287     dispose();
288   }
289
290 }
291
Popular Tags