001 package hep.aida.ref.sql; 002 003 // FreeHEP 004 import hep.aida.ref.tuple.AbstractTuple; 005 import hep.aida.ref.tuple.TupleColumn; 006 import hep.aida.ref.tuple.FTupleColumn; 007 import hep.aida.ref.tuple.FTupleCursor; 008 import org.freehep.util.Value; 009 010 // Log4J 011 import org.apache.log4j.Logger; 012 013 // AIDA 014 import hep.aida.ITuple; 015 import hep.aida.IBaseTupleColumn; 016 import hep.aida.ICloud1D; 017 import hep.aida.ICloud2D; 018 import hep.aida.ICloud3D; 019 import hep.aida.IHistogram1D; 020 import hep.aida.IHistogram2D; 021 import hep.aida.IHistogram3D; 022 import hep.aida.IProfile1D; 023 import hep.aida.IProfile2D; 024 import hep.aida.IEvaluator; 025 import hep.aida.IFilter; 026 027 // SQL 028 import java.sql.PreparedStatement; 029 import java.sql.ResultSet; 030 import java.sql.ResultSetMetaData; 031 import java.sql.SQLException; 032 033 // Java 034 import java.util.Collection; 035 import java.util.ArrayList; 036 import java.lang.reflect.Constructor; 037 import java.lang.reflect.InvocationTargetException; 038 039 /** <code>SQLTuple</code> is an extension of {@link ITuple} 040 * for SQL database. 041 * <br> 042 * <code>SQLTuple</code> contains several extensions to {@link ITuple} 043 * and {@link ITuple}: 044 * <ul> 045 * <li><code>void addIndex(String[] columnName);</code></li> 046 * <li><code>void addColumn(String columnName, Class columnType, IEvaluator evaluator);</code></li> 047 * <li><code>void start(IFilter filter);</code></li> 048 * <li><code>void start(String[] columns);</code></li> 049 * <li><code>void start(IFilter filter, String[] columns);</code></li> 050 * <li><code>void start(String stmtSrc);</code></li> 051 * <li><code>void start(IFilter filter, String stmtSrc);</code></li> 052 * <li><code>String[] getRowData();</code></li> 053 * <li><code>boolean getBoolean(String column);</code></li> 054 * <li><code>byte getByte(String column);</code></li> 055 * <li><code>char getChar(String column);</code></li> 056 * <li><code>short getShort(String column);</code></li> 057 * <li><code>int getInt(String column);</code></li> 058 * <li><code>long getLong(String column);</code></li> 059 * <li><code>float getFloat(String column);</code></li> 060 * <li><code>double getDouble(String column);</code></li> 061 * <li><code>String getString(String column);</code></li> 062 * <li><code>Object getObject(String column);</code></li> 063 * <li><code>ITuple getTuple(String column);</code></li> 064 * <li><code>void fill(String column, boolean value);</code></li> 065 * <li><code>void fill(String column, byte value);</code></li> 066 * <li><code>void fill(String column, char value);</code></li> 067 * <li><code>void fill(String column, short value);</code></li> 068 * <li><code>void fill(String column, int value);</code></li> 069 * <li><code>void fill(String column, long value);</code></li> 070 * <li><code>void fill(String column, float value);</code></li> 071 * <li><code>void fill(String column, double value);</code></li> 072 * <li><code>void fill(String column, String value);</code></li> 073 * <li><code>void fill(String column, Object value);</code></li> 074 * <li><code>void fill(String column, ITuple value);</code></li> 075 * <li><code>double groupValue(String operator, int column);</code></li> 076 * <li><code>String columnDefault(int param);</code></li> 077 * <li><code>String[] columnDefaults();</code></li> 078 * <li><code>Collection<String> getColumn(String cName);</code></li> 079 * <li><code><T> Collection<T> getColumn(String cName, Class<T> cl);</code></li> 080 * <li><code>Collection<String> getColumn(String cName, IFilter filter);</code></li> 081 * <li><code><T> Collection<T> getColumn(String cName, Class<T> cl, IFilter filter);</code></li> 082 * </ul> 083 * <p><font color="#880088"> 084 * <pre> 085 * $Log: SQLTuple.java,v $ 086 * Revision 1.82 2007/05/23 16:38:44 hrivnac 087 * logical connections for Plotter; better UML 088 * 089 * Revision 1.81 2006/12/15 00:16:13 hrivnac 090 * FORWARD_ONLY allows to plot big ntuples 091 * 092 * Revision 1.80 2006/12/12 15:21:42 hrivnac 093 * McKoi replaced with Derby; uppercase-only dbs handled better; moving to JAS 0.8.3 094 * 095 * Revision 1.79 2006/11/22 23:55:36 hrivnac 096 * fixed non-double values, added intr database 097 * 098 * Revision 1.78 2006/11/20 16:56:08 hrivnac 099 * fixing input params for Plotter command line 100 * 101 * Revision 1.77 2006/11/17 17:11:34 hrivnac 102 * chooser.jsp closes tree too 103 * 104 * Revision 1.76 2006/11/15 16:16:01 hrivnac 105 * Oracle work fine in CERN, cache enabled 106 * 107 * Revision 1.75 2006/11/14 16:06:18 hrivnac 108 * improving Web Service 109 * 110 * Revision 1.74 2006/10/12 15:02:58 hrivnac 111 * bug fixes 112 * 113 * Revision 1.73 2005/09/28 18:22:42 hrivnac 114 * javadoc fixed 115 * 116 * Revision 1.72 2005/09/28 16:21:06 hrivnac 117 * code cleaning 118 * 119 * Revision 1.71 2005/09/21 23:00:38 hrivnac 120 * readonly tuples can be read 121 * 122 * Revision 1.70 2005/09/21 14:49:49 hrivnac 123 * better support for Oracle types 124 * 125 * Revision 1.69 2005/09/19 14:30:12 hrivnac 126 * projection bugs fixed 127 * 128 * Revision 1.68 2005/09/02 14:10:31 hrivnac 129 * moved to JAS3 0.8.2 130 * 131 * Revision 1.67 2005/06/15 15:26:04 hrivnac 132 * ITuple._rows only evaluated when requested 133 * 134 * Revision 1.66 2005/03/18 12:12:11 hrivnac 135 * ITuple.start() resets ITuple to its original shape even after customised ITuple.start(...) calls 136 * 137 * Revision 1.65 2005/03/09 15:25:52 hrivnac 138 * ITuple.rows() improved 139 * 140 * Revision 1.64 2005/03/08 17:05:51 hrivnac 141 * ... 142 * 143 * Revision 1.63 2005/02/10 20:07:51 hrivnac 144 * bug fixes to support new ColMan 145 * 146 * Revision 1.62 2005/01/27 17:30:41 hrivnac 147 * PreparedStatement with default values 148 * 149 * Revision 1.61 2005/01/25 16:45:03 hrivnac 150 * Adding rows uses PreparedStatement 151 * 152 * Revision 1.60 2004/12/01 16:07:15 hrivnac 153 * better support for ColMan JAS3 plugin 154 * 155 * Revision 1.59 2004/11/30 14:06:04 hrivnac 156 * SQLTuple.rows() fix 157 * 158 * Revision 1.58 2004/10/29 22:27:25 hrivnac 159 * imports corrected 160 * 161 * Revision 1.57 2004/10/21 15:46:49 hrivnac 162 * doc improved 163 * 164 * Revision 1.56 2004/10/20 23:02:29 hrivnac 165 * Types mapping simplified 166 * 167 * Revision 1.55 2004/10/13 12:25:39 hrivnac 168 * defaults work fine 169 * 170 * Revision 1.54 2004/10/13 09:21:21 hrivnac 171 * defaults used 172 * 173 * Revision 1.53 2004/10/12 13:25:40 hrivnac 174 * small improvements 175 * 176 * Revision 1.52 2004/10/08 15:22:33 hrivnac 177 * JAS3 plugin works 178 * 179 * Revision 1.51 2004/07/06 14:24:50 hrivnac 180 * support for Oracle 181 * 182 * Revision 1.50 2004/06/30 13:01:05 hrivnac 183 * oracle sceleton 184 * 185 * Revision 1.49 2004/06/23 08:04:53 hrivnac 186 * documentation fixes 187 * 188 * Revision 1.48 2004/06/18 09:17:31 hrivnac 189 * StmtSrc can be accessed directkly 190 * 191 * Revision 1.47 2004/06/16 21:56:43 hrivnac 192 * StringBuffer in SQLTuple.addRow() -> speed 193 * 194 * Revision 1.46 2004/05/22 15:12:59 hrivnac 195 * class id reformated 196 * 197 * Revision 1.45 2004/05/04 08:50:33 hrivnac 198 * can run with JAS3 199 * 200 * Revision 1.44 2004/05/03 19:22:30 hrivnac 201 * basic support for JAS3 202 * 203 * Revision 1.43 2004/04/21 13:41:32 hrivnac 204 * explicit dependency on MySQL removed 205 * 206 * Revision 1.42 2004/04/21 08:24:50 hrivnac 207 * some explicit MySQL dependencies removed 208 * 209 * Revision 1.41 2004/04/20 12:46:49 hrivnac 210 * tuples use always primitive types 211 * 212 * Revision 1.40 2004/04/15 08:49:01 hrivnac 213 * ColMan fixes 214 * 215 * Revision 1.39 2004/04/14 13:54:41 hrivnac 216 * potential bugs fixed 217 * 218 * Revision 1.38 2004/04/14 13:39:47 hrivnac 219 * 1.5 warnings fixed 220 * 221 * Revision 1.37 2004/04/13 15:45:54 hrivnac 222 * AIDA URL introduced 223 * 224 * Revision 1.36 2004/02/10 14:50:58 hrivnac 225 * JavaDoc tags completed 226 * 227 * Revision 1.35 2004/02/04 13:30:39 hrivnac 228 * - improvement of Enums internal mapping 229 * - general cleaning 230 * 231 * Revision 1.34 2003/11/24 15:13:22 hrivnac 232 * Logging improved. 233 * 234 * Revision 1.33 2003/11/20 17:21:58 hrivnac 235 * Java 1.5 natively supported, Log4J reporting improved. 236 * 237 * Revision 1.32 2003/11/17 15:01:12 hrivnac 238 * More BM results. 239 * 240 * Revision 1.31 2003/11/17 10:18:29 hrivnac 241 * Cleaning. 242 * 243 * Revision 1.30 2003/11/13 18:19:38 hrivnac 244 * BenchMarks running for all DBs, Reporting class added. 245 * 246 * Revision 1.29 2003/11/13 15:43:08 hrivnac 247 * BenchMarking introduced. 248 * 249 * Revision 1.28 2003/11/13 11:07:31 hrivnac 250 * EventSelector prototype added. 251 * 252 * Revision 1.27 2003/11/05 19:46:22 hrivnac 253 * - FreeHEP 1.2.1 254 * - JAIDA 3.2.1 255 * 256 * Revision 1.18 2003/10/30 11:42:40 hrivnac 257 * ArrayList -> Collection 258 * 259 * Revision 1.15 2003/10/22 17:59:39 hrivnac 260 * Refactored. 261 * 262 * Revision 1.13 2003/10/21 13:56:00 hrivnac 263 * Default values supported. 264 * 265 * Revision 1.12 2003/10/21 13:24:52 hrivnac 266 * Constructor from columnString implemented. 267 * 268 * Revision 1.11 2003/10/10 10:12:21 hrivnac 269 * All three testing pgms work. 270 * 271 * Revision 1.8 2003/10/07 10:15:57 hrivnac 272 * SQL extensions to ITuple added. 273 * 274 * Revision 1.5 2003/10/03 16:02:21 hrivnac 275 * Better handling of multiple technologies. 276 * 277 * Revision 1.3 2003/10/02 14:24:01 hrivnac 278 * Cleaning. 279 * 280 * Revision 1.7 2003/09/30 20:30:47 hrivnac 281 * special Pool functions 282 * 283 * Revision 1.6 2003/09/30 16:46:02 hrivnac 284 * - Writing test in TestWrite 285 * - SQLTuple projections supported 286 * 287 * Revision 1.5 2003/09/30 14:11:48 hrivnac 288 * Can created SQLTuples. 289 * 290 * Revision 1.4 2003/09/30 12:29:19 hrivnac 291 * Tuples can be written. 292 * 293 * Revision 1.3 2003/09/29 16:15:54 hrivnac 294 * More complete. 295 * 296 * Revision 1.2 2003/09/29 14:36:40 hrivnac 297 * Works per attribute. 298 * 299 * </pre> 300 * </font></p> 301 * @opt attributes 302 * @opt operations 303 * @opt types 304 * @opt visibility 305 * @version $Id: SQLTuple.java,v 1.82 2007/05/23 16:38:44 hrivnac Exp $ 306 * @author <a href="mailto:Julius.Hrivnac@cern.ch">J.Hrivnac</a> */ 307 public class SQLTuple extends AbstractTuple { 308 309 /** Just call superclass constructor. 310 * @param name The name of the ITuple. 311 * @param title The title of the ITuple. 312 * @param columnName The names of columns. 313 * @param columnType The types of columns. 314 * @param options The options to be used to create the ITuple. */ 315 public SQLTuple(String name, 316 String title, 317 String[] columnName, 318 Class[] columnType, 319 String options) { 320 super(name, title, options); 321 initSQLTuple(name, title, columnName, columnType, options); 322 } 323 324 /** Just calls superclass constructor. 325 * @param name The name of the ITuple. 326 * @param title The title of the ITuple. 327 * @param columnsString The columns definition. 328 * @param options The options to be used to create the ITuple. */ 329 public SQLTuple(String name, 330 String title, 331 String columnsString, 332 String options) { 333 super(name, title, options); 334 initSQLTuple(name, title, super.columnNames(), super.columnTypes(), options); 335 } 336 337 /** Initialise internal variables. Is called from the constructor. 338 * @param name The name of the ITuple. 339 * @param title The title of the ITuple. 340 * @param columnName The names of columns. 341 * @param columnType The types of columns. 342 * @param options The options to be used to create the ITuple. 343 * @throws IllegalArgumentException if the ITuple can't be created. */ 344 protected void initSQLTuple(String name, 345 String title, 346 String[] columnName, 347 Class[] columnType, 348 String options) throws IllegalArgumentException { 349 try { 350 setOptions(options); 351 _names = columnName; 352 _types = columnType; 353 _defaults = new String[ _names.length]; 354 _defaultObjects = new Object[ _names.length]; 355 _filled = new boolean[_names.length]; 356 int eq; 357 for (int i = 0; i < _names.length; i++) { 358 _defaults[i] = null; 359 eq = columnName[i].indexOf("="); 360 if (eq > -1) { 361 _defaults[i] = _names[i].substring(eq + 1 ).trim(); 362 _names[i] = _names[i].substring(0 , eq).trim(); 363 _defaultObjects[i] = type2Object(_defaults[i], _types[i]); 364 } 365 } 366 _namesOrig = _names; 367 _typesOrig = _types; 368 _defaultsOrig = _defaults; 369 _defaultObjectsOrig = _defaultObjects; 370 _stmtSrc = new StmtSrc(_accessor, title); 371 prepare(); 372 _rows = -1; 373 } 374 catch (SQLTupleException e) { 375 throw new IllegalArgumentException("Can't initialise SQLTuple " + name + " / " + title, e); 376 } 377 378 } 379 380 /** <code>SQLTuple</code> extension: add indexes into SQL table. 381 * @param columnName The array of column names to be indexed. */ 382 public void addIndex(String[] columnName) { 383 for (String name : columnName) { 384 String[] args = {"index_" + title() + "_" + name, name}; 385 update("addIndex", args); 386 } 387 } 388 389 /** <code>SQLTuple</code> extension: add column into SQL table. 390 * @param columnName The name of column to be added. 391 * @param columnType The type of column to be added. 392 * @param evaluator The evaluator to be used to compute new column values. */ 393 public void addColumn(String columnName, 394 Class columnType, 395 IEvaluator evaluator) { 396 // Check whether it is a new column 397 for (int i = 0; i < columns(); i++) { 398 if (columnName.equals(_names[i])) { 399 log.warn("Column " + columnName + " already exists"); 400 return; 401 } 402 } 403 // Add column into table 404 String[] args1 = {columnName, _accessor.sqlName(columnType)}; 405 update("addColumnAlter", args1); 406 // Fill table with values 407 String[] args2 = {columnName, evaluator.expression()}; 408 update("addColumnUpdate", args2); 409 // Update internal variables 410 String[] names0 = new String[columns() + 1]; 411 String[] defaults0 = new String[columns() + 1]; 412 Object[] defaultObjects0 = new Object[columns() + 1]; 413 Class[] types0 = new Class[ columns() + 1]; 414 _filled = new boolean[columns() + 1]; 415 for (int i = 0; i < columns(); i++) { 416 names0[ i] = _names[ i]; 417 defaults0[i] = _defaults[ i]; 418 defaultObjects0[i] = _defaultObjects[i]; 419 types0[ i] = _types[ i]; 420 } 421 names0[ columns()] = columnName; 422 defaults0[columns()] = null; 423 defaultObjects0[columns()] = type2Object(null, columnType); 424 types0[ columns()] = columnType; 425 _names = names0; 426 _defaults = defaults0; 427 _defaultObjects = defaultObjects0; 428 _types = types0; 429 for (int i = 0; i < columns(); i++) { 430 _filled[i] = false;; 431 } 432 } 433 434 /** <code>SQLTuple</code> is never in memory => false. 435 * @return <code>false</code>. */ 436 public boolean isInMemory() { 437 return false; 438 } 439 440 /** Use SQL <code>min<code> function. 441 * @param column The column to get the minimum of. 442 * @return The found minimum. */ 443 public double columnMin(int column) { 444 return groupValue("min", column); 445 } 446 447 /** Use SQL <code>max<code> function. 448 * @param column The column to get the maximum of. 449 * @return The found maximum. */ 450 public double columnMax(int column) { 451 return groupValue("max", column); 452 } 453 454 /** Use SQL <code>avg<code> function. 455 * @param column The column to get the average of. 456 * @return The found average. */ 457 public double columnMean(int column) { 458 return groupValue("avg", column); 459 } 460 461 /** Use SQL <code>std<code> function. 462 * @param column The column to get the std of. 463 * @return The found std. */ 464 public double columnRms(int column) { 465 return groupValue("std", column); 466 } 467 468 /** Apply an operator to a column. 469 * @param operator The operator to be applied.. 470 * @param column The column to be evalated. 471 * @return The found result of the operator applied on the column. 472 * @throws IllegalArgumentException if the operator can't be applied on the column. */ 473 private double groupValue(String operator, int column) { 474 String[] args = {operator, columnName(column)}; 475 ResultSet rs = query("groupValue", args); 476 try { 477 rs.next(); 478 } 479 catch (SQLException e) { 480 log.error(Util.report("Can't perform operation " + operator + " on column " + column, e), e); 481 throw new IllegalArgumentException("Couldn't perform operation " + operator + " on column " + column, e); 482 } 483 return getDouble(rs, 1); 484 } 485 486 /** Apply an operator to a column. 487 * @param operator The operator to be applied.. 488 * @param column The column formula to be evalated. 489 * @return The found result of the operator applied on the column. 490 * @throws IllegalArgumentException if the operator can't be applied on the column. */ 491 public double groupValue(String operator, String column) { 492 String[] args = {operator, column}; 493 ResultSet rs = query("groupValue", args); 494 try { 495 rs.next(); 496 } 497 catch (SQLException e) { 498 log.error(Util.report("Can't perform operation " + operator + " on formula " + column, e), e); 499 throw new IllegalArgumentException("Couldn't perform operation " + operator + " on formula " + column, e); 500 } 501 return getDouble(rs, 1); 502 } 503 504 /** Find column number from the column name. 505 * @param name The name of the column. 506 * @return The number of the specified column. 507 * @throws IllegalArgumentException if no column of that name exists. */ 508 public int findColumn(String name) throws IllegalArgumentException { 509 if (_accessor.supportsOnlyUpperCase()) { 510 name = name.toUpperCase(); 511 } 512 for (int i = 0; i < _names.length; i++) { 513 if (_names[i].equals(name)) { 514 return i; 515 } 516 } 517 throw new IllegalArgumentException("There is no column " + name); 518 } 519 520 /** Get boolean value of a column. 521 * @param column The column name. 522 * @return The value of the current row. */ 523 public boolean getBoolean(String column) { 524 return getBoolean(findColumn(column)); 525 } 526 527 /** Get boolean value of a column. 528 * @param column The column number. 529 * @return The value of the current row. */ 530 public boolean getBoolean(int column) { 531 try { 532 return _rs.getBoolean(column+1); 533 } 534 catch (SQLException e) { 535 log.error(Util.report("Can't get boolean of column " + column + ", return default", e), e); 536 } 537 return Boolean.parseBoolean(_defaults[column]); 538 } 539 540 /** Get byte value of a column. 541 * @param column The column name. 542 * @return The value of the current row. */ 543 public byte getByte(String column) { 544 return getByte(findColumn(column)); 545 } 546 547 /** Get byte value of a column. 548 * @param column The column number. 549 * @return The value of the current row. */ 550 public byte getByte(int column) { 551 try { 552 return _rs.getByte(column+1); 553 } 554 catch (SQLException e) { 555 log.error(Util.report("Can't get byte of column " + column + ", return default", e), e); 556 } 557 return Byte.parseByte(_defaults[column]); 558 } 559 560 /** Get char value of a column. 561 * @param column The column name. 562 * @return The value of the current row. */ 563 public char getChar(String column) { 564 return getChar(findColumn(column)); 565 } 566 567 /** Get char value of a column. 568 * @param column The column number. 569 * @return The value of the current row. */ 570 public char getChar(int column) { 571 try { 572 return _rs.getString(column+1).charAt(0); 573 } 574 catch (SQLException e) { 575 log.error(Util.report("Can't get char of column " + column + ", return default", e), e); 576 } 577 return _defaults[column].toCharArray()[0]; 578 } 579 580 /** Get double value of a column. 581 * @param column The column name. 582 * @return The value of the current row. */ 583 public double getDouble(String column) { 584 return getDouble(findColumn(column)); 585 } 586 587 /** Get double value of a column. 588 * @param column The column number. 589 * @return The value of the current row. */ 590 public double getDouble(int column) { 591 try { 592 return _rs.getDouble(column+1); 593 } 594 catch (SQLException e) { 595 log.error(Util.report("Can't get double of column " + column + ", return default", e), e); 596 } 597 return Double.parseDouble(_defaults[column]); 598 } 599 600 /** Get float value of a column. 601 * @param column The column name. 602 * @return The value of the current row. */ 603 public float getFloat(String column) { 604 return getFloat(findColumn(column)); 605 } 606 607 /** Get float value of a column. 608 * @param column The column number. 609 * @return The value of the current row. */ 610 public float getFloat(int column) { 611 try { 612 return _rs.getFloat(column+1); 613 } 614 catch (SQLException e) { 615 log.error(Util.report("Can't get double of column " + column + ", return default", e), e); 616 } 617 return Float.parseFloat(_defaults[column]); 618 } 619 620 /** Get int value of a column. 621 * @param column The column name. 622 * @return The value of the current row. */ 623 public int getInt(String column) { 624 return getInt(findColumn(column)); 625 } 626 627 /** Get int value of a column. 628 * @param column The column number. 629 * @return The value of the current row. */ 630 public int getInt(int column) { 631 try { 632 return _rs.getInt(column+1); 633 } 634 catch (SQLException e) { 635 log.error(Util.report("Can't get int of column " + column + ", return default", e), e); 636 } 637 return Integer.parseInt(_defaults[column]); 638 } 639 640 /** Get long value of a column. 641 * @param column The column name. 642 * @return The value of the current row. */ 643 public long getLong(String column) { 644 return getLong(findColumn(column)); 645 } 646 647 /** Get long value of a column. 648 * @param column The column number. 649 * @return The value of the current row. */ 650 public long getLong(int column) { 651 try { 652 return _rs.getLong(column+1); 653 } 654 catch (SQLException e) { 655 log.error(Util.report("Can't get long of column " + column + ", return default", e), e); 656 } 657 return Long.parseLong(_defaults[column]); 658 } 659 660 /** Get Object value of a column. 661 * @param column The column name. 662 * @return The value of the current row. */ 663 public Object getObject(String column) { 664 return getObject(findColumn(column)); 665 } 666 667 /** Get Object value of a column. 668 * @param column The column number. 669 * @return The value of the current row. */ 670 public Object getObject(int column) { 671 try { 672 return _rs.getObject(column+1); 673 } 674 catch (SQLException e) { 675 log.error(Util.report("Can't get Object of column " + column + ", return default String", e), e); 676 } 677 return _defaults[column]; 678 } 679 680 /** Get short value of a column. 681 * @param column The column name. 682 * @return The value of the current row. */ 683 public short getShort(String column) { 684 return getShort(findColumn(column)); 685 } 686 687 /** Get short value of a column. 688 * @param column The column number. 689 * @return The value of the current row. */ 690 public short getShort(int column) { 691 try { 692 return _rs.getShort(column+1); 693 } 694 catch (SQLException e) { 695 log.error(Util.report("Can't get short of column " + column + ", return default", e), e); 696 } 697 return Short.parseShort(_defaults[column]); 698 } 699 700 /** Get String value of a column. 701 * @param column The column name. 702 * @return The value of the current row. */ 703 public String getString(String column) { 704 return getString(findColumn(column)); 705 } 706 707 /** Get String value of a column. 708 * @param column The column number. 709 * @return The value of the current row. */ 710 public String getString(int column) { 711 try { 712 return _rs.getString(column+1); 713 } 714 catch (SQLException e) { 715 log.error(Util.report("Can't get String of column " + column + ", return default", e), e); 716 } 717 return _defaults[column]; 718 } 719 720 /** Get ITuple value of a column. 721 * @param column The column name. 722 * @return The value of the current row. */ 723 public ITuple getTuple(String column) { 724 return getTuple(findColumn(column)); 725 } 726 727 /** Fill {@link Value} in a column. 728 * @param column The column name. 729 * @param value The {@link Value} to be filled in the current row. 730 * @throws IllegalArgumentException if {@link Value} can't be filled. */ 731 public void fill(int column, Value value) throws IllegalArgumentException { 732 if (_readOnly) { 733 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 734 } 735 try { 736 _statement.setString(column+1, value.getString()); 737 } 738 catch (SQLException e) { 739 log.error(Util.report("Can't set column " + column + " to value " + value, e), e); 740 throw new IllegalArgumentException("Couldn't column " + column + " to value " + value, e); 741 } 742 _filled[column] = true; 743 } 744 745 /** Fill int value in a column. 746 * @param column The column name. 747 * @param value The value to be filled in the current row. 748 * @throws IllegalArgumentException if value can't be filled. */ 749 public void fill(String column, int value) throws IllegalArgumentException { 750 fill(findColumn(column), value); 751 } 752 753 /** Fill int value in a column. 754 * @param column The column number. 755 * @param value The value to be filled in the current row. 756 * @throws IllegalArgumentException if value can't be filled. */ 757 public void fill(int column, int value) throws IllegalArgumentException { 758 if (_readOnly) { 759 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 760 } 761 try { 762 _statement.setInt(column+1, value); 763 } 764 catch (SQLException e) { 765 log.error(Util.report("Can't set column " + column + " to int value " + value, e), e); 766 throw new IllegalArgumentException("Couldn't column " + column + " to int value " + value, e); 767 } 768 _filled[column] = true; 769 } 770 771 /** Fill short value in a column. 772 * @param column The column name. 773 * @param value The value to be filled in the current row. 774 * @throws IllegalArgumentException if value can't be filled. */ 775 public void fill(String column, short value) throws IllegalArgumentException { 776 fill(findColumn(column), value); 777 } 778 779 /** Fill short value in a column. 780 * @param column The column number. 781 * @param value The value to be filled in the current row. 782 * @throws IllegalArgumentException if value can't be filled. */ 783 public void fill(int column, short value) throws IllegalArgumentException { 784 if (_readOnly) { 785 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 786 } 787 try { 788 _statement.setShort(column+1, value); 789 } 790 catch (SQLException e) { 791 log.error(Util.report("Can't set column " + column + " to short value " + value, e), e); 792 throw new IllegalArgumentException("Couldn't column " + column + " to short value " + value, e); 793 } 794 _filled[column] = true; 795 } 796 797 /** Fill long value in a column. 798 * @param column The column name. 799 * @param value The value to be filled in the current row. 800 * @throws IllegalArgumentException if value can't be filled. */ 801 public void fill(String column, long value) throws IllegalArgumentException { 802 fill(findColumn(column), value); 803 } 804 805 /** Fill long value in a column. 806 * @param column The column number. 807 * @param value The value to be filled in the current row. 808 * @throws IllegalArgumentException if value can't be filled. */ 809 public void fill(int column, long value) throws IllegalArgumentException { 810 if (_readOnly) { 811 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 812 } 813 try { 814 _statement.setLong(column+1, value); 815 } 816 catch (SQLException e) { 817 log.error(Util.report("Can't set column " + column + " to long value " + value, e), e); 818 throw new IllegalArgumentException("Couldn't column " + column + " to long value " + value, e); 819 } 820 _filled[column] = true; 821 } 822 823 /** Fill double value in a column. 824 * @param column The column name. 825 * @param value The value to be filled in the current row. 826 * @throws IllegalArgumentException if value can't be filled. */ 827 public void fill(String column, double value) throws IllegalArgumentException { 828 fill(findColumn(column), value); 829 } 830 831 /** Fill double value in a column. 832 * @param column The column number. 833 * @param value The value to be filled in the current row. 834 * @throws IllegalArgumentException if value can't be filled. */ 835 public void fill(int column, double value) throws IllegalArgumentException { 836 if (_readOnly) { 837 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 838 } 839 try { 840 _statement.setDouble(column+1, value); 841 } 842 catch (SQLException e) { 843 log.error(Util.report("Can't set column " + column + " to double value " + value, e), e); 844 throw new IllegalArgumentException("Couldn't column " + column + " to double value " + value, e); 845 } 846 _filled[column] = true; 847 } 848 849 /** Fill float value in a column. 850 * @param column The column name. 851 * @param value The value to be filled in the current row. 852 * @throws IllegalArgumentException if value can't be filled. */ 853 public void fill(String column, float value) throws IllegalArgumentException { 854 fill(findColumn(column), value); 855 } 856 857 /** Fill float value in a column. 858 * @param column The column number. 859 * @param value The value to be filled in the current row. 860 * @throws IllegalArgumentException if value can't be filled. */ 861 public void fill(int column, float value) throws IllegalArgumentException { 862 if (_readOnly) { 863 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 864 } 865 try { 866 _statement.setFloat(column+1, value); 867 } 868 catch (SQLException e) { 869 log.error(Util.report("Can't set column " + column + " to float value " + value, e), e); 870 throw new IllegalArgumentException("Couldn't column " + column + " to float value " + value, e); 871 } 872 _filled[column] = true; 873 } 874 875 /** Fill boolean value in a column. 876 * @param column The column name. 877 * @param value The value to be filled in the current row. 878 * @throws IllegalArgumentException if value can't be filled. */ 879 public void fill(String column, boolean value) throws IllegalArgumentException { 880 fill(findColumn(column), value); 881 } 882 883 /** Fill boolean value in a column. 884 * @param column The column number 885 * @param value The value to be filled in the current row. 886 * @throws IllegalArgumentException if value can't be filled. */ 887 public void fill(int column, boolean value) throws IllegalArgumentException { 888 if (_readOnly) { 889 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 890 } 891 try { 892 _statement.setBoolean(column+1, value); 893 } 894 catch (SQLException e) { 895 log.error(Util.report("Can't set column " + column + " to boolean value " + value, e), e); 896 throw new IllegalArgumentException("Couldn't column " + column + " to boolean value " + value, e); 897 } 898 _filled[column] = true; 899 } 900 901 /** Fill byte value in a column. 902 * @param column The column name 903 * @param value The value to be filled in the current row. 904 * @throws IllegalArgumentException if value can't be filled. */ 905 public void fill(String column, byte value) throws IllegalArgumentException { 906 fill(findColumn(column), value); 907 } 908 909 /** Fill byte value in a column. 910 * @param column The column number. 911 * @param value The value to be filled in the current row. 912 * @throws IllegalArgumentException if value can't be filled. */ 913 public void fill(int column, byte value) throws IllegalArgumentException { 914 if (_readOnly) { 915 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 916 } 917 try { 918 _statement.setByte(column+1, value); 919 } 920 catch (SQLException e) { 921 log.error(Util.report("Can't set column " + column + " to byte value " + value, e), e); 922 throw new IllegalArgumentException("Couldn't column " + column + " to byte value " + value, e); 923 } 924 _filled[column] = true; 925 } 926 927 /** Fill char value in a column. 928 * @param column The column name. 929 * @param value The value to be filled in the current row. 930 * @throws IllegalArgumentException if value can't be filled. */ 931 public void fill(String column, char value) throws IllegalArgumentException { 932 fill(findColumn(column), value); 933 } 934 935 /** Fill char value in a column. 936 * @param column The column number. 937 * @param value The value to be filled in the current row. 938 * @throws IllegalArgumentException if value can't be filled. */ 939 public void fill(int column, char value) throws IllegalArgumentException { 940 if (_readOnly) { 941 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 942 } 943 try { 944 _statement.setString(column+1, Character.toString(value)); 945 } 946 catch (SQLException e) { 947 log.error(Util.report("Can't set column " + column + " to char value " + value, e), e); 948 throw new IllegalArgumentException("Couldn't column " + column + " to char value " + value, e); 949 } 950 _filled[column] = true; 951 } 952 953 /** Fill String value in a column. 954 * @param column The column name. 955 * @param value The value to be filled in the current row. 956 * @throws IllegalArgumentException if value can't be filled. */ 957 public void fill(String column, String value) throws IllegalArgumentException { 958 fill(findColumn(column), value); 959 } 960 961 /** Fill String value in a column. 962 * @param column The column number. 963 * @param value The value to be filled in the current row. 964 * @throws IllegalArgumentException if value can't be filled. */ 965 public void fill(int column, String value) throws IllegalArgumentException { 966 if (_readOnly) { 967 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 968 } 969 try { 970 _statement.setString(column+1, value); 971 } 972 catch (SQLException e) { 973 log.error(Util.report("Can't set column " + column + " to String value " + value, e), e); 974 throw new IllegalArgumentException("Couldn't column " + column + " to String value " + value, e); 975 } 976 _filled[column] = true; 977 } 978 979 /** Fill Object value in a column. 980 * @param column The column name. 981 * @param value The value to be filled in the current row. 982 * @throws IllegalArgumentException if value can't be filled. */ 983 public void fill(String column, Object value) throws IllegalArgumentException { 984 fill(findColumn(column), value); 985 } 986 987 /** Fill Object value in a column. 988 * @param column The column number. 989 * @param value The value to be filled in the current row. 990 * @throws IllegalArgumentException if value can't be filled. */ 991 public void fill(int column, Object value) throws IllegalArgumentException { 992 if (_readOnly) { 993 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 994 } 995 try { 996 _statement.setObject(column+1, value); 997 } 998 catch (SQLException e) { 999 log.error(Util.report("Can't set column " + column + " to Object value " + value, e), e); 1000 throw new IllegalArgumentException("Couldn't column " + column + " to Object value " + value, e); 1001 } 1002 _filled[column] = true; 1003 } 1004 1005 /** Fill float values into current row. 1006 * @param values The values to be filled in the current row. 1007 * @throws IllegalArgumentException if value can't be filled. */ 1008 public void fill(float[] values) throws IllegalArgumentException { 1009 if (_readOnly) { 1010 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 1011 } 1012 for (int i = 0; i < columns(); i++) { 1013 try { 1014 _statement.setFloat(i+1, values[i]); 1015 } 1016 catch (SQLException e) { 1017 log.error(Util.report("Can't set column " + i + " to float value " + values[i], e), e); 1018 throw new IllegalArgumentException("Couldn't column " + i + " to float value " + values[i], e); 1019 } 1020 _filled[i] = true; 1021 } 1022 } 1023 1024 /** Fill double values into current row. 1025 * @param values The values to be filled in the current row. 1026 * @throws IllegalArgumentException if value can't be filled. */ 1027 public void fill(double[] values) throws IllegalArgumentException { 1028 if (_readOnly) { 1029 throw new IllegalArgumentException("SQLTuple is readonly, can't be filled"); 1030 } 1031 for (int i = 0; i < columns(); i++) { 1032 try { 1033 _statement.setDouble(i+1, values[i]); 1034 } 1035 catch (SQLException e) { 1036 log.error(Util.report("Can't set column " + i + " to double value " + values[i], e), e); 1037 throw new IllegalArgumentException("Couldn't column " + i + " to double value " + values[i], e); 1038 } 1039 _filled[i] = true; 1040 } 1041 } 1042 1043 /** Get the number of the current row. 1044 * @return The current row number. */ 1045 public int row() { 1046 return getRow(); 1047 } 1048 1049 /** Get the number of the current row. 1050 * @return The current row number. */ 1051 public int getRow() { 1052 try { 1053 return _rs.getRow(); 1054 } 1055 catch (SQLException e) { 1056 log.error(Util.report("Can't get row, returned 0", e), e); 1057 } 1058 return 0; 1059 } 1060 1061 /** Go to the row with specified number. 1062 * @param row The number of row to go to. 1063 * @throws IllegalArgumentException if can't go to specified row.*/ 1064 public void setRow(int row) throws IllegalArgumentException { 1065 try { 1066 _rs.absolute(row); 1067 } 1068 catch (SQLException e) { 1069 log.error(Util.report("Can't set row to " + row, e), e); 1070 throw new IllegalArgumentException("Couldn't set row to " + row, e); 1071 } 1072 } 1073 1074 /** Start looping, positions in the first row. */ 1075 public void start() { 1076 if (_names != _namesOrig) { 1077 _names = _namesOrig; 1078 _types = _typesOrig; 1079 _defaults = _defaultsOrig; 1080 _defaultObjects = _defaultObjectsOrig; 1081 } 1082 String[] args = {title()}; 1083 _rs = query("start", args); 1084 } 1085 1086 /** <code>SQLTuple</code> extension: get subNTuple (subset of rows) 1087 * and positions in the first row. Use {@link IFilter}. 1088 * @param filter The IFilter to be used to select rows. 1089 * @throws SQLTupleException if can't get subNTuple.*/ 1090 public void start(IFilter filter) throws SQLTupleException { 1091 String[] args = {filter.expression()}; 1092 _rs = query("startFilter", args); 1093 } 1094 1095 /** <code>SQLTuple</code> extension: get subNTuple (subset of columns) 1096 * and positions in the first row. Use SQL command from {@link StmtSrc}. 1097 * @param stmtSrc The SQL Stmt String to be used to select rows. 1098 * @throws SQLTupleException if can't get subNTuple.*/ 1099 public void start(String stmtSrc) throws SQLTupleException { 1100 String[] args = {}; 1101 _rs = query(stmtSrc, args); 1102 try { 1103 ResultSetMetaData rsmd = _rs.getMetaData(); 1104 int cols = rsmd.getColumnCount(); 1105 _names = new String[cols]; 1106 _types = new Class[cols]; 1107 for (int i = 0; i < cols; i++) { 1108 _names[i] = rsmd.getColumnName(i+1); 1109 for (int j = 0; j < _namesOrig.length; j++) { 1110 if (_names[i].equals(_namesOrig[j])) { 1111 _types[i] = _typesOrig[j]; 1112 break; 1113 } 1114 } 1115 } 1116 } 1117 catch (SQLException e) { 1118 throw new SQLTupleException("Can't start using Statement " + stmtSrc, e); 1119 } 1120 } 1121 1122 /** <code>SQLTuple</code> extension: get subNTuple (subset of rows and columns) 1123 * and positions in the first row. Use {@link IFilter} and 1124 * SQL command from {@link StmtSrc}. 1125 * @param filter The IFilter to be used to select rows. 1126 * @param stmtSrc The SQL Stmt String to be used to select rows. 1127 * @throws SQLTupleException if can't get subNTuple.*/ 1128 public void start(IFilter filter, 1129 String stmtSrc) throws SQLTupleException { 1130 String[] args = {filter.expression()}; 1131 _rs = query(stmtSrc, args); 1132 try { 1133 ResultSetMetaData rsmd = _rs.getMetaData(); 1134 int cols = rsmd.getColumnCount(); 1135 _names = new String[cols]; 1136 _types = new Class[cols]; 1137 for (int i = 0; i < cols; i++) { 1138 _names[i] = rsmd.getColumnName(i+1); 1139 for (int j = 0; j < _namesOrig.length; j++) { 1140 if (_names[i].equals(_namesOrig[j])) { 1141 _types[i] = _typesOrig[j]; 1142 break; 1143 } 1144 } 1145 } 1146 } 1147 catch (SQLException e) { 1148 throw new SQLTupleException("Can't start using Statement " + stmtSrc, e); 1149 } 1150 } 1151 1152 /** <code>SQLTuple</code> extension: get subNTuple (subset of columns) 1153 * and positions in the first row. 1154 * @param columns The names of column to be extracted. 1155 * @throws SQLTupleException if can't get subNTuple.*/ 1156 public void start(String[] columns) throws SQLTupleException { 1157 String[] args = new String[1]; 1158 args[0] = ""; 1159 for (int i = 0; i < columns.length; i++) { 1160 args[0] += columns[i]; 1161 if (i < columns.length - 1) { 1162 args[0] += ","; 1163 } 1164 } 1165 _rs = query("getColumn", args); 1166 try { 1167 ResultSetMetaData rsmd = _rs.getMetaData(); 1168 int cols = rsmd.getColumnCount(); 1169 _names = new String[cols]; 1170 _types = new Class[cols]; 1171 for (int i = 0; i < cols; i++) { 1172 _names[i] = rsmd.getColumnName(i+1); 1173 for (int j = 0; j < _namesOrig.length; j++) { 1174 if (_names[i].equals(_namesOrig[j])) { 1175 _types[i] = _typesOrig[j]; 1176 break; 1177 } 1178 } 1179 } 1180 } 1181 catch (SQLException e) { 1182 throw new SQLTupleException("Can't start using Statement getColumnFilter", e); 1183 } 1184 } 1185 1186 /** <code>SQLTuple</code> extension: get subNTuple (subset of rows and columns) 1187 * and positions in the first row. Uses {@link IFilter} and 1188 * SQL command from {@link StmtSrc}. 1189 * @param filter The IFilter to be used to select rows. 1190 * @param columns The names of column to be extracted. 1191 * @throws SQLTupleException if can't get subNTuple.*/ 1192 public void start(IFilter filter, String[] columns) throws SQLTupleException { 1193 String[] args = new String[2]; 1194 args[0] = ""; 1195 for (int i = 0; i < columns.length; i++) { 1196 args[0] += columns[i]; 1197 if (i < columns.length - 1) { 1198 args[0] += ","; 1199 } 1200 } 1201 args[1] = filter.expression(); 1202 _rs = query("getColumnFilter", args); 1203 try { 1204 ResultSetMetaData rsmd = _rs.getMetaData(); 1205 int cols = rsmd.getColumnCount(); 1206 _names = new String[cols]; 1207 _types = new Class[cols]; 1208 for (int i = 0; i < cols; i++) { 1209 _names[i] = rsmd.getColumnName(i+1); 1210 for (int j = 0; j < _namesOrig.length; j++) { 1211 if (_names[i].equals(_namesOrig[j])) { 1212 _types[i] = _typesOrig[j]; 1213 break; 1214 } 1215 } 1216 } 1217 } 1218 catch (SQLException e) { 1219 throw new SQLTupleException("Can't start using Statement getColumnFilter", e); 1220 } 1221 } 1222 1223 /** Skip rows. 1224 * @param rows The number of rows to skip. */ 1225 public void skip(int rows) { 1226 try { 1227 _rs.relative(rows); 1228 } 1229 catch (SQLException e) { 1230 log.error(Util.report("Can't skip " + rows + " rows", e), e); 1231 throw new IllegalArgumentException("Couldn't skip " + rows + " rows", e); 1232 } 1233 } 1234 1235 /** Go into the next row. 1236 * @return true if success. */ 1237 public boolean next() { 1238 try { 1239 if (_rs == null) { 1240 throw new SQLException("ResultSet not available"); 1241 } 1242 return _rs.next(); 1243 } 1244 catch (SQLException e) { 1245 log.error(Util.report("Can't go to next row", e), e); 1246 } 1247 return false; 1248 } 1249 1250 /** <code>SQLTuple</code> extension: return current Row Data. 1251 * @return The array of Strings representing the current row. */ 1252 public String[] getRowData() { 1253 String[] values = new String[_names.length]; 1254 try { 1255 for (int i = 0; i < values.length; i++) { 1256 values[i] = _rs.getString(i+1); 1257 } 1258 } 1259 catch (SQLException e) { 1260 log.error(Util.report("Can't get Row Data", e), e); 1261 } 1262 return values; 1263 } 1264 1265 /** Add the current row into NTuple and reset. 1266 * Not set columns are set to their default values. */ 1267 public void addRow() { 1268 for (int i = 0; i < columns(); i++) { 1269 if (!_filled[i]) { 1270 log.debug("Value of column " + i + " not set, using default value: " + _types[i] + " " + _names[i] + " = " + _defaults[i]); 1271 fill(i, _defaultObjects[i]); 1272 } 1273 } 1274 try { 1275 if (_rows == -1) { 1276 rows(); 1277 } 1278 _rows += updatePrepared(_statement); 1279 } 1280 catch (SQLTupleException e) { 1281 log.error(Util.report("Can't execute PreparedStatement", e), e); 1282 } 1283 finally { 1284 resetRow(); 1285 } 1286 } 1287 1288 /** Prepare statement for adding row. */ 1289 public void prepare(){ 1290 StringBuffer values = new StringBuffer(); 1291 for (int i = 0; i < _names.length; i++) { 1292 _filled[i] = false; 1293 values.append("?"); 1294 if (i < _names.length - 1) { 1295 values.append(", "); 1296 } 1297 } 1298 String[] args = {values.toString()}; 1299 try { 1300 _statement = _stmtSrc.prepare("addRow", args); 1301 } 1302 catch (SQLTupleException e) { 1303 log.warn("Can't prepare statement addRow"); 1304 _readOnly = true; 1305 } 1306 } 1307 1308 /** Gets the name of the column number <code>param</code>. 1309 * @param param The number of column. 1310 * @return The name of the column. */ 1311 public String columnName(int param) { 1312 return _names[param]; 1313 } 1314 1315 /** Gets the number of the column name <code>name</code>. 1316 * @param name The number of column. 1317 * @return The number of the column. 1318 * @throws IllegalArgumentException if no column with that name exists. */ 1319 public int columnNumber(String name) throws IllegalArgumentException { 1320 if (_names != null) { 1321 for (int i = 0; i < _names.length; i++) { 1322 if (_names[i].equals(name)) { 1323 return i; 1324 } 1325 } 1326 } 1327 throw new IllegalArgumentException("There is no column " + name); 1328 } 1329 1330 /** Get all column names. 1331 * @return The array of Strings with all column names. */ 1332 public String[] columnNames() { 1333 return _names; 1334 } 1335 1336 /** Get the type of the column number <code>param</code>. 1337 * @param param The number of column. 1338 * @return The type of the column. */ 1339 public Class columnType(int param) { 1340 return _types[param]; 1341 } 1342 1343 /** Get all column types. 1344 * @return The array of Classes with all column types. */ 1345 public Class[] columnTypes() { 1346 return _types; 1347 } 1348 1349 /** <code>SQLTuple</code> extension: 1350 * Get the default value of the column number <code>param</code>. 1351 * @param param The number of column. 1352 * @return The default value of the column. */ 1353 public String columnDefault(int param) { 1354 return _defaults[param]; 1355 } 1356 1357 /** Give the default as a String. 1358 * @param column The number of column. 1359 * @return The String representation of the default. */ 1360 public String columnDefaultString(int column) { 1361 return _defaults[column]; 1362 } 1363 1364 /** <code>SQLTuple</code> extension: 1365 * Get all column default values. 1366 * @return The array of Strings with all column default values. */ 1367 public String[] columnDefaults() { 1368 return _defaults; 1369 } 1370 1371 /** Gets the number of columns. 1372 * @return The number of columns. */ 1373 public int columns() { 1374 return _names.length; 1375 } 1376 1377 /** Reset the NTuple/table, close it. */ 1378 public void reset() { 1379 try { 1380 _rs.close(); 1381 } 1382 catch (SQLException e) { 1383 log.error(Util.report("Can't reset", e), e); 1384 } 1385 _rs = null; 1386 } 1387 1388 /** Reset the current row. */ 1389 public void resetRow() throws IllegalArgumentException { 1390 try { 1391 _statement.clearParameters(); 1392 for (int i = 0; i < columns(); i++) { 1393 _filled[i] = false; 1394 } 1395 } 1396 catch (SQLException e) { 1397 log.error(Util.report("Can't reset row", e), e); 1398 throw new IllegalArgumentException("Couldn't reset row", e); 1399 } 1400 } 1401 1402 /** Get the number of rows. 1403 * @return The number of rows. */ 1404 public int rows() throws IllegalArgumentException { 1405 if (_rows == -1) { 1406 try { 1407 ResultSet rs = query("rows", null); 1408 rs.next(); 1409 _rows = rs.getInt(1); 1410 rs.close(); 1411 } 1412 catch (SQLException e) { 1413 log.error(Util.report("Can't get rows", e), e); 1414 throw new IllegalArgumentException("Couldn't get rows", e); 1415 } 1416 } 1417 return _rows; 1418 } 1419 1420 /** Get column. 1421 * @param index The column number. 1422 * @return The requested {@link TupleColumn} */ 1423 public IBaseTupleColumn column(int index) { 1424 return new SQLTupleColumn(this, index); 1425 } 1426 1427 /** Get column. 1428 * @param name The column name. 1429 * @return The requested {@link TupleColumn} */ 1430 public FTupleColumn columnByName(String name) { 1431 return new SQLTupleColumn(this, findColumn(name)); 1432 } 1433 1434 /** Give nested {@link ITuple}. It is not supported. 1435 * @param index The column's index of the Folder. 1436 * @return The nested {@link ITuple}. 1437 * @throws UnsupportedOperationException always, because opereation is not supported. */ 1438 public ITuple findTuple(int index) throws UnsupportedOperationException { 1439 throw new UnsupportedOperationException("Operation not supported in SQLTuple"); 1440 } 1441 1442 /** Get {@link FTupleCursor}. 1443 * @return The requested {@link FTupleCursor} */ 1444 public FTupleCursor cursor() throws IllegalStateException { 1445 return new SQLTupleCursor(this); 1446 } 1447 1448 /** Get {@link Value} of column at {@link FTupleCursor}. 1449 * @param column The column, value of which is requested. 1450 * @param value The {@link Value} to be filled. */ 1451 public void columnValue(int column, Value value) { 1452 Class cl = columnType(column); 1453 if (cl == Byte.TYPE) value.set(getByte(column)); 1454 else if (cl == Boolean.TYPE) value.set(getBoolean(column)); 1455 else if (cl == Character.TYPE) value.set(getChar(column)); 1456 else if (cl == Short.TYPE) value.set(getShort(column)); 1457 else if (cl == Integer.TYPE) value.set(getInt(column)); 1458 else if (cl == Long.TYPE) value.set(getLong(column)); 1459 else if (cl == Float.TYPE) value.set(getFloat(column)); 1460 else if (cl == Double.TYPE) value.set(getDouble(column)); 1461 else if (cl == String.class) value.set(getString(column)); 1462 else value.set(getString(column)); 1463 } 1464 1465 /** Get {@link Value} of column at {@link FTupleCursor}. 1466 * @param column The column, value of which is requested. 1467 * @param cursor The {@link FTupleCursor} pointing to requested row. 1468 * @param value The {@link Value} to be filled. */ 1469 public void columnValue(int column, FTupleCursor cursor, Value value) { 1470 columnValue(column, value); 1471 } 1472 1473 /** Get double value from the {@link ResultSet}. If direct <code>rs.getDouble(...)</code> 1474 * fails, <code>rs.getString(...)</code> and conversion to String is tried. 1475 * @param rs The {@link ResultSet} to be used. The current row will be inspected. 1476 * @param i The column to be used. 1477 * @return The found double value. 1478 * @throws IllegalArgumentException if double value can't be extracted, even via String value. */ 1479 private double getDouble(ResultSet rs, int i) throws IllegalArgumentException { 1480 // Try as double 1481 try { 1482 return rs.getDouble(i); 1483 } 1484 // Double failed 1485 catch (SQLException e) { 1486 // Try as String, convert to double 1487 try { 1488 String s = rs.getString(i); 1489 log.debug("Can't make projection, can't convert " + s + " to double, going via String: " + e.toString()); 1490 return new Double(s); 1491 } 1492 // String failed 1493 catch (SQLException ee) { 1494 log.error(Util.report("Can't make projection", ee), ee); 1495 throw new IllegalArgumentException("Couldn't make projection", ee); 1496 } 1497 } 1498 } 1499 1500 public void project(ICloud1D cloud, 1501 IEvaluator evaluatorX) throws IllegalArgumentException { 1502 String[] args = {evaluatorX.expression()}; 1503 ResultSet rs = query("projectX", args); 1504 try { 1505 while (rs.next()) { 1506 cloud.fill(getDouble(rs, 1)); 1507 } 1508 } 1509 catch (Exception e) { 1510 log.error(Util.report("Can't make projection", e), e); 1511 throw new IllegalArgumentException("Couldn't make projection", e); 1512 } 1513 } 1514 1515 public void project(ICloud1D cloud, 1516 IEvaluator evaluatorX, 1517 IEvaluator weight) throws IllegalArgumentException { 1518 String[] args = {evaluatorX.expression(), 1519 weight.expression()}; 1520 ResultSet rs = query("projectXW", args); 1521 try { 1522 while (rs.next()) { 1523 cloud.fill(getDouble(rs, 1), getDouble(rs, 2)); 1524 } 1525 } 1526 catch (SQLException e) { 1527 log.error(Util.report("Can't make projection", e), e); 1528 throw new IllegalArgumentException("Couldn't make projection", e); 1529 } 1530 } 1531 1532 public void project(ICloud1D cloud, 1533 IEvaluator evaluatorX, 1534 IFilter filter) throws IllegalArgumentException { 1535 String[] args = {evaluatorX.expression(), 1536 filter.expression()}; 1537 ResultSet rs = query("projectXF", args); 1538 try { 1539 while (rs.next()) { 1540 cloud.fill(getDouble(rs, 1)); 1541 } 1542 } 1543 catch (SQLException e) { 1544 log.error(Util.report("Can't make projection", e), e); 1545 throw new IllegalArgumentException("Couldn't make projection", e); 1546 } 1547 } 1548 1549 public void project(ICloud1D cloud, 1550 IEvaluator evaluatorX, 1551 IFilter filter, 1552 IEvaluator weight) throws IllegalArgumentException { 1553 String[] args = {evaluatorX.expression(), 1554 weight.expression(), 1555 filter.expression()}; 1556 ResultSet rs = query("projectXFW", args); 1557 try { 1558 while (rs.next()) { 1559 cloud.fill(getDouble(rs, 1), getDouble(rs, 2)); 1560 } 1561 } 1562 catch (SQLException e) { 1563 log.error(Util.report("Can't make projection", e), e); 1564 throw new IllegalArgumentException("Couldn't make projection", e); 1565 } 1566 } 1567 1568 public void project(ICloud2D cloud, 1569 IEvaluator evaluatorX, 1570 IEvaluator evaluatorY) throws IllegalArgumentException { 1571 String[] args = {evaluatorX.expression(), 1572 evaluatorY.expression()}; 1573 ResultSet rs = query("projectXY", args); 1574 try { 1575 while (rs.next()) { 1576 cloud.fill(getDouble(rs, 1), getDouble(rs, 2)); 1577 } 1578 } 1579 catch (SQLException e) { 1580 log.error(Util.report("Can't make projection", e), e); 1581 throw new IllegalArgumentException("Couldn't make projection", e); 1582 } 1583 } 1584 1585 public void project(ICloud2D cloud, 1586 IEvaluator evaluatorX, 1587 IEvaluator evaluatorY, 1588 IEvaluator weight) throws IllegalArgumentException { 1589 String[] args = {evaluatorX.expression(), 1590 evaluatorY.expression(), 1591 weight.expression()}; 1592 ResultSet rs = query("projectXYW", args); 1593 try { 1594 while (rs.next()) { 1595 cloud.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3)); 1596 } 1597 } 1598 catch (SQLException e) { 1599 log.error(Util.report("Can't make projection", e), e); 1600 throw new IllegalArgumentException("Couldn't make projection", e); 1601 } 1602 } 1603 1604 public void project(ICloud2D cloud, 1605 IEvaluator evaluatorX, 1606 IEvaluator evaluatorY, 1607 IFilter filter) throws IllegalArgumentException { 1608 String[] args = {evaluatorX.expression(), 1609 evaluatorY.expression(), 1610 filter.expression()}; 1611 ResultSet rs = query("projectXYF", args); 1612 try { 1613 while (rs.next()) { 1614 cloud.fill(getDouble(rs, 1), getDouble(rs, 2)); 1615 } 1616 } 1617 catch (SQLException e) { 1618 log.error(Util.report("Can't make projection", e), e); 1619 throw new IllegalArgumentException("Couldn't make projection", e); 1620 } 1621 } 1622 1623 public void project(ICloud2D cloud, 1624 IEvaluator evaluatorX, 1625 IEvaluator evaluatorY, 1626 IFilter filter, 1627 IEvaluator weight) throws IllegalArgumentException { 1628 String[] args = {evaluatorX.expression(), 1629 evaluatorY.expression(), 1630 weight.expression(), 1631 filter.expression()}; 1632 ResultSet rs = query("projectXYFW", args); 1633 try { 1634 while (rs.next()) { 1635 cloud.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3)); 1636 } 1637 } 1638 catch (SQLException e) { 1639 log.error(Util.report("Can't make projection", e), e); 1640 throw new IllegalArgumentException("Couldn't make projection", e); 1641 } 1642 } 1643 1644 public void project(ICloud3D cloud, 1645 IEvaluator evaluatorX, 1646 IEvaluator evaluatorY, 1647 IEvaluator evaluatorZ) throws IllegalArgumentException { 1648 String[] args = {evaluatorX.expression(), 1649 evaluatorY.expression(), 1650 evaluatorZ.expression()}; 1651 ResultSet rs = query("projectXYZ", args); 1652 try { 1653 while (rs.next()) { 1654 cloud.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3)); 1655 } 1656 } 1657 catch (SQLException e) { 1658 log.error(Util.report("Can't make projection", e), e); 1659 throw new IllegalArgumentException("Couldn't make projection", e); 1660 } 1661 } 1662 1663 public void project(ICloud3D cloud, 1664 IEvaluator evaluatorX, 1665 IEvaluator evaluatorY, 1666 IEvaluator evaluatorZ, 1667 IEvaluator weight) throws IllegalArgumentException { 1668 String[] args = {evaluatorX.expression(), 1669 evaluatorY.expression(), 1670 evaluatorZ.expression(), 1671 weight.expression()}; 1672 ResultSet rs = query("projectXYZW", args); 1673 try { 1674 while (rs.next()) { 1675 cloud.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3), getDouble(rs, 4)); 1676 } 1677 } 1678 catch (SQLException e) { 1679 log.error(Util.report("Can't make projection", e), e); 1680 throw new IllegalArgumentException("Couldn't make projection", e); 1681 } 1682 } 1683 1684 public void project(ICloud3D cloud, 1685 IEvaluator evaluatorX, 1686 IEvaluator evaluatorY, 1687 IEvaluator evaluatorZ, 1688 IFilter filter) throws IllegalArgumentException { 1689 String[] args = {evaluatorX.expression(), 1690 evaluatorY.expression(), 1691 evaluatorZ.expression(), 1692 filter.expression()}; 1693 ResultSet rs = query("projectXYZF", args); 1694 try { 1695 while (rs.next()) { 1696 cloud.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3), getDouble(rs, 4)); 1697 } 1698 } 1699 catch (SQLException e) { 1700 log.error(Util.report("Can't make projection", e), e); 1701 throw new IllegalArgumentException("Couldn't make projection", e); 1702 } 1703 } 1704 1705 public void project(ICloud3D cloud, 1706 IEvaluator evaluatorX, 1707 IEvaluator evaluatorY, 1708 IEvaluator evaluatorZ, 1709 IFilter filter, 1710 IEvaluator weight) throws IllegalArgumentException { 1711 String[] args = {evaluatorX.expression(), 1712 evaluatorY.expression(), 1713 evaluatorZ.expression(), 1714 weight.expression(), 1715 filter.expression()}; 1716 ResultSet rs = query("projectXYZFW", args); 1717 try { 1718 while (rs.next()) { 1719 cloud.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3), getDouble(rs, 4)); 1720 } 1721 } 1722 catch (SQLException e) { 1723 log.error(Util.report("Can't make projection", e), e); 1724 throw new IllegalArgumentException("Couldn't make projection", e); 1725 } 1726 } 1727 1728 public void project(IHistogram1D histogram, 1729 IEvaluator evaluatorX) throws IllegalArgumentException { 1730 String[] args = {evaluatorX.expression()}; 1731 ResultSet rs = query("projectX", args); 1732 try { 1733 while (rs.next()) { 1734 histogram.fill(getDouble(rs, 1)); 1735 } 1736 } 1737 catch (SQLException e) { 1738 log.error(Util.report("Can't make projection", e), e); 1739 throw new IllegalArgumentException("Couldn't make projection", e); 1740 } 1741 } 1742 1743 public void project(IHistogram1D histogram, 1744 IEvaluator evaluatorX, 1745 IEvaluator weight) throws IllegalArgumentException { 1746 String[] args = {evaluatorX.expression(), 1747 weight.expression()}; 1748 ResultSet rs = query("projectXW", args); 1749 try { 1750 while (rs.next()) { 1751 histogram.fill(getDouble(rs, 1), getDouble(rs, 2)); 1752 } 1753 } 1754 catch (SQLException e) { 1755 log.error(Util.report("Can't make projection", e), e); 1756 throw new IllegalArgumentException("Couldn't make projection", e); 1757 } 1758 } 1759 1760 public void project(IHistogram1D histogram, 1761 IEvaluator evaluatorX, 1762 IFilter filter) throws IllegalArgumentException { 1763 String[] args = {evaluatorX.expression(), 1764 filter.expression()}; 1765 ResultSet rs = query("projectXF", args); 1766 try { 1767 while (rs.next()) { 1768 histogram.fill(getDouble(rs, 1)); 1769 } 1770 } 1771 catch (SQLException e) { 1772 log.error(Util.report("Can't make projection", e), e); 1773 throw new IllegalArgumentException("Couldn't make projection", e); 1774 } 1775 } 1776 1777 public void project(IHistogram1D histogram, 1778 IEvaluator evaluatorX, 1779 IFilter filter, 1780 IEvaluator weight) throws IllegalArgumentException { 1781 String[] args = {evaluatorX.expression(), 1782 weight.expression(), 1783 filter.expression()}; 1784 ResultSet rs = query("projectXFW", args); 1785 try { 1786 while (rs.next()) { 1787 histogram.fill(getDouble(rs, 1), getDouble(rs, 2)); 1788 } 1789 } 1790 catch (SQLException e) { 1791 log.error(Util.report("Can't make projection", e), e); 1792 throw new IllegalArgumentException("Couldn't make projection", e); 1793 } 1794 } 1795 1796 public void project(IHistogram2D histogram, 1797 IEvaluator evaluatorX, 1798 IEvaluator evaluatorY) throws IllegalArgumentException { 1799 String[] args = {evaluatorX.expression(), 1800 evaluatorY.expression()}; 1801 ResultSet rs = query("projectXY", args); 1802 try { 1803 while (rs.next()) { 1804 histogram.fill(getDouble(rs, 1), getDouble(rs, 2)); 1805 } 1806 } 1807 catch (SQLException e) { 1808 log.error(Util.report("Can't make projection", e), e); 1809 throw new IllegalArgumentException("Couldn't make projection", e); 1810 } 1811 } 1812 1813 public void project(IHistogram2D histogram, 1814 IEvaluator evaluatorX, 1815 IEvaluator evaluatorY, 1816 IEvaluator weight) throws IllegalArgumentException { 1817 String[] args = {evaluatorX.expression(), 1818 evaluatorY.expression(), 1819 weight.expression()}; 1820 ResultSet rs = query("projectXYW", args); 1821 try { 1822 while (rs.next()) { 1823 histogram.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3)); 1824 } 1825 } 1826 catch (SQLException e) { 1827 log.error(Util.report("Can't make projection", e), e); 1828 throw new IllegalArgumentException("Couldn't make projection", e); 1829 } 1830 } 1831 1832 public void project(IHistogram2D histogram, 1833 IEvaluator evaluatorX, 1834 IEvaluator evaluatorY, 1835 IFilter filter) throws IllegalArgumentException { 1836 String[] args = {evaluatorX.expression(), 1837 evaluatorY.expression(), 1838 filter.expression()}; 1839 ResultSet rs = query("projectXYF", args); 1840 try { 1841 while (rs.next()) { 1842 histogram.fill(getDouble(rs, 1), getDouble(rs, 2)); 1843 } 1844 } 1845 catch (SQLException e) { 1846 log.error(Util.report("Can't make projection", e), e); 1847 throw new IllegalArgumentException("Couldn't make projection", e); 1848 } 1849 } 1850 1851 public void project(IHistogram2D histogram, 1852 IEvaluator evaluatorX, 1853 IEvaluator evaluatorY, 1854 IFilter filter, 1855 IEvaluator weight) throws IllegalArgumentException { 1856 String[] args = {evaluatorX.expression(), 1857 evaluatorY.expression(), 1858 weight.expression(), 1859 filter.expression()}; 1860 ResultSet rs = query("projectXYFW", args); 1861 try { 1862 while (rs.next()) { 1863 histogram.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3)); 1864 } 1865 } 1866 catch (SQLException e) { 1867 log.error(Util.report("Can't make projection", e), e); 1868 throw new IllegalArgumentException("Couldn't make projection", e); 1869 } 1870 } 1871 1872 public void project(IHistogram3D histogram, 1873 IEvaluator evaluatorX, 1874 IEvaluator evaluatorY, 1875 IEvaluator evaluatorZ) throws IllegalArgumentException { 1876 String[] args = {evaluatorX.expression(), 1877 evaluatorY.expression(), 1878 evaluatorZ.expression()}; 1879 ResultSet rs = query("projectXYZ", args); 1880 try { 1881 while (rs.next()) { 1882 histogram.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3)); 1883 } 1884 } 1885 catch (SQLException e) { 1886 log.error(Util.report("Can't make projection", e), e); 1887 throw new IllegalArgumentException("Couldn't make projection", e); 1888 } 1889 } 1890 1891 public void project(IHistogram3D histogram, 1892 IEvaluator evaluatorX, 1893 IEvaluator evaluatorY, 1894 IEvaluator evaluatorZ, 1895 IEvaluator weight) throws IllegalArgumentException { 1896 String[] args = {evaluatorX.expression(), 1897 evaluatorY.expression(), 1898 evaluatorZ.expression(), 1899 weight.expression()}; 1900 ResultSet rs = query("projectXYZW", args); 1901 try { 1902 while (rs.next()) { 1903 histogram.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3), getDouble(rs, 4)); 1904 } 1905 } 1906 catch (SQLException e) { 1907 log.error(Util.report("Can't make projection", e), e); 1908 throw new IllegalArgumentException("Couldn't make projection", e); 1909 } 1910 } 1911 1912 public void project(IHistogram3D histogram, 1913 IEvaluator evaluatorX, 1914 IEvaluator evaluatorY, 1915 IEvaluator evaluatorZ, 1916 IFilter filter) throws IllegalArgumentException { 1917 String[] args = {evaluatorX.expression(), 1918 evaluatorY.expression(), 1919 evaluatorZ.expression(), 1920 filter.expression()}; 1921 ResultSet rs = query("projectXYZF", args); 1922 try { 1923 while (rs.next()) { 1924 histogram.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3), getDouble(rs, 4)); 1925 } 1926 } 1927 catch (SQLException e) { 1928 log.error(Util.report("Can't make projection", e), e); 1929 throw new IllegalArgumentException("Couldn't make projection", e); 1930 } 1931 } 1932 1933 public void project(IHistogram3D histogram, 1934 IEvaluator evaluatorX, 1935 IEvaluator evaluatorY, 1936 IEvaluator evaluatorZ, 1937 IFilter filter, 1938 IEvaluator weight) throws IllegalArgumentException { 1939 String[] args = {evaluatorX.expression(), 1940 evaluatorY.expression(), 1941 evaluatorZ.expression(), 1942 weight.expression(), 1943 filter.expression()}; 1944 ResultSet rs = query("projectXYZFW", args); 1945 try { 1946 while (rs.next()) { 1947 histogram.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3), getDouble(rs, 4)); 1948 } 1949 } 1950 catch (SQLException e) { 1951 log.error(Util.report("Can't make projection", e), e); 1952 throw new IllegalArgumentException("Couldn't make projection", e); 1953 } 1954 } 1955 1956 public void project(IProfile1D profile, 1957 IEvaluator evaluatorX, 1958 IEvaluator evaluatorY) throws IllegalArgumentException { 1959 String[] args = {evaluatorX.expression(), 1960 evaluatorY.expression()}; 1961 ResultSet rs = query("projectXY", args); 1962 try { 1963 while (rs.next()) { 1964 profile.fill(getDouble(rs, 1), getDouble(rs, 2)); 1965 } 1966 } 1967 catch (SQLException e) { 1968 log.error(Util.report("Can't make projection", e), e); 1969 throw new IllegalArgumentException("Couldn't make projection", e); 1970 } 1971 } 1972 1973 public void project(IProfile1D profile, 1974 IEvaluator evaluatorX, 1975 IEvaluator evaluatorY, 1976 IEvaluator weight) throws IllegalArgumentException { 1977 String[] args = {evaluatorX.expression(), 1978 evaluatorY.expression(), 1979 weight.expression()}; 1980 ResultSet rs = query("projectXYW", args); 1981 try { 1982 while (rs.next()) { 1983 profile.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3)); 1984 } 1985 } 1986 catch (SQLException e) { 1987 log.error(Util.report("Can't make projection", e), e); 1988 throw new IllegalArgumentException("Couldn't make projection", e); 1989 } 1990 } 1991 1992 public void project(IProfile1D profile, 1993 IEvaluator evaluatorX, 1994 IEvaluator evaluatorY, 1995 IFilter filter) throws IllegalArgumentException { 1996 String[] args = {evaluatorX.expression(), 1997 evaluatorY.expression(), 1998 filter.expression()}; 1999 ResultSet rs = query("projectXYF", args); 2000 try { 2001 while (rs.next()) { 2002 profile.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3)); 2003 } 2004 } 2005 catch (SQLException e) { 2006 log.error(Util.report("Can't make projection", e), e); 2007 throw new IllegalArgumentException("Couldn't make projection", e); 2008 } 2009 } 2010 2011 public void project(IProfile1D profile, 2012 IEvaluator evaluatorX, 2013 IEvaluator evaluatorY, 2014 IFilter filter, 2015 IEvaluator weight) throws IllegalArgumentException { 2016 String[] args = {evaluatorX.expression(), 2017 evaluatorY.expression(), 2018 weight.expression(), 2019 filter.expression()}; 2020 ResultSet rs = query("projectXYFW", args); 2021 try { 2022 while (rs.next()) { 2023 profile.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3)); 2024 } 2025 } 2026 catch (SQLException e) { 2027 log.error(Util.report("Can't make projection", e), e); 2028 throw new IllegalArgumentException("Couldn't make projection", e); 2029 } 2030 } 2031 2032 public void project(IProfile2D profile, 2033 IEvaluator evaluatorX, 2034 IEvaluator evaluatorY, 2035 IEvaluator evaluatorZ) throws IllegalArgumentException { 2036 String[] args = {evaluatorX.expression(), 2037 evaluatorY.expression(), 2038 evaluatorZ.expression()}; 2039 ResultSet rs = query("projectXYZ", args); 2040 try { 2041 while (rs.next()) { 2042 profile.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3)); 2043 } 2044 } 2045 catch (SQLException e) { 2046 log.error(Util.report("Can't make projection", e), e); 2047 throw new IllegalArgumentException("Couldn't make projection", e); 2048 } 2049 } 2050 2051 public void project(IProfile2D profile, 2052 IEvaluator evaluatorX, 2053 IEvaluator evaluatorY, 2054 IEvaluator evaluatorZ, 2055 IEvaluator weight) throws IllegalArgumentException { 2056 String[] args = {evaluatorX.expression(), 2057 evaluatorY.expression(), 2058 evaluatorZ.expression(), 2059 weight.expression()}; 2060 ResultSet rs = query("projectXYZW", args); 2061 try { 2062 while (rs.next()) { 2063 profile.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3), getDouble(rs, 4)); 2064 } 2065 } 2066 catch (SQLException e) { 2067 log.error(Util.report("Can't make projection", e), e); 2068 throw new IllegalArgumentException("Couldn't make projection", e); 2069 } 2070 } 2071 2072 public void project(IProfile2D profile, 2073 IEvaluator evaluatorX, 2074 IEvaluator evaluatorY, 2075 IEvaluator evaluatorZ, 2076 IFilter filter) throws IllegalArgumentException { 2077 String[] args = {evaluatorX.expression(), 2078 evaluatorY.expression(), 2079 evaluatorZ.expression(), 2080 filter.expression()}; 2081 ResultSet rs = query("projectXYZF", args); 2082 try { 2083 while (rs.next()) { 2084 profile.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3), getDouble(rs, 4)); 2085 } 2086 } 2087 catch (SQLException e) { 2088 log.error(Util.report("Can't make projection", e), e); 2089 throw new IllegalArgumentException("Couldn't make projection", e); 2090 } 2091 } 2092 2093 public void project(IProfile2D profile, 2094 IEvaluator evaluatorX, 2095 IEvaluator evaluatorY, 2096 IEvaluator evaluatorZ, 2097 IFilter filter, 2098 IEvaluator weight) throws IllegalArgumentException { 2099 String[] args = {evaluatorX.expression(), 2100 evaluatorY.expression(), 2101 evaluatorZ.expression(), 2102 weight.expression(), 2103 filter.expression()}; 2104 ResultSet rs = query("projectXYZFW", args); 2105 try { 2106 while (rs.next()) { 2107 profile.fill(getDouble(rs, 1), getDouble(rs, 2), getDouble(rs, 3), getDouble(rs, 4)); 2108 } 2109 } 2110 catch (SQLException e) { 2111 log.error(Util.report("Can't make projection", e), e); 2112 throw new IllegalArgumentException("Couldn't make projection", e); 2113 } 2114 } 2115 2116 /** <code>SQLTuple</code> extension: get the whole column as an array 2117 * of Strings. 2118 * @param cName The name of the column. 2119 * @return The {@link Collection} containing the whole column as Strings. */ 2120 public Collection<String> getColumn(String cName) { 2121 return getColumn(cName, String.class); 2122 } 2123 2124 /** <code>SQLTuple</code> extension: get the whole column as an array 2125 * of Objects of the specified Class (which has to have a String constructor). 2126 * @param cName The name of the column. 2127 * @param cl The Class (with String constructor) to be used to create Objects for {@link Collection}. 2128 * @return The {@link Collection} containing the whole column as Objects of specified Class. */ 2129 public <T> Collection<T> getColumn(String cName, 2130 Class<T> cl) { 2131 return getColumn(cName, cl, null); 2132 } 2133 2134 /** <code>SQLTuple</code> extension: get the filtered column as an array 2135 * of Strings. 2136 * @param cName The name of the column. 2137 * @param filter The {@link IFilter} to be used to select rows. 2138 * @return The [@link Collection} containing the whole column as Strings. */ 2139 public Collection<String> getColumn(String cName, 2140 IFilter filter) { 2141 return getColumn(cName, String.class, filter); 2142 } 2143 2144 /** <code>SQLTuple</code> extension: get the filtered column as an array 2145 * of Objects of the specified Class (it has to have a String constructor). 2146 * @param cName The name of the column. 2147 * @param cl The Class (with String constructor) to be used to create Objects for {@link Collection}. 2148 * @param filter The {@link IFilter} to be used to select rows. 2149 * @return The {@link Collection} containing the whole column as Objects of specified Class. */ 2150 public <T> Collection<T> getColumn(String cName, 2151 Class<T> cl, 2152 IFilter filter) { 2153 Collection<T> values = new ArrayList<T>(); 2154 Class[] parameters = {String.class}; 2155 Constructor<T> constructor = null; 2156 try { 2157 constructor = cl.getConstructor(parameters); 2158 } 2159 catch(NoSuchMethodException e) { 2160 log.error(Util.report("Can't find constructor " + cl + "(" + cName + "), return empty Collection", e), e); 2161 return values; 2162 } 2163 Object args[]; 2164 T obj = null; 2165 ResultSet rs = null; 2166 if (filter == null) { 2167 String[] args0 = {cName}; 2168 rs = query("getColumn", args0); 2169 } 2170 else { 2171 String[] args0 = {cName, filter.expression()}; 2172 rs = query("getColumnFilter", args0); 2173 } 2174 try { 2175 while (rs.next()) { 2176 args = new Object[1]; 2177 args[0] = rs.getString(1); 2178 try { 2179 obj = constructor.newInstance(args); 2180 values.add((T)obj); 2181 } 2182 catch(InstantiationException e) { 2183 log.error(Util.report("Can't construct " + cl + " from " + args[0] + ", return empty Collection", e), e); 2184 } 2185 catch(IllegalAccessException e) { 2186 log.error(Util.report("Can't construct " + cl + " from " + args[0] + ", return empty Collection", e), e); 2187 } 2188 catch(InvocationTargetException e) { 2189 log.error(Util.report("Can't construct " + cl + " from " + args[0] + ", return empty Collection", e), e); 2190 } 2191 } 2192 } 2193 catch (SQLException e) { 2194 log.error(Util.report("Can't get column " + cName + " with filter " + filter.expression() + " as Collection<String>, return empty Collection", e), e); 2195 } 2196 return values; 2197 } 2198 2199 /** Register options. 2200 * @param options The options string to be registered. 2201 * @throws SQLTupleException if Accessor can't be created. */ 2202 public void setOptions(String options) throws SQLTupleException { 2203 _accessor = Accessor.getAccessor(options); 2204 } 2205 2206 /** Get attached {@link Accessor}. 2207 * @return The associated Accessor. */ 2208 public Accessor accessor() { 2209 return _accessor; 2210 } 2211 2212 /** Perform update operation via {@link StmtSrc}. 2213 * @param statementString The SQL statement to be used. 2214 * @param args The arguments to be filled into the SQL statement in place of X*. 2215 * @return The number of added rows. 2216 * @throws IllegalArgumentException if the update can't be performed. */ 2217 private int update(String statementString, 2218 String[] args) throws IllegalArgumentException { 2219 try { 2220 return _stmtSrc.update(statementString, args); 2221 } 2222 catch(SQLTupleException e) { 2223 log.error(Util.report("Can't perform update " + statementString, e), e); 2224 throw new IllegalArgumentException("Couldn't perform update " + statementString, e); 2225 } 2226 } 2227 2228 /** Perform update operation via {@link StmtSrc} using {@link PreparedStatement}. 2229 * @param statement The SQL {@link PreparedStatement} to be used. 2230 * @return The number of added rows. 2231 * @throws SQLTupleException if the update can't be performed. */ 2232 private int updatePrepared(PreparedStatement statement) throws SQLTupleException { 2233 try { 2234 return _stmtSrc.updatePrepared(statement); 2235 } 2236 catch(SQLTupleException e) { 2237 log.error(Util.report("Can't perform update using Prepared Statement " + statement, e), e); 2238 throw new IllegalArgumentException("Couldn't perform update using Prepared Statement " + statement, e); 2239 } 2240 } 2241 2242 /** Perform query operation via {@link StmtSrc}. 2243 * @param statementString The SQL statement to be used. 2244 * @param args The arguments to be filled into the SQL statement in place of X*. 2245 * @return The results of the SQL command. 2246 * @throws IllegalArgumentException if the update can't be performed. */ 2247 private ResultSet query(String statementString, 2248 String[] args) throws IllegalArgumentException { 2249 try { 2250 ResultSet rs = _stmtSrc.query(statementString, args); 2251 if (!_accessor.forwardOnly()) { 2252 rs.last(); 2253 _rows = rs.getRow(); 2254 rs.beforeFirst(); 2255 } 2256 return rs; 2257 } 2258 catch(Exception e) { 2259 log.error(Util.report("Can't perform query " + statementString, e), e); 2260 throw new IllegalArgumentException("Couldn't perform query " + statementString, e); 2261 } 2262 } 2263 2264 /** Give attached {@link StmtSrc}. 2265 * @return The attached {@link StmtSrc}. */ 2266 public StmtSrc stmtSrc() { 2267 return _stmtSrc; 2268 } 2269 2270 /** Attached {@link StmtSrc}. 2271 * @param url The {@link StmtSrc} to be attached. */ 2272 public void setStmtSrc(String url) { 2273 String src = _accessor.src(); 2274 _accessor.setSrc(url); 2275 try { 2276 _stmtSrc = new StmtSrc(_accessor, title()); 2277 } 2278 catch (SQLTupleException e) { 2279 log.error(Util.report("Can't (re)set StmtSrc to " + url, e), e); 2280 _accessor.setSrc(src); 2281 } 2282 } 2283 2284 /** Create Object from String value. 2285 * @param value The value as {@link String}. 2286 * @param type The type of the requested Object. 2287 * @return The Object of the requested type with the requested value. */ 2288 private Object type2Object(String value, Class type) { 2289 Object valueObject; 2290 if (type == Integer.TYPE ) valueObject = ((value == null) ? (int )0 : Integer.parseInt( value)); 2291 else if (type == Short.TYPE ) valueObject = ((value == null) ? (short )0 : Short.parseShort( value)); 2292 else if (type == Long.TYPE ) valueObject = ((value == null) ? (long )0 : Long.parseLong( value)); 2293 else if (type == Float.TYPE ) valueObject = ((value == null) ? (float )0 : Float.parseFloat( value)); 2294 else if (type == Double.TYPE ) valueObject = ((value == null) ? (double)0 : Double.parseDouble(value)); 2295 else if (type == Boolean.TYPE ) valueObject = ((value == null) ? false : Boolean.valueOf( value).booleanValue()); 2296 else if (type == Byte.TYPE ) valueObject = ((value == null) ? (byte )0 : Byte.parseByte( value)); 2297 else if (type == Character.TYPE) valueObject = ((value == null) ? (char )0 : value.charAt(0)); 2298 else valueObject = ((value == null) ? "" : value); 2299 return valueObject; 2300 } 2301 2302 private Accessor _accessor; 2303 2304 private StmtSrc _stmtSrc; 2305 2306 private PreparedStatement _statement; 2307 2308 private ResultSet _rs; 2309 2310 private String[] _names; 2311 2312 private Class[] _types; 2313 2314 private String[] _defaults; 2315 2316 private Object[] _defaultObjects; 2317 2318 private String[] _namesOrig; 2319 2320 private Class[] _typesOrig; 2321 2322 private String[] _defaultsOrig; 2323 2324 private Object[] _defaultObjectsOrig; 2325 2326 private boolean[] _filled; 2327 2328 private int _rows; 2329 2330 private boolean _readOnly = false; 2331 2332 /** Logging . */ 2333 private static Logger log = Logger.getLogger(SQLTuple.class); 2334 2335 }