| 1 25 26 package org.objectweb.cjdbc.driver; 27 28 import java.io.ByteArrayInputStream ; 29 import java.io.IOException ; 30 import java.io.InputStream ; 31 import java.io.NotSerializableException ; 32 import java.io.ObjectInputStream ; 33 import java.math.BigDecimal ; 34 import java.math.BigInteger ; 35 import java.net.URL ; 36 import java.sql.PreparedStatement ; 37 import java.sql.Ref ; 38 import java.sql.ResultSet ; 39 import java.sql.SQLException ; 40 import java.sql.SQLWarning ; 41 import java.sql.Time ; 42 import java.sql.Timestamp ; 43 import java.util.ArrayList ; 44 import java.util.Calendar ; 45 import java.util.Hashtable ; 46 import java.util.Iterator ; 47 48 import org.objectweb.cjdbc.common.exceptions.NotImplementedException; 49 import org.objectweb.cjdbc.common.exceptions.ProtocolException; 50 import org.objectweb.cjdbc.common.stream.CJDBCInputStream; 51 import org.objectweb.cjdbc.common.stream.CJDBCOutputStream; 52 import org.objectweb.cjdbc.driver.protocol.SQLDataSerialization; 53 import org.objectweb.cjdbc.driver.protocol.TypeTag; 54 55 108 public class DriverResultSet 109 implements 110 java.sql.ResultSet , 111 java.io.Serializable , 112 java.lang.Cloneable  113 { 114 private static final long serialVersionUID = 7408879935608629886L; 115 116 117 protected int currentRow = -1; 118 119 protected int nbOfRows = -1; 120 121 protected int nbOfColumns = -1; 122 123 protected ArrayList data; 124 125 private boolean hasMoreData; 126 127 protected int fetchDirection = FETCH_FORWARD; 128 129 protected int fetchSize = 0; 130 131 private String cursorName; 132 133 134 protected Field[] fields; 135 136 137 private SQLDataSerialization.Serializer[] serializers; 138 139 140 protected boolean wasNullFlag = false; 141 142 protected transient Hashtable columnNameToIndex = null; 143 144 protected transient Hashtable fullColumnNameToIndex = null; 145 146 147 protected int resultSetType = 0; 148 149 protected int resultSetConcurrency = 0; 150 151 protected SQLWarning warnings = null; 152 153 protected transient Statement owningStatement; 154 155 private final Connection connection; 156 157 private boolean isClosed = true; 158 159 160 private transient PreparedStatement deleteStatement = null; 161 162 private transient PreparedStatement insertStatement = null; 163 164 private transient PreparedStatement refreshStatement = null; 165 166 private transient PreparedStatement updateStatement = null; 167 168 private transient boolean inserting = false; 169 170 private transient boolean updating = false; 171 172 private transient Object [] tempRow = null; 173 174 private transient String [] primaryKeyColumns = null; 175 176 private static final String UPDATEABLE_MESSAGE = "ResultSet not updateable. The " 177 + "query that generated this result set must select only one table, and must " 178 + "select all primary keys from that table. See the JDBC 2.1 API Specification, " 179 + "section 5.6 for more details."; 180 181 185 197 public boolean next() throws java.sql.SQLException  198 { 199 checkIfClosed(); 200 201 if (inserting) 202 { 203 insertStatement.clearParameters(); 204 tempRow = null; 205 inserting = false; 206 } 207 208 if (updating) 209 cancelRowUpdates(); 210 211 if (nbOfRows == 0) 212 return false; 213 214 if (currentRow + 1 >= nbOfRows) 215 { 216 if (hasMoreData) 217 { 218 this.connection.fetchNextData(cursorName, fetchSize, this); 219 currentRow = 0; 220 if (data == null) 221 { 222 nbOfRows = 0; 223 return false; 224 } 225 else 226 { 227 nbOfRows = data.size(); 228 return true; 229 } 230 } 231 232 currentRow = nbOfRows; 234 return false; 235 } 236 237 clearWarnings(); 238 currentRow++; 239 return true; 240 } 241 242 254 public boolean prev() throws SQLException  255 { 256 checkIfClosed(); 257 258 if (inserting) 259 { 260 insertStatement.clearParameters(); 261 tempRow = null; 262 inserting = false; 263 } 264 265 if (updating) 266 cancelRowUpdates(); 267 268 if (currentRow - 1 >= 0) 269 { 270 currentRow--; 271 return true; 272 } 273 274 return false; 275 } 276 277 287 public boolean isBeforeFirst() throws SQLException  288 { 289 checkIfClosed(); 290 if (nbOfRows == 0) 291 return false; 292 else 293 return (currentRow == -1); 294 } 295 296 306 public boolean isAfterLast() throws SQLException  307 { 308 checkIfClosed(); 309 if (nbOfRows == 0) 310 return false; 311 else 312 return (currentRow >= nbOfRows); 313 } 314 315 324 public boolean isFirst() throws SQLException  325 { 326 checkIfClosed(); 327 if (nbOfRows == 0) 328 return false; 329 else 330 return (currentRow == 0); 331 } 332 333 345 public boolean isLast() throws SQLException  346 { 347 checkIfClosed(); 348 if (nbOfRows == 0) 349 return false; 350 else 351 return (currentRow == nbOfRows - 1); 352 } 353 354 363 public void beforeFirst() throws SQLException  364 { 365 checkIfClosed(); 366 367 if (inserting) 368 { 369 insertStatement.clearParameters(); 370 tempRow = null; 371 inserting = false; 372 } 373 374 if (updating) 375 cancelRowUpdates(); 376 377 currentRow = -1; 378 } 379 380 389 public void afterLast() throws SQLException  390 { 391 checkIfClosed(); 392 393 if (inserting) 394 { 395 insertStatement.clearParameters(); 396 tempRow = null; 397 inserting = false; 398 } 399 400 if (updating) 401 cancelRowUpdates(); 402 403 if (nbOfRows != 0) 404 currentRow = nbOfRows; 405 } 406 407 417 public boolean first() throws SQLException  418 { 419 checkIfClosed(); 420 421 if (inserting) 422 { 423 insertStatement.clearParameters(); 424 tempRow = null; 425 inserting = false; 426 } 427 428 if (updating) 429 cancelRowUpdates(); 430 431 if (nbOfRows == 0) 432 return false; 433 434 currentRow = 0; 435 return true; 436 } 437 438 448 public boolean last() throws SQLException  449 { 450 checkIfClosed(); 451 452 if (inserting) 453 { 454 insertStatement.clearParameters(); 455 tempRow = null; 456 inserting = false; 457 } 458 459 if (updating) 460 cancelRowUpdates(); 461 462 if (nbOfRows == 0) 463 return false; 464 465 currentRow = nbOfRows - 1; 466 return true; 467 } 468 469 478 public int getRow() throws SQLException  479 { 480 checkIfClosed(); 481 if (currentRow < 0 || currentRow >= nbOfRows || nbOfRows == 0) 482 return 0; 483 else 484 return currentRow + 1; 485 } 486 487 510 public boolean absolute(int row) throws SQLException  511 { 512 checkIfClosed(); 513 514 if (inserting) 515 { 516 insertStatement.clearParameters(); 517 tempRow = null; 518 inserting = false; 519 } 520 521 if (updating) 522 cancelRowUpdates(); 523 524 if (nbOfRows == 0) 525 return false; 526 527 if (row == 0) 528 throw new SQLException ("Cannot absolute position to row 0"); 529 530 if (row == 1) 531 return first(); 532 533 if (row == -1) 534 return last(); 535 536 if (row > nbOfRows) 537 { 538 afterLast(); 539 return false; 540 } 541 542 if (row < 0) 543 { int newRowPosition = nbOfRows + row + 1; 545 546 if (newRowPosition <= 0) 547 { 548 beforeFirst(); 549 return false; 550 } 551 552 return absolute(newRowPosition); 553 } 554 else 555 { 556 row--; currentRow = row; 558 return true; 559 } 560 } 561 562 580 public boolean relative(int rows) throws SQLException  581 { 582 checkIfClosed(); 583 584 if (inserting) 585 { 586 insertStatement.clearParameters(); 587 tempRow = null; 588 inserting = false; 589 } 590 591 if (updating) 592 cancelRowUpdates(); 593 594 if (nbOfRows == 0) 595 return false; 596 597 return absolute(currentRow + rows + 1); 598 } 599 600 612 public boolean previous() throws SQLException  613 { 614 return prev(); 615 } 616 617 629 public void setFetchDirection(int direction) throws SQLException  630 { 631 if (direction != FETCH_FORWARD && direction != FETCH_REVERSE) 632 throw new SQLException ("Illegal value for fetch direction"); 633 else 634 fetchDirection = direction; 635 } 636 637 643 public int getFetchDirection() throws SQLException  644 { 645 return fetchDirection; 646 } 647 648 661 public void setFetchSize(int rows) throws SQLException  662 { 663 if (rows < 0) 666 throw new SQLException ("Value must be between 0 and getMaxRows()"); 667 668 fetchSize = rows; 669 } 670 671 677 public int getFetchSize() throws SQLException  678 { 679 return fetchSize; 680 } 681 682 688 695 public String getString(int columnIndex) throws SQLException  696 { 697 checkRowAndColPosAndSetNullFlag(columnIndex); 698 699 if (wasNullFlag) 700 return null; 701 702 if (inserting || updating) 703 return tempRow[columnIndex - 1].toString(); 704 else 705 return (((Object []) data.get(currentRow))[columnIndex - 1]).toString(); 706 } 707 708 715 public boolean getBoolean(int columnIndex) throws SQLException  716 { 717 checkRowAndColPosAndSetNullFlag(columnIndex); 718 719 if (wasNullFlag) 720 return false; 721 722 Object object; 723 if (inserting || updating) 724 object = tempRow[columnIndex - 1]; 725 else 726 object = (((Object []) data.get(currentRow))[columnIndex - 1]); 727 728 String stringVal = object.toString(); 729 if ((stringVal != null) && (stringVal.length() > 0)) 730 { 731 stringVal = stringVal.toLowerCase(); 732 733 if (this.connection.getPreparedStatementBooleanTrue().equals( 735 stringVal)) 736 { 737 return true; 738 } 739 else if (this.connection.getPreparedStatementBooleanFalse() 740 .equals(stringVal)) 741 { 742 return false; 743 } 744 745 else if ("t".equals(stringVal)) 747 { 748 return true; 749 } 750 else if ("f".equals(stringVal)) 751 { 752 return false; 753 } 754 else if ("true".equals(stringVal)) 755 { 756 return true; 757 } 758 else if ("false".equals(stringVal)) 759 { 760 return false; 761 } 762 else if ("1".equals(stringVal)) 763 { 764 return true; 765 } 766 else if ("0".equals(stringVal)) 767 { 768 return false; 769 } 770 else if ("y".equals(stringVal)) 771 { 772 return true; 773 } 774 else if ("n".equals(stringVal)) 775 { 776 return false; 777 } 778 else if ("yes".equals(stringVal)) 779 { 780 return true; 781 } 782 else if ("no".equals(stringVal)) 783 { 784 return false; 785 } 786 else if (object instanceof Number ) 787 { 788 int value = ((Number ) object).intValue(); 789 if (value == 0) 790 return false; 791 else if (value == 1) 792 return true; 793 } 795 796 throw new SQLException ("column value " + stringVal 798 + " could not be converted to boolean"); 799 } 800 else 801 { 802 return false; 803 } 804 } 805 806 813 public short getShort(int columnIndex) throws SQLException  814 { 815 checkRowAndColPosAndSetNullFlag(columnIndex); 816 817 if (wasNullFlag) 818 return 0; 819 820 Object obj; 821 if (inserting || updating) 822 obj = tempRow[columnIndex - 1]; 823 else 824 obj = ((Object []) data.get(currentRow))[columnIndex - 1]; 825 826 if (obj instanceof Number ) 827 { 828 return ((Number ) obj).shortValue(); 829 } 830 831 try 833 { 834 String string = obj.toString(); 835 string = string.trim(); 836 return Short.parseShort(string); 837 } 838 catch (NumberFormatException e) 839 { 840 throw new SQLException ("the value " + obj.toString() 841 + " is not a valid short number"); 842 } 843 } 844 845 852 public int getInt(int columnIndex) throws SQLException  853 { 854 checkRowAndColPosAndSetNullFlag(columnIndex); 855 856 if (wasNullFlag) 857 return 0; 858 859 Object obj; 860 if (inserting || updating) 861 obj = tempRow[columnIndex - 1]; 862 else 863 obj = ((Object []) data.get(currentRow))[columnIndex - 1]; 864 865 if (obj instanceof Number ) 866 { 867 return ((Number ) obj).intValue(); 868 } 869 870 try 872 { 873 String string = obj.toString(); 874 string = string.trim(); 875 return Integer.parseInt(string); 876 } 877 catch (NumberFormatException e) 878 { 879 throw new SQLException ("the value " + obj.toString() 880 + " is not a valid int number"); 881 } 882 } 883 884 891 public long getLong(int columnIndex) throws SQLException  892 { 893 checkRowAndColPosAndSetNullFlag(columnIndex); 894 895 if (wasNullFlag) 896 return 0; 897 898 Object obj; 899 if (inserting || updating) 900 obj = tempRow[columnIndex - 1]; 901 else 902 obj = ((Object []) data.get(currentRow))[columnIndex - 1]; 903 904 if (obj instanceof Number ) 905 { 906 return ((Number ) obj).longValue(); 907 } 908 909 try 911 { 912 String string = obj.toString(); 913 string = string.trim(); 914 return Long.parseLong(string); 915 } 916 catch (NumberFormatException e) 917 { 918 throw new SQLException ("the value " + obj.toString() 919 + " is not a valid long number"); 920 } 921 } 922 923 930 public float getFloat(int columnIndex) throws SQLException  931 { 932 checkRowAndColPosAndSetNullFlag(columnIndex); 933 934 if (wasNullFlag) 935 return 0; 936 937 Object obj; 938 if (inserting || updating) 939 obj = tempRow[columnIndex - 1]; 940 else 941 obj = ((Object []) data.get(currentRow))[columnIndex - 1]; 942 943 if (obj instanceof Number ) 944 { 945 return ((Number ) obj).floatValue(); 946 } 947 948 try 950 { 951 String string = obj.toString(); 952 string = string.trim(); 953 return Float.parseFloat(string); 954 } 955 catch (NumberFormatException e) 956 { 957 throw new SQLException ("the value " + obj.toString() 958 + " is not a valid float number"); 959 } 960 } 961 962 969 public double getDouble(int columnIndex) throws SQLException  970 { 971 checkRowAndColPosAndSetNullFlag(columnIndex); 972 973 if (wasNullFlag) 974 return 0; 975 976 Object obj; 977 if (inserting || updating) 978 obj = tempRow[columnIndex - 1]; 979 else 980 obj = ((Object []) data.get(currentRow))[columnIndex - 1]; 981 982 if (obj instanceof Number ) 983 { 984 return ((Number ) obj).doubleValue(); 985 } 986 987 try 989 { 990 String string = obj.toString(); 991 string = string.trim(); 992 return Double.parseDouble(string); 993 } 994 catch (NumberFormatException e) 995 { 996 throw new SQLException ("the value " + obj.toString() 997 + " is not a valid double number"); 998 } 999 } 1000 1001 |