All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src-main.org.awakefw.sql.jdbc.ResultSetHttp Maven / Gradle / Ivy

Go to download

Awake SQL is an open source framework that allows remote and secure JDBC access through HTTP.

The newest version!
/*
 * This file is part of Awake SQL. 
 * Awake SQL: Remote JDBC access over HTTP.                                    
 * Copyright (C) 2013,  KawanSoft SAS
 * (http://www.kawansoft.com). All rights reserved.                    
 *                                                                         
 * Awake SQL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.         
 *              
 * Awake SQL is distributed in the hope that it will be useful,               
 * but WITHOUT ANY WARRANTY; without even the implied warranty of                
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU          
 * Lesser General Public License for more details.       
 *                                  
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see .
 *
 * If you develop commercial activities using Awake SQL, you must: 
 * a) disclose and distribute all source code of your own product,
 * b) license your own product under the GNU General Public License.
 * 
 * You can be released from the requirements of the license by
 * purchasing a commercial license. Buying such a license will allow you 
 * to ship Awake SQL with your closed source products without disclosing 
 * the source code.
 *
 * For more information, please contact KawanSoft SAS at this
 * address: [email protected]
 * 
 * Any modifications to this file must keep this entire header
 * intact.
 */
package org.awakefw.sql.jdbc;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.awakefw.commons.api.client.AwakeProgressManager;
import org.awakefw.commons.api.client.HttpProtocolParameters;
import org.awakefw.commons.jdbc.abstracts.AbstractResultSet;
import org.awakefw.file.api.client.AwakeFileSession;
import org.awakefw.file.api.util.AwakeDebug;
import org.awakefw.file.api.util.HtmlConverter;
import org.awakefw.file.util.AwakeClientLogger;
import org.awakefw.file.util.AwakeFileUtil;
import org.awakefw.file.util.KeepTempFilePolicyParms;
import org.awakefw.file.util.Tag;
import org.awakefw.sql.jdbc.http.JdbcHttpStatementTransfer;
import org.awakefw.sql.jdbc.http.JdbcHttpTransferUtil;
import org.awakefw.sql.jdbc.util.ColPositionBuilder;
import org.awakefw.sql.jdbc.util.FileBackedListRs;
import org.awakefw.sql.jdbc.util.JsonLineDecryptor;
import org.awakefw.sql.jdbc.util.ResultSetFileSplitter;
import org.awakefw.sql.json.StatementHolder;
import org.awakefw.sql.json.no_obfuscation.ResultSetMetaDataHolder;
import org.awakefw.sql.json.no_obfuscation.ResultSetMetaDataHolderTransport;
import org.awakefw.sql.transport.ArrayTransporter;
import org.awakefw.sql.transport.RowIdTransporter;
import org.awakefw.sql.transport.TransportConverter;
import org.awakefw.sql.transport.UrlTransporter;
import org.awakefw.sql.util.crypto.StatementHolderCrypto;

