1 package com.workingdogs.village;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.sql.Connection;
23 import java.sql.ResultSet;
24 import java.sql.SQLException;
25
26 import java.util.Enumeration;
27
28 /***
29 * This class is used for doing select/insert/delete/update on the database. A TableDataSet cannot be used to join multiple tables
30 * for an update, if you need join functionality on a select, you should use a <a href="QueryDataSet.html">QueryDataSet</a>.
31 *
32 * <P>
33 * Here is an example usage for this code that gets the first 10 records where column "a" = 1:
34 * <PRE>
35 * KeyDef kd = new KeyDef().setAttrib("column");
36 * TableDataSet tds = new TableDataSet(connection, "table_name", kd );
37 * tds.where ("a=1" ); // WHERE a = 1
38 * tds.fetchRecords(10); // fetch first 10 records where column a=1
39 * for ( int i=0;i< tds.size(); i++ )
40 * {
41 * Record rec = tds.getRecord(i); // zero based
42 * String columnA = rec.getValue("a");
43 * if ( columnA.equals ("1") )
44 * System.out.print ("We got a column!");
45 * }
46 * tds.close();
47 * </PRE>
48 * </p>
49 *
50 * <P>
51 * It is important to remember to always close() the TableDataSet when you are finished with it.
52 * </p>
53 *
54 * <P>
55 * As you can see, using a TableDataSet makes doing selects from the database trivial. You do not need to write any SQL and it
56 * makes it easy to cache a TableDataSet for future use within your application.
57 * </p>
58 *
59 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
60 * @version $Revision: 568 $
61 */
62 public class TableDataSet
63 extends DataSet
64 {
65 /*** the optimistic locking column value */
66 private String optimisticLockingCol;
67
68 /*** the value for the sql where clause */
69 private String where = null;
70
71 /*** the value for the sql order by clause */
72 private String order = null;
73
74 /*** the value for the sql other clause */
75 private String other = null;
76
77
78
79 /*** TODO: DOCUMENT ME! */
80 private boolean refreshOnSave = false;
81
82 /***
83 * Default constructor.
84 *
85 * @exception SQLException
86 * @exception DataSetException
87 */
88 public TableDataSet()
89 throws SQLException, DataSetException
90 {
91 super();
92 }
93
94 /***
95 * Creates a new TableDataSet object.
96 *
97 * @param conn TODO: DOCUMENT ME!
98 * @param tableName TODO: DOCUMENT ME!
99 *
100 * @throws SQLException TODO: DOCUMENT ME!
101 * @throws DataSetException TODO: DOCUMENT ME!
102 */
103 public TableDataSet(Connection conn, String tableName)
104 throws SQLException, DataSetException
105 {
106 super(conn, tableName);
107 }
108
109 /***
110 * Creates a new TableDataSet object.
111 *
112 * @param conn TODO: DOCUMENT ME!
113 * @param schema TODO: DOCUMENT ME!
114 * @param keydef TODO: DOCUMENT ME!
115 *
116 * @throws SQLException TODO: DOCUMENT ME!
117 * @throws DataSetException TODO: DOCUMENT ME!
118 */
119 public TableDataSet(Connection conn, Schema schema, KeyDef keydef)
120 throws SQLException, DataSetException
121 {
122 super(conn, schema, keydef);
123 }
124
125 /***
126 * Creates a new TableDataSet object.
127 *
128 * @param conn TODO: DOCUMENT ME!
129 * @param tableName TODO: DOCUMENT ME!
130 * @param keydef TODO: DOCUMENT ME!
131 *
132 * @throws SQLException TODO: DOCUMENT ME!
133 * @throws DataSetException TODO: DOCUMENT ME!
134 */
135 public TableDataSet(Connection conn, String tableName, KeyDef keydef)
136 throws SQLException, DataSetException
137 {
138 super(conn, tableName, keydef);
139 }
140
141 /***
142 * Creates a new TableDataSet object.
143 *
144 * @param conn TODO: DOCUMENT ME!
145 * @param tableName TODO: DOCUMENT ME!
146 * @param columns TODO: DOCUMENT ME!
147 *
148 * @throws SQLException TODO: DOCUMENT ME!
149 * @throws DataSetException TODO: DOCUMENT ME!
150 */
151 public TableDataSet(Connection conn, String tableName, String columns)
152 throws SQLException, DataSetException
153 {
154 super(conn, tableName, columns);
155 }
156
157 /***
158 * Creates a new TableDataSet object.
159 *
160 * @param conn TODO: DOCUMENT ME!
161 * @param tableName TODO: DOCUMENT ME!
162 * @param columns TODO: DOCUMENT ME!
163 * @param keydef TODO: DOCUMENT ME!
164 *
165 * @throws SQLException TODO: DOCUMENT ME!
166 * @throws DataSetException TODO: DOCUMENT ME!
167 */
168 public TableDataSet(Connection conn, String tableName, String columns, KeyDef keydef)
169 throws SQLException, DataSetException
170 {
171 super(conn, tableName, columns, keydef);
172 }
173
174 /***
175 * Use the TDS fetchRecords instead of the DataSet.fetchRecords
176 *
177 * @return an instance of myself
178 *
179 * @exception SQLException
180 * @exception DataSetException
181 */
182 public DataSet fetchRecords()
183 throws SQLException, DataSetException
184 {
185 return fetchRecords(-1);
186 }
187
188 /***
189 * Use the TDS fetchRecords instead of the DataSet.fetchRecords
190 *
191 * @param max
192 *
193 * @return an instance of myself
194 *
195 * @exception SQLException
196 * @exception DataSetException
197 */
198 public DataSet fetchRecords(int max)
199 throws SQLException, DataSetException
200 {
201 return fetchRecords(0, max);
202 }
203
204 /***
205 * Fetch start to max records. start is at Record 0
206 *
207 * @param start
208 * @param max
209 *
210 * @return an instance of myself
211 *
212 * @exception SQLException
213 * @exception DataSetException
214 */
215 public DataSet fetchRecords(int start, int max)
216 throws SQLException, DataSetException
217 {
218 buildSelectString();
219
220 return super.fetchRecords(start, max);
221 }
222
223 /***
224 * this is a string that contains the columns for the table that this TableDataSet represents.
225 *
226 * @return columns separated by ","
227 */
228 public String attributes()
229 {
230 return super.getColumns();
231 }
232
233 /***
234 * Returns the KeyDef for the DataSet
235 *
236 * @return a keydef
237 */
238 public KeyDef keydef()
239 {
240 return super.keydef();
241 }
242
243 /***
244 * Returns the ResultSet for the DataSet
245 *
246 * @return a ResultSet
247 *
248 * @throws SQLException TODO: DOCUMENT ME!
249 * @throws DataSetException TODO: DOCUMENT ME!
250 */
251 public ResultSet resultSet()
252 throws SQLException, DataSetException
253 {
254 return super.resultSet();
255 }
256
257 /***
258 * Returns the Schema for the DataSet
259 *
260 * @return a Schema
261 */
262 public Schema schema()
263 {
264 return super.schema();
265 }
266
267 /***
268 * Saves all the records in the DataSet.
269 *
270 * @return total number of records updated/inserted/deleted
271 *
272 * @throws SQLException TODO: DOCUMENT ME!
273 * @throws DataSetException TODO: DOCUMENT ME!
274 */
275 public int save()
276 throws SQLException, DataSetException
277 {
278 return save(connection(), false);
279 }
280
281 /***
282 * Saves all the records in the DataSet with the intransaction boolean value.
283 *
284 * @param intransaction TODO: DOCUMENT ME!
285 *
286 * @return total number of records updated/inserted/deleted
287 *
288 * @throws SQLException TODO: DOCUMENT ME!
289 * @throws DataSetException TODO: DOCUMENT ME!
290 */
291 public int save(boolean intransaction)
292 throws SQLException, DataSetException
293 {
294 return save(connection(), intransaction);
295 }
296
297 /***
298 * Saves all the records in the DataSet with the given connection and intransaction boolean value.
299 *
300 * @param conn TODO: DOCUMENT ME!
301 * @param intransaction TODO: DOCUMENT ME!
302 *
303 * @return total number of records updated/inserted/deleted
304 *
305 * @throws SQLException TODO: DOCUMENT ME!
306 * @throws DataSetException TODO: DOCUMENT ME!
307 */
308 public int save(Connection conn, boolean intransaction)
309 throws SQLException, DataSetException
310 {
311 int j = 0;
312
313 for (Enumeration e = records.elements(); e.hasMoreElements();)
314 {
315 Record rec = (Record) e.nextElement();
316 rec.save(conn);
317 j++;
318 }
319
320
321
322
323 removeDeletedRecords();
324
325 return j;
326 }
327
328 /***
329 * Not yet implemented
330 *
331 * @param conn TODO: DOCUMENT ME!
332 *
333 * @return TODO: DOCUMENT ME!
334 *
335 * @throws SQLException TODO: DOCUMENT ME!
336 * @throws DataSetException TODO: DOCUMENT ME!
337 */
338 public int saveWithoutStatusUpdate(Connection conn)
339 throws SQLException, DataSetException
340 {
341 throw new DataSetException("Not yet implemented!");
342 }
343
344 /***
345 * Hell if I know what this does.
346 *
347 * @return TODO: DOCUMENT ME!
348 */
349 public String debugInfo()
350 {
351 return "Not yet implemented!";
352 }
353
354 /***
355 * Removes any records that are marked as a zombie.
356 *
357 * @throws DataSetException TODO: DOCUMENT ME!
358 */
359 public void removeDeletedRecords()
360 throws DataSetException
361 {
362 for (Enumeration e = records.elements(); e.hasMoreElements();)
363 {
364 Record rec = (Record) e.nextElement();
365
366 if (rec.isAZombie())
367 {
368 removeRecord(rec);
369 }
370 }
371 }
372
373 /***
374 * Sets the table column used for optomistic locking.
375 *
376 * @param olc TODO: DOCUMENT ME!
377 */
378 public void setOptimisticLockingColumn(String olc)
379 {
380 this.optimisticLockingCol = olc;
381 }
382
383 /***
384 * Gets the table column used for optomistic locking.
385 *
386 * @return string
387 */
388 public String optimisticLockingCol()
389 {
390 return this.optimisticLockingCol;
391 }
392
393 /***
394 * Sets the value for the SQL portion of the WHERE statement
395 *
396 * @param where TODO: DOCUMENT ME!
397 *
398 * @return instance of self
399 *
400 * @throws DataSetException TODO: DOCUMENT ME!
401 */
402 public TableDataSet where(String where)
403 throws DataSetException
404 {
405 if (where == null)
406 {
407 throw new DataSetException("null not allowed for where clause");
408 }
409
410 this.where = where;
411
412 return this;
413 }
414
415 /***
416 * Gets the value of the SQL portion of WHERE.
417 *
418 * @return string
419 */
420 String getWhere()
421 {
422 return this.where;
423 }
424
425 /***
426 * Sets the value for the SQL portion of the ORDER statement
427 *
428 * @param order TODO: DOCUMENT ME!
429 *
430 * @return instance of self
431 *
432 * @throws DataSetException TODO: DOCUMENT ME!
433 */
434 public TableDataSet order(String order)
435 throws DataSetException
436 {
437 if (order == null)
438 {
439 throw new DataSetException("null not allowed for order clause");
440 }
441
442 this.order = order;
443
444 return this;
445 }
446
447 /***
448 * Gets the value of the SQL portion of ORDER.
449 *
450 * @return string
451 */
452 String getOrder()
453 {
454 return this.order;
455 }
456
457 /***
458 * Sets the value for the SQL portion of the OTHER statement
459 *
460 * @param other TODO: DOCUMENT ME!
461 *
462 * @return instance of self
463 *
464 * @throws DataSetException TODO: DOCUMENT ME!
465 */
466 public TableDataSet other(String other)
467 throws DataSetException
468 {
469 if (other == null)
470 {
471 throw new DataSetException("null not allowed for other clause");
472 }
473
474 this.other = other;
475
476 return this;
477 }
478
479 /***
480 * Gets the value of the SQL portion of OTHER.
481 *
482 * @return string
483 */
484 String getOther()
485 {
486 return this.other;
487 }
488
489 /***
490 * This method refreshes all of the Records stored in this TableDataSet.
491 *
492 * @param conn TODO: DOCUMENT ME!
493 *
494 * @throws SQLException TODO: DOCUMENT ME!
495 * @throws DataSetException TODO: DOCUMENT ME!
496 */
497 public void refresh(Connection conn)
498 throws SQLException, DataSetException
499 {
500 for (Enumeration e = records.elements(); e.hasMoreElements();)
501 {
502 Record rec = (Record) e.nextElement();
503 rec.refresh(conn);
504 }
505 }
506
507 /***
508 * Setting this causes each Record to refresh itself when a save() is performed on it.
509 *
510 * <P>
511 * Default value is false.
512 * </p>
513 *
514 * @param val TODO: DOCUMENT ME!
515 */
516 public void setRefreshOnSave(boolean val)
517 {
518 this.refreshOnSave = val;
519 }
520
521 /***
522 * Setting this causes each Record to refresh itself when a save() is performed on it.
523 *
524 * <P>
525 * Default value is false.
526 * </p>
527 *
528 * @return true if it is on; false otherwise
529 */
530 public boolean refreshOnSave()
531 {
532 return this.refreshOnSave;
533 }
534
535 /***
536 * This sets additional SQL for the table name. The string appears after the table name. Sybase users would set this to
537 * "HOLDLOCK" to get repeatable reads.
538 *
539 * <P>
540 * FIXME: Is this right? I don't use Sybase.
541 * </p>
542 *
543 * @param tq TODO: DOCUMENT ME!
544 *
545 * @return an instance of self
546 */
547 public TableDataSet tableQualifier(String tq)
548 {
549
550 schema().appendTableName(tq);
551
552 return this;
553 }
554
555 /***
556 * The name of the table for which this TableDataSet was created.
557 *
558 * @return string
559 *
560 * @throws DataSetException TODO: DOCUMENT ME!
561 */
562 public String tableName()
563 throws DataSetException
564 {
565 return super.tableName();
566 }
567
568 /***
569 * Not yet implemented
570 *
571 * @exception SQLException
572 * @exception DataSetException
573 */
574 public void updateStatus()
575 throws SQLException, DataSetException
576 {
577 throw new DataSetException("Not yet implemented!");
578 }
579
580 /***
581 * Builds the select string that was used to populate this TableDataSet.
582 *
583 * @return SQL select string
584 *
585 * @throws DataSetException TODO: DOCUMENT ME!
586 */
587 public String getSelectString()
588 throws DataSetException
589 {
590 buildSelectString();
591
592 return this.selectString.toString();
593 }
594
595 /***
596 * Used by getSelectString to build the select string that was used to populate this TableDataSet.
597 *
598 * @throws DataSetException TODO: DOCUMENT ME!
599 */
600 private void buildSelectString()
601 throws DataSetException
602 {
603 if (selectString == null)
604 {
605 selectString = new StringBuffer(256);
606 }
607 else
608 {
609 selectString.setLength(0);
610 }
611
612 selectString.append("SELECT ");
613 selectString.append(schema().attributes());
614 selectString.append(" FROM ");
615 selectString.append(schema().tableName());
616
617 if ((this.where != null) && (this.where.length() > 0))
618 {
619 selectString.append(" WHERE " + this.where);
620 }
621
622 if ((this.order != null) && (this.order.length() > 0))
623 {
624 selectString.append(" ORDER BY " + this.order);
625 }
626
627 if ((this.other != null) && (this.other.length() > 0))
628 {
629 selectString.append(this.other);
630 }
631 }
632 }