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

org.kawanfw.sql.jdbc.ResultSetHttp Maven / Gradle / Ivy

/*
 * This file is part of AceQL. 
 * AceQL: Remote JDBC access over HTTP.                                     
 * Copyright (C) 2015,  KawanSoft SAS
 * (http://www.kawansoft.com). All rights reserved.                                
 *                                                                               
 * AceQL is free software; you can redistribute it and/or                 
 * modify it under the terms of the GNU Lesser General Public                    
 * License as published by the Free Software Foundation; either                  
 * version 2.1 of the License, or (at your option) any later version.            
 *                                                                               
 * AceQL 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 Lesser General Public              
 * License along with this library; if not, write to the Free Software           
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
 * 02110-1301  USA
 *
 * Any modifications to this file must keep this entire header
 * intact.
 */
package org.kawanfw.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.FileNotFoundException;
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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.logging.Level;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.kawanfw.commons.api.client.SessionParameters;
import org.kawanfw.commons.jdbc.abstracts.AbstractResultSet;
import org.kawanfw.commons.util.ClientLogger;
import org.kawanfw.commons.util.FrameworkDebug;
import org.kawanfw.commons.util.HtmlConverter;
import org.kawanfw.commons.util.KeepTempFilePolicyParms;
import org.kawanfw.commons.util.Tag;
import org.kawanfw.file.api.client.RemoteFile;
import org.kawanfw.file.api.client.RemoteInputStream;
import org.kawanfw.file.api.client.RemoteSession;
import org.kawanfw.file.api.util.client.FilesTransferWithProgress;
import org.kawanfw.sql.jdbc.http.JdbcHttpStatementTransfer;
import org.kawanfw.sql.jdbc.http.JdbcHttpTransferUtil;
import org.kawanfw.sql.jdbc.util.ColPositionBuilder;
import org.kawanfw.sql.jdbc.util.FileBackedListRs;
import org.kawanfw.sql.jdbc.util.JsonLineDecryptor;
import org.kawanfw.sql.jdbc.util.ResultSetFileSplitter;
import org.kawanfw.sql.json.StatementHolder;
import org.kawanfw.sql.json.no_obfuscation.ResultSetMetaDataHolder;
import org.kawanfw.sql.json.no_obfuscation.ResultSetMetaDataHolderTransport;
import org.kawanfw.sql.transport.TransportConverter;
import org.kawanfw.sql.transport.UrlTransporter;
import org.kawanfw.sql.transport.no_obfsucation.ArrayTransporter;
import org.kawanfw.sql.transport.no_obfsucation.RowIdTransporter;
import org.kawanfw.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 = FrameworkDebug.isSet(ResultSetHttp.class); /** Universal and clean line separator */ private static String CR_LF = System.getProperty("line.separator"); /** * Map that stores ResultSetMetaData per ResultSet to avoid server * re-contact if programmer calls many times ResultSet.getMetaData() in a * loop instead of reusing the result value, as in: int columnType = * resultSet.getMetaData().getColumnType(columnIndex.intValue()); */ private static Map resultSetMetaDataMap = new HashMap(); /** The RemoteConnection 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 list of remote file to delete at close */ private List remoteFiles = 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 produced by a * getMetaData function */ private File rsMetaDataFileTypeFunction = null; /** * The file that contains the MetaData of the Result Set produced by a * classical/normal statement or preparedStatement */ private File rsMetaDataFileTypeNormal = 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.PRODUCT_PRODUCT_FAIL + "connectionHttp can not be null!"; throw new SQLException(message, new IOException(message)); } if (rsAndMetaDataFile == null) { String message = Tag.PRODUCT_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(); rsMetaDataFileTypeFunction = resultSetFileSplitter.getMetaDataFile(); debug("rsAndMetaDataFile: " + rsAndMetaDataFile); debug("rsFile : " + rsMetaDataFileTypeFunction); debug("rsMetaDataFile : " + rsMetaDataFileTypeFunction); // 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.PRODUCT_PRODUCT_FAIL + "connectionHttp can not be null!"; throw new SQLException(message, new IOException(message)); } if (rsFile == null) { String message = Tag.PRODUCT_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(); } // Split the result file into two files: 1) ResultSet itself 2) // ResultSet.getMetaData try { debug("rsFile: " + CR_LF + FileUtils.readFileToString(rsFile)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } debug("connectionHttp.isJoinResultSetMetaData(): " + connectionHttp.isJoinResultSetMetaData()); if (connectionHttp.isJoinResultSetMetaData()) { ResultSetFileSplitter resultSetFileSplitter = new ResultSetFileSplitter( rsFile); File rsFileOnly = resultSetFileSplitter.getResultSetFile(); rsMetaDataFileTypeNormal = resultSetFileSplitter.getMetaDataFile(); // Build the column position map: ColPositionBuilder colPositionBuilder = new ColPositionBuilder( rsFileOnly, connectionHttp); colPosition = colPositionBuilder.getColPosition(); // Build the List of Strings // list = new FileBackedListOfMaps>(rsFile); list = new FileBackedListRs>(rsFileOnly, connectionHttp); } else { // 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.kawanfw.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.PRODUCT_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; } /** * 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.KAWANFW_BYTES_STREAM_FILE)) { InputStream in = null; String remoteFile = StringUtils.substringAfter(value, TransportConverter.KAWANFW_BYTES_STREAM_FILE); // HACK if (!remoteFile.startsWith("/")) { remoteFile = "/" + remoteFile; } 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.KAWANFW_BYTES_STREAM_FILE)) { String remoteFile = StringUtils.substringAfter(value, TransportConverter.KAWANFW_BYTES_STREAM_FILE); // HACK if (!remoteFile.startsWith("/")) { remoteFile = "/" + remoteFile; } 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; // Be cause we open an InputWtream on remot file, we have to // say to delete it at cose() remoteFiles.add(remoteFile); debug("begin - remoteFile: " + remoteFile); // if remote file length is // TransportConverter.KAWANFW_STREAM_NULL.length() // There is huge probability that its' a null stream message, so // download it and test it with a temp stream RemoteSession remoteSession = connectionHttp.getRemoteSession(); try { List remoteFiles = new ArrayList(); remoteFiles.add(remoteFile); long length = remoteSession.length(remoteFiles); if (length == TransportConverter.KAWANFW_STREAM_NULL.length()) { boolean isNull = isInputStreamNull(remoteFile); if (isNull) { RemoteInputStream nullStream = null; return nullStream; } else { // Ok remote file does not correspond to null input stream in = new RemoteInputStream(remoteSession, remoteFile); } } else { // Now use a remote input stream in = new RemoteInputStream(remoteSession, remoteFile); } } catch (Exception e) { JdbcHttpTransferUtil.wrapExceptionAsSQLException(e); } return in; } /** * Tells if the remote says the input stream is null * * @param remoteFile * the remote file * @return * @throws Exception * @throws IOException * @throws FileNotFoundException */ private boolean isInputStreamNull(String remoteFile) throws Exception, IOException, FileNotFoundException { File localFile = BlobHttp.createUniqueBlobFile(); // Simple download RemoteSession remoteSession = connectionHttp.getRemoteSession(); remoteSession.download(remoteFile, localFile); debug("localFile: " + localFile); try { if (localFile.length() == TransportConverter.KAWANFW_STREAM_NULL .length()) { debug("before content"); String content = FileUtils.readFileToString(localFile); debug("content: " + content); // Return null if the file content is // TransportConverter.KAWANFW_STREAM_NULL if (content.contains(TransportConverter.KAWANFW_STREAM_NULL)) { return true; } } debug("localFile: " + localFile); return false; } finally { // We won't reuse the local file so delete it! localFile.delete(); } } /** * 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 = ClobHttp.createUniqueClobFile(); downloadBlobClob(localFile, remoteFile); if (localFile.length() == TransportConverter.KAWANFW_STREAM_NULL .length()) { String content = FileUtils.readFileToString(localFile); // Return null if the file content is // TransportConverter.KAWANFW_STREAM_NULL if (content.contains(TransportConverter.KAWANFW_STREAM_NULL)) { localFiles.add(localFile); return null; } } reader = new BufferedReader(new FileReader( getLocalFileHtmlDecoded(localFile))); } 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 { RemoteSession remoteSession = connectionHttp.getRemoteSession(); debug("getInputStreamFromRemoteFile: " + remoteFile); List remoteFiles = new ArrayList(); remoteFiles.add(remoteFile); long filesLength = remoteSession.length(remoteFiles); debug(""); debug("getInputStreamFromRemoteFile()"); debug("localFile : " + localFile); debug("remoteFile: " + remoteFile); // reinit progress connectionHttp.getProgress().set(0); FilesTransferWithProgress filesTransferWithProgress = new FilesTransferWithProgress( connectionHttp.getRemoteSession(), connectionHttp.getProgress(), connectionHttp.getCancelled()); // HACK if (!remoteFile.startsWith("/")) { remoteFile = "/" + remoteFile; } filesTransferWithProgress.download(remoteFile, localFile, filesLength); // Fire and forget in thread deleteRemoteBlobFile(remoteFile, remoteSession); } /** * @param remoteFile * @param fileSession */ private void deleteRemoteBlobFile(String remoteFile, RemoteSession remoteSession) { // if (KeepTempFilePolicyParms.KEEP_TEMP_FILE || DEBUG) { // return; // } // final FileSession fileSessionDelete = fileSession.clone(); // final String remoteFileDelete = remoteFile; // // Runnable doWorkRunnable = new Runnable() { // public void run() { // // try { // fileSessionDelete.delete(remoteFileDelete); // } catch (Exception e) { // e.printStackTrace(); // } // } // }; // // doWorkRunnable.run(); try { // fileSession.delete(remoteFile); RemoteFile theRemoteFile = new RemoteFile(remoteSession, remoteFile); theRemoteFile.delete(); } catch (Exception e) { e.printStackTrace(); } } /** * 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) { ClientLogger.getLogger().log(Level.WARNING, 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 { ResultSetMetaData resultSetMetaDataLocal = resultSetMetaDataMap .get(this); if (resultSetMetaDataLocal != null) { debug("getMetaData(): return ResultSetMetaData from cache."); return resultSetMetaDataLocal; } File receiveFile = null; if (rsMetaDataFileTypeNormal != null && statementHolder != null) { debug("getMetaData(): receiveFile = rsMetaDataFileTypeNormal. "); receiveFile = rsMetaDataFileTypeNormal; } else if (statementHolder != null) { debug("getMetaData(): contacting server. "); // 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... SessionParameters sessionParameters = connectionHttp .getSessionParameters(); if (sessionParameters != null && sessionParameters.getEncryptionPassword() != null) { char[] password = sessionParameters .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 (rsMetaDataFileTypeFunction != null) { receiveFile = rsMetaDataFileTypeFunction; } 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); ResultSetMetaData resultSetMetaData = new ResultSetMetaDataHttp( resultSetMetaDataHolder); resultSetMetaDataMap.put(this, resultSetMetaData); return resultSetMetaData; } /** * 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.PRODUCT_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.KAWANFW_BYTES_STREAM_FILE)) { return getFileAsString(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.PRODUCT_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); debug("array : " + array.toString()); return array; } catch (ClassNotFoundException e) { String reason = Tag.PRODUCT_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.PRODUCT_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.kawanfw.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 file as a string * * @param s * the file address & name * @return the content as string * @throws SQLException */ private String getFileAsString(String s) throws SQLException { Reader reader = null; String remoteFile = StringUtils.substringAfter(s, TransportConverter.KAWANFW_BYTES_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.KAWANFW_BYTES_STREAM_FILE)) { String remoteFile = StringUtils.substringAfter(value, TransportConverter.KAWANFW_BYTES_STREAM_FILE); reader = getReaderFromRemoteFile(remoteFile); } else { String stringValue = getString(columnIndex); debug("Reader in String!"); 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.KAWANFW_BYTES_STREAM_FILE)) { String remoteFile = StringUtils.substringAfter(value, TransportConverter.KAWANFW_BYTES_STREAM_FILE); // HACK if (!remoteFile.startsWith("/")) { remoteFile = "/" + remoteFile; } in = getAsciiInputStreamFromRemoteFile(remoteFile); } else { String stringValue = getString(columnIndex); debug("AsciiStream in String!"); 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 eventually html encoded * @return the eventually html decoded ascii input stream */ private InputStream getAsciiInputStreamFromRemoteFile(String remoteFile) throws SQLException { debug("begin: " + remoteFile); InputStream in = null; try { File localFile = ClobHttp.createUniqueClobFile(); downloadBlobClob(localFile, remoteFile); debug("localFile: " + localFile); if (localFile.length() == TransportConverter.KAWANFW_STREAM_NULL .length()) { debug("before content"); String content = FileUtils.readFileToString(localFile); debug("content: " + content); // Return null if the file content is // TransportConverter.KAWANFW_STREAM_NULL if (content.contains(TransportConverter.KAWANFW_STREAM_NULL)) { localFiles.add(localFile); return null; } } debug("localFile: " + localFile); in = new BufferedInputStream(new FileInputStream( getLocalFileHtmlDecoded(localFile))); } catch (Exception e) { JdbcHttpTransferUtil.wrapExceptionAsSQLException(e); } return in; } /** * * Html decode the text file is necessary * * @param localFile * the local text file * @return a new local text file but h that is html decoded if necessary * @throws FileNotFoundException * @throws IOException */ private File getLocalFileHtmlDecoded(File localFile) throws FileNotFoundException, IOException { if (connectionHttp.isHtmlEncodingOn()) { localFiles.add(localFile); return localFile; } 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(); } } return localFileDecoded; } /** * 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(); InputStream in = getBinaryStream(i); if (in == null) { return null; } else { Blob blob = new BlobHttp(getBinaryStream(i), connectionHttp); 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 ResultSet 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(); // debug("resultSetMetaDataMap: " + resultSetMetaDataMap); resultSetMetaDataMap.remove(this); // debug("resultSetMetaDataMap: " + resultSetMetaDataMap); // if (KeepTempFilePolicyParms.KEEP_TEMP_FILE || DEBUG) { // return; // } try { if (list != null) { debug("Before list.clear()"); list.clear(); // To close and delete the underlying // file. // MANDATORY FOR CLOSE. debug("After list.clear()"); } if (rsMetaDataFileTypeFunction != null) { rsMetaDataFileTypeFunction.delete(); } if (rsMetaDataFileTypeNormal != null) { rsMetaDataFileTypeNormal.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); } } } // Delete all the remotes files in the list // if (remoteFiles != null) { // FileSession fileSession = connectionHttp.getFileSession(); // for (String remoteFile : remoteFiles) { // boolean deleted = fileSession.delete(remoteFile); // // if (!deleted) { // debug("remoteFile not deleted: " + remoteFile); // } // } // } if (remoteFiles != null) { RemoteSession remoteSession = connectionHttp.getRemoteSession(); for (String remoteFile : remoteFiles) { // boolean deleted = fileSession.delete(remoteFile); boolean deleted = new RemoteFile(remoteSession, remoteFile) .delete(); if (!deleted) { debug("remoteFile not deleted: " + remoteFile); } } } } catch (Exception e) { // we do not care e.printStackTrace(); } finally { statementHolder = null; localFiles = null; colPosition = null; list = null; rsMetaDataFileTypeFunction = null; } } /** * 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