001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2007-2011 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.olap4j; 011 012import org.olap4j.OlapWrapper; 013 014import java.io.InputStream; 015import java.io.Reader; 016import java.math.BigDecimal; 017import java.net.URL; 018import java.sql.*; 019import java.sql.Date; 020import java.util.*; 021import javax.sql.rowset.RowSetMetaDataImpl; 022 023/** 024 * Implementation of {@link ResultSet} which returns 0 rows. 025 * 026 * <p>This class is used to implement {@link java.sql.DatabaseMetaData} 027 * methods for querying object types where those object types never have 028 * any instances for this particular driver.</p> 029 * 030 * <p>This class has sub-classes which implement JDBC 3.0 and JDBC 4.0 APIs; 031 * it is instantiated using {@link Factory#newEmptyResultSet}.</p> 032 * 033 * @author jhyde 034 * @since May 24, 2007 035 */ 036abstract class EmptyResultSet implements ResultSet, OlapWrapper { 037 final MondrianOlap4jConnection olap4jConnection; 038 private final List<String> headerList; 039 private final List<List<Object>> rowList; 040 private int rowOrdinal = -1; 041 private final RowSetMetaDataImpl metaData = new RowSetMetaDataImpl(); 042 043 EmptyResultSet( 044 MondrianOlap4jConnection olap4jConnection, 045 List<String> headerList, 046 List<List<Object>> rowList) 047 { 048 this.olap4jConnection = olap4jConnection; 049 this.headerList = headerList; 050 this.rowList = rowList; 051 try { 052 metaData.setColumnCount(headerList.size()); 053 for (int i = 0; i < headerList.size(); i++) { 054 metaData.setColumnName(i + 1, headerList.get(i)); 055 deduceType(rowList, i); 056 } 057 } catch (SQLException e) { 058 throw new RuntimeException(e); 059 } 060 } 061 062 protected void deduceType(List<List<Object>> rowList, int column) 063 throws SQLException 064 { 065 int nullability = ResultSetMetaData.columnNoNulls; 066 int type = Types.OTHER; 067 int maxLen = 0; 068 for (List<Object> objects : rowList) { 069 final Object o = objects.get(column); 070 if (o == null) { 071 nullability = ResultSetMetaData.columnNullable; 072 } else { 073 if (type == Types.OTHER) { 074 type = deduceColumnType(o); 075 } 076 if (o instanceof String) { 077 maxLen = Math.max(maxLen, ((String) o).length()); 078 } 079 } 080 } 081 metaData.setNullable(column + 1, nullability); 082 metaData.setColumnType(column + 1, type); 083 if (maxLen > 0) { 084 metaData.setPrecision(column + 1, maxLen); 085 } 086 } 087 088 private int deduceColumnType(Object o) { 089 if (o instanceof String) { 090 return Types.VARCHAR; 091 } else if (o instanceof Integer) { 092 return Types.INTEGER; 093 } else if (o instanceof Long) { 094 return Types.BIGINT; 095 } else if (o instanceof Double) { 096 return Types.DOUBLE; 097 } else if (o instanceof Float) { 098 return Types.FLOAT; 099 } else if (o instanceof Boolean) { 100 return Types.BOOLEAN; 101 } else { 102 return Types.VARCHAR; 103 } 104 } 105 106 // helper methods 107 108 /** 109 * Returns the value of a given column 110 * @param columnOrdinal 0-based ordinal 111 * @return Value 112 */ 113 private Object getColumn(int columnOrdinal) { 114 return rowList.get(rowOrdinal).get(columnOrdinal); 115 } 116 117 private Object getColumn(String columnLabel) throws SQLException { 118 int column = headerList.indexOf(columnLabel); 119 if (column < 0) { 120 throw new SQLException("Column not found: " + columnLabel); 121 } 122 return rowList.get(rowOrdinal).get(column); 123 } 124 125 // implement ResultSet 126 127 public boolean next() throws SQLException { 128 // note that if rowOrdinal == rowList.size - 1, we move but then return 129 // false 130 if (rowOrdinal < rowList.size()) { 131 ++rowOrdinal; 132 } 133 return rowOrdinal < rowList.size(); 134 } 135 136 public void close() throws SQLException { 137 } 138 139 public boolean wasNull() throws SQLException { 140 throw new UnsupportedOperationException(); 141 } 142 143 public String getString(int columnIndex) throws SQLException { 144 final Object result = getColumn(columnIndex - 1); 145 return result == null ? null : String.valueOf(result); 146 } 147 148 public boolean getBoolean(int columnIndex) throws SQLException { 149 Object o = getColumn(columnIndex - 1); 150 if (o instanceof Boolean) { 151 return (Boolean) o; 152 } else if (o instanceof String) { 153 return Boolean.valueOf((String) o); 154 } else { 155 return !o.equals(0); 156 } 157 } 158 159 public byte getByte(int columnIndex) throws SQLException { 160 Object o = getColumn(columnIndex - 1); 161 return ((Number) o).byteValue(); 162 } 163 164 public short getShort(int columnIndex) throws SQLException { 165 Object o = getColumn(columnIndex - 1); 166 return ((Number) o).shortValue(); 167 } 168 169 public int getInt(int columnIndex) throws SQLException { 170 Object o = getColumn(columnIndex - 1); 171 return ((Number) o).intValue(); 172 } 173 174 public long getLong(int columnIndex) throws SQLException { 175 Object o = getColumn(columnIndex - 1); 176 return ((Number) o).longValue(); 177 } 178 179 public float getFloat(int columnIndex) throws SQLException { 180 Object o = getColumn(columnIndex - 1); 181 return ((Number) o).floatValue(); 182 } 183 184 public double getDouble(int columnIndex) throws SQLException { 185 Object o = getColumn(columnIndex - 1); 186 return ((Number) o).doubleValue(); 187 } 188 189 public BigDecimal getBigDecimal( 190 int columnIndex, int scale) throws SQLException 191 { 192 throw new UnsupportedOperationException(); 193 } 194 195 public byte[] getBytes(int columnIndex) throws SQLException { 196 Object o = getColumn(columnIndex - 1); 197 return (byte[]) o; 198 } 199 200 public Date getDate(int columnIndex) throws SQLException { 201 Object o = getColumn(columnIndex - 1); 202 return (Date) o; 203 } 204 205 public Time getTime(int columnIndex) throws SQLException { 206 Object o = getColumn(columnIndex - 1); 207 return (Time) o; 208 } 209 210 public Timestamp getTimestamp(int columnIndex) throws SQLException { 211 Object o = getColumn(columnIndex - 1); 212 return (Timestamp) o; 213 } 214 215 public InputStream getAsciiStream(int columnIndex) throws SQLException { 216 throw new UnsupportedOperationException(); 217 } 218 219 public InputStream getUnicodeStream(int columnIndex) throws SQLException { 220 throw new UnsupportedOperationException(); 221 } 222 223 public InputStream getBinaryStream(int columnIndex) throws SQLException { 224 throw new UnsupportedOperationException(); 225 } 226 227 public String getString(String columnLabel) throws SQLException { 228 final Object result = getColumn(columnLabel); 229 return result == null ? null : String.valueOf(result); 230 } 231 232 public boolean getBoolean(String columnLabel) throws SQLException { 233 Object o = getColumn(columnLabel); 234 if (o instanceof Boolean) { 235 return (Boolean) o; 236 } else if (o instanceof String) { 237 return Boolean.valueOf((String) o); 238 } else { 239 return !o.equals(0); 240 } 241 } 242 243 public byte getByte(String columnLabel) throws SQLException { 244 Object o = getColumn(columnLabel); 245 return ((Number) o).byteValue(); 246 } 247 248 public short getShort(String columnLabel) throws SQLException { 249 Object o = getColumn(columnLabel); 250 return ((Number) o).shortValue(); 251 } 252 253 public int getInt(String columnLabel) throws SQLException { 254 Object o = getColumn(columnLabel); 255 return ((Number) o).intValue(); 256 } 257 258 public long getLong(String columnLabel) throws SQLException { 259 Object o = getColumn(columnLabel); 260 return ((Number) o).longValue(); 261 } 262 263 public float getFloat(String columnLabel) throws SQLException { 264 Object o = getColumn(columnLabel); 265 return ((Number) o).floatValue(); 266 } 267 268 public double getDouble(String columnLabel) throws SQLException { 269 Object o = getColumn(columnLabel); 270 return ((Number) o).doubleValue(); 271 } 272 273 public BigDecimal getBigDecimal( 274 String columnLabel, int scale) throws SQLException 275 { 276 throw new UnsupportedOperationException(); 277 } 278 279 public byte[] getBytes(String columnLabel) throws SQLException { 280 Object o = getColumn(columnLabel); 281 return (byte[]) o; 282 } 283 284 public Date getDate(String columnLabel) throws SQLException { 285 Object o = getColumn(columnLabel); 286 return (Date) o; 287 } 288 289 public Time getTime(String columnLabel) throws SQLException { 290 Object o = getColumn(columnLabel); 291 return (Time) o; 292 } 293 294 public Timestamp getTimestamp(String columnLabel) throws SQLException { 295 Object o = getColumn(columnLabel); 296 return (Timestamp) o; 297 } 298 299 public InputStream getAsciiStream(String columnLabel) throws SQLException { 300 throw new UnsupportedOperationException(); 301 } 302 303 public InputStream getUnicodeStream(String columnLabel) throws SQLException 304 { 305 throw new UnsupportedOperationException(); 306 } 307 308 public InputStream getBinaryStream(String columnLabel) throws SQLException { 309 throw new UnsupportedOperationException(); 310 } 311 312 public SQLWarning getWarnings() throws SQLException { 313 throw new UnsupportedOperationException(); 314 } 315 316 public void clearWarnings() throws SQLException { 317 throw new UnsupportedOperationException(); 318 } 319 320 public String getCursorName() throws SQLException { 321 throw new UnsupportedOperationException(); 322 } 323 324 public ResultSetMetaData getMetaData() throws SQLException { 325 return metaData; 326 } 327 328 public Object getObject(int columnIndex) throws SQLException { 329 throw new UnsupportedOperationException(); 330 } 331 332 public Object getObject(String columnLabel) throws SQLException { 333 throw new UnsupportedOperationException(); 334 } 335 336 public int findColumn(String columnLabel) throws SQLException { 337 throw new UnsupportedOperationException(); 338 } 339 340 public Reader getCharacterStream(int columnIndex) throws SQLException { 341 throw new UnsupportedOperationException(); 342 } 343 344 public Reader getCharacterStream(String columnLabel) throws SQLException { 345 throw new UnsupportedOperationException(); 346 } 347 348 public BigDecimal getBigDecimal(int columnIndex) throws SQLException { 349 throw new UnsupportedOperationException(); 350 } 351 352 public BigDecimal getBigDecimal(String columnLabel) throws SQLException { 353 throw new UnsupportedOperationException(); 354 } 355 356 public boolean isBeforeFirst() throws SQLException { 357 return rowOrdinal < 0; 358 } 359 360 public boolean isAfterLast() throws SQLException { 361 return rowOrdinal >= rowList.size(); 362 } 363 364 public boolean isFirst() throws SQLException { 365 return rowOrdinal == 0; 366 } 367 368 public boolean isLast() throws SQLException { 369 return rowOrdinal == rowList.size() - 1; 370 } 371 372 public void beforeFirst() throws SQLException { 373 rowOrdinal = -1; 374 } 375 376 public void afterLast() throws SQLException { 377 rowOrdinal = rowList.size(); 378 } 379 380 public boolean first() throws SQLException { 381 if (rowList.size() == 0) { 382 return false; 383 } else { 384 rowOrdinal = 0; 385 return true; 386 } 387 } 388 389 public boolean last() throws SQLException { 390 if (rowList.size() == 0) { 391 return false; 392 } else { 393 rowOrdinal = rowList.size() - 1; 394 return true; 395 } 396 } 397 398 public int getRow() throws SQLException { 399 return rowOrdinal + 1; // 1-based 400 } 401 402 public boolean absolute(int row) throws SQLException { 403 int newRowOrdinal = row - 1;// convert to 0-based 404 if (newRowOrdinal >= 0 && newRowOrdinal < rowList.size()) { 405 rowOrdinal = newRowOrdinal; 406 return true; 407 } else { 408 return false; 409 } 410 } 411 412 public boolean relative(int rows) throws SQLException { 413 int newRowOrdinal = rowOrdinal + (rows - 1); 414 if (newRowOrdinal >= 0 && newRowOrdinal < rowList.size()) { 415 rowOrdinal = newRowOrdinal; 416 return true; 417 } else { 418 return false; 419 } 420 } 421 422 public boolean previous() throws SQLException { 423 // converse of next(); note that if rowOrdinal == 0, we decrement 424 // but return false 425 if (rowOrdinal >= 0) { 426 --rowOrdinal; 427 } 428 return rowOrdinal >= 0; 429 } 430 431 public void setFetchDirection(int direction) throws SQLException { 432 throw new UnsupportedOperationException(); 433 } 434 435 public int getFetchDirection() throws SQLException { 436 throw new UnsupportedOperationException(); 437 } 438 439 public void setFetchSize(int rows) throws SQLException { 440 throw new UnsupportedOperationException(); 441 } 442 443 public int getFetchSize() throws SQLException { 444 throw new UnsupportedOperationException(); 445 } 446 447 public int getType() throws SQLException { 448 throw new UnsupportedOperationException(); 449 } 450 451 public int getConcurrency() throws SQLException { 452 throw new UnsupportedOperationException(); 453 } 454 455 public boolean rowUpdated() throws SQLException { 456 throw new UnsupportedOperationException(); 457 } 458 459 public boolean rowInserted() throws SQLException { 460 throw new UnsupportedOperationException(); 461 } 462 463 public boolean rowDeleted() throws SQLException { 464 throw new UnsupportedOperationException(); 465 } 466 467 public void updateNull(int columnIndex) throws SQLException { 468 throw new UnsupportedOperationException(); 469 } 470 471 public void updateBoolean(int columnIndex, boolean x) throws SQLException { 472 throw new UnsupportedOperationException(); 473 } 474 475 public void updateByte(int columnIndex, byte x) throws SQLException { 476 throw new UnsupportedOperationException(); 477 } 478 479 public void updateShort(int columnIndex, short x) throws SQLException { 480 throw new UnsupportedOperationException(); 481 } 482 483 public void updateInt(int columnIndex, int x) throws SQLException { 484 throw new UnsupportedOperationException(); 485 } 486 487 public void updateLong(int columnIndex, long x) throws SQLException { 488 throw new UnsupportedOperationException(); 489 } 490 491 public void updateFloat(int columnIndex, float x) throws SQLException { 492 throw new UnsupportedOperationException(); 493 } 494 495 public void updateDouble(int columnIndex, double x) throws SQLException { 496 throw new UnsupportedOperationException(); 497 } 498 499 public void updateBigDecimal( 500 int columnIndex, BigDecimal x) throws SQLException 501 { 502 throw new UnsupportedOperationException(); 503 } 504 505 public void updateString(int columnIndex, String x) throws SQLException { 506 throw new UnsupportedOperationException(); 507 } 508 509 public void updateBytes(int columnIndex, byte x[]) throws SQLException { 510 throw new UnsupportedOperationException(); 511 } 512 513 public void updateDate(int columnIndex, Date x) throws SQLException { 514 throw new UnsupportedOperationException(); 515 } 516 517 public void updateTime(int columnIndex, Time x) throws SQLException { 518 throw new UnsupportedOperationException(); 519 } 520 521 public void updateTimestamp( 522 int columnIndex, Timestamp x) throws SQLException 523 { 524 throw new UnsupportedOperationException(); 525 } 526 527 public void updateAsciiStream( 528 int columnIndex, InputStream x, int length) throws SQLException 529 { 530 throw new UnsupportedOperationException(); 531 } 532 533 public void updateBinaryStream( 534 int columnIndex, InputStream x, int length) throws SQLException 535 { 536 throw new UnsupportedOperationException(); 537 } 538 539 public void updateCharacterStream( 540 int columnIndex, Reader x, int length) throws SQLException 541 { 542 throw new UnsupportedOperationException(); 543 } 544 545 public void updateObject( 546 int columnIndex, Object x, int scaleOrLength) throws SQLException 547 { 548 throw new UnsupportedOperationException(); 549 } 550 551 public void updateObject(int columnIndex, Object x) throws SQLException { 552 throw new UnsupportedOperationException(); 553 } 554 555 public void updateNull(String columnLabel) throws SQLException { 556 throw new UnsupportedOperationException(); 557 } 558 559 public void updateBoolean( 560 String columnLabel, boolean x) throws SQLException 561 { 562 throw new UnsupportedOperationException(); 563 } 564 565 public void updateByte(String columnLabel, byte x) throws SQLException { 566 throw new UnsupportedOperationException(); 567 } 568 569 public void updateShort(String columnLabel, short x) throws SQLException { 570 throw new UnsupportedOperationException(); 571 } 572 573 public void updateInt(String columnLabel, int x) throws SQLException { 574 throw new UnsupportedOperationException(); 575 } 576 577 public void updateLong(String columnLabel, long x) throws SQLException { 578 throw new UnsupportedOperationException(); 579 } 580 581 public void updateFloat(String columnLabel, float x) throws SQLException { 582 throw new UnsupportedOperationException(); 583 } 584 585 public void updateDouble(String columnLabel, double x) throws SQLException { 586 throw new UnsupportedOperationException(); 587 } 588 589 public void updateBigDecimal( 590 String columnLabel, BigDecimal x) throws SQLException 591 { 592 throw new UnsupportedOperationException(); 593 } 594 595 public void updateString(String columnLabel, String x) throws SQLException { 596 throw new UnsupportedOperationException(); 597 } 598 599 public void updateBytes(String columnLabel, byte x[]) throws SQLException { 600 throw new UnsupportedOperationException(); 601 } 602 603 public void updateDate(String columnLabel, Date x) throws SQLException { 604 throw new UnsupportedOperationException(); 605 } 606 607 public void updateTime(String columnLabel, Time x) throws SQLException { 608 throw new UnsupportedOperationException(); 609 } 610 611 public void updateTimestamp( 612 String columnLabel, Timestamp x) throws SQLException 613 { 614 throw new UnsupportedOperationException(); 615 } 616 617 public void updateAsciiStream( 618 String columnLabel, InputStream x, int length) throws SQLException 619 { 620 throw new UnsupportedOperationException(); 621 } 622 623 public void updateBinaryStream( 624 String columnLabel, InputStream x, int length) throws SQLException 625 { 626 throw new UnsupportedOperationException(); 627 } 628 629 public void updateCharacterStream( 630 String columnLabel, Reader reader, int length) throws SQLException 631 { 632 throw new UnsupportedOperationException(); 633 } 634 635 public void updateObject( 636 String columnLabel, Object x, int scaleOrLength) throws SQLException 637 { 638 throw new UnsupportedOperationException(); 639 } 640 641 public void updateObject(String columnLabel, Object x) throws SQLException { 642 throw new UnsupportedOperationException(); 643 } 644 645 public void insertRow() throws SQLException { 646 throw new UnsupportedOperationException(); 647 } 648 649 public void updateRow() throws SQLException { 650 throw new UnsupportedOperationException(); 651 } 652 653 public void deleteRow() throws SQLException { 654 throw new UnsupportedOperationException(); 655 } 656 657 public void refreshRow() throws SQLException { 658 throw new UnsupportedOperationException(); 659 } 660 661 public void cancelRowUpdates() throws SQLException { 662 throw new UnsupportedOperationException(); 663 } 664 665 public void moveToInsertRow() throws SQLException { 666 throw new UnsupportedOperationException(); 667 } 668 669 public void moveToCurrentRow() throws SQLException { 670 throw new UnsupportedOperationException(); 671 } 672 673 public Statement getStatement() throws SQLException { 674 throw new UnsupportedOperationException(); 675 } 676 677 public Object getObject( 678 int columnIndex, Map<String, Class<?>> map) throws SQLException 679 { 680 throw new UnsupportedOperationException(); 681 } 682 683 public Ref getRef(int columnIndex) throws SQLException { 684 throw new UnsupportedOperationException(); 685 } 686 687 public Blob getBlob(int columnIndex) throws SQLException { 688 throw new UnsupportedOperationException(); 689 } 690 691 public Clob getClob(int columnIndex) throws SQLException { 692 throw new UnsupportedOperationException(); 693 } 694 695 public Array getArray(int columnIndex) throws SQLException { 696 throw new UnsupportedOperationException(); 697 } 698 699 public Object getObject( 700 String columnLabel, Map<String, Class<?>> map) throws SQLException 701 { 702 throw new UnsupportedOperationException(); 703 } 704 705 public Ref getRef(String columnLabel) throws SQLException { 706 throw new UnsupportedOperationException(); 707 } 708 709 public Blob getBlob(String columnLabel) throws SQLException { 710 throw new UnsupportedOperationException(); 711 } 712 713 public Clob getClob(String columnLabel) throws SQLException { 714 throw new UnsupportedOperationException(); 715 } 716 717 public Array getArray(String columnLabel) throws SQLException { 718 throw new UnsupportedOperationException(); 719 } 720 721 public Date getDate(int columnIndex, Calendar cal) throws SQLException { 722 throw new UnsupportedOperationException(); 723 } 724 725 public Date getDate(String columnLabel, Calendar cal) throws SQLException { 726 throw new UnsupportedOperationException(); 727 } 728 729 public Time getTime(int columnIndex, Calendar cal) throws SQLException { 730 throw new UnsupportedOperationException(); 731 } 732 733 public Time getTime(String columnLabel, Calendar cal) throws SQLException { 734 throw new UnsupportedOperationException(); 735 } 736 737 public Timestamp getTimestamp( 738 int columnIndex, Calendar cal) throws SQLException 739 { 740 throw new UnsupportedOperationException(); 741 } 742 743 public Timestamp getTimestamp( 744 String columnLabel, Calendar cal) throws SQLException 745 { 746 throw new UnsupportedOperationException(); 747 } 748 749 public URL getURL(int columnIndex) throws SQLException { 750 throw new UnsupportedOperationException(); 751 } 752 753 public URL getURL(String columnLabel) throws SQLException { 754 throw new UnsupportedOperationException(); 755 } 756 757 public void updateRef(int columnIndex, Ref x) throws SQLException { 758 throw new UnsupportedOperationException(); 759 } 760 761 public void updateRef(String columnLabel, Ref x) throws SQLException { 762 throw new UnsupportedOperationException(); 763 } 764 765 public void updateBlob(int columnIndex, Blob x) throws SQLException { 766 throw new UnsupportedOperationException(); 767 } 768 769 public void updateBlob(String columnLabel, Blob x) throws SQLException { 770 throw new UnsupportedOperationException(); 771 } 772 773 public void updateClob(int columnIndex, Clob x) throws SQLException { 774 throw new UnsupportedOperationException(); 775 } 776 777 public void updateClob(String columnLabel, Clob x) throws SQLException { 778 throw new UnsupportedOperationException(); 779 } 780 781 public void updateArray(int columnIndex, Array x) throws SQLException { 782 throw new UnsupportedOperationException(); 783 } 784 785 public void updateArray(String columnLabel, Array x) throws SQLException { 786 throw new UnsupportedOperationException(); 787 } 788 789 // implement Wrapper 790 791 public <T> T unwrap(Class<T> iface) throws SQLException { 792 if (iface.isInstance(this)) { 793 return iface.cast(this); 794 } 795 throw olap4jConnection.helper.createException("cannot cast"); 796 } 797 798 public boolean isWrapperFor(Class<?> iface) throws SQLException { 799 return iface.isInstance(this); 800 } 801} 802 803// End EmptyResultSet.java