/**
 * ResultSet Wrapper. 
* Implements all the ResultSet methods. Usage is exactly the same as a * ResultSet. * */ public class ResultSetHttp extends AbstractResultSet implements ResultSet { private static final String HTML_DECODED = ".html-decoded.txt"; /** Debug flag */ private static boolean DEBUG = AwakeDebug.isSet(ResultSetHttp.class); /** Universal and clean line separator */ private static String CR_LF = System.getProperty("line.separator"); /** The HttpConnection in use */ private ConnectionHttp connectionHttp = null; /** * The holder that contains the sql order and the list if (parameter type, * parameter value ) for prepared statements **/ private StatementHolder statementHolder = null; /** * The original Statement associated to the Result Set (maybe null for * Metadata calls) */ private Statement statement = null; /** The list of files to delete at close */ private List localFiles = new Vector(); /** The result set type. Defaults to ResultSet.TYPE_FORWARD_ONLY */ private int resultSetType = ResultSet.TYPE_FORWARD_ONLY; /** The result set concurrency. Defaults to CONCUR_READ_ONLY */ private int resultSetConcurrency = ResultSet.CONCUR_READ_ONLY; /** The result set holdability. Defaults to CLOSE_CURSORS_AT_COMMIT */ private int resultSetHoldability = ResultSet.CLOSE_CURSORS_AT_COMMIT; /** The map of (Column Name, Column Position) */ private Map colPosition = null; /** The List of column values for 1 result set row */ // private List> list = null; private List> list = null; /** The cursor of the current row */ private int cursor = 0; /** Says if the last accessed value was null */ private boolean wasNull = false; /** * Method name if, we want to to a ResultSet.getMetaData() on the ResultSet * produced by a Connection.getMetaData() */ @SuppressWarnings("unused") private String MetaDataMethodName = null; /** Parms of the MetaDataMethodName */ @SuppressWarnings("unused") private Object[] MetaDataMethodParams = null; /** * The file that contains the MetaData of the Result Set prodcued by a * getMetaData function */ private File rsMetaDataFile = null; /** * Constructor when building the ResultSet from a getMetaData function. * Allows to use directly a getMetaData() on the ResultSet without a new * call on server * * @param connectionHttp * The Http Connection * @param rsAndMetaDataFile * the result file that contains both the ResultSet and it's * MetaData * @param metaDataMethodName * The method name that produced the result set * @param metaDataMethodParams * The parameters of the method */ public ResultSetHttp(ConnectionHttp connectionHttp, String metaDataMethodName, File rsAndMetaDataFile, Object... metaDataMethodParams) throws SQLException { if (connectionHttp == null) { String message = Tag.AWAKE_PRODUCT_FAIL + "connectionHttp can not be null!"; throw new SQLException(message, new IOException(message)); } if (rsAndMetaDataFile == null) { String message = Tag.AWAKE_PRODUCT_FAIL + "Result Set as String can not be null!"; throw new SQLException(message, new IOException(message)); } this.connectionHttp = connectionHttp; this.MetaDataMethodName = metaDataMethodName; this.MetaDataMethodParams = metaDataMethodParams; resultSetType = ResultSet.TYPE_SCROLL_INSENSITIVE; // Split the result file into two files: 1) ResultSet itself 2) // ResultSet.getMetaData ResultSetFileSplitter resultSetFileSplitter = new ResultSetFileSplitter( rsAndMetaDataFile); File rsFile = resultSetFileSplitter.getResultSetFile(); rsMetaDataFile = resultSetFileSplitter.getMetaDataFile(); debug("rsAndMetaDataFile: " + rsAndMetaDataFile); debug("rsFile : " + rsMetaDataFile); debug("rsMetaDataFile : " + rsMetaDataFile); // Build the column position map: ColPositionBuilder colPositionBuilder = new ColPositionBuilder(rsFile, connectionHttp); colPosition = colPositionBuilder.getColPosition(); // Build the List of Strings list = new FileBackedListRs>(rsFile, connectionHttp); } /** * Constructor * * @param connectionHttp * The Http Connection * @param statementHolder * The holder that contains the sql order and the list if * (parameter type, parameter value ) for prepared statements. * (May be null for DatabaseMetaData.method calls) * @param statement * @param rsFile * the Result Set as a file:
* - one {columnName1=value2, columnName2=value2, ... * columnNamei=valuei} per line * @param connection * the Jdbc Connection * */ public ResultSetHttp(ConnectionHttp connectionHttp, StatementHolder statementHolder, Statement statement, File rsFile) throws SQLException { if (connectionHttp == null) { String message = Tag.AWAKE_PRODUCT_FAIL + "connectionHttp can not be null!"; throw new SQLException(message, new IOException(message)); } if (rsFile == null) { String message = Tag.AWAKE_PRODUCT_FAIL + "Result Set as String can not be null!"; throw new SQLException(message, new IOException(message)); } this.connectionHttp = connectionHttp; this.statementHolder = statementHolder; this.statement = statement; if (statementHolder != null) { this.resultSetType = statementHolder.getResultSetType(); this.resultSetConcurrency = statementHolder .getResultSetConcurrency(); this.resultSetHoldability = statementHolder .getResultSetConcurrency(); } // Build the column position map: ColPositionBuilder colPositionBuilder = new ColPositionBuilder(rsFile, connectionHttp); colPosition = colPositionBuilder.getColPosition(); // Build the List of Strings // list = new FileBackedListOfMaps>(rsFile); list = new FileBackedListRs>(rsFile, connectionHttp); } /* * (non-Javadoc) * * @see org.awakefw.sql.jdbc.abstracts.AbstractResultSet#getStatement() */ @Override public Statement getStatement() throws SQLException { return statement; } /** * Get the value of the column using the map inside the List * * @param columnIndex * the first column is 1, the second is 2, ... * @boolean isString if true, the returned value is a String ==> Parse it to remove * special characters ! * @return the value of the column using the map inside the List * * @throws SQLException */ private String getValueOfList(int columnIndex, boolean isString) throws SQLException { if (isBeforeFirst() || isAfterLast()) { throw new SQLException( "The ResultSet is not positioned properly, you may need to call next()"); } List theRow = list.get(cursor - 1); if (theRow == null) { String message = Tag.AWAKE_PRODUCT_FAIL + "No value found in List theRow."; throw new SQLException(message, new IOException(message)); } String value = null; int listIndex = columnIndex - 1; try { value = theRow.get(listIndex); } catch (Exception e) { throw new SQLException("Column index is out of bounds: " + columnIndex + ". Number of columns: " + theRow.size()); } if (isString) { value = HtmlConverter.fromHtml(value); } wasNull = false; if (value != null && value.equalsIgnoreCase("NULL")) { wasNull = true; } return value; } // /** // * Returns the column index corresponding to the column name // * // * @param columnName // * the column Name // * @return the columnIndex, 1 for fist, 2 for second, etc. // * // * @throws AwakeSQLException // * @throws SQLException // */ // private int getColumnIndexFromColumnName(String columnName) // throws AwakeSQLException, SQLException { // if (columnName == null) { // String message = Tag.AWAKE_FAIL + "Column Name is null!"; // throw new AwakeSQLException(message, new IOException(message)); // } // // columnName = columnName.toLowerCase(); // columnName = columnName.trim(); // // Integer theColPosition = colPosition.get(columnName); // // if (theColPosition == null) { // throw new SQLException("Column Name not found: " + columnName); // } // // // Add to colPosition because result set getters start at 1 // theColPosition++; // return theColPosition.intValue(); // } /** * Get the value of the column using the map inside the List * * @param columnIndex * the first column is 1, the second is 2, ... * @boolean if true, the returned value is a String ==> Parse it to remove * special characters ! * @return the value of the column using the map inside the List * * @throws SQLException */ private byte[] getBinaryValueOfList(int columnIndex) throws SQLException { String value = getValueOfList(columnIndex, false); if (value == null) { // Not sure what to do throw new SQLException("Column Index is out of bound: " + columnIndex); } byte[] bytes = null; // Check if we must get the byte array from an input stream if (value.startsWith(TransportConverter.AWAKE_STREAM_FILE)) { InputStream in = null; String remoteFile = StringUtils.substringAfter(value, TransportConverter.AWAKE_STREAM_FILE); try { in = getInputStreamFromRemoteFile(remoteFile); bytes = getBytesFromInputStream(in); } finally { IOUtils.closeQuietly(in); } } else { bytes = TransportConverter.fromTransportFormatToBytes(value); } return bytes; } /** * Get the value of the column using the map inside the List * * @param columnIndex * the first column is 1, the second is 2, ... * @boolean if true, the returned value is a String ==> Parse it to remove * special characters ! * @return the value of the column using the map inside the List * * @throws SQLException */ private InputStream getInputStreamOfMap(int columnIndex) throws SQLException { String value = getValueOfList(columnIndex, false); if (value == null) { // Not sure what to do throw new SQLException("Column Index is out of bound: " + columnIndex); } InputStream in = null; // Check if we must get the byte array from an input stream if (value.startsWith(TransportConverter.AWAKE_STREAM_FILE)) { String remoteFile = StringUtils.substringAfter(value, TransportConverter.AWAKE_STREAM_FILE); in = getInputStreamFromRemoteFile(remoteFile); } else { byte[] bytes = TransportConverter.fromTransportFormatToBytes(value); in = new ByteArrayInputStream(bytes); } return in; } /** * Return a InputStream from a remote file * * @param remoteFile * the generic name of the remote file * @return the input stream corresponding to the remote file * * @throws SQLException */ private InputStream getInputStreamFromRemoteFile(String remoteFile) throws SQLException { InputStream in = null; debug("begin: " + remoteFile); try { File localFile = new File(AwakeFileUtil.getAwakeTempDir() + remoteFile); localFiles.add(localFile); downloadBlobClob(localFile, remoteFile); debug("localFile: " + localFile); if (localFile.length() == TransportConverter.AWAKE_STREAM_NULL .length()) { debug("before content"); String content = FileUtils.readFileToString(localFile); debug("content: " + content); // Return null if the file content is // TransportConverter.AWAKE_STREAM_NULL if (content.contains(TransportConverter.AWAKE_STREAM_NULL)) { return null; } } debug("localFile: " + localFile); in = new BufferedInputStream(new FileInputStream(localFile)); } catch (Exception e) { JdbcHttpTransferUtil.wrapExceptionAsSQLException(e); } return in; } /** * Return a Reader from a remote file * * @param remoteFile * the generic name of the remote file * @return the Reader corresponding to the remote file * * @throws SQLException */ private Reader getReaderFromRemoteFile(String remoteFile) throws SQLException { Reader reader = null; try { File localFile = new File(AwakeFileUtil.getAwakeTempDir() + remoteFile); downloadBlobClob(localFile, remoteFile); if (localFile.length() == TransportConverter.AWAKE_STREAM_NULL .length()) { String content = FileUtils.readFileToString(localFile); // Return null if the file content is // TransportConverter.AWAKE_STREAM_NULL if (content.contains(TransportConverter.AWAKE_STREAM_NULL)) { localFiles.add(localFile); return null; } } if (connectionHttp.isHtmlEncodingOn()) { File localFileDecoded = new File(localFile.toString() + HTML_DECODED); localFiles.add(localFileDecoded); BufferedReader br = null; Writer writer = null; try { br = new BufferedReader(new FileReader(localFile)); writer = new BufferedWriter( new FileWriter(localFileDecoded)); String line = null; while ((line = br.readLine()) != null) { line = HtmlConverter.fromHtml(line); writer.write(line + CR_LF); } } finally { IOUtils.closeQuietly(br); IOUtils.closeQuietly(writer); if (!KeepTempFilePolicyParms.KEEP_TEMP_FILE && !DEBUG) { localFile.delete(); } } reader = new BufferedReader(new FileReader(localFileDecoded)); } else { localFiles.add(localFile); reader = new BufferedReader(new FileReader(localFile)); } } // catch (InterruptedException e) // { // // re-throw if exception occurred // throw new SQLException(Tag.InterruptedException, e); // } catch (Exception e) { throw new SQLException(e.getMessage(), e); } return reader; } /** * Download a remote file into a local file * * @param localFile * the local file to create a Clob * @param remoteFile * the corresponding remote file * @throws SQLException */ private void downloadBlobClob(File localFile, String remoteFile) throws Exception { AwakeFileSession awakeFileSession = connectionHttp .getAwakeFileSession(); debug("getInputStreamFromRemoteFile: " + remoteFile); long filesLength = awakeFileSession.length(remoteFile); AwakeProgressManager awakeProgressManager = connectionHttp .getAwakeProgressManager(); // Initialize the AwakeProgressManager progress if (awakeProgressManager != null) { awakeProgressManager.setProgress(0); awakeProgressManager.setLengthToTransfer(filesLength); awakeFileSession.setAwakeProgressManager(awakeProgressManager); } debug(""); debug("getInputStreamFromRemoteFile()"); debug("localFile : " + localFile); debug("remoteFile: " + remoteFile); try { awakeFileSession.download(remoteFile, localFile); } finally { if (awakeProgressManager != null) { awakeProgressManager.setProgress(100); } } // Fire and forget in thread deleteRemoteBlobFile(remoteFile, awakeFileSession); } /** * @param remoteFile * @param awakeFileSession */ private void deleteRemoteBlobFile(String remoteFile, AwakeFileSession awakeFileSession) { if (KeepTempFilePolicyParms.KEEP_TEMP_FILE || DEBUG) { return; } final AwakeFileSession awakeFileSessionDelete = awakeFileSession .clone(); final String remoteFileDelete = remoteFile; Runnable doWorkRunnable = new Runnable() { public void run() { try { awakeFileSessionDelete.delete(remoteFileDelete); } catch (Exception e) { e.printStackTrace(); } } }; doWorkRunnable.run(); } /** * Return the content of an input stream into a byte array * * @param in * the input stream * @return the read byte array * * @throws SQLException */ private byte[] getBytesFromInputStream(InputStream in) throws SQLException { if (in == null) { return null; } ByteArrayOutputStream bos = null; try { bos = new ByteArrayOutputStream(); IOUtils.copy(in, bos); } catch (IOException e) { throw new SQLException(e.getMessage(), e); } finally { IOUtils.closeQuietly(in); } return bos.toByteArray(); } /** * Displays the given message if DEBUG is set. * * @param sMsg * the debug message */ private void debug(String s) { if (DEBUG) { AwakeClientLogger.log(s); } } /** * Retrieves the number, types and properties of this ResultSet * object's columns. * * @return the description of this ResultSet object's columns * @exception SQLException * if a database access error occurs */ public ResultSetMetaData getMetaData() throws SQLException { File receiveFile = null; if (statementHolder != null) { // We modify statementHolder to say that it's for a getMetaData() // request statementHolder.setDoExtractResultSetMetaData(true); // We must *decrypt* it before passing it to // JdbcHttpStatementTransfer! // This is because it's a call back... HttpProtocolParameters httpProtocolParameters = connectionHttp .getHttpProtocolParameters(); if (httpProtocolParameters != null && httpProtocolParameters.getEncryptionPassword() != null) { char[] password = httpProtocolParameters .getEncryptionPassword(); StatementHolderCrypto statementHolderCrypto = new StatementHolderCrypto( statementHolder, password); try { statementHolder = statementHolderCrypto.decrypt(); } catch (Exception e) { throw new SQLException(e); } } JdbcHttpStatementTransfer jdbcHttpStatementTransfer = new JdbcHttpStatementTransfer( connectionHttp, connectionHttp.getAuthenticationToken()); receiveFile = jdbcHttpStatementTransfer .getFileFromExecuteQueryOnServer(statementHolder); debug("getFileFromexecuteOnServer() : " + receiveFile); } else if (rsMetaDataFile != null) { receiveFile = rsMetaDataFile; } else { throw new SQLException( "statementHolder and rsMetaDataFile can not be both null!"); } debug("getMetaData.statementHolder: " + statementHolder); // The file contains one line of JSON String jsonString = null; try { jsonString = FileUtils.readFileToString(receiveFile); debug("getMetaData().jsonString: " + jsonString); debug("jsonString.length() : " + jsonString.length()); jsonString = jsonString.trim(); // Very important when encrypted // string // It may be encrypted jsonString = JsonLineDecryptor.decrypt(jsonString, connectionHttp); debug("jsonString.decrypted() : " + jsonString); } catch (IOException e) { throw new SQLException(e.getMessage(), e); } localFiles.add(receiveFile); jsonString = HtmlConverter.fromHtml(jsonString); ResultSetMetaDataHolder resultSetMetaDataHolder = ResultSetMetaDataHolderTransport .fromJson(jsonString); return new ResultSetMetaDataHttp(resultSetMetaDataHolder); } /** * Retrieves the first warning reported by calls on this * ResultSet object. Subsequent warnings on this * ResultSet object will be chained to the * SQLWarning object that this method returns. * *

* The warning chain is automatically cleared each time a new row is read. * This method may not be called on a ResultSet object that has * been closed; doing so will cause an SQLException to be * thrown. *

* Note: This warning chain only covers warnings caused by * ResultSet methods. Any warning caused by * Statement methods (such as reading OUT parameters) will be * chained on the Statement object. * * @return the first SQLWarning object reported or * null if there are none * @exception SQLException * if a database access error occurs or this method is called * on a closed result set */ @Override public SQLWarning getWarnings() throws SQLException { return null; } /** * Clears all warnings reported on this ResultSet object. After * this method is called, the method getWarnings returns * null until a new warning is reported for this * ResultSet object. * * @exception SQLException * if a database access error occurs */ @Override public void clearWarnings() throws SQLException { // does nothing } /** * Moves the cursor down one row from its current position. A * ResultSet cursor is initially positioned before the first * row; the first call to the method next makes the first row * the current row; the second call makes the second row the current row, * and so on. * *

* If an input stream is open for the current row, a call to the method * next will implicitly close it. A ResultSet * object's warning chain is cleared when a new row is read. * * @return true if the new current row is valid; * false if there are no more rows * @exception SQLException * if a database access error occurs */ @Override public boolean next() throws SQLException { testIfClosed(); if (list == null) { String message = Tag.AWAKE_PRODUCT_FAIL + "The List of Maps (Column Name, Column Value) is null!"; throw new SQLException(message, new IOException(message)); } cursor++; if (cursor > list.size()) { return false; } else { return true; } } // --------------------------------------------------------------------- // Traversal/Positioning // --------------------------------------------------------------------- /** * Retrieves whether the cursor is before the first row in this * ResultSet object. * * @return true if the cursor is before the first row; * false if the cursor is at any other position or the * result set contains no rows * @exception SQLException * if a database access error occurs * @since 1.2 */ @Override public boolean isBeforeFirst() throws SQLException { testIfClosed(); if (cursor == 0) { return true; } else { return false; } } /** * Retrieves whether the cursor is after the last row in this * ResultSet object. * * @return true if the cursor is after the last row; * false if the cursor is at any other position or the * result set contains no rows * @exception SQLException * if a database access error occurs * @since 1.2 */ @Override public boolean isAfterLast() throws SQLException { testIfClosed(); if (cursor >= list.size() + 1) { return true; } else { return false; } } /** * Retrieves whether the cursor is on the first row of this * ResultSet object. * * @return true if the cursor is on the first row; * false otherwise * @exception SQLException * if a database access error occurs * @since 1.2 */ @Override public boolean isFirst() throws SQLException { testIfClosed(); if (cursor == 1) { return true; } else { return false; } } /** * Retrieves whether the cursor is on the last row of this * ResultSet object. Note: Calling the method * isLast may be expensive because the JDBC driver might need * to fetch ahead one row in order to determine whether the current row is * the last row in the result set. * * @return true if the cursor is on the last row; * false otherwise * @exception SQLException * if a database access error occurs * @since 1.2 */ @Override public boolean isLast() throws SQLException { testIfClosed(); if (cursor == list.size()) { return true; } else { return false; } } /** * Moves the cursor to the front of this ResultSet object, just * before the first row. This method has no effect if the result set * contains no rows. * * @exception SQLException * if a database access error occurs or the result set type * is TYPE_FORWARD_ONLY * @since 1.2 */ @Override public void beforeFirst() throws SQLException { testIfClosed(); cursor = 0; } /** * Moves the cursor to the end of this ResultSet object, just * after the last row. This method has no effect if the result set contains * no rows. * * @exception SQLException * if a database access error occurs or the result set type * is TYPE_FORWARD_ONLY * @since 1.2 */ @Override public void afterLast() throws SQLException { testIfClosed(); cursor = list.size() + 1; } /** * Moves the cursor to the first row in this ResultSet object. * * @return true if the cursor is on a valid row; * false if there are no rows in the result set * @exception SQLException * if a database access error occurs or the result set type * is TYPE_FORWARD_ONLY * @since 1.2 */ @Override public boolean first() throws SQLException { testIfClosed(); cursor = 1; return true; } /** * Moves the cursor to the last row in this ResultSet object. * * @return true if the cursor is on a valid row; * false if there are no rows in the result set * @exception SQLException * if a database access error occurs or the result set type * is TYPE_FORWARD_ONLY * @since 1.2 */ @Override public boolean last() throws SQLException { testIfClosed(); cursor = list.size(); return true; } /** * Retrieves the current row number. The first row is number 1, the second * number 2, and so on. * * @return the current row number; 0 if there is no current row * @exception SQLException * if a database access error occurs * @since 1.2 */ @Override public int getRow() throws SQLException { testIfClosed(); if (isAfterLast()) { return 0; } return cursor; } /** * Moves the cursor to the given row number in this ResultSet * object. * *

* If the row number is positive, the cursor moves to the given row number * with respect to the beginning of the result set. The first row is row 1, * the second is row 2, and so on. * *

* If the given row number is negative, the cursor moves to an absolute row * position with respect to the end of the result set. For example, calling * the method absolute(-1) positions the cursor on the last * row; calling the method absolute(-2) moves the cursor to the * next-to-last row, and so on. * *

* An attempt to position the cursor beyond the first/last row in the result * set leaves the cursor before the first row or after the last row. * *

* Note: Calling absolute(1) is the same as calling * first(). Calling absolute(-1) is the same as * calling last(). * * @param row * the number of the row to which the cursor should move. A * positive number indicates the row number counting from the * beginning of the result set; a negative number indicates the * row number counting from the end of the result set * @return true if the cursor is on the result set; * false otherwise * @exception SQLException * if a database access error occurs, or the result set type * is TYPE_FORWARD_ONLY * @since 1.2 */ @Override public boolean absolute(int row) throws SQLException { testIfClosed(); cursor = row; if (cursor < 0) { cursor = 0; } if (isAfterLast() || isBeforeFirst()) { return false; } else { return true; } } /** * Moves the cursor a relative number of rows, either positive or negative. * Attempting to move beyond the first/last row in the result set positions * the cursor before/after the the first/last row. Calling * relative(0) is valid, but does not change the cursor * position. * *

* Note: Calling the method relative(1) is identical to calling * the method next() and calling the method * relative(-1) is identical to calling the method * previous(). * * @param rows * an int specifying the number of rows to move from * the current row; a positive number moves the cursor forward; a * negative number moves the cursor backward * @return true if the cursor is on a row; false * otherwise * @exception SQLException * if a database access error occurs, there is no current * row, or the result set type is * TYPE_FORWARD_ONLY * @since 1.2 */ @Override public boolean relative(int rows) throws SQLException { testIfClosed(); cursor += rows; if (cursor < 0) { cursor = 0; } if (isAfterLast() || isBeforeFirst()) { return false; } else { return true; } } /** * Moves the cursor to the previous row in this ResultSet * object. * * @return true if the cursor is on a valid row; * false if it is off the result set * @exception SQLException * if a database access error occurs or the result set type * is TYPE_FORWARD_ONLY * @since 1.2 */ @Override public boolean previous() throws SQLException { testIfClosed(); cursor--; if (cursor < 1) { return false; } else { return true; } } // ====================================================================== // Methods for accessing results by column index // ====================================================================== /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a String in the Java * programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs */ @Override public String getString(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, true); if (s == null || s.equalsIgnoreCase("NULL")) { return null; } // Test if have a Clob if (s.startsWith(TransportConverter.AWAKE_STREAM_FILE)) { return getAwakeFileAsString(s); } if (s.startsWith(UrlTransporter.URL_HEADER)) { // It's an URL ==> Transform it to String UrlTransporter urlTransporter = new UrlTransporter(); URL url = null; try { url = urlTransporter.fromBase64(s); return url.toString(); } catch (Exception e) { throw new SQLException(e); } } return s; } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a boolean in the Java * programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is false * @exception SQLException * if a database access error occurs */ @Override public boolean getBoolean(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return false; } // For Oracle: "1", for SQL Anywhere: 1,00000 if (s.startsWith("1")) { return true; } try { return Boolean.parseBoolean(s); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * /** Retrieves the value of the designated column in the current row of * this ResultSet object as a byte in the Java * programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public byte getByte(int columnIndex) throws SQLException { testIfClosed(); byte[] bytes = getBinaryValueOfList(columnIndex); if (bytes == null) { wasNull = true; return -1; } byte theByte = bytes[0]; return theByte; } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a short in the Java * programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public short getShort(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return -1; } try { return Short.parseShort(s); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as an int in the Java * programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public int getInt(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return -1; } try { return Integer.parseInt(s); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a long in the Java * programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public long getLong(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return -1; } try { return Long.parseLong(s); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a float in the Java * programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public float getFloat(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return -1; } try { return Float.parseFloat(s); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a double in the Java * programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public double getDouble(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return -1; } try { return Double.parseDouble(s); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.math.BigDecimal with * full precision. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value (full precision); if the value is SQL * NULL, the value returned is null in the * Java programming language. * @exception SQLException * if the columnIndex is not valid; if a database access * error occurs or this method is called on a closed result * set * @since 1.2 */ public BigDecimal getBigDecimal(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return null; } try { return new BigDecimal(s); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.sql.BigDecimal in * the Java programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @param scale * the number of digits to the right of the decimal point * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs * @deprecated */ @Override public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { if (scale < 0) { throw new SQLException("invalid scale: "+ scale + ". Scale must be >= 0" ); } BigDecimal bd = getBigDecimal(columnIndex); if (bd != null) { bd = bd.setScale(scale, BigDecimal.ROUND_DOWN); } return bd; } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a byte array in the Java * programming language. The bytes represent the raw values returned by the * driver. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs */ @Override public byte[] getBytes(int columnIndex) throws SQLException { testIfClosed(); byte[] bytes = getBinaryValueOfList(columnIndex); if (bytes == null) { wasNull = true; } return bytes; } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.sql.Date object in * the Java programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs */ @Override public java.sql.Date getDate(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return null; } try { return timestampOrDateValueOf(s); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.sql.Time object in * the Java programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs */ @Override public java.sql.Time getTime(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return null; } try { return java.sql.Time.valueOf(s); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.sql.Timestamp object * in the Java programming language. * * @param columnIndex * the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs */ @Override public java.sql.Timestamp getTimestamp(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return null; } try { return java.sql.Timestamp.valueOf(s); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.net.URL object in * the Java programming language. * * @param columnIndex * the index of the column 1 is the first, 2 is the second,... * @return the column value as a java.net.URL object; if the * value is SQL NULL, the value returned is * null in the Java programming language * @exception SQLException * if a database access error occurs, or if a URL is * malformed * @since 1.4 */ @Override public URL getURL(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return null; } debug("getUrl(columnIndex) : " + s); UrlTransporter urlTransporter = new UrlTransporter(); URL url = null; try { url = urlTransporter.fromBase64(s); return url; } catch (ClassNotFoundException e) { String reason = Tag.AWAKE_EXCEPTION_RAISED + "Impossible to convert BASE64 serialized URL back to URL"; throw new SQLException(reason, e); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as an Array object in the Java * programming language. * * @param i * the first column is 1, the second is 2, ... * @return an Array object representing the SQL * ARRAY value in the specified column * @exception SQLException * if a database access error occurs * @since 1.2 */ @Override public Array getArray(int i) throws SQLException { testIfClosed(); String s = getValueOfList(i, false); if (s == null || s.equalsIgnoreCase("NULL")) { return null; } debug("getArray(i) : " + s); ArrayTransporter arrayTransporter = new ArrayTransporter(); Array array = null; try { array = arrayTransporter.fromBase64(s); return array; } catch (ClassNotFoundException e) { String reason = Tag.AWAKE_EXCEPTION_RAISED + "Impossible to convert BASE64 serialized Array back to Array"; throw new SQLException(reason, e); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row * of this ResultSet object as * a String in the Java programming language. * It is intended for use when * accessing NCHAR,NVARCHAR * and LONGNVARCHAR columns. * * @param columnIndex the first column is 1, the second is 2, ... * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException if the columnIndex is not valid; * if a database access error occurs * or this method is called on a closed result set * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @since 1.6 */ @Override public String getNString(int columnIndex) throws SQLException { // Translation was already done on server... return getString(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.sql.RowId object in the Java * programming language. * * @param columnIndex the first column is 1, the second 2, ... * @return the column value; if the value is a SQL NULL the * value returned is null * @throws SQLException if the columnIndex is not valid; * if a database access error occurs * or this method is called on a closed result set * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @since 1.6 */ public RowId getRowId(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, false); if (s == null || s.equalsIgnoreCase("NULL")) { return null; } debug("getRowId(columnLabel) : " + s); RowIdTransporter rowIdTransporter = new RowIdTransporter(); RowId rowId = null; try { rowId = rowIdTransporter.fromBase64(s); return rowId; } catch (ClassNotFoundException e) { String reason = Tag.AWAKE_EXCEPTION_RAISED + "Impossible to convert BASE64 serialized RowId back to RowId"; throw new SQLException(reason, e); } catch (Exception e) { String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); throw new SQLException("Invalid value for " + methodName + "(): " + "\'" + s + "\'"); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a String in the Java * programming language. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs */ @Override public String getString(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getString(columnIndex); } /** * Retrieves the value of the designated column in the current row * of this ResultSet object as * a String in the Java programming language. * It is intended for use when * accessing NCHAR,NVARCHAR * and LONGNVARCHAR columns. * * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException if the columnLabel is not valid; * if a database access error occurs * or this method is called on a closed result set * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @since 1.6 */ @Override public String getNString(String columnLabel) throws SQLException { int columnIndex = findColumn(columnLabel); return getNString(columnIndex); } /* (non-Javadoc) * @see org.awakefw.commons.jdbc.abstracts.AbstractResultSet#getURL(java.lang.String) */ @Override public URL getURL(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getURL(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as an Array object in the Java * programming language. * * @param colName * the name of the column from which to retrieve the value * @return an Array object representing the SQL * ARRAY value in the specified column * @exception SQLException * if a database access error occurs * @since 1.2 */ @Override public Array getArray(String colName) throws SQLException { int columnIndex = findColumn(colName); return getArray(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.sql.RowId object in the Java * programming language. * * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column * @return the column value ; if the value is a SQL NULL the * value returned is null * @throws SQLException if the columnLabel is not valid; * if a database access error occurs * or this method is called on a closed result set * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @since 1.6 */ public RowId getRowId(String columnLabel) throws SQLException { int columnIndex = findColumn(columnLabel); return getRowId(columnIndex); } /** * Return the underlying awake file as a string * * @param s * the awake file address & name * @return the content as string * @throws SQLException */ private String getAwakeFileAsString(String s) throws SQLException { Reader reader = null; String remoteFile = StringUtils.substringAfter(s, TransportConverter.AWAKE_STREAM_FILE); try { reader = getReaderFromRemoteFile(remoteFile); if (reader == null) { return null; } StringWriter stringWriter = new StringWriter(); IOUtils.copy(reader, stringWriter); return stringWriter.toString(); } catch (Exception e) { throw new SQLException(e.getMessage(), e); } finally { IOUtils.closeQuietly(reader); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a boolean in the Java * programming language. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is false * @exception SQLException * if a database access error occurs */ @Override public boolean getBoolean(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getBoolean(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a byte in the Java * programming language. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public byte getByte(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getByte(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a short in the Java * programming language. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public short getShort(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getShort(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as an int in the Java * programming language. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public int getInt(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getInt(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a long in the Java * programming language. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public long getLong(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getLong(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a float in the Java * programming language. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public float getFloat(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getFloat(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a double in the Java * programming language. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is 0 * @exception SQLException * if a database access error occurs */ @Override public double getDouble(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getDouble(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.math.BigDecimal with * full precision. * * @param columnLabel * the label for the column specified with the SQL AS clause. If * the SQL AS clause was not specified, then the label is the * name of the column * @return the column value (full precision); if the value is SQL * NULL, the value returned is null in the * Java programming language. * @exception SQLException * if the columnLabel is not valid; if a database access * error occurs or this method is called on a closed result * set * @since 1.2 * */ @Override public BigDecimal getBigDecimal(String columnLabel) throws SQLException { int columnIndex = findColumn(columnLabel); return getBigDecimal(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.math.BigDecimal in * the Java programming language. * * @param columnName * the SQL name of the column * @param scale * the number of digits to the right of the decimal point * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs * @deprecated */ @Override public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException { int columnIndex = findColumn(columnName); return getBigDecimal(columnIndex, scale); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a byte array in the Java * programming language. The bytes represent the raw values returned by the * driver. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs */ @Override public byte[] getBytes(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getBytes(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.sql.Date object in * the Java programming language. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs */ @Override public java.sql.Date getDate(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getDate(columnIndex); } /** * Because ORACLE always format Date as Timestamp, we must test the length * of the string return a java.sql.Date formated from a Timestamp.toString() * or java.sql.Date.toString() input * * @param s * the Timestamp.toString() or java.sql.Date.toString() input * @return the java.sql.Date corresponding to the Timestamp.toString() or * java.sql.Date.toString() input */ private java.sql.Date timestampOrDateValueOf(String s) { // Because ORACLE always format Date as Timestamp, we must test the // length of the string if (s.length() > "yyyy-mm-dd".length()) { Timestamp ts = Timestamp.valueOf(s); java.sql.Date date = new java.sql.Date(ts.getTime()); return date; } else { return java.sql.Date.valueOf(s); } } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.sql.Time object in * the Java programming language. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs */ @Override public java.sql.Time getTime(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getTime(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.sql.Timestamp * object. * * @param columnName * the SQL name of the column * @return the column value; if the value is SQL NULL, the * value returned is null * @exception SQLException * if a database access error occurs */ @Override public java.sql.Timestamp getTimestamp(String columnName) throws SQLException { int columnIndex = findColumn(columnName); return getTimestamp(columnIndex); } /** *

* Gets the value of the designated column in the current row of this * ResultSet object as an Object in the Java * programming language. * *

* This method will return the value of the given column as a Java object. * The type of the Java object will be the default Java object type * corresponding to the column's SQL type, following the mapping for * built-in types specified in the JDBC specification. If the value is an * SQL NULL, the driver returns a Java null. * *

* This method may also be used to read database-specific abstract data * types. * * In the JDBC 2.0 API, the behavior of method getObject is * extended to materialize data of SQL user-defined types. *

* If Connection.getTypeMap does not throw a * SQLFeatureNotSupportedException, then when a column contains * a structured or distinct value, the behavior of this method is as if it * were a call to: getObject(columnIndex, * this.getStatement().getConnection().getTypeMap()). * * If Connection.getTypeMap does throw a * SQLFeatureNotSupportedException, then structured values are * not supported, and distinct values are mapped to the default Java class * as determined by the underlying SQL type of the DISTINCT type. * * @param columnIndex * the first column is 1, the second is 2, ... * @return a java.lang.Object holding the column value * @exception SQLException * if the columnIndex is not valid; if a database access * error occurs or this method is called on a closed result * set */ @Override public Object getObject(int columnIndex) throws SQLException { testIfClosed(); String s = getValueOfList(columnIndex, true); if (s == null || s.equalsIgnoreCase("NULL")) { return null; } return s; } /** *

* Gets the value of the designated column in the current row of this * ResultSet object as an Object in the Java * programming language. * *

* This method will return the value of the given column as a Java object. * The type of the Java object will be the default Java object type * corresponding to the column's SQL type, following the mapping for * built-in types specified in the JDBC specification. If the value is an * SQL NULL, the driver returns a Java null. *

* This method may also be used to read database-specific abstract data * types. *

* In the JDBC 2.0 API, the behavior of the method getObject is * extended to materialize data of SQL user-defined types. When a column * contains a structured or distinct value, the behavior of this method is * as if it were a call to: getObject(columnIndex, * this.getStatement().getConnection().getTypeMap()). * * @param columnLabel * the label for the column specified with the SQL AS clause. If * the SQL AS clause was not specified, then the label is the * name of the column * @return a java.lang.Object holding the column value * @exception SQLException * if the columnLabel is not valid; if a database access * error occurs or this method is called on a closed result * set */ @Override public Object getObject(String columnLabel) throws SQLException { int columnIndex = findColumn(columnLabel); return getObject(columnIndex); } // ---------------------------------------------------------------- /** * Maps the given ResultSet column name to its * ResultSet column index. * * @param columnName * the name of the column * @return the column index of the given column name * @exception SQLException * if the ResultSet object does not contain * columnName or a database access error occurs */ public int findColumn(String columnName) throws SQLException { testIfClosed(); if (columnName == null) { throw new NullPointerException("columnName is null!"); } // return getColumnIndexFromColumnName(columnName); columnName = columnName.toLowerCase(); columnName = columnName.trim(); Integer theColPosition = colPosition.get(columnName); if (theColPosition == null) { throw new SQLException("Column Name not found: " + columnName); } // Add to colPosition because result set getters start at 1 theColPosition++; return theColPosition.intValue(); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.io.Reader object. * * @return a java.io.Reader object that contains the column * value; if the value is SQL NULL, the value returned * is null in the Java programming language. * @param columnIndex * the first column is 1, the second is 2, ... * @exception SQLException * if the columnIndex is not valid; if a database access * error occurs or this method is called on a closed result * set * @since 1.2 */ @Override public java.io.Reader getCharacterStream(int columnIndex) throws SQLException { testIfClosed(); String value = getValueOfList(columnIndex, true); if (value == null) { // Not sure what to do throw new SQLException("Column Index is out of bound: " + columnIndex); } Reader reader = null; // Check if we must get the byte array from an input stream if (value.startsWith(TransportConverter.AWAKE_STREAM_FILE)) { String remoteFile = StringUtils.substringAfter(value, TransportConverter.AWAKE_STREAM_FILE); reader = getReaderFromRemoteFile(remoteFile); } else { String stringValue = getString(columnIndex); if (stringValue == null) { return null; } else { try { // Put back clean CR_LF BufferedReader bufferedReader = new BufferedReader( new StringReader(stringValue)); StringWriter stringWriter = new StringWriter(); String line = null; while ((line = bufferedReader.readLine()) != null) { stringWriter.write(line + CR_LF); } String cleaned = stringWriter.toString(); reader = new StringReader(cleaned); } catch (Exception e) { throw new SQLException(e.getMessage(), e); } } } return reader; } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a java.io.Reader object. * * @param columnLabel * the label for the column specified with the SQL AS clause. If * the SQL AS clause was not specified, then the label is the * name of the column * @return a java.io.Reader object that contains the column * value; if the value is SQL NULL, the value returned * is null in the Java programming language * @exception SQLException * if the columnLabel is not valid; if a database access * error occurs or this method is called on a closed result * set * @since 1.2 */ @Override public java.io.Reader getCharacterStream(String columnLabel) throws SQLException { int columnIndex = findColumn(columnLabel); return getCharacterStream(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a stream of ASCII characters. The value * can then be read in chunks from the stream. This method is particularly * suitable for retrieving large LONGVARCHAR values. The JDBC * driver will do any necessary conversion from the database format into * ASCII. * *

* Note: All the data in the returned stream must be read prior to * getting the value of any other column. The next call to a getter method * implicitly closes the stream. Also, a stream may return 0 * when the method available is called whether there is data * available or not. * * @param columnName * the SQL name of the column * @return a Java input stream that delivers the database column value as a * stream of one-byte ASCII characters. If the value is SQL * NULL, the value returned is null. * @exception SQLException * if a database access error occurs */ public java.io.InputStream getAsciiStream(String columnName) throws SQLException { testIfClosed(); int columnIndex = findColumn(columnName); return getAsciiStream(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a stream of ASCII characters. The value * can then be read in chunks from the stream. This method is particularly * suitable for retrieving large LONGVARCHAR values. The JDBC * driver will do any necessary conversion from the database format into * ASCII. * *

* Note: All the data in the returned stream must be read prior to * getting the value of any other column. The next call to a getter method * implicitly closes the stream. Also, a stream may return 0 * when the method InputStream.available is called whether * there is data available or not. * * @param columnIndex * the first column is 1, the second is 2, ... * @return a Java input stream that delivers the database column value as a * stream of one-byte ASCII characters; if the value is SQL * NULL, the value returned is null * @exception SQLException * if a database access error occurs */ public java.io.InputStream getAsciiStream(int columnIndex) throws SQLException { testIfClosed(); String value = getValueOfList(columnIndex, true); if (value == null) { // Not sure what to do throw new SQLException("Column Index is out of bound: " + columnIndex); } InputStream in = null; // Check if we must get the byte array from an input stream if (value.startsWith(TransportConverter.AWAKE_STREAM_FILE)) { String remoteFile = StringUtils.substringAfter(value, TransportConverter.AWAKE_STREAM_FILE); in = getAsciiInputStreamFromRemoteFile(remoteFile); } else { String stringValue = getString(columnIndex); try { // Put back clean CR_LF BufferedReader bufferedReader = new BufferedReader( new StringReader(stringValue)); StringWriter stringWriter = new StringWriter(); String line = null; while ((line = bufferedReader.readLine()) != null) { stringWriter.write(line + CR_LF); } String cleaned = stringWriter.toString(); byte[] bytes = cleaned.getBytes(); in = new ByteArrayInputStream(bytes); } catch (Exception e) { throw new SQLException(e.getMessage(), e); } } return in; } /** * * Return the InputStream corresponding to a getAsciiStream * * @param remoteFile * the remote file base64 encoded * @return the base64 decoded ascii input stream */ private InputStream getAsciiInputStreamFromRemoteFile(String remoteFile) throws SQLException { debug("begin: " + remoteFile); InputStream in = null; try { File localFile = new File(AwakeFileUtil.getAwakeTempDir() + remoteFile); downloadBlobClob(localFile, remoteFile); debug("localFile: " + localFile); if (localFile.length() == TransportConverter.AWAKE_STREAM_NULL .length()) { debug("before content"); String content = FileUtils.readFileToString(localFile); debug("content: " + content); // Return null if the file content is // TransportConverter.AWAKE_STREAM_NULL if (content.contains(TransportConverter.AWAKE_STREAM_NULL)) { localFiles.add(localFile); return null; } } debug("localFile: " + localFile); if (connectionHttp.isHtmlEncodingOn()) { File localFileDecoded = new File(localFile.toString() + HTML_DECODED); localFiles.add(localFileDecoded); BufferedReader br = null; Writer writer = null; try { br = new BufferedReader(new FileReader(localFile)); writer = new BufferedWriter( new FileWriter(localFileDecoded)); String line = null; while ((line = br.readLine()) != null) { line = HtmlConverter.fromHtml(line); writer.write(line + CR_LF); } } finally { IOUtils.closeQuietly(br); IOUtils.closeQuietly(writer); if (!KeepTempFilePolicyParms.KEEP_TEMP_FILE && !DEBUG) { localFile.delete(); } } in = new BufferedInputStream(new FileInputStream( localFileDecoded)); } else { localFiles.add(localFile); in = new BufferedInputStream(new FileInputStream(localFile)); } } catch (Exception e) { JdbcHttpTransferUtil.wrapExceptionAsSQLException(e); } return in; } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a stream of uninterpreted bytes. The * value can then be read in chunks from the stream. This method is * particularly suitable for retrieving large LONGVARBINARY * values. * *

* Note: All the data in the returned stream must be read prior to * getting the value of any other column. The next call to a getter method * implicitly closes the stream. Also, a stream may return 0 * when the method InputStream.available is called whether * there is data available or not. * * @param columnIndex * the first column is 1, the second is 2, ... * @return a Java input stream that delivers the database column value as a * stream of uninterpreted bytes; if the value is SQL * NULL, the value returned is null * @exception SQLException * if the columnIndex is not valid; if a database access * error occurs or this method is called on a closed result * set */ @Override public java.io.InputStream getBinaryStream(int columnIndex) throws SQLException { testIfClosed(); return getInputStreamOfMap(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a stream of uninterpreted * bytes. The value can then be read in chunks from the stream. * This method is particularly suitable for retrieving large * LONGVARBINARY values. * *

* Note: All the data in the returned stream must be read prior to * getting the value of any other column. The next call to a getter method * implicitly closes the stream. Also, a stream may return 0 * when the method available is called whether there is data * available or not. * * @param columnLabel * the label for the column specified with the SQL AS clause. If * the SQL AS clause was not specified, then the label is the * name of the column * @return a Java input stream that delivers the database column value as a * stream of uninterpreted bytes; if the value is SQL * NULL, the result is null * @exception SQLException * if the columnLabel is not valid; if a database access * error occurs or this method is called on a closed result * set */ @Override public java.io.InputStream getBinaryStream(String columnLabel) throws SQLException { testIfClosed(); int columnIndex = findColumn(columnLabel); return getBinaryStream(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a Blob object in the Java * programming language. * * @param i * the first column is 1, the second is 2, ... * @return a Blob object representing the SQL BLOB * value in the specified column * @exception SQLException * if a database access error occurs * @since 1.2 */ @Override public Blob getBlob(int i) throws SQLException { testIfClosed(); Blob blob = new BlobHttp(getBinaryStream(i)); return blob; } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a Blob object in the Java * programming language. * * @param colName * the name of the column from which to retrieve the value * @return a Blob object representing the SQL BLOB * value in the specified column * @exception SQLException * if a database access error occurs * @since 1.2 */ @Override public Blob getBlob(String colName) throws SQLException { int columnIndex = findColumn(colName); return getBlob(columnIndex); } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a Clob object in the Java * programming language. * * @param i * the first column is 1, the second is 2, ... * @return a Clob object representing the SQL CLOB * value in the specified column * @exception SQLException * if a database access error occurs * @since 1.2 */ @Override public Clob getClob(int i) throws SQLException { testIfClosed(); Clob clob = new ClobHttp(this.getCharacterStream(i)); return clob; } /** * Retrieves the value of the designated column in the current row of this * ResultSet object as a Clob object in the Java * programming language. * * @param colName * the name of the column from which to retrieve the value * @return a Clob object representing the SQL CLOB * value in the specified column * @exception SQLException * if a database access error occurs * @since 1.2 */ @Override public Clob getClob(String colName) throws SQLException { return getClob(findColumn(colName)); } /** * Test if a result set is still open * * @throws SQLException * it the Connection is closed */ private void testIfClosed() throws SQLException { if (isClosed()) { throw new SQLException("This Awake Result Set is closed!"); } } /** * Releases this ResultSet object's database and JDBC resources * immediately instead of waiting for this to happen when it is * automatically closed. * *

* Note: A ResultSet object is automatically closed by * the Statement object that generated it when that * Statement object is closed, re-executed, or is used to * retrieve the next result from a sequence of multiple results. A * ResultSet object is also automatically closed when it is * garbage collected. * * @exception SQLException * if a database access error occurs */ @Override public void close() throws SQLException { super.close(); if (KeepTempFilePolicyParms.KEEP_TEMP_FILE || DEBUG) { return; } Runnable doWorkRunnable = new Runnable() { public void run() { try { if (list != null) { list.clear(); // To close and delete the underlying // file. // MANDATORY FOR CLOSE. } if (rsMetaDataFile != null) { rsMetaDataFile.delete(); } // Delete all the files in the list if (localFiles != null) { for (File localFile : localFiles) { boolean deleted = localFile.delete(); if (!deleted) { // debug("localFile not deleted: " + localFile); } } } } catch (Exception e) { // we do not care e.printStackTrace(); } finally { statementHolder = null; localFiles = null; colPosition = null; list = null; rsMetaDataFile = null; } } }; doWorkRunnable.run(); } /** * Reports whether the last column read had a value of SQL NULL * . Note that you must first call one of the getter methods on a column to * try to read its value and then call the method wasNull to * see if the value read was SQL NULL. * * @return true if the last column value read was SQL * NULL and false otherwise * @exception SQLException * if a database access error occurs */ @Override public boolean wasNull() throws SQLException { testIfClosed(); return wasNull; } /** * Retrieves the type of this ResultSet object. The type is * determined by the Statement object that created the result * set. * * @return ResultSet.TYPE_FORWARD_ONLY, * ResultSet.TYPE_SCROLL_INSENSITIVE, or * ResultSet.TYPE_SCROLL_SENSITIVE * @exception SQLException * if a database access error occurs * @since 1.2 */ public int getType() throws SQLException { testIfClosed(); return this.resultSetType; } /** * Retrieves the concurrency mode of this ResultSet object. The * concurrency used is determined by the Statement object that * created the result set. * * @return the concurrency type, either * ResultSet.CONCUR_READ_ONLY or * ResultSet.CONCUR_UPDATABLE * @exception SQLException * if a database access error occurs * @since 1.2 */ public int getConcurrency() throws SQLException { testIfClosed(); return this.resultSetConcurrency; } /** * Retrieves the holdability of this ResultSet object * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT * @throws SQLException if a database access error occurs * or this method is called on a closed result set * @since 1.6 */ public int getHoldability() throws SQLException { testIfClosed(); return this.resultSetHoldability; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy