| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| Table |
|
| 1.0;1 |
| 1 | /* | |
| 2 | * $Source$ | |
| 3 | * $Revision$ | |
| 4 | * | |
| 5 | * Copyright (C) 2000 William Chesters | |
| 6 | * | |
| 7 | * Part of Melati (http://melati.org), a framework for the rapid | |
| 8 | * development of clean, maintainable web applications. | |
| 9 | * | |
| 10 | * Melati is free software; Permission is granted to copy, distribute | |
| 11 | * and/or modify this software under the terms either: | |
| 12 | * | |
| 13 | * a) the GNU General Public License as published by the Free Software | |
| 14 | * Foundation; either version 2 of the License, or (at your option) | |
| 15 | * any later version, | |
| 16 | * | |
| 17 | * or | |
| 18 | * | |
| 19 | * b) any version of the Melati Software License, as published | |
| 20 | * at http://melati.org | |
| 21 | * | |
| 22 | * You should have received a copy of the GNU General Public License and | |
| 23 | * the Melati Software License along with this program; | |
| 24 | * if not, write to the Free Software Foundation, Inc., | |
| 25 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the | |
| 26 | * GNU General Public License and visit http://melati.org to obtain the | |
| 27 | * Melati Software License. | |
| 28 | * | |
| 29 | * Feel free to contact the Developers of Melati (http://melati.org), | |
| 30 | * if you would like to work out a different arrangement than the options | |
| 31 | * outlined here. It is our intention to allow Melati to be used by as | |
| 32 | * wide an audience as possible. | |
| 33 | * | |
| 34 | * This program is distributed in the hope that it will be useful, | |
| 35 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 36 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 37 | * GNU General Public License for more details. | |
| 38 | * | |
| 39 | * Contact details for copyright holder: | |
| 40 | * | |
| 41 | * William Chesters <williamc At paneris.org> | |
| 42 | * http://paneris.org/~williamc | |
| 43 | * Obrechtstraat 114, 2517VX Den Haag, The Netherlands | |
| 44 | */ | |
| 45 | ||
| 46 | package org.melati.poem; | |
| 47 | ||
| 48 | import org.melati.poem.util.Cache; | |
| 49 | ||
| 50 | import java.util.Enumeration; | |
| 51 | import java.util.List; | |
| 52 | import java.io.PrintStream; | |
| 53 | import java.sql.ResultSet; | |
| 54 | import java.sql.SQLException; | |
| 55 | ||
| 56 | /** | |
| 57 | * A table. | |
| 58 | * | |
| 59 | * @since 14-Apr-2008 | |
| 60 | */ | |
| 61 | public interface Table<P extends Persistent> { | |
| 62 | /** | |
| 63 | * The database to which the table is attached. | |
| 64 | * @return the db | |
| 65 | */ | |
| 66 | Database getDatabase(); | |
| 67 | ||
| 68 | /** | |
| 69 | * Initialise the table. | |
| 70 | */ | |
| 71 | void init(); | |
| 72 | /** | |
| 73 | * Do stuff immediately after table initialisation. | |
| 74 | * <p> | |
| 75 | * This base method clears the column info caches and adds a listener | |
| 76 | * to the column info table to maintain the caches. | |
| 77 | * <p> | |
| 78 | * It may be overridden to perform other actions. For example to | |
| 79 | * ensure required rows exist in tables that define numeric ID's for | |
| 80 | * codes. | |
| 81 | * | |
| 82 | * @see #notifyColumnInfo(ColumnInfo) | |
| 83 | * @see #clearColumnInfoCaches() | |
| 84 | */ | |
| 85 | void postInitialise(); | |
| 86 | ||
| 87 | /** | |
| 88 | * Create the (possibly overridden) TableInfo if it has not yet been created. | |
| 89 | */ | |
| 90 | void createTableInfo(); | |
| 91 | /** | |
| 92 | * The table's programmatic name. Identical with its name in the DSD (if the | |
| 93 | * table was defined there) and in its <TT>tableinfo</TT> entry. | |
| 94 | * This will normally be the same as the name in the RDBMS itself, however that name | |
| 95 | * may be translated to avoid DBMS specific name clashes. | |
| 96 | * | |
| 97 | * @return the table name, case as defined in the DSD | |
| 98 | * @see org.melati.poem.dbms.Dbms#melatiName(String) | |
| 99 | */ | |
| 100 | String getName(); | |
| 101 | ||
| 102 | /** | |
| 103 | * @return table name quoted using the DBMS' specific quoting rules. | |
| 104 | */ | |
| 105 | String quotedName(); | |
| 106 | ||
| 107 | /** | |
| 108 | * The human-readable name of the table. POEM itself doesn't use this, but | |
| 109 | * it's available to applications and Melati's generic admin system as a | |
| 110 | * default label for the table and caption for its records. | |
| 111 | * @return The human-readable name of the table | |
| 112 | */ | |
| 113 | String getDisplayName(); | |
| 114 | ||
| 115 | /** | |
| 116 | * A brief description of the table's function. POEM itself doesn't use | |
| 117 | * this, but it's available to applications and Melati's generic admin system | |
| 118 | * as a default label for the table and caption for its records. | |
| 119 | * @return the brief description | |
| 120 | */ | |
| 121 | String getDescription(); | |
| 122 | ||
| 123 | /** | |
| 124 | * The category of this table. POEM itself doesn't use | |
| 125 | * this, but it's available to applications and Melati's generic admin system | |
| 126 | * as a default label for the table and caption for its records. | |
| 127 | * | |
| 128 | * @return the category | |
| 129 | */ | |
| 130 | TableCategory getCategory(); | |
| 131 | ||
| 132 | /** | |
| 133 | * @return the {@link org.melati.poem.TableInfo} for this table | |
| 134 | */ | |
| 135 | TableInfo getInfo(); | |
| 136 | ||
| 137 | /** | |
| 138 | * The troid (<TT>id</TT>) of the table's entry in the <TT>tableinfo</TT> | |
| 139 | * table. It will always have one (except during initialisation, which the | |
| 140 | * application programmer will never see). | |
| 141 | * | |
| 142 | * @return id in TableInfo metadata table | |
| 143 | */ | |
| 144 | Integer tableInfoID(); | |
| 145 | ||
| 146 | /** | |
| 147 | * The table's column with a given name. If the table is defined in the DSD | |
| 148 | * under the name <TT><I>foo</I></TT>, there will be an | |
| 149 | * application-specialised <TT>Table</TT> subclass, called | |
| 150 | * <TT><I>Foo</I>Table</TT> (and available as <TT>get<I>Foo</I>Table</TT> | |
| 151 | * from the application-specialised <TT>Database</TT> subclass) which has | |
| 152 | * extra named methods for accessing the table's predefined <TT>Column</TT>s. | |
| 153 | * | |
| 154 | * @param nameP name of column to get | |
| 155 | * @return column of that name | |
| 156 | * @throws org.melati.poem.NoSuchColumnPoemException if there is no column with that name | |
| 157 | */ | |
| 158 | Column<?> getColumn(String nameP) throws NoSuchColumnPoemException; | |
| 159 | ||
| 160 | /** | |
| 161 | * All the table's columns. | |
| 162 | * | |
| 163 | * @return an <TT>Enumeration</TT> of <TT>Column</TT>s | |
| 164 | * @see org.melati.poem.Column | |
| 165 | */ | |
| 166 | Enumeration<Column<?>> columns(); | |
| 167 | ||
| 168 | /** | |
| 169 | * A list of all the table's columns. | |
| 170 | */ | |
| 171 | List<Column<?>> getColumns(); | |
| 172 | ||
| 173 | /** | |
| 174 | * @return the number of columns in this table. | |
| 175 | */ | |
| 176 | int getColumnsCount(); | |
| 177 | ||
| 178 | /** | |
| 179 | * @param columnInfoID the Id for the Column table | |
| 180 | * @return the Column with a TROID equal to columnInfoID | |
| 181 | */ | |
| 182 | Column<?> columnWithColumnInfoID(int columnInfoID); | |
| 183 | ||
| 184 | /** | |
| 185 | * The table's troid column. Every table in a POEM database must have a | |
| 186 | * troid (table row ID, or table-unique non-nullable integer primary key), | |
| 187 | * often but not necessarily called <TT>id</TT>, so that it can be | |
| 188 | * conveniently `named'. | |
| 189 | * | |
| 190 | * @return the id column | |
| 191 | * @see #getObject(Integer) | |
| 192 | */ | |
| 193 | Column<Integer> troidColumn(); | |
| 194 | ||
| 195 | /** | |
| 196 | * @return The table's deleted-flag column, if any. | |
| 197 | */ | |
| 198 | Column<Boolean> deletedColumn(); | |
| 199 | ||
| 200 | /** | |
| 201 | * The table's primary display column, the Troid column if not set. | |
| 202 | * This is the column used to represent records from the table | |
| 203 | * concisely in reports or whatever. It is determined | |
| 204 | * at initialisation time by examining the <TT>Column</TT>s | |
| 205 | * <TT>getPrimaryDisplay()</TT> flags. | |
| 206 | * | |
| 207 | * @return the table's display column, or <TT>null</TT> if it hasn't got one | |
| 208 | * | |
| 209 | * see Column#setColumnInfo | |
| 210 | * @see org.melati.poem.ReferencePoemType#_stringOfCooked | |
| 211 | * @see org.melati.poem.DisplayLevel#primary | |
| 212 | */ | |
| 213 | Column<?> displayColumn(); | |
| 214 | ||
| 215 | /** | |
| 216 | * @param column the display column to set | |
| 217 | */ | |
| 218 | void setDisplayColumn(Column<?> column); | |
| 219 | ||
| 220 | /** | |
| 221 | * In a similar manner to the primary display column, each table can have | |
| 222 | * one primary criterion column. | |
| 223 | * <p> | |
| 224 | * The Primary Criterion is the main grouping field of the table, | |
| 225 | * ie the most important non-unique type field. | |
| 226 | * <p> | |
| 227 | * For example the Primary Criterion for a User table might be Nationality. | |
| 228 | * | |
| 229 | * @return the search column, if any | |
| 230 | * @see org.melati.poem.Searchability | |
| 231 | */ | |
| 232 | Column<?> primaryCriterionColumn(); | |
| 233 | ||
| 234 | /** | |
| 235 | * @param column the search column to set | |
| 236 | */ | |
| 237 | void setSearchColumn(Column<?> column); | |
| 238 | ||
| 239 | /** | |
| 240 | * If the troidColumn has yet to be set then returns an empty string. | |
| 241 | * | |
| 242 | * @return comma separated list of the columns to order by | |
| 243 | */ | |
| 244 | String defaultOrderByClause(); | |
| 245 | ||
| 246 | /** | |
| 247 | * Clear caches. | |
| 248 | */ | |
| 249 | void clearColumnInfoCaches(); | |
| 250 | ||
| 251 | /** | |
| 252 | * Clears columnInfo caches, normally a no-op. | |
| 253 | * | |
| 254 | * @param infoP the possibly null ColumnInfo meta-data persistent | |
| 255 | */ | |
| 256 | void notifyColumnInfo(ColumnInfo infoP); | |
| 257 | ||
| 258 | /** | |
| 259 | * Return columns at a display level in display order. | |
| 260 | * | |
| 261 | * @param level the {@link org.melati.poem.DisplayLevel} to select | |
| 262 | * @return an Enumeration of columns at the given level | |
| 263 | */ | |
| 264 | Enumeration<Column<?>> displayColumns(DisplayLevel level); | |
| 265 | ||
| 266 | /** | |
| 267 | * @param level the {@link org.melati.poem.DisplayLevel} to select | |
| 268 | * @return the number of columns at a display level. | |
| 269 | */ | |
| 270 | int displayColumnsCount(DisplayLevel level); | |
| 271 | ||
| 272 | /** | |
| 273 | * The table's columns for detailed display in display order. | |
| 274 | * | |
| 275 | * @return an <TT>Enumeration</TT> of <TT>Column</TT>s | |
| 276 | * @see org.melati.poem.Column | |
| 277 | * @see #displayColumns(org.melati.poem.DisplayLevel) | |
| 278 | * @see org.melati.poem.DisplayLevel#detail | |
| 279 | */ | |
| 280 | Enumeration<Column<?>> getDetailDisplayColumns(); | |
| 281 | ||
| 282 | /** | |
| 283 | * @return the number of columns at display level <tt>Detail</tt> | |
| 284 | */ | |
| 285 | int getDetailDisplayColumnsCount(); | |
| 286 | ||
| 287 | /** | |
| 288 | * The table's columns designated for display in a record, in display order. | |
| 289 | * | |
| 290 | * @return an <TT>Enumeration</TT> of <TT>Column</TT>s | |
| 291 | * @see org.melati.poem.Column | |
| 292 | * @see #displayColumns(org.melati.poem.DisplayLevel) | |
| 293 | * @see org.melati.poem.DisplayLevel#record | |
| 294 | */ | |
| 295 | Enumeration<Column<?>> getRecordDisplayColumns(); | |
| 296 | ||
| 297 | /** | |
| 298 | * @return the number of columns at display level <tt>Record</tt> | |
| 299 | */ | |
| 300 | int getRecordDisplayColumnsCount(); | |
| 301 | ||
| 302 | /** | |
| 303 | * The table's columns designated for display in a record summary, in display | |
| 304 | * order. | |
| 305 | * | |
| 306 | * @return an <TT>Enumeration</TT> of <TT>Column</TT>s | |
| 307 | * @see org.melati.poem.Column | |
| 308 | * @see #displayColumns(org.melati.poem.DisplayLevel) | |
| 309 | * @see org.melati.poem.DisplayLevel#summary | |
| 310 | */ | |
| 311 | Enumeration<Column<?>> getSummaryDisplayColumns(); | |
| 312 | ||
| 313 | /** | |
| 314 | * @return the number of columns at display level <tt>Summary</tt> | |
| 315 | */ | |
| 316 | int getSummaryDisplayColumnsCount(); | |
| 317 | ||
| 318 | /** | |
| 319 | * The table's columns designated for use as search criteria, in display | |
| 320 | * order. | |
| 321 | * | |
| 322 | * @return an <TT>Enumeration</TT> of <TT>Column</TT>s | |
| 323 | * @see org.melati.poem.Column | |
| 324 | */ | |
| 325 | Enumeration<Column<?>> getSearchCriterionColumns(); | |
| 326 | ||
| 327 | /** | |
| 328 | * @return the number of columns which are searchable | |
| 329 | */ | |
| 330 | int getSearchCriterionColumnsCount(); | |
| 331 | ||
| 332 | /** | |
| 333 | * Use this for DDL statements, ie those which alter the structure of the db. | |
| 334 | * Postgresql in particular does not like DDL statements being executed within a transaction. | |
| 335 | * | |
| 336 | * @param sql the SQL DDL statement to execute | |
| 337 | * @throws org.melati.poem.StructuralModificationFailedPoemException | |
| 338 | */ | |
| 339 | void dbModifyStructure(String sql) | |
| 340 | throws StructuralModificationFailedPoemException; | |
| 341 | ||
| 342 | /** | |
| 343 | * Constraints are not used in POEM, but you might want to use them if | |
| 344 | * exporting the db or using schema visualisation tools. | |
| 345 | */ | |
| 346 | void dbAddConstraints(); | |
| 347 | ||
| 348 | /** | |
| 349 | * When deleting a table and used in tests. | |
| 350 | */ | |
| 351 | void invalidateTransactionStuffs(); | |
| 352 | ||
| 353 | /** | |
| 354 | * @param transaction possibly null if working with the committed transaction | |
| 355 | * @param persistent the Persistent to load | |
| 356 | */ | |
| 357 | void load(PoemTransaction transaction, Persistent persistent); | |
| 358 | ||
| 359 | /** | |
| 360 | * The Transaction cannot be null, as this is trapped in | |
| 361 | * #deleteLock(SessionToken). | |
| 362 | * @param troid id of row to delete | |
| 363 | * @param transaction a non-null transaction | |
| 364 | */ | |
| 365 | void delete(Integer troid, PoemTransaction transaction); | |
| 366 | ||
| 367 | /** | |
| 368 | * @param transaction our PoemTransaction | |
| 369 | * @param p the Persistent to write | |
| 370 | */ | |
| 371 | void writeDown(PoemTransaction transaction, Persistent p); | |
| 372 | ||
| 373 | /** | |
| 374 | * Invalidate table cache. | |
| 375 | * | |
| 376 | * NOTE Invalidated cache elements are reloaded when next read | |
| 377 | */ | |
| 378 | void uncache(); | |
| 379 | ||
| 380 | /** | |
| 381 | * @param maxSize new maximum size | |
| 382 | */ | |
| 383 | void trimCache(int maxSize); | |
| 384 | ||
| 385 | /** | |
| 386 | * @return the Cache Info object | |
| 387 | */ | |
| 388 | Cache.Info getCacheInfo(); | |
| 389 | ||
| 390 | /** | |
| 391 | * Add a {@link org.melati.poem.TableListener} to this Table. | |
| 392 | */ | |
| 393 | void addListener(TableListener listener); | |
| 394 | ||
| 395 | /** | |
| 396 | * Notify the table that one if its records is about to be changed in a | |
| 397 | * transaction. You can (with care) use this to support cacheing of | |
| 398 | * frequently-used facts about the table's records. | |
| 399 | * | |
| 400 | * @param transaction the transaction in which the change will be made | |
| 401 | * @param persistent the record to be changed | |
| 402 | */ | |
| 403 | void notifyTouched(PoemTransaction transaction, Persistent persistent); | |
| 404 | ||
| 405 | /** | |
| 406 | * @return the Transaction serial | |
| 407 | */ | |
| 408 | long serial(PoemTransaction transaction); | |
| 409 | ||
| 410 | /** | |
| 411 | * Lock this record. | |
| 412 | */ | |
| 413 | void readLock(); | |
| 414 | ||
| 415 | /** | |
| 416 | * The object from the table with a given troid. | |
| 417 | * | |
| 418 | * @param troid Every record (object) in a POEM database must have a | |
| 419 | * troid (table row ID, or table-unique non-nullable | |
| 420 | * integer primary key), often but not necessarily called | |
| 421 | * <TT>id</TT>, so that it can be conveniently `named' for | |
| 422 | * retrieval by this method. | |
| 423 | * | |
| 424 | * @return A <TT>Persistent</TT> of the record with the given troid; | |
| 425 | * or, if the table was defined in the DSD under the name | |
| 426 | * <TT><I>foo</I></TT>, an application-specialised subclass | |
| 427 | * <TT><I>Foo</I></TT> of <TT>Persistent</TT>. In that case, there | |
| 428 | * will also be an application-specialised <TT>Table</TT> subclass, | |
| 429 | * called <TT><I>Foo</I>Table</TT> (and available as | |
| 430 | * <TT>get<I>Foo</I>Table</TT> from the application-specialised | |
| 431 | * <TT>Database</TT> subclass), which has a matching method | |
| 432 | * <TT>get<I>Foo</I>Object</TT> for obtaining the specialised object | |
| 433 | * under its own type. Note that no access checks are done at this | |
| 434 | * stage: you may not be able to do anything with the object handle | |
| 435 | * returned from this method without provoking a | |
| 436 | * <TT>PoemAccessException</TT>. | |
| 437 | * | |
| 438 | * @exception org.melati.poem.NoSuchRowPoemException | |
| 439 | * if there is no row in the table with the given troid | |
| 440 | * | |
| 441 | * @see org.melati.poem.Persistent#getTroid() | |
| 442 | */ | |
| 443 | P getObject(Integer troid) throws NoSuchRowPoemException; | |
| 444 | ||
| 445 | /** | |
| 446 | * The object from the table with a given troid. See previous. | |
| 447 | * | |
| 448 | * @param troid the table row id | |
| 449 | * @return the Persistent | |
| 450 | * @throws org.melati.poem.NoSuchRowPoemException if not found | |
| 451 | * @see #getObject(Integer) | |
| 452 | */ | |
| 453 | Persistent getObject(int troid) throws NoSuchRowPoemException; | |
| 454 | ||
| 455 | /** | |
| 456 | * The from clause has been added as an argument because it is | |
| 457 | * inextricably linked to the when clause, but the default is | |
| 458 | * {@link #quotedName()}. | |
| 459 | * | |
| 460 | * It is the programmer's responsibility to ensure that the where clause | |
| 461 | * is suitable for the target DBMS. | |
| 462 | * | |
| 463 | * @param fromClause Comma separated list of table names or null for default. | |
| 464 | * @param whereClause SQL fragment | |
| 465 | * @param orderByClause Comma separated list | |
| 466 | * @param includeDeleted Flag as to whether to include soft deleted records | |
| 467 | * @param excludeUnselectable Whether to append unselectable exclusion SQL | |
| 468 | * TODO Should work within some kind of limit | |
| 469 | * @return an SQL SELECT statement put together from the arguments and | |
| 470 | * default order by clause. | |
| 471 | */ | |
| 472 | String selectionSQL(String fromClause, String whereClause, | |
| 473 | String orderByClause, boolean includeDeleted, | |
| 474 | boolean excludeUnselectable); | |
| 475 | ||
| 476 | /** | |
| 477 | * It is the programmer's responsibility to ensure that the where clause | |
| 478 | * is suitable for the target DBMS. | |
| 479 | * | |
| 480 | * @return an {@link java.util.Enumeration} of Troids satisfying the criteria. | |
| 481 | */ | |
| 482 | Enumeration<Integer> troidSelection(String whereClause, String orderByClause, | |
| 483 | boolean includeDeleted, | |
| 484 | PoemTransaction transaction); | |
| 485 | ||
| 486 | /** | |
| 487 | * | |
| 488 | * @see #troidSelection(String, String, boolean, org.melati.poem.PoemTransaction) | |
| 489 | * @param criteria Represents selection criteria possibly on joined tables | |
| 490 | * @param transaction A transaction or null for | |
| 491 | * {@link org.melati.poem.PoemThread#transaction()} | |
| 492 | * @return a selection of troids given arguments specifying a query | |
| 493 | */ | |
| 494 | Enumeration<Integer> troidSelection(Persistent criteria, String orderByClause, | |
| 495 | boolean includeDeleted, | |
| 496 | boolean excludeUnselectable, | |
| 497 | PoemTransaction transaction); | |
| 498 | ||
| 499 | /** | |
| 500 | * @param flag whether to remember or forget | |
| 501 | */ | |
| 502 | void rememberAllTroids(boolean flag); | |
| 503 | ||
| 504 | /** | |
| 505 | * @param limit the limit to set | |
| 506 | */ | |
| 507 | void setCacheLimit(Integer limit); | |
| 508 | ||
| 509 | /** | |
| 510 | * A <TT>SELECT</TT>ion of troids of objects from the table meeting given | |
| 511 | * criteria. | |
| 512 | * | |
| 513 | * It is the programmer's responsibility to ensure that the where clause | |
| 514 | * is suitable for the target DBMS. | |
| 515 | * | |
| 516 | * If the orderByClause is null, then the default order by clause is applied. | |
| 517 | * If the orderByClause is an empty string, ie "", then no ordering is | |
| 518 | * applied. | |
| 519 | * | |
| 520 | * @param whereClause an SQL snippet | |
| 521 | * @param orderByClause an SQL snippet | |
| 522 | * @param includeDeleted whether to include deleted records, if any | |
| 523 | * | |
| 524 | * @return an <TT>Enumeration</TT> of <TT>Integer</TT>s, which can be mapped | |
| 525 | * onto <TT>Persistent</TT> objects using <TT>getObject</TT>; | |
| 526 | * or you can just use <TT>selection</TT> | |
| 527 | * | |
| 528 | * @see #getObject(Integer) | |
| 529 | * @see #selection(String, String, boolean) | |
| 530 | */ | |
| 531 | Enumeration<Integer> troidSelection(String whereClause, String orderByClause, | |
| 532 | boolean includeDeleted) | |
| 533 | throws SQLPoemException; | |
| 534 | ||
| 535 | /** | |
| 536 | * All the objects in the table. | |
| 537 | * | |
| 538 | * @return An <TT>Enumeration</TT> of <TT>Persistent</TT>s, or, if the table | |
| 539 | * was defined in the DSD under the name <TT><I>foo</I></TT>, of | |
| 540 | * application-specialised subclasses <TT><I>Foo</I></TT>. Note | |
| 541 | * that no access checks are done at this stage: you may not be able | |
| 542 | * to do anything with some of the object handles in the enumeration | |
| 543 | * without provoking a <TT>PoemAccessException</TT>. If the table | |
| 544 | * has a <TT>deleted</TT> column, the objects flagged as deleted will | |
| 545 | * be passed over. | |
| 546 | * @see Selectable#selection() | |
| 547 | */ | |
| 548 | Enumeration<P> selection() throws SQLPoemException; | |
| 549 | ||
| 550 | /** | |
| 551 | * A <TT>SELECT</TT>ion of objects from the table meeting given criteria. | |
| 552 | * This is one way to run a search against the database and return the | |
| 553 | * results as a series of typed POEM objects. | |
| 554 | * | |
| 555 | * It is the programmer's responsibility to ensure that the where clause | |
| 556 | * is suitable for the target DBMS. | |
| 557 | * | |
| 558 | * @param whereClause SQL <TT>SELECT</TT>ion criteria for the search: | |
| 559 | * the part that should appear after the | |
| 560 | * <TT>WHERE</TT> keyword | |
| 561 | * | |
| 562 | * @return An <TT>Enumeration</TT> of <TT>Persistent</TT>s, or, if the table | |
| 563 | * was defined in the DSD under the name <TT><I>foo</I></TT>, of | |
| 564 | * application-specialised subclasses <TT><I>Foo</I></TT>. Note | |
| 565 | * that no access checks are done at this stage: you may not be able | |
| 566 | * to do anything with some of the object handles in the enumeration | |
| 567 | * without provoking a <TT>PoemAccessException</TT>. If the table | |
| 568 | * has a <TT>deleted</TT> column, the objects flagged as deleted will | |
| 569 | * be passed over. | |
| 570 | * | |
| 571 | * @see org.melati.poem.Column#selectionWhereEq(Object) | |
| 572 | */ | |
| 573 | Enumeration<P> selection(String whereClause) | |
| 574 | throws SQLPoemException; | |
| 575 | ||
| 576 | /** | |
| 577 | * Get an object satisfying the where clause. | |
| 578 | * It is the programmer's responsibility to use this in a | |
| 579 | * context where only one result will be found, if more than one | |
| 580 | * actually exist only the first will be returned. | |
| 581 | * | |
| 582 | * It is the programmer's responsibility to ensure that the where clause | |
| 583 | * is suitable for the target DBMS. | |
| 584 | * | |
| 585 | * @param whereClause SQL <TT>SELECT</TT>ion criteria for the search: | |
| 586 | * the part that should appear after the | |
| 587 | * <TT>WHERE</TT> keyword | |
| 588 | * @return the first item satisfying criteria | |
| 589 | */ | |
| 590 | Persistent firstSelection(String whereClause); | |
| 591 | ||
| 592 | /** | |
| 593 | * A <TT>SELECT</TT>ion of objects from the table meeting given criteria, | |
| 594 | * possibly including those flagged as deleted. | |
| 595 | * | |
| 596 | * If the orderByClause is null, then the default order by clause is applied. | |
| 597 | * If the orderByClause is an empty string, ie "", then no ordering is | |
| 598 | * applied. | |
| 599 | * | |
| 600 | * It is the programmer's responsibility to ensure that the where clause | |
| 601 | * is suitable for the target DBMS. | |
| 602 | * | |
| 603 | * @param includeDeleted whether to return objects flagged as deleted | |
| 604 | * (ignored if the table doesn't have a | |
| 605 | * <TT>deleted</TT> column) | |
| 606 | * @return a ResultSet as an Enumeration | |
| 607 | * @see #selection(String) | |
| 608 | */ | |
| 609 | Enumeration<P> selection(String whereClause, String orderByClause, | |
| 610 | boolean includeDeleted) | |
| 611 | throws SQLPoemException; | |
| 612 | ||
| 613 | /** | |
| 614 | * Return a selection of rows given an exemplar. | |
| 615 | * | |
| 616 | * @param criteria Represents selection criteria possibly on joined tables | |
| 617 | * @return an enumeration of like objects | |
| 618 | * @see #selection(String, String, boolean) | |
| 619 | */ | |
| 620 | Enumeration<P> selection(Persistent criteria) | |
| 621 | throws SQLPoemException; | |
| 622 | ||
| 623 | /** | |
| 624 | * Return a selection of rows given arguments specifying a query. | |
| 625 | * | |
| 626 | * @see #selection(String, String, boolean) | |
| 627 | * @param criteria Represents selection criteria possibly on joined tables | |
| 628 | * @param orderByClause Comma separated list | |
| 629 | * @return an enumeration of like objects with the specified ordering | |
| 630 | */ | |
| 631 | Enumeration<P> selection(Persistent criteria, String orderByClause) | |
| 632 | throws SQLPoemException; | |
| 633 | ||
| 634 | /** | |
| 635 | * Return a selection of rows given arguments specifying a query. | |
| 636 | * | |
| 637 | * @see #selection(String, String, boolean) | |
| 638 | * @param criteria Represents selection criteria possibly on joined tables | |
| 639 | * @param orderByClause Comma separated list | |
| 640 | * @param excludeUnselectable Whether to append unselectable exclusion SQL | |
| 641 | * @return an enumeration of like Persistents | |
| 642 | */ | |
| 643 | Enumeration<P> selection(Persistent criteria, String orderByClause, | |
| 644 | boolean includeDeleted, boolean excludeUnselectable) | |
| 645 | throws SQLPoemException; | |
| 646 | ||
| 647 | ||
| 648 | /** | |
| 649 | * @param whereClause the SQL fragment to count the results of | |
| 650 | * @return the SQL string for the current SQL dialect | |
| 651 | */ | |
| 652 | String countSQL(String whereClause); | |
| 653 | ||
| 654 | /** | |
| 655 | * Return an SQL statement to count rows put together from the arguments. | |
| 656 | * | |
| 657 | * It is the programmer's responsibility to ensure that the where clause | |
| 658 | * is suitable for the target DBMS. | |
| 659 | * | |
| 660 | * @param fromClause Comma separated list of table names | |
| 661 | * @return the SQL query | |
| 662 | */ | |
| 663 | String countSQL(String fromClause, String whereClause, | |
| 664 | boolean includeDeleted, boolean excludeUnselectable); | |
| 665 | ||
| 666 | /** | |
| 667 | * It is the programmer's responsibility to ensure that the where clause | |
| 668 | * is suitable for the target DBMS. | |
| 669 | * | |
| 670 | * @return the number records satisfying criteria. | |
| 671 | */ | |
| 672 | int count(String whereClause, | |
| 673 | boolean includeDeleted, boolean excludeUnselectable) | |
| 674 | throws SQLPoemException; | |
| 675 | ||
| 676 | /** | |
| 677 | * It is the programmer's responsibility to ensure that the where clause | |
| 678 | * is suitable for the target DBMS. | |
| 679 | * | |
| 680 | * @return the number records satisfying criteria. | |
| 681 | */ | |
| 682 | int count(String whereClause, boolean includeDeleted) | |
| 683 | throws SQLPoemException; | |
| 684 | ||
| 685 | /** | |
| 686 | * It is the programmer's responsibility to ensure that the where clause | |
| 687 | * is suitable for the target DBMS. | |
| 688 | * | |
| 689 | * @return the number of records satisfying criteria. | |
| 690 | */ | |
| 691 | int count(String whereClause) | |
| 692 | throws SQLPoemException; | |
| 693 | ||
| 694 | /** | |
| 695 | * @return the number of records in this table. | |
| 696 | */ | |
| 697 | int count() | |
| 698 | throws SQLPoemException; | |
| 699 | ||
| 700 | /** | |
| 701 | * It is the programmer's responsibility to ensure that the where clause | |
| 702 | * is suitable for the target DBMS. | |
| 703 | * | |
| 704 | * @param whereClause the SQL criteria | |
| 705 | * @return whether any records satisfy criteria. | |
| 706 | */ | |
| 707 | boolean exists(String whereClause) throws SQLPoemException; | |
| 708 | ||
| 709 | /** | |
| 710 | * @param persistent a {@link org.melati.poem.Persistent} with some fields filled in | |
| 711 | * @return whether any records exist with the same fields filled | |
| 712 | */ | |
| 713 | boolean exists(Persistent persistent); | |
| 714 | ||
| 715 | /** | |
| 716 | * Append an SQL logical expression to the given buffer to match rows | |
| 717 | * according to criteria represented by the given object. | |
| 718 | * <p> | |
| 719 | * This default selects rows for which the non-null fields in the | |
| 720 | * given object match, but subtypes may add other criteria. | |
| 721 | * <p> | |
| 722 | * The column names are now qualified with the table name so that | |
| 723 | * subtypes can append elements of a join but there is no filtering | |
| 724 | * by canselect columns. | |
| 725 | * | |
| 726 | * TODO Add mechanism for searching for Nulls (that would be query | |
| 727 | * constructs as per SQL parse tree, but efferent not afferent) | |
| 728 | * | |
| 729 | * @see #notifyColumnInfo(org.melati.poem.ColumnInfo) | |
| 730 | * @see #clearColumnInfoCaches() | |
| 731 | */ | |
| 732 | void appendWhereClause(StringBuffer clause, Persistent persistent); | |
| 733 | ||
| 734 | /** | |
| 735 | * Return an SQL WHERE clause to select rows that match the non-null | |
| 736 | * fields of the given object. | |
| 737 | * <p> | |
| 738 | * This does not filter out any rows with a capability the user | |
| 739 | * does not have in a canselect column, nor did it ever filter | |
| 740 | * out rows deleted according to a "deleted" column. | |
| 741 | * But the caller usually gets a second chance to do both. | |
| 742 | * @return an SQL fragment | |
| 743 | */ | |
| 744 | String whereClause(Persistent criteria); | |
| 745 | ||
| 746 | /** | |
| 747 | * Return an SQL WHERE clause to select rows using the given object | |
| 748 | * as a selection criteria and optionally deleted rows or those | |
| 749 | * included rows the user is not capable of selecting. | |
| 750 | * <p> | |
| 751 | * This is currently implemented in terms of | |
| 752 | * {@link org.melati.poem.Table#appendWhereClause(StringBuffer, org.melati.poem.Persistent)}. | |
| 753 | * @return an SQL fragment | |
| 754 | */ | |
| 755 | String whereClause(Persistent criteria, | |
| 756 | boolean includeDeleted, boolean excludeUnselectable); | |
| 757 | ||
| 758 | /** | |
| 759 | * @return an SQL fragment | |
| 760 | * @see #cnfWhereClause(java.util.Enumeration, boolean, boolean) | |
| 761 | * @see #whereClause(org.melati.poem.Persistent) | |
| 762 | */ | |
| 763 | String cnfWhereClause(Enumeration<P> persistents); | |
| 764 | ||
| 765 | /** | |
| 766 | * Return a Conjunctive Normal Form (CNF) where clause. | |
| 767 | * See http://en.wikipedia.org/wiki/Conjunctive_normal_form. | |
| 768 | * | |
| 769 | * @return an SQL fragment | |
| 770 | */ | |
| 771 | String cnfWhereClause(Enumeration<P> persistents, | |
| 772 | boolean includeDeleted, boolean excludeUnselectable); | |
| 773 | ||
| 774 | /** | |
| 775 | * All the objects in the table which refer to a given object. If none of | |
| 776 | * the table's columns are reference columns, the <TT>Enumeration</TT> | |
| 777 | * returned will obviously be empty. | |
| 778 | * <p> | |
| 779 | * It is not guaranteed to be quick to execute! | |
| 780 | * | |
| 781 | * @return an <TT>Enumeration</TT> of <TT>Persistent</TT>s | |
| 782 | */ | |
| 783 | ||
| 784 | Enumeration<P> referencesTo(Persistent object); | |
| 785 | ||
| 786 | /** | |
| 787 | * All the columns in the table which refer to the given table. | |
| 788 | * | |
| 789 | * @param table the table to count the references within | |
| 790 | * @return an Enumeration of Columns referring to the specified Table | |
| 791 | */ | |
| 792 | Enumeration<Column<?>> referencesTo(Table<?> table); | |
| 793 | ||
| 794 | /** | |
| 795 | * @return the current highest troid | |
| 796 | */ | |
| 797 | int getMostRecentTroid(); | |
| 798 | ||
| 799 | /** | |
| 800 | * @param persistent unused parameter, but might be needed in another troid schema | |
| 801 | * @return the next Troid | |
| 802 | */ | |
| 803 | Integer troidFor(Persistent persistent); | |
| 804 | ||
| 805 | /** | |
| 806 | * Write a new row containing the given object. | |
| 807 | * <p> | |
| 808 | * The given object will be assigned the next troid and its internal | |
| 809 | * state will also be modified. | |
| 810 | * | |
| 811 | * @exception org.melati.poem.InitialisationPoemException The object failed validation | |
| 812 | * (currently one of its field values failed). | |
| 813 | */ | |
| 814 | void create(Persistent p) | |
| 815 | throws AccessPoemException, ValidationPoemException, | |
| 816 | InitialisationPoemException; | |
| 817 | ||
| 818 | /** | |
| 819 | * Create a new object (record) in the table. | |
| 820 | * | |
| 821 | * @param initialiser A piece of code for setting the new object's | |
| 822 | * initial values. You'll probably want to define | |
| 823 | * it as an anonymous class. | |
| 824 | * | |
| 825 | * @return A <TT>Persistent</TT> representing the new object, or, if the | |
| 826 | * table was defined in the DSD under the name <TT><I>foo</I></TT>, | |
| 827 | * an application-specialised subclass <TT><I>Foo</I></TT> of | |
| 828 | * <TT>Persistent</TT>. | |
| 829 | * | |
| 830 | * @exception org.melati.poem.AccessPoemException | |
| 831 | * if <TT>initialiser</TT> provokes one during its work (which | |
| 832 | * is unlikely, since POEM's standard checks are disabled | |
| 833 | * while it runs) | |
| 834 | * @exception org.melati.poem.ValidationPoemException | |
| 835 | * if <TT>initialiser</TT> provokes one during its work | |
| 836 | * @exception org.melati.poem.InitialisationPoemException | |
| 837 | * if the object is left by <TT>initialiser</TT> in a state in | |
| 838 | * which not all of its fields have legal values, or in which | |
| 839 | * the calling thread would not be allowed write access to the | |
| 840 | * object under its <TT>AccessToken</TT>---<I>i.e.</I> you | |
| 841 | * can't create objects you wouldn't be allowed to write to. | |
| 842 | * | |
| 843 | * @see org.melati.poem.Initialiser#init(Persistent) | |
| 844 | * @see org.melati.poem.PoemThread#accessToken() | |
| 845 | * @see #getCanCreate() | |
| 846 | */ | |
| 847 | Persistent create(Initialiser initialiser) | |
| 848 | throws AccessPoemException, ValidationPoemException, | |
| 849 | InitialisationPoemException; | |
| 850 | ||
| 851 | /** | |
| 852 | * @return A freshly minted floating <TT>Persistent</TT> object for this table, | |
| 853 | * ie one without a troid set | |
| 854 | */ | |
| 855 | Persistent newPersistent(); | |
| 856 | ||
| 857 | /** | |
| 858 | * It is the programmer's responsibility to ensure that the where clause | |
| 859 | * is suitable for the target DBMS. | |
| 860 | * | |
| 861 | * @param whereClause the criteria | |
| 862 | */ | |
| 863 | void delete_unsafe(String whereClause); | |
| 864 | ||
| 865 | /** | |
| 866 | * The number of `extra' (non-DSD-defined) columns in the table. | |
| 867 | */ | |
| 868 | int extrasCount(); | |
| 869 | ||
| 870 | /** | |
| 871 | * The capability required for reading records from the table, unless | |
| 872 | * overridden in the record itself. This simply comes from the table's | |
| 873 | * record in the <TT>tableinfo</TT> table. | |
| 874 | * | |
| 875 | * @return the capability needed to read this table | |
| 876 | */ | |
| 877 | Capability getDefaultCanRead(); | |
| 878 | ||
| 879 | /** | |
| 880 | * The capability required for updating records in the table, unless | |
| 881 | * overridden in the record itself. This simply comes from the table's | |
| 882 | * record in the <TT>tableinfo</TT> table. | |
| 883 | * | |
| 884 | * @return the default {@link org.melati.poem.Capability} required to write a | |
| 885 | * {@link org.melati.poem.Persistent}, if any | |
| 886 | */ | |
| 887 | Capability getDefaultCanWrite(); | |
| 888 | ||
| 889 | /** | |
| 890 | * The capability required for deleting records in the table, unless | |
| 891 | * overridden in the record itself. This simply comes from the table's | |
| 892 | * record in the <TT>tableinfo</TT> table. | |
| 893 | * @return the default {@link org.melati.poem.Capability} required to delete a | |
| 894 | * {@link org.melati.poem.Persistent}, if any | |
| 895 | */ | |
| 896 | Capability getDefaultCanDelete(); | |
| 897 | ||
| 898 | /** | |
| 899 | * The capability required for creating records in the table. This simply | |
| 900 | * comes from the table's record in the <TT>tableinfo</TT> table. | |
| 901 | * | |
| 902 | * @return the Capability required to write to this table | |
| 903 | * @see #create(Initialiser) | |
| 904 | */ | |
| 905 | Capability getCanCreate(); | |
| 906 | ||
| 907 | /** | |
| 908 | * @return the canReadColumn or the canSelectColumn or null | |
| 909 | */ | |
| 910 | Column<Capability> canReadColumn(); | |
| 911 | ||
| 912 | /** | |
| 913 | * @return the canSelectColumn or null | |
| 914 | */ | |
| 915 | Column<Capability> canSelectColumn(); | |
| 916 | ||
| 917 | /** | |
| 918 | * @return the canWriteColumn or null | |
| 919 | */ | |
| 920 | Column<Capability> canWriteColumn(); | |
| 921 | ||
| 922 | /** | |
| 923 | * @return the canDeleteColumn or null | |
| 924 | */ | |
| 925 | Column<Capability> canDeleteColumn(); | |
| 926 | ||
| 927 | /** | |
| 928 | * Add a {@link org.melati.poem.Column} to the database and the {@link org.melati.poem.TableInfo} table. | |
| 929 | * | |
| 930 | * @param infoP the meta data about the {@link org.melati.poem.Column} | |
| 931 | * @return the newly added column | |
| 932 | */ | |
| 933 | Column<?> addColumnAndCommit(ColumnInfo infoP) throws PoemException; | |
| 934 | ||
| 935 | /** | |
| 936 | * @param columnInfo metadata about the column to delete, which is itself deleted | |
| 937 | */ | |
| 938 | void deleteColumnAndCommit(ColumnInfo columnInfo) throws PoemException; | |
| 939 | ||
| 940 | /** | |
| 941 | * A concise string to stand in for the table. The table's name and a | |
| 942 | * description of where it was defined (the DSD, the metadata tables or the | |
| 943 | * JDBC metadata). | |
| 944 | * {@inheritDoc} | |
| 945 | * @see Object#toString() | |
| 946 | */ | |
| 947 | String toString(); | |
| 948 | ||
| 949 | /** | |
| 950 | * Print some diagnostic information about the contents and consistency of | |
| 951 | * POEM's cache for this table to stderr. | |
| 952 | */ | |
| 953 | void dumpCacheAnalysis(); | |
| 954 | ||
| 955 | /** | |
| 956 | * Print information about the structure of the table to stdout. | |
| 957 | */ | |
| 958 | void dump(); | |
| 959 | ||
| 960 | /** | |
| 961 | * Print information to PrintStream. | |
| 962 | * | |
| 963 | * @param ps PrintStream to dump to | |
| 964 | */ | |
| 965 | void dump(PrintStream ps); | |
| 966 | ||
| 967 | /** | |
| 968 | * A mechanism for caching a selection of records. | |
| 969 | * | |
| 970 | * It is the programmer's responsibility to ensure that the where clause | |
| 971 | * is suitable for the target DBMS. | |
| 972 | * | |
| 973 | * @param whereClause raw SQL selection clause appropriate for this DBMS | |
| 974 | * @param orderByClause which field to order by or null | |
| 975 | * @return the results | |
| 976 | */ | |
| 977 | CachedSelection<P> cachedSelection(String whereClause, | |
| 978 | String orderByClause); | |
| 979 | ||
| 980 | /** | |
| 981 | * A mechanism for caching a record count. | |
| 982 | * | |
| 983 | * It is the programmer's responsibility to ensure that the where clause | |
| 984 | * is suitable for the target DBMS. | |
| 985 | * | |
| 986 | * @param whereClause raw SQL selection clause appropriate for this DBMS | |
| 987 | * @param includeDeleted whether to include soft deleted records | |
| 988 | * @return a cached count | |
| 989 | */ | |
| 990 | CachedCount cachedCount(String whereClause, boolean includeDeleted); | |
| 991 | ||
| 992 | /** | |
| 993 | * A mechanism for caching a record count. | |
| 994 | * | |
| 995 | * It is the programmer's responsibility to ensure that the where clause | |
| 996 | * is suitable for the target DBMS. | |
| 997 | * | |
| 998 | * @param whereClause raw SQL selection clause appropriate for this DBMS | |
| 999 | * @param includeDeleted whether to include soft deleted records | |
| 1000 | * @param excludeUnselectable whether to exclude columns which cannot be selected | |
| 1001 | * @return a cached count | |
| 1002 | */ | |
| 1003 | CachedCount cachedCount(String whereClause, boolean includeDeleted, | |
| 1004 | boolean excludeUnselectable); | |
| 1005 | ||
| 1006 | /** | |
| 1007 | * A mechanism for caching a record count. | |
| 1008 | * | |
| 1009 | * @param criteria a {@link org.melati.poem.Persistent} with selection fields filled | |
| 1010 | * @param includeDeleted whether to include soft deleted records | |
| 1011 | * @param excludeUnselectable whether to exclude columns which cannot be selected | |
| 1012 | * @return a cached count | |
| 1013 | */ | |
| 1014 | CachedCount cachedCount(Persistent criteria, boolean includeDeleted, | |
| 1015 | boolean excludeUnselectable); | |
| 1016 | ||
| 1017 | /** | |
| 1018 | * @param criteria a Persistent to extract where clause from | |
| 1019 | * @return a CachedCount of records matching Criteria | |
| 1020 | */ | |
| 1021 | CachedCount cachedCount(Persistent criteria); | |
| 1022 | ||
| 1023 | /** | |
| 1024 | * A mechanism for caching a record count. | |
| 1025 | * | |
| 1026 | * It is the programmer's responsibility to ensure that the where clause | |
| 1027 | * is suitable for the target DBMS. | |
| 1028 | * | |
| 1029 | * @param whereClause raw SQL selection clause appropriate for this DBMS | |
| 1030 | * @return a cached count | |
| 1031 | */ | |
| 1032 | CachedCount cachedCount(String whereClause); | |
| 1033 | ||
| 1034 | /** | |
| 1035 | * @return a cached count of all records in the table, | |
| 1036 | * obeying includedDeleted and other exclusions | |
| 1037 | */ | |
| 1038 | CachedCount cachedCount(); | |
| 1039 | ||
| 1040 | /** | |
| 1041 | * A mechanism for caching an existance. | |
| 1042 | * | |
| 1043 | * It is the programmer's responsibility to ensure that the where clause | |
| 1044 | * is suitable for the target DBMS. | |
| 1045 | * | |
| 1046 | * NOTE It is possible for the count to be written simultaneously, | |
| 1047 | * but the cache will end up with the same result. | |
| 1048 | * | |
| 1049 | * @param whereClause raw SQL selection clause appropriate for this DBMS | |
| 1050 | * @return a cached exists | |
| 1051 | */ | |
| 1052 | CachedExists cachedExists(String whereClause); | |
| 1053 | ||
| 1054 | /** | |
| 1055 | * A mechanism for caching a record count. | |
| 1056 | * | |
| 1057 | * It is the programmer's responsibility to ensure that the where clause | |
| 1058 | * is suitable for the target DBMS. | |
| 1059 | * | |
| 1060 | * @param whereClause raw SQL selection clause appropriate for this DBMS | |
| 1061 | * @param orderByClause raw SQL order clause appropriate for this DBMS | |
| 1062 | * @param nullable whether the ReferencePoemType is nullable | |
| 1063 | * @return a {@link org.melati.poem.RestrictedReferencePoemType} | |
| 1064 | */ | |
| 1065 | RestrictedReferencePoemType<?> cachedSelectionType(String whereClause, | |
| 1066 | String orderByClause, boolean nullable); | |
| 1067 | ||
| 1068 | /** | |
| 1069 | * Make up a <TT>Field</TT> object whose possible values are a selected | |
| 1070 | * subset of the records in the table. You can make a "dropdown" offering a | |
| 1071 | * choice of your green customers by putting this in your handler | |
| 1072 | * | |
| 1073 | * <BLOCKQUOTE><PRE> | |
| 1074 | * context.put("greens", | |
| 1075 | * melati.getDatabase().getCustomerTable().cachedSelectionField( | |
| 1076 | * "colour = 'green'", null, true, null, "greens")); | |
| 1077 | * </PRE></BLOCKQUOTE> | |
| 1078 | * | |
| 1079 | * and this in your template | |
| 1080 | * | |
| 1081 | * <BLOCKQUOTE><PRE> | |
| 1082 | * Select a customer: $ml.input($greens) | |
| 1083 | * </PRE></BLOCKQUOTE> | |
| 1084 | * | |
| 1085 | * The list of member records is implicitly cached---permanently, and however | |
| 1086 | * big it turns out to be. So don't go mad with this. It is recomputed on | |
| 1087 | * demand if the contents of the table are changed. The <TT>whereClause</TT> | |
| 1088 | * and <TT>orderByClause</TT> you pass in are checked to see if you have | |
| 1089 | * asked for the same list before, so however many times you call this | |
| 1090 | * method, you should only trigger actual <TT>SELECT</TT>s when the table | |
| 1091 | * contents have changed. The list is also transaction-safe, in that it will | |
| 1092 | * always reflect the state of affairs within your transaction even if you | |
| 1093 | * haven't done a commit. | |
| 1094 | * | |
| 1095 | * It is the programmer's responsibility to ensure that the where clause | |
| 1096 | * is suitable for the target DBMS. | |
| 1097 | * | |
| 1098 | * @param whereClause an SQL expression (the bit after the | |
| 1099 | * <TT>SELECT</TT> ... <TT>WHERE</TT>) for picking | |
| 1100 | * out the records you want | |
| 1101 | * | |
| 1102 | * @param orderByClause a comma-separated list of column names which | |
| 1103 | * determine the order in which the records are | |
| 1104 | * presented; if this is <TT>null</TT>, the | |
| 1105 | * <TT>displayorderpriority</TT> attributes of the | |
| 1106 | * table's columns determine the order | |
| 1107 | * | |
| 1108 | * @param nullable whether to allow a blank <TT>NULL</TT> option | |
| 1109 | * as the first possibility | |
| 1110 | * | |
| 1111 | * @param selectedTroid the troid of the record to which the | |
| 1112 | * <TT>SELECT</TT> field should initially be set | |
| 1113 | * | |
| 1114 | * @param nameP the HTML name attribute of the field, | |
| 1115 | * <I>i.e.</I> | |
| 1116 | * <TT><SELECT NAME=<I>name</I>></TT> | |
| 1117 | * @return a Field object | |
| 1118 | */ | |
| 1119 | Field<?> cachedSelectionField( | |
| 1120 | String whereClause, String orderByClause, boolean nullable, | |
| 1121 | Integer selectedTroid, String nameP); | |
| 1122 | ||
| 1123 | /** | |
| 1124 | * Don't call this in your application code. | |
| 1125 | * Columns should be defined either in the DSD (in which | |
| 1126 | * case the boilerplate code generated by the preprocessor will call this | |
| 1127 | * method) or directly in the RDBMS (in which case the initialisation code | |
| 1128 | * will). | |
| 1129 | */ | |
| 1130 | void defineColumn(Column<?> column) | |
| 1131 | throws DuplicateColumnNamePoemException, | |
| 1132 | DuplicateTroidColumnPoemException, | |
| 1133 | DuplicateDeletedColumnPoemException; | |
| 1134 | ||
| 1135 | /** | |
| 1136 | * @return incremented extra columns index | |
| 1137 | */ | |
| 1138 | int getNextExtrasIndex(); | |
| 1139 | ||
| 1140 | /** | |
| 1141 | * @param tableInfo the TableInfo to set | |
| 1142 | */ | |
| 1143 | void setTableInfo(TableInfo tableInfo); | |
| 1144 | ||
| 1145 | /** | |
| 1146 | * @return the {@link org.melati.poem.TableInfo} for this table. | |
| 1147 | */ | |
| 1148 | TableInfo getTableInfo(); | |
| 1149 | ||
| 1150 | /** | |
| 1151 | * @return a DBMS table type eg TEXT | |
| 1152 | */ | |
| 1153 | String getDbmsTableType(); | |
| 1154 | ||
| 1155 | ||
| 1156 | /** | |
| 1157 | * Match columnInfo with this Table's columns. | |
| 1158 | * Conversely, create a ColumnInfo for any columns which don't have one. | |
| 1159 | */ | |
| 1160 | void unifyWithColumnInfo() throws PoemException; | |
| 1161 | ||
| 1162 | /** Unify SQL REMARKS with table.description. | |
| 1163 | * | |
| 1164 | * @param tableDescriptions a JDBC {@link java.sql.ResultSet} with cursor at current row | |
| 1165 | */ | |
| 1166 | void unifyWithMetadata(ResultSet tableDescriptions) throws SQLException; | |
| 1167 | ||
| 1168 | /** | |
| 1169 | * Unify the JDBC description of this tables columns with the | |
| 1170 | * meta data held in the {@link org.melati.poem.TableInfo} | |
| 1171 | * | |
| 1172 | * @param colDescs a JDBC {@link java.sql.ResultSet} describing the columns with cursor at current row | |
| 1173 | * @param primaryKey name of primary key column | |
| 1174 | */ | |
| 1175 | void unifyWithDB(ResultSet colDescs, String primaryKey) | |
| 1176 | throws PoemException; | |
| 1177 | ||
| 1178 | String defaultDisplayName(); | |
| 1179 | ||
| 1180 | String defaultDescription(); | |
| 1181 | ||
| 1182 | int defaultDisplayOrder(); | |
| 1183 | ||
| 1184 | Integer defaultCacheLimit(); | |
| 1185 | ||
| 1186 | boolean defaultRememberAllTroids(); | |
| 1187 | ||
| 1188 | String defaultCategory(); | |
| 1189 | ||
| 1190 | ||
| 1191 | } |