0001: /*
0002: Copyright (C) 2003 Know Gate S.L. All rights reserved.
0003: C/Oņa, 107 1ē2 28050 Madrid (Spain)
0004:
0005: Redistribution and use in source and binary forms, with or without
0006: modification, are permitted provided that the following conditions
0007: are met:
0008:
0009: 1. Redistributions of source code must retain the above copyright
0010: notice, this list of conditions and the following disclaimer.
0011:
0012: 2. The end-user documentation included with the redistribution,
0013: if any, must include the following acknowledgment:
0014: "This product includes software parts from hipergate
0015: (http://www.hipergate.org/)."
0016: Alternately, this acknowledgment may appear in the software itself,
0017: if and wherever such third-party acknowledgments normally appear.
0018:
0019: 3. The name hipergate must not be used to endorse or promote products
0020: derived from this software without prior written permission.
0021: Products derived from this software may not be called hipergate,
0022: nor may hipergate appear in their name, without prior written
0023: permission.
0024:
0025: This library is distributed in the hope that it will be useful,
0026: but WITHOUT ANY WARRANTY; without even the implied warranty of
0027: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
0028:
0029: You should have received a copy of hipergate License with this code;
0030: if not, visit http://www.hipergate.org or mail to info@hipergate.org
0031: */
0032:
0033: package com.knowgate.dataobjs;
0034:
0035: import java.io.FileNotFoundException;
0036: import java.io.UnsupportedEncodingException;
0037: import java.io.IOException;
0038: import java.io.OutputStream;
0039: import java.io.PrintWriter;
0040:
0041: import java.sql.Connection;
0042: import java.sql.ResultSet;
0043: import java.sql.ResultSetMetaData;
0044: import java.sql.Statement;
0045: import java.sql.CallableStatement;
0046: import java.sql.PreparedStatement;
0047: import java.sql.SQLException;
0048: import java.sql.Time;
0049: import java.sql.Timestamp;
0050: import java.sql.Types;
0051:
0052: import java.math.BigDecimal;
0053:
0054: import java.text.DecimalFormat;
0055: import java.text.SimpleDateFormat;
0056:
0057: import java.util.StringTokenizer;
0058: import java.util.Vector;
0059: import java.util.Date;
0060: import java.util.List;
0061: import java.util.Map;
0062: import java.util.HashMap;
0063:
0064: import com.knowgate.debug.DebugFile;
0065: import com.knowgate.jdc.JDCConnection;
0066: import com.knowgate.misc.Gadgets;
0067: import com.knowgate.misc.CSVParser;
0068: import com.knowgate.math.Money;
0069:
0070: /**
0071: *
0072: * <p>A bidimensional array representing data readed from a database table.</p>
0073: * The DBSubset object is used for reading a collection of registers from the database
0074: * and kept them in memory for inmediate access.
0075: * As hipergate reuses database connections by recycling them at the {@link JDCConnectionPool},
0076: * it is a good programming practice to read just the needed number of registers in a single
0077: * step operation and then free the connection as soon as possible for being used by another processs.
0078: * Another reason for this "read fast and leave" tactic is that some JDBC drivers have problems
0079: * managing multiple open resultsets with pending results in a single connection.
0080: * @author Sergio Montoro Ten
0081: * @version 3.0
0082: */
0083:
0084: public final class DBSubset {
0085:
0086: /**
0087: * </p>Contructs a DBSubset.</p>
0088: * @param sTableName Base table or tables, ie. "k_products" or "k_products p, k_x_cat_objs x"
0089: * @param sColumnList Column list to be retirved from base tables i.e "p.gu_product,p.nm_product"
0090: * @param sFilterClause SQL filter clause or <b>null</b> if there is no filter clause to be applied.
0091: * @param iFetchSize Space for number of rows initailly allocated. Is DBSubset later loads more rows
0092: * the buffer is automatically expanded. This parameter may also have a great effect on reducing
0093: * network round trips as the ResultSet.setFetchSize(iFetchSize) method is called prior to fetching
0094: * rows. Fetching rows in batches is much faster than doing so one by one. When iFetchSize is set,
0095: * the JDBC driver may optimize accesses to fetched rows by reading bursts and
0096: * caching rows at client side.
0097: */
0098:
0099: public DBSubset(String sTableName, String sColumnList,
0100: String sFilterClause, int iFetchSize) {
0101: if (DebugFile.trace)
0102: DebugFile.writeln("new DBSubset(" + sTableName + ","
0103: + sColumnList + "," + sFilterClause + ","
0104: + String.valueOf(iFetchSize) + ")");
0105:
0106: sTable = sTableName;
0107: sColList = sColumnList;
0108:
0109: if (null != sFilterClause) {
0110: sFilter = sFilterClause;
0111:
0112: if (sFilter.length() > 0)
0113: sSelect = "SELECT " + sColList + " FROM " + sTable
0114: + " WHERE " + sFilter;
0115: else
0116: sSelect = "SELECT " + sColList + " FROM " + sTable;
0117: } else {
0118: sFilter = "";
0119: sSelect = "SELECT " + sColList + " FROM " + sTable;
0120: }
0121:
0122: if (DebugFile.trace)
0123: DebugFile.writeln(sSelect);
0124:
0125: oResults = null;
0126: sInsert = "";
0127: iFetch = iFetchSize;
0128: iColCount = 0;
0129: iMaxRows = -1;
0130: iTimeOut = 60;
0131: bEOF = true;
0132: sColDelim = "`";
0133: sRowDelim = "¨";
0134: sTxtQualifier = "\"";
0135: oShortDate = null;
0136: }
0137:
0138: // ----------------------------------------------------------
0139:
0140: /**
0141: * Delete rows from base table
0142: * @param oConn Connection
0143: * @param aFilterValues Object[] Parameters for sFilter parameter specified at constructor
0144: * @return int Number of rows deleted
0145: * @throws SQLException
0146: */
0147: public int clear(Connection oConn, Object[] aFilterValues)
0148: throws SQLException {
0149: int iAffected = 0;
0150: PreparedStatement oStmt;
0151:
0152: if (DebugFile.trace) {
0153: DebugFile
0154: .writeln("Begin DBSubset.clear([Connection], Object[])");
0155: DebugFile.incIdent();
0156: }
0157:
0158: // Begin SQLException
0159:
0160: if (sFilter.length() > 0)
0161: oStmt = oConn.prepareStatement("DELETE FROM " + sTable
0162: + " WHERE " + sFilter);
0163: else
0164: oStmt = oConn.prepareStatement("DELETE FROM " + sTable);
0165:
0166: try {
0167: oStmt.setQueryTimeout(iTimeOut);
0168: } catch (SQLException sqle) {
0169: if (DebugFile.trace)
0170: DebugFile
0171: .writeln("Error at PreparedStatement.setQueryTimeout("
0172: + String.valueOf(iTimeOut)
0173: + ")"
0174: + sqle.getMessage());
0175: }
0176:
0177: for (int c = 0; c < aFilterValues.length; c++)
0178: oStmt.setObject(c + 1, aFilterValues[c]);
0179:
0180: iAffected = oStmt.executeUpdate();
0181: oStmt.close();
0182:
0183: // End SQLException
0184:
0185: oResults = null;
0186:
0187: if (DebugFile.trace) {
0188: DebugFile.decIdent();
0189: DebugFile.writeln("End DBSubset.clear()");
0190: }
0191:
0192: return iAffected;
0193: } // clear
0194:
0195: // ----------------------------------------------------------
0196:
0197: /**
0198: * @return <b>true</b> if call() or load() methods readed all available rows,
0199: * <b>false</b> if more rows where pending of reading when getMaxRows() was
0200: * reached.<br>
0201: * Also, after calling store(), eof() is <b>true</b> if all rows were stored
0202: * successfully or <b>false</b> if any row failed to be inserted or updated.
0203: */
0204: public boolean eof() {
0205: return bEOF;
0206: }
0207:
0208: // ----------------------------------------------------------
0209:
0210: /**
0211: * @return Maximum number of rows to be readed from database
0212: */
0213: public int getMaxRows() {
0214: return iMaxRows;
0215: }
0216:
0217: // ----------------------------------------------------------
0218:
0219: /**
0220: * <p>Maximum number of rows to be readed from database</p>
0221: * <p>The exact behavior of this property depends on the RDBMS used.</p>
0222: * <p>For <b>PostgreSQL</b> [LIMIT n] clause is appended to DBSubset query and all returned rows are readed.</p>
0223: * <p>For <b>Microsoft SQL Server</b> [OPTION FAST(n)] clause is appended to DBSubset query
0224: * and then the number of readed rows is limited at client side fetching.</p>
0225: * <p>For <b>Oracle</b> there is no standard way of limiting the resultset size.
0226: * The number of readed rows is just limited at client side fetching.</p>
0227: */
0228:
0229: public void setMaxRows(int iMax) {
0230: iMaxRows = iMax;
0231: }
0232:
0233: // ----------------------------------------------------------
0234:
0235: /**
0236: * @return Maximum amount of time in seconds that a query may run before being cancelled.
0237: */
0238:
0239: public int getQueryTimeout() {
0240: return iTimeOut;
0241: }
0242:
0243: // ----------------------------------------------------------
0244:
0245: /**
0246: * Maximum number of seconds that a query can be executing before raising a timeout exception
0247: * @param iMaxSeconds
0248: */
0249: public void setQueryTimeout(int iMaxSeconds) {
0250: iTimeOut = iMaxSeconds;
0251: }
0252:
0253: // ----------------------------------------------------------
0254:
0255: private void setFetchSize(JDCConnection oConn, ResultSet oRSet)
0256: throws SQLException {
0257:
0258: if (DebugFile.trace) {
0259: DebugFile.writeln("Begin DBSubset.setFetchSize()");
0260: DebugFile.incIdent();
0261: }
0262:
0263: if (oConn.getDataBaseProduct() == JDCConnection.DBMS_POSTGRESQL)
0264: // PostgreSQL does not support setFetchSize()
0265: iFetch = 1;
0266:
0267: else {
0268:
0269: try {
0270: if (0 != iFetch)
0271: oRSet.setFetchSize(iFetch);
0272: else
0273: iFetch = oRSet.getFetchSize();
0274: } catch (SQLException e) {
0275: if (DebugFile.trace)
0276: DebugFile.writeln(e.getMessage());
0277: iFetch = 1;
0278: }
0279: }
0280:
0281: if (DebugFile.trace) {
0282: DebugFile.decIdent();
0283: DebugFile
0284: .writeln("End DBSubset.setFetchSize() : " + iFetch);
0285: }
0286: } // setFetchSize
0287:
0288: // ----------------------------------------------------------
0289:
0290: private int fetchResultSet(ResultSet oRSet, int iSkip)
0291: throws SQLException, ArrayIndexOutOfBoundsException {
0292: Vector oRow;
0293: int iCol;
0294: int iRetVal = 0;
0295: int iMaxRow = iMaxRows < 0 ? 2147483647 : iMaxRows;
0296: long lFetchTime = 0;
0297: Object oFieldValue;
0298:
0299: if (DebugFile.trace) {
0300: DebugFile
0301: .writeln("Begin DBSubset.fetchResultSet([ResultSet], "
0302: + String.valueOf(iSkip) + ")");
0303: DebugFile.incIdent();
0304: DebugFile.writeln("column count = "
0305: + String.valueOf(iColCount));
0306: DebugFile
0307: .writeln("max. rows = " + String.valueOf(iMaxRows));
0308: DebugFile.writeln("new Vector(" + String.valueOf(iFetch)
0309: + "," + String.valueOf(iFetch) + ")");
0310: lFetchTime = System.currentTimeMillis();
0311: }
0312:
0313: oResults = new Vector(iFetch, iFetch);
0314:
0315: if (0 != iSkip) {
0316: oRSet.next();
0317:
0318: if (DebugFile.trace)
0319: DebugFile.writeln("ResultSet.relative("
0320: + String.valueOf(iSkip - 1) + ")");
0321:
0322: oRSet.relative(iSkip - 1);
0323: } // fi(iSkip)
0324:
0325: boolean bHasNext = oRSet.next();
0326:
0327: while (bHasNext && iRetVal < iMaxRow) {
0328:
0329: iRetVal++;
0330: oRow = new Vector(iColCount);
0331:
0332: for (iCol = 1; iCol <= iColCount; iCol++) {
0333: oFieldValue = oRSet.getObject(iCol);
0334: if (oRSet.wasNull())
0335: oRow.add(null);
0336: else
0337: oRow.add(oFieldValue);
0338: } // next
0339:
0340: oResults.add(oRow);
0341:
0342: bHasNext = oRSet.next();
0343: } // wend
0344:
0345: if (0 == iRetVal || iRetVal < iMaxRow) {
0346: bEOF = true;
0347: if (DebugFile.trace)
0348: DebugFile.writeln("readed " + String.valueOf(iRetVal)
0349: + " rows eof() = true");
0350: } else {
0351: bEOF = !bHasNext;
0352:
0353: if (DebugFile.trace)
0354: DebugFile.writeln("readed max "
0355: + String.valueOf(iMaxRow) + " rows eof() = "
0356: + String.valueOf(bEOF));
0357: }
0358:
0359: if (DebugFile.trace) {
0360: DebugFile.writeln("fetching done in "
0361: + String.valueOf(System.currentTimeMillis()
0362: - lFetchTime) + " ms");
0363: DebugFile.decIdent();
0364: DebugFile.writeln("End DBSubset.fetchResultSet() : "
0365: + String.valueOf(iRetVal));
0366: }
0367:
0368: return iRetVal;
0369: } // fetchResultSet
0370:
0371: // ----------------------------------------------------------
0372:
0373: /**
0374: * <p>Execute a stored procedure returning a ResultSet</p>
0375: * @param oConn Database Connection
0376: * @return Number of rows retrieved
0377: * @throws SQLException
0378: */
0379:
0380: public int call(JDCConnection oConn) throws SQLException {
0381: return call(oConn, 0);
0382: }
0383:
0384: // ----------------------------------------------------------
0385:
0386: /**
0387: * <p>Execute a stored procedure returning a ResultSet</p>
0388: * @param oConn Database Connection
0389: * @param iSkip Number of rows to be skipped before reading
0390: * @return Number of rows retrieved
0391: * @throws SQLException
0392: * @throws IllegalArgumentException if iSkip<0
0393: * @throws ArrayIndexOutOfBoundsException
0394: */
0395:
0396: public int call(JDCConnection oConn, int iSkip)
0397: throws SQLException, IllegalArgumentException,
0398: ArrayIndexOutOfBoundsException {
0399: CallableStatement oStmt;
0400: ResultSet oRSet;
0401: ResultSetMetaData oMDat;
0402: int iRows = 0;
0403: int iType = (iSkip == 0 ? ResultSet.TYPE_FORWARD_ONLY
0404: : ResultSet.TYPE_SCROLL_INSENSITIVE);
0405:
0406: if (DebugFile.trace) {
0407: DebugFile.writeln("Begin DBSubset.call([Connection],"
0408: + iSkip + ")");
0409: DebugFile.incIdent();
0410: }
0411:
0412: // Begin SQLException
0413:
0414: if (DebugFile.trace)
0415: DebugFile.writeln("Connection.prepareCall({call " + sTable
0416: + "()}");
0417: oStmt = oConn.prepareCall("{call " + sTable + "()}", iType,
0418: ResultSet.CONCUR_READ_ONLY);
0419:
0420: if (DebugFile.trace)
0421: DebugFile
0422: .writeln("Connection.executeQuery(" + sTable + ")");
0423:
0424: oRSet = oStmt.executeQuery();
0425:
0426: oMDat = oRSet.getMetaData();
0427: iColCount = oMDat.getColumnCount();
0428: ColNames = new String[iColCount];
0429:
0430: for (int c = 1; c <= iColCount; c++) {
0431: ColNames[c - 1] = oMDat.getColumnName(c).toLowerCase();
0432: }
0433: oMDat = null;
0434:
0435: setFetchSize(oConn, oRSet);
0436:
0437: iRows = fetchResultSet(oRSet, iSkip);
0438:
0439: oRSet.close();
0440: oRSet = null;
0441:
0442: oStmt.close();
0443: oStmt = null;
0444:
0445: // End SQLException
0446:
0447: if (DebugFile.trace) {
0448: DebugFile.decIdent();
0449: DebugFile.writeln("End DBSubset.call()");
0450: }
0451:
0452: return iRows;
0453: } // call()
0454:
0455: // ----------------------------------------------------------
0456:
0457: /**
0458: * <p>Execute a stored procedure returning a ResultSet</p>
0459: * @param oConn Database Connection
0460: * @param aFilterValues Values to be binded and JDBC PreparedStatement query paramenters.
0461: * @return Number of rows retrieved
0462: * @throws SQLException
0463: */
0464:
0465: public int call(JDCConnection oConn, Object[] aFilterValues)
0466: throws SQLException {
0467: return call(oConn, aFilterValues, 0);
0468: }
0469:
0470: // ----------------------------------------------------------
0471:
0472: /**
0473: * <p>Execute a stored procedure returning a ResultSet</p>
0474: * @param oConn Database Connection
0475: * @param aFilterValues Values to be binded and JDBC PreparedStatement query paramenters.
0476: * @param iSkip Number of rows to be skipped before reading
0477: * @return Number of rows retrieved,
0478: * the maximum number of rows to be retrieved is determined by calling method
0479: * setMaxRows(), if setMaxRows() is not called before call() then all rows existing are retrieved.
0480: * @throws SQLException
0481: * @throws IllegalArgumentException
0482: * @throws ArrayIndexOutOfBoundsException
0483: */
0484:
0485: public int call(JDCConnection oConn, Object[] aFilterValues,
0486: int iSkip) throws SQLException, IllegalArgumentException,
0487: ArrayIndexOutOfBoundsException {
0488: CallableStatement oStmt;
0489: ResultSet oRSet;
0490: ResultSetMetaData oMDat;
0491:
0492: int iRows = 0;
0493: int iType = (iSkip == 0 ? ResultSet.TYPE_FORWARD_ONLY
0494: : ResultSet.TYPE_SCROLL_INSENSITIVE);
0495:
0496: if (DebugFile.trace) {
0497: DebugFile
0498: .writeln("Begin DBSubset.call([Connection], Object[],"
0499: + iSkip + ")");
0500: DebugFile.incIdent();
0501: }
0502:
0503: // Begin SQLException
0504: if (DebugFile.trace)
0505: DebugFile.writeln("Connection.prepareCall({call " + sTable
0506: + "()}");
0507: oStmt = oConn.prepareCall("{call " + sTable + "()}", iType,
0508: ResultSet.CONCUR_READ_ONLY);
0509:
0510: for (int p = 0; p < aFilterValues.length; p++)
0511: oStmt.setObject(p + 1, aFilterValues[p]);
0512:
0513: if (DebugFile.trace)
0514: DebugFile.writeln("Connection.executeQuery()");
0515:
0516: oRSet = oStmt.executeQuery();
0517:
0518: oMDat = oRSet.getMetaData();
0519: iColCount = oMDat.getColumnCount();
0520: ColNames = new String[iColCount];
0521:
0522: for (int c = 1; c <= iColCount; c++) {
0523: ColNames[c - 1] = oMDat.getColumnName(c).toLowerCase();
0524: }
0525: oMDat = null;
0526:
0527: setFetchSize(oConn, oRSet);
0528:
0529: iRows = fetchResultSet(oRSet, iSkip);
0530:
0531: oRSet.close();
0532: oRSet = null;
0533:
0534: oStmt.close();
0535: oStmt = null;
0536:
0537: // End SQLException
0538:
0539: if (DebugFile.trace) {
0540: DebugFile.decIdent();
0541: DebugFile.writeln("End DBSubset.call()");
0542: }
0543:
0544: return iRows;
0545: } // call
0546:
0547: // ----------------------------------------------------------
0548:
0549: /**
0550: * <p>Execute a JDBC Statement and load query ResultSet in an internal bidimensional matrix</p>
0551: * @param oConn Database Connection
0552: * @return Number of rows retrieved
0553: * the maximum number of rows to be retrieved is determined by calling method
0554: * setMaxRows(), if setMaxRows() is not called before call() then all rows existing are retrieved.
0555: * @throws SQLException
0556: */
0557:
0558: public int load(JDCConnection oConn) throws SQLException,
0559: ArrayIndexOutOfBoundsException, NullPointerException {
0560: return load(oConn, 0);
0561: }
0562:
0563: // ----------------------------------------------------------
0564:
0565: /**
0566: * <p>Execute a JDBC Statement and load query ResultSet in an internal bidimensional matrix</p>
0567: * @param oConn Database Connection
0568: * @param iSkip Number of rows to be skipped before reading. On database systems that support an
0569: * OFFSET clause (such as PostgreSQL) the native offset feature of the DBMS is used, in case that
0570: * the DBMS does not provide offset capabilities, the data is fetched and discarded at client side
0571: * before returning the DBSubset. Care must be taken when skipping a large number of rows in client
0572: * side mode as it may cause heavy network traffic and round trips to the database.
0573: * @return Number of rows retrieved
0574: * the maximum number of rows to be retrieved is determined by calling method
0575: * setMaxRows(), if setMaxRows() is not called before call() then all rows existing are retrieved.
0576: * @throws SQLException
0577: * @throws IllegalArgumentException if iSkip<0
0578: * @throws ArrayIndexOutOfBoundsException
0579: * @throws NullPointerException
0580: */
0581:
0582: public int load(JDCConnection oConn, int iSkip)
0583: throws SQLException, IllegalArgumentException,
0584: ArrayIndexOutOfBoundsException, NullPointerException {
0585:
0586: Statement oStmt = null;
0587: ResultSet oRSet = null;
0588: ResultSetMetaData oMDat;
0589: int iRows = 0;
0590: int iType = (iSkip == 0 ? ResultSet.TYPE_FORWARD_ONLY
0591: : ResultSet.TYPE_SCROLL_INSENSITIVE);
0592: long lQueryTime = 0;
0593:
0594: if (DebugFile.trace) {
0595: DebugFile.writeln("Begin DBSubset.load([Connection],"
0596: + iSkip + ")");
0597: lQueryTime = System.currentTimeMillis();
0598: }
0599:
0600: if (iSkip < 0)
0601: throw new IllegalArgumentException(
0602: "row offset must be equal to or greater than zero");
0603:
0604: if (null == oConn)
0605: throw new NullPointerException(
0606: "DBSubset.load() JDCConnection parameter is null");
0607:
0608: if (DebugFile.trace)
0609: DebugFile.incIdent();
0610:
0611: try {
0612:
0613: oStmt = oConn.createStatement(iType,
0614: ResultSet.CONCUR_READ_ONLY);
0615:
0616: if (iMaxRows > 0) {
0617:
0618: switch (oConn.getDataBaseProduct()) {
0619:
0620: case JDCConnection.DBMS_MSSQL:
0621: if (DebugFile.trace)
0622: DebugFile.writeln("Statement.executeQuery("
0623: + sSelect + " OPTION (FAST "
0624: + String.valueOf(iMaxRows) + ")" + ")");
0625: oRSet = oStmt.executeQuery(sSelect
0626: + " OPTION (FAST "
0627: + String.valueOf(iMaxRows) + ")");
0628: break;
0629:
0630: case JDCConnection.DBMS_MYSQL:
0631: if (DebugFile.trace)
0632: DebugFile.writeln("Statement.executeQuery("
0633: + sSelect + " LIMIT "
0634: + String.valueOf(iSkip) + ","
0635: + String.valueOf(iMaxRows + 2) + ")");
0636: oRSet = oStmt.executeQuery(sSelect + " LIMIT "
0637: + String.valueOf(iSkip) + ","
0638: + String.valueOf(iMaxRows + 2));
0639: iSkip = 0; // Use PostgreSQL native OFFSET clause, so do not skip any rows before client side fetching
0640: break;
0641:
0642: case JDCConnection.DBMS_POSTGRESQL:
0643: if (DebugFile.trace)
0644: DebugFile.writeln("Statement.executeQuery("
0645: + sSelect + " LIMIT "
0646: + String.valueOf(iMaxRows + 2)
0647: + " OFFSET " + String.valueOf(iSkip)
0648: + ")");
0649: oRSet = oStmt.executeQuery(sSelect + " LIMIT "
0650: + String.valueOf(iMaxRows + 2) + " OFFSET "
0651: + String.valueOf(iSkip));
0652: iSkip = 0; // Use PostgreSQL native OFFSET clause, so do not skip any rows before client side fetching
0653: break;
0654:
0655: default:
0656: if (DebugFile.trace)
0657: DebugFile.writeln("Statement.executeQuery("
0658: + sSelect + ")");
0659: oRSet = oStmt.executeQuery(sSelect);
0660: } // end switch
0661: } else {
0662: switch (oConn.getDataBaseProduct()) {
0663:
0664: case JDCConnection.DBMS_MYSQL:
0665: if (DebugFile.trace)
0666: DebugFile.writeln("Statement.executeQuery("
0667: + sSelect + " LIMIT "
0668: + String.valueOf(iSkip)
0669: + ",2147483647)");
0670: oRSet = oStmt.executeQuery(sSelect + " LIMIT "
0671: + String.valueOf(iSkip) + ",2147483647");
0672: iSkip = 0; // Use MySQL native LIMIT clause, so do not skip any rows before client side fetching
0673: break;
0674:
0675: case JDCConnection.DBMS_POSTGRESQL:
0676: if (DebugFile.trace)
0677: DebugFile.writeln("Statement.executeQuery("
0678: + sSelect + " OFFSET "
0679: + String.valueOf(iSkip) + ")");
0680: oRSet = oStmt.executeQuery(sSelect + " OFFSET "
0681: + String.valueOf(iSkip));
0682: iSkip = 0; // Use PostgreSQL native OFFSET clause, so do not skip any rows before client side fetching
0683: break;
0684:
0685: default:
0686: if (DebugFile.trace)
0687: DebugFile.writeln("Statement.executeQuery("
0688: + sSelect + ")");
0689: oRSet = oStmt.executeQuery(sSelect);
0690: } // end switch
0691: }
0692:
0693: if (DebugFile.trace) {
0694: DebugFile.writeln("query executed in "
0695: + String.valueOf(System.currentTimeMillis()
0696: - lQueryTime) + " ms");
0697: DebugFile.writeln("ResultSet.getMetaData()");
0698: }
0699:
0700: oMDat = oRSet.getMetaData();
0701: iColCount = oMDat.getColumnCount();
0702: ColNames = new String[iColCount];
0703:
0704: for (int c = 1; c <= iColCount; c++) {
0705: ColNames[c - 1] = oMDat.getColumnName(c).toLowerCase();
0706: }
0707:
0708: oMDat = null;
0709:
0710: setFetchSize(oConn, oRSet);
0711:
0712: iRows = fetchResultSet(oRSet, iSkip);
0713:
0714: if (DebugFile.trace)
0715: DebugFile.writeln("ResultSet.close()");
0716:
0717: oRSet.close();
0718: oRSet = null;
0719:
0720: if (DebugFile.trace)
0721: DebugFile.writeln("PreparedStatement.close()");
0722:
0723: oStmt.close();
0724: oStmt = null;
0725:
0726: } catch (SQLException sqle) {
0727: try {
0728: if (null != oRSet)
0729: oRSet.close();
0730: } catch (Exception logit) {
0731: if (DebugFile.trace)
0732: DebugFile.writeln(logit.getClass().getName() + " "
0733: + logit.getMessage());
0734: }
0735: try {
0736: if (null != oStmt)
0737: oStmt.close();
0738: } catch (Exception logit) {
0739: if (DebugFile.trace)
0740: DebugFile.writeln(logit.getClass().getName() + " "
0741: + logit.getMessage());
0742: }
0743: throw new SQLException(sqle.getMessage(), sqle
0744: .getSQLState(), sqle.getErrorCode());
0745: } catch (ArrayIndexOutOfBoundsException aiob) {
0746: try {
0747: if (null != oRSet)
0748: oRSet.close();
0749: } catch (Exception logit) {
0750: if (DebugFile.trace)
0751: DebugFile.writeln(logit.getClass().getName() + " "
0752: + logit.getMessage());
0753: }
0754: try {
0755: if (null != oStmt)
0756: oStmt.close();
0757: } catch (Exception logit) {
0758: if (DebugFile.trace)
0759: DebugFile.writeln(logit.getClass().getName() + " "
0760: + logit.getMessage());
0761: }
0762: throw new ArrayIndexOutOfBoundsException("DBSubset.load() "
0763: + aiob.getMessage());
0764: } catch (NullPointerException npe) {
0765: try {
0766: if (null != oRSet)
0767: oRSet.close();
0768: } catch (Exception logit) {
0769: if (DebugFile.trace)
0770: DebugFile.writeln(logit.getClass().getName() + " "
0771: + logit.getMessage());
0772: }
0773: try {
0774: if (null != oStmt)
0775: oStmt.close();
0776: } catch (Exception logit) {
0777: if (DebugFile.trace)
0778: DebugFile.writeln(logit.getClass().getName() + " "
0779: + logit.getMessage());
0780: }
0781: throw new NullPointerException("DBSubset.load()");
0782: }
0783:
0784: if (DebugFile.trace) {
0785: DebugFile.decIdent();
0786: DebugFile.writeln("End DBSubset.load() : "
0787: + String.valueOf(iRows));
0788: }
0789:
0790: return iRows;
0791: } // load()
0792:
0793: // ----------------------------------------------------------
0794:
0795: /**
0796: * <p>Execute a JDBC Statement and load query ResultSet in an internal bidimensional matrix</p>
0797: * @param oConn Database Connection
0798: * @param aFilterValues Values to be binded and JDBC PreparedStatement query paramenters.
0799: * @return Number of rows retrieved
0800: * the maximum number of rows to be retrieved is determined by calling method
0801: * setMaxRows(), if setMaxRows() is not called before call() then all rows existing are retrieved.
0802: * @throws SQLException
0803: */
0804:
0805: public int load(JDCConnection oConn, Object[] aFilterValues)
0806: throws SQLException, ArrayIndexOutOfBoundsException,
0807: NullPointerException {
0808:
0809: return load(oConn, aFilterValues, 0);
0810: }
0811:
0812: /**
0813: * <p>Execute a JDBC Statement and load query ResultSet in an internal bidimensional matrix</p>
0814: * @param oConn Database Connection
0815: * @param aFilterValues Values to be binded and JDBC PreparedStatement query paramenters.
0816: * @param iSkip Number of rows to be skipped before reading. On database systems that support an
0817: * OFFSET clause (such as PostgreSQL) the native offset feature of the DBMS is used, in case that
0818: * the DBMS does not provide offset capabilities, the data is fetched and discarded at client side
0819: * before returning the DBSubset. Care must be taken when skipping a large number of rows in client
0820: * side mode as it may cause heavy network traffic and round trips to the database.
0821: * @return Number of rows retrieved
0822: * the maximum number of rows to be retrieved is determined by calling method
0823: * setMaxRows(), if setMaxRows() is not called before call() then all rows existing are retrieved.
0824: * @throws SQLException
0825: * @throws IllegalArgumentException if iSkip<0
0826: */
0827:
0828: // ----------------------------------------------------------
0829: public int load(JDCConnection oConn, Object[] aFilterValues,
0830: int iSkip) throws SQLException, IllegalArgumentException,
0831: ArrayIndexOutOfBoundsException, NullPointerException {
0832:
0833: PreparedStatement oStmt = null;
0834: ResultSet oRSet = null;
0835: ResultSetMetaData oMDat;
0836:
0837: int iRows = 0;
0838: int iType = (iSkip == 0 ? ResultSet.TYPE_FORWARD_ONLY
0839: : ResultSet.TYPE_SCROLL_INSENSITIVE);
0840: long lQueryTime = 0;
0841:
0842: if (DebugFile.trace)
0843: DebugFile
0844: .writeln("Begin DBSubset.load([Connection], Object[],"
0845: + iSkip + ")");
0846:
0847: if (iSkip < 0)
0848: throw new IllegalArgumentException(
0849: "row offset must be equal to or greater than zero");
0850:
0851: if (null == oConn)
0852: throw new NullPointerException(
0853: "DBSubset.load() JDCConnection parameter is null");
0854:
0855: if (DebugFile.trace)
0856: DebugFile.incIdent();
0857:
0858: try {
0859:
0860: if (iMaxRows > 0) {
0861:
0862: switch (oConn.getDataBaseProduct()) {
0863:
0864: case JDCConnection.DBMS_MSSQL:
0865: if (DebugFile.trace)
0866: DebugFile
0867: .writeln("Connection.prepareStatement("
0868: + sSelect + " OPTION (FAST "
0869: + String.valueOf(iMaxRows)
0870: + ")" + ")");
0871: oStmt = oConn.prepareStatement(sSelect
0872: + " OPTION (FAST "
0873: + String.valueOf(iMaxRows) + ")", iType,
0874: ResultSet.CONCUR_READ_ONLY);
0875: break;
0876:
0877: case JDCConnection.DBMS_POSTGRESQL:
0878: case JDCConnection.DBMS_MYSQL:
0879: if (DebugFile.trace)
0880: DebugFile
0881: .writeln("Connection.prepareStatement("
0882: + sSelect + " LIMIT "
0883: + String.valueOf(iMaxRows + 2)
0884: + " OFFSET "
0885: + String.valueOf(iSkip) + ")");
0886: oStmt = oConn.prepareStatement(sSelect + " LIMIT "
0887: + String.valueOf(iMaxRows + 2) + " OFFSET "
0888: + String.valueOf(iSkip),
0889: ResultSet.TYPE_FORWARD_ONLY,
0890: ResultSet.CONCUR_READ_ONLY);
0891: iSkip = 0; // Use PostgreSQL native OFFSET clause, so do not skip any rows before client side fetching
0892: break;
0893:
0894: default:
0895: if (DebugFile.trace)
0896: DebugFile
0897: .writeln("Connection.prepareStatement("
0898: + sSelect + ")");
0899: oStmt = oConn.prepareStatement(sSelect, iType,
0900: ResultSet.CONCUR_READ_ONLY);
0901: } // end switch
0902: }
0903:
0904: else {
0905: switch (oConn.getDataBaseProduct()) {
0906:
0907: case JDCConnection.DBMS_POSTGRESQL:
0908: if (DebugFile.trace)
0909: DebugFile
0910: .writeln("Connection.prepareStatement("
0911: + sSelect + " OFFSET "
0912: + String.valueOf(iSkip) + ")");
0913: oStmt = oConn.prepareStatement(sSelect + " OFFSET "
0914: + String.valueOf(iSkip),
0915: ResultSet.TYPE_FORWARD_ONLY,
0916: ResultSet.CONCUR_READ_ONLY);
0917: iSkip = 0; // Use PostgreSQL native OFFSET clause, so do not skip any rows before client side fetching
0918: break;
0919:
0920: default:
0921: if (DebugFile.trace)
0922: DebugFile
0923: .writeln("Connection.prepareStatement("
0924: + sSelect + ")");
0925: oStmt = oConn.prepareStatement(sSelect, iType,
0926: ResultSet.CONCUR_READ_ONLY);
0927: } // end switch
0928:
0929: } // fi (iMaxRows)
0930:
0931: try {
0932: oStmt.setQueryTimeout(iTimeOut);
0933: } catch (SQLException sqle) {
0934: if (DebugFile.trace)
0935: DebugFile
0936: .writeln("Error at PreparedStatement.setQueryTimeout("
0937: + String.valueOf(iTimeOut)
0938: + ")"
0939: + sqle.getMessage());
0940: }
0941:
0942: for (int p = 0; p < aFilterValues.length; p++) {
0943: Object oParam = aFilterValues[p];
0944: if (DebugFile.trace) {
0945: if (null == oParam)
0946: DebugFile
0947: .writeln("PreparedStatement.setObject("
0948: + String.valueOf(p + 1)
0949: + ",null)");
0950: else
0951: DebugFile
0952: .writeln("PreparedStatement.setObject("
0953: + String.valueOf(p + 1) + ","
0954: + oParam.toString() + ")");
0955: }
0956: oStmt.setObject(p + 1, oParam);
0957: }
0958:
0959: if (DebugFile.trace) {
0960: DebugFile.writeln("PreparedStatement.executeQuery()");
0961: lQueryTime = System.currentTimeMillis();
0962: }
0963:
0964: oRSet = oStmt.executeQuery();
0965:
0966: if (DebugFile.trace) {
0967: DebugFile.writeln("query executed in "
0968: + String.valueOf(System.currentTimeMillis()
0969: - lQueryTime) + " ms");
0970: DebugFile.writeln("ResultSet.getMetaData()");
0971: }
0972:
0973: oMDat = oRSet.getMetaData();
0974: iColCount = oMDat.getColumnCount();
0975: ColNames = new String[iColCount];
0976:
0977: for (int c = 1; c <= iColCount; c++) {
0978: ColNames[c - 1] = oMDat.getColumnName(c).toLowerCase();
0979: }
0980: oMDat = null;
0981:
0982: setFetchSize(oConn, oRSet);
0983:
0984: iRows = fetchResultSet(oRSet, iSkip);
0985:
0986: if (DebugFile.trace)
0987: DebugFile.writeln("ResultSet.close()");
0988:
0989: oRSet.close();
0990: oRSet = null;
0991:
0992: if (DebugFile.trace)
0993: DebugFile.writeln("PreparedStatement.close()");
0994:
0995: oStmt.close();
0996: oStmt = null;
0997: } catch (SQLException sqle) {
0998: try {
0999: if (null != oRSet)
1000: oRSet.close();
1001: } catch (Exception logit) {
1002: if (DebugFile.trace)
1003: DebugFile.writeln(logit.getClass().getName() + " "
1004: + logit.getMessage());
1005: }
1006: try {
1007: if (null != oStmt)
1008: oStmt.close();
1009: } catch (Exception logit) {
1010: if (DebugFile.trace)
1011: DebugFile.writeln(logit.getClass().getName() + " "
1012: + logit.getMessage());
1013: }
1014: throw new SQLException(sqle.getMessage(), sqle
1015: .getSQLState(), sqle.getErrorCode());
1016: } catch (ArrayIndexOutOfBoundsException aiob) {
1017: try {
1018: if (null != oRSet)
1019: oRSet.close();
1020: } catch (Exception logit) {
1021: if (DebugFile.trace)
1022: DebugFile.writeln(logit.getClass().getName() + " "
1023: + logit.getMessage());
1024: }
1025: try {
1026: if (null != oStmt)
1027: oStmt.close();
1028: } catch (Exception logit) {
1029: if (DebugFile.trace)
1030: DebugFile.writeln(logit.getClass().getName() + " "
1031: + logit.getMessage());
1032: }
1033: throw new ArrayIndexOutOfBoundsException("DBSubset.load() "
1034: + aiob.getMessage());
1035: } catch (NullPointerException npe) {
1036: try {
1037: if (null != oRSet)
1038: oRSet.close();
1039: } catch (Exception logit) {
1040: if (DebugFile.trace)
1041: DebugFile.writeln(logit.getClass().getName() + " "
1042: + logit.getMessage());
1043: }
1044: try {
1045: if (null != oStmt)
1046: oStmt.close();
1047: } catch (Exception logit) {
1048: if (DebugFile.trace)
1049: DebugFile.writeln(logit.getClass().getName() + " "
1050: + logit.getMessage());
1051: }
1052: throw new NullPointerException("DBSubset.load()");
1053: }
1054:
1055: if (DebugFile.trace) {
1056: DebugFile.decIdent();
1057: DebugFile.writeln("End DBSubset.load() : "
1058: + String.valueOf(iRows));
1059: }
1060:
1061: return iRows;
1062: } // load()
1063:
1064: // ----------------------------------------------------------
1065:
1066: /**
1067: * <p>Find a value in a given column<p>
1068: * Value is searched by brute force from the begining to the end of the column.<br>
1069: * Trying to find a <b>null</b> value is allowed.<br>
1070: * Find is case sensitive.
1071: * @param iCol Column to be searched [0..getColumnCount()-1]
1072: * @param oVal Value searched
1073: * @return Row where seached value was found or -1 is value was not found.
1074: */
1075:
1076: public int find(int iCol, Object oVal) {
1077: int iFound = -1;
1078: int iRowCount;
1079: Object objCol;
1080:
1081: if (DebugFile.trace) {
1082: if (null == oVal)
1083: DebugFile.writeln("Begin DBSubset.find("
1084: + String.valueOf(iCol) + ", null)");
1085: else
1086: DebugFile.writeln("Begin DBSubset.find("
1087: + String.valueOf(iCol) + ", " + oVal.toString()
1088: + ")");
1089:
1090: DebugFile.incIdent();
1091: }
1092:
1093: if (oResults != null)
1094: iRowCount = oResults.size();
1095: else
1096: iRowCount = -1;
1097:
1098: if (DebugFile.trace)
1099: DebugFile.writeln("row count is "
1100: + String.valueOf(iRowCount));
1101:
1102: for (int iRow = 0; iRow < iRowCount; iRow++) {
1103:
1104: objCol = get(iCol, iRow);
1105:
1106: if (null != objCol) {
1107: if (null != oVal) {
1108: if (objCol.equals(oVal)) {
1109: iFound = iRow;
1110: break;
1111: }
1112: }
1113: } else if (null == oVal) {
1114: iFound = iRow;
1115: break;
1116: } // fi()
1117:
1118: } // next (iRow)
1119:
1120: if (DebugFile.trace) {
1121: DebugFile.decIdent();
1122: DebugFile.writeln("Begin DBSubset.find() : "
1123: + String.valueOf(iFound));
1124: }
1125:
1126: return iFound;
1127: } // find
1128:
1129: // ----------------------------------------------------------
1130:
1131: /**
1132: * @return Column delimiter for print() and toString() methods.
1133: */
1134: public String getColumnDelimiter() {
1135: return sColDelim;
1136: }
1137:
1138: // ----------------------------------------------------------
1139:
1140: /**
1141: * @param sDelim Column delimiter for print() and toString() methods.
1142: * The default delimiter is '`' character
1143: */
1144: public void setColumnDelimiter(String sDelim) {
1145: sColDelim = sDelim;
1146: }
1147:
1148: // ----------------------------------------------------------
1149:
1150: /**
1151: * @return Row delimiter for print() and toString() methods.
1152: */
1153: public String getRowDelimiter() {
1154: return sRowDelim;
1155: }
1156:
1157: // ----------------------------------------------------------
1158:
1159: /**
1160: * @param sDelim Row delimiter for print() and toString() methods.
1161: * The default delimiter is '¨' character
1162: */
1163:
1164: public void setRowDelimiter(String sDelim) {
1165: sRowDelim = sDelim;
1166: }
1167:
1168: // ----------------------------------------------------------
1169:
1170: /**
1171: * @return Text qualifier for quoting fields in print() and toString() methods.
1172: */
1173: public String getTextQualifier() {
1174: return sTxtQualifier;
1175: }
1176:
1177: // ----------------------------------------------------------
1178:
1179: /**
1180: * @param sQualifier Text qualifier for quoting fields in print() and toString() methods.
1181: */
1182: public void setTextQualifier(String sQualifier) {
1183: sTxtQualifier = sQualifier;
1184: }
1185:
1186: // ----------------------------------------------------------
1187:
1188: /**
1189: * @return Number of columns retrieved.
1190: */
1191: public int getColumnCount() {
1192: return iColCount;
1193: }
1194:
1195: // ----------------------------------------------------------
1196:
1197: /**
1198: * <p>Get column names</p>
1199: * @return String[] An array with names of columns from the most recently SQL SELECT sentence.
1200: * @since 3.0
1201: */
1202: public String[] getColumnNames() {
1203: return ColNames;
1204: }
1205:
1206: // ----------------------------------------------------------
1207:
1208: /**
1209: * @param sColumnName Name of column witch position is to be returned. Column names are case insensitive.
1210: * @return Column position or -1 if no column with such name exists.
1211: */
1212: public int getColumnPosition(String sColumnName) {
1213: int iColPos = -1;
1214:
1215: for (int iCol = 0; iCol < iColCount; iCol++) {
1216: if (sColumnName.equalsIgnoreCase(ColNames[iCol])) {
1217: iColPos = iCol;
1218: break;
1219: }
1220: } // endfor
1221:
1222: return iColPos;
1223: } // getColumnPosition
1224:
1225: // ----------------------------------------------------------
1226:
1227: /**
1228: * @return number of rows retrieved by last call() or load() method invocation.
1229: */
1230: public int getRowCount() {
1231: int iRows;
1232:
1233: if (null == oResults)
1234: iRows = 0;
1235: else
1236: iRows = oResults.size();
1237:
1238: return iRows;
1239:
1240: } // getRowCount
1241:
1242: // ----------------------------------------------------------
1243:
1244: /**
1245: * Get DBSubset column as a List interface
1246: * @param iCol int Column position [0..getColumnCount()-1]
1247: * @return List
1248: * @throws ArrayIndexOutOfBoundsException
1249: * @throws IllegalStateException if DBSubset has not been loaded
1250: */
1251: public List getColumnAsList(int iCol)
1252: throws ArrayIndexOutOfBoundsException,
1253: IllegalStateException {
1254: Vector oRow, oCol;
1255: int iRowCount;
1256: if (oResults == null)
1257: throw new IllegalStateException("DBSubset.getColumnAsList("
1258: + String.valueOf(iCol) + ") DBSubset not loaded");
1259: else
1260: iRowCount = oResults.size();
1261: if (0 == iRowCount) {
1262: oCol = new Vector();
1263: } else {
1264: oCol = new Vector(iRowCount);
1265: for (int iRow = 0; iRow < iRowCount; iRow++) {
1266: oRow = (Vector) oResults.get(iRow);
1267: oCol.add(oRow.get(iCol));
1268: } // next
1269: }
1270: return oCol;
1271: } // getColumnAsList
1272:
1273: // ----------------------------------------------------------
1274:
1275: /**
1276: * Get DBSubset row as a List interface
1277: * @param iRow int Row position [0..getRowCount()-1]
1278: * @return List
1279: * @throws ArrayIndexOutOfBoundsException
1280: * @throws IllegalStateException if DBSubset has not been loaded
1281: */
1282: public List getRowAsList(int iRow)
1283: throws ArrayIndexOutOfBoundsException,
1284: IllegalStateException {
1285: if (oResults != null)
1286: return (List) oResults.get(iRow);
1287: else
1288: throw new IllegalStateException("DBSubset.getRowAsList("
1289: + String.valueOf(iRow) + ") DBSubset not loaded");
1290: } // getRowAsList
1291:
1292: // ----------------------------------------------------------
1293:
1294: /**
1295: * Get DBSubset row as a Map interface
1296: * @param iRow int Row position [0..getRowCount()-1]
1297: * @return Map
1298: * @throws ArrayIndexOutOfBoundsException
1299: * @throws IllegalStateException if DBSubset has not been loaded
1300: */
1301: public Map getRowAsMap(int iRow)
1302: throws ArrayIndexOutOfBoundsException,
1303: IllegalStateException {
1304: if (oResults == null)
1305: throw new IllegalStateException("DBSubset.getRowAsMap("
1306: + String.valueOf(iRow) + ") DBSubset not loaded");
1307:
1308: Vector oRow = (Vector) oResults.get(iRow);
1309: HashMap oRetVal = new HashMap(iColCount * 2);
1310:
1311: for (int iCol = 0; iCol < iColCount; iCol++) {
1312: oRetVal.put(ColNames[iCol], oRow.get(iCol));
1313: } // endfor
1314:
1315: return oRetVal;
1316: } // getRowMap
1317:
1318: // ----------------------------------------------------------
1319:
1320: /**
1321: * Get DBSubset row as a Vector
1322: * @param iRow int Row position [0..getRowCount()-1]
1323: * @return Vector
1324: * @throws ArrayIndexOutOfBoundsException
1325: * @throws IllegalStateException if DBSubset has not been loaded
1326: * @since 3.0
1327: */
1328: public Vector getRowAsVector(int iRow)
1329: throws ArrayIndexOutOfBoundsException,
1330: IllegalStateException {
1331: if (oResults != null)
1332: return (Vector) oResults.get(iRow);
1333: else
1334: throw new IllegalStateException("DBSubset.getRowAsList("
1335: + String.valueOf(iRow) + ") DBSubset not loaded");
1336: } // getRowAsVector
1337:
1338: // ----------------------------------------------------------
1339:
1340: /**
1341: * <p>Get pre-loaded field</p>
1342: * @param iCol Column position [0..getColumnCount()-1]
1343: * @param iRow Row position [0..getRowCount()-1]
1344: * @throws ArrayIndexOutOfBoundsException
1345: */
1346: public Object get(int iCol, int iRow)
1347: throws ArrayIndexOutOfBoundsException {
1348: return ((Vector) oResults.get(iRow)).get(iCol);
1349: }
1350:
1351: // ----------------------------------------------------------
1352:
1353: /**
1354: * <p>Get pre-loaded field by name</p>
1355: * @param sCol Column name
1356: * @param iRow Row position [0..getRowCount()-1]
1357: * @throws ArrayIndexOutOfBoundsException If no column with such name was found
1358: */
1359: public Object get(String sCol, int iRow)
1360: throws ArrayIndexOutOfBoundsException {
1361:
1362: int iCol = getColumnPosition(sCol);
1363:
1364: if (iCol == -1)
1365: throw new ArrayIndexOutOfBoundsException("Column " + sCol
1366: + " not found");
1367:
1368: return ((Vector) oResults.get(iRow)).get(iCol);
1369: }
1370:
1371: // ----------------------------------------------------------
1372:
1373: /**
1374: * <p>Get pre-loaded value for a Boolean field</p>
1375: * @param iCol Column position [0..getColumnCount()-1]
1376: * @param iRow Row position [0..getRowCount()-1]
1377: * @return <b>boolean</b> value for field.
1378: * @throws ClassCastException
1379: * @throws ArrayIndexOutOfBoundsException
1380: * @throws NullPointerException
1381: */
1382: public boolean getBoolean(int iCol, int iRow)
1383: throws ClassCastException, ArrayIndexOutOfBoundsException,
1384: NullPointerException {
1385:
1386: boolean bRetVal;
1387: Object oObj = get(iCol, iRow);
1388:
1389: if (oObj.getClass().equals(Integer.TYPE))
1390:
1391: bRetVal = (((Integer) oObj).intValue() != 0 ? true : false);
1392:
1393: else if (oObj.getClass().equals(Short.TYPE))
1394: bRetVal = (((Short) oObj).shortValue() != (short) 0 ? true
1395: : false);
1396:
1397: else
1398: bRetVal = ((Boolean) get(iCol, iRow)).booleanValue();
1399:
1400: return bRetVal;
1401: }
1402:
1403: // ----------------------------------------------------------
1404:
1405: /**
1406: * <p>Get pre-loaded value for a Date field</p>
1407: * @param iCol Column position [0..getColumnCount()-1]
1408: * @param iRow Row position [0..getRowCount()-1]
1409: * @throws ClassCastException
1410: * @throws ArrayIndexOutOfBoundsException
1411: * @version 3.1
1412: */
1413:
1414: public java.util.Date getDate(int iCol, int iRow)
1415: throws ClassCastException, ArrayIndexOutOfBoundsException {
1416: Object oDt = ((Vector) oResults.get(iRow)).get(iCol);
1417:
1418: if (null != oDt) {
1419: if (oDt.getClass().equals(ClassUtilDate))
1420: return (java.util.Date) oDt;
1421: else if (oDt.getClass().equals(ClassTimestamp))
1422: return new java.util.Date(((java.sql.Timestamp) oDt)
1423: .getTime());
1424: else if (oDt.getClass().equals(ClassSQLDate))
1425: return new java.util.Date(((java.sql.Date) oDt)
1426: .getYear(), ((java.sql.Date) oDt).getMonth(),
1427: ((java.sql.Date) oDt).getDate());
1428: else if (oDt.getClass().equals(ClassLangString)) {
1429: if (null == oDateTime24)
1430: oDateTime24 = new SimpleDateFormat(
1431: "yyyy-MM-dd HH:mm:ss");
1432: try {
1433: return oDateTime24.parse((String) oDt);
1434: } catch (java.text.ParseException pe) {
1435: throw new ClassCastException("Cannot parse Date "
1436: + oDt);
1437: }
1438: } else
1439: throw new ClassCastException("Cannot cast "
1440: + oDt.getClass().getName() + " to Date");
1441: } else
1442: return null;
1443:
1444: } // getDate()
1445:
1446: // ----------------------------------------------------------
1447:
1448: /**
1449: * <p>Get pre-loaded value for a Date field</p>
1450: * @param iCol Column position [0..getColumnCount()-1]
1451: * @param iRow Row position [0..getRowCount()-1]
1452: * @return java.sql.Date
1453: * @throws ClassCastException
1454: * @throws ArrayIndexOutOfBoundsException
1455: * @since 3.0
1456: */
1457:
1458: public java.sql.Date getSQLDate(int iCol, int iRow)
1459: throws ClassCastException, ArrayIndexOutOfBoundsException {
1460: Object oDt = ((Vector) oResults.get(iRow)).get(iCol);
1461:
1462: if (null != oDt) {
1463: if (oDt.getClass().equals(ClassSQLDate))
1464: return (java.sql.Date) oDt;
1465: else if (oDt.getClass().equals(ClassTimestamp))
1466: return new java.sql.Date(((java.sql.Timestamp) oDt)
1467: .getTime());
1468: else if (oDt.getClass().equals(ClassUtilDate))
1469: return new java.sql.Date(((java.util.Date) oDt)
1470: .getTime());
1471: else
1472: throw new ClassCastException("Cannot cast "
1473: + oDt.getClass().getName() + " to Date");
1474: } else
1475: return null;
1476: } // getSQLDate()
1477:
1478: /**
1479: * <p>Get pre-loaded value for a Date field</p>
1480: * @param sCol String Column name
1481: * @param iRow Row position [0..getRowCount()-1]
1482: * @return java.sql.Date
1483: * @throws ClassCastException
1484: * @throws ArrayIndexOutOfBoundsException
1485: * @since 3.0
1486: */
1487: public java.sql.Date getSQLDate(String sCol, int iRow)
1488: throws ArrayIndexOutOfBoundsException {
1489: int iCol = getColumnPosition(sCol);
1490:
1491: if (iCol == -1)
1492: throw new ArrayIndexOutOfBoundsException("Column " + sCol
1493: + " not found");
1494:
1495: return getSQLDate(iCol, iRow);
1496: } // getSQLDate()
1497:
1498: // ----------------------------------------------------------
1499:
1500: /**
1501: * <p>Get pre-loaded value for a Time field</p>
1502: * @param iCol Column position [0..getColumnCount()-1]
1503: * @param iRow Row position [0..getRowCount()-1]
1504: * @throws ClassCastException
1505: * @throws ArrayIndexOutOfBoundsException
1506: * @since 3.0
1507: */
1508:
1509: public java.sql.Time getSQLTime(int iCol, int iRow)
1510: throws ClassCastException, ArrayIndexOutOfBoundsException {
1511: Object oDt = ((Vector) oResults.get(iRow)).get(iCol);
1512:
1513: if (null != oDt) {
1514: if (oDt.getClass().equals(ClassSQLTime))
1515: return (java.sql.Time) oDt;
1516: else if (oDt.getClass().equals(ClassTimestamp))
1517: return new java.sql.Time(((java.sql.Timestamp) oDt)
1518: .getTime());
1519: else if (oDt.getClass().equals(ClassUtilDate))
1520: return new java.sql.Time(((java.util.Date) oDt)
1521: .getTime());
1522: else
1523: throw new ClassCastException("Cannot cast "
1524: + oDt.getClass().getName() + " to Time");
1525: } else
1526: return null;
1527: } // getTime()
1528:
1529: // ----------------------------------------------------------
1530:
1531: /**
1532: * <p>Get pre-loaded value for a Time field</p>
1533: * @param sCol Column name
1534: * @param iRow Row position [0..getRowCount()-1]
1535: * @return Time
1536: * @throws ClassCastException
1537: * @throws ArrayIndexOutOfBoundsException
1538: * @since 3.0
1539: */
1540: public java.sql.Time getSQLTime(String sCol, int iRow)
1541: throws ClassCastException, ArrayIndexOutOfBoundsException {
1542: int iCol = getColumnPosition(sCol);
1543:
1544: if (iCol == -1)
1545: throw new ArrayIndexOutOfBoundsException("Column " + sCol
1546: + " not found");
1547:
1548: return getSQLTime(iCol, iRow);
1549: } // getSQLTime()
1550:
1551: // ----------------------------------------------------------
1552:
1553: /**
1554: * <p>Get pre-loaded value for a Date field</p>
1555: * @param sCol Column name
1556: * @param iRow Row position [0..getRowCount()-1]
1557: * @throws ClassCastException
1558: * @throws ArrayIndexOutOfBoundsException if column is not found
1559: */
1560:
1561: public java.util.Date getDate(String sCol, int iRow)
1562: throws ArrayIndexOutOfBoundsException {
1563: int iCol = getColumnPosition(sCol);
1564:
1565: if (iCol == -1)
1566: throw new ArrayIndexOutOfBoundsException("Column " + sCol
1567: + " not found");
1568:
1569: return getDate(iCol, iRow);
1570: } // getDate()
1571:
1572: // ----------------------------------------------------------
1573:
1574: /**
1575: * <p>Get pre-loaded value for a Date field formated as a short Date "yyyy-MM-dd"</p>
1576: * @param iCol Column position [0..getColumnCount()-1]
1577: * @param iRow Row position [0..getRowCount()-1]
1578: * @return String with format "yyyy-MM-dd" or <b>null</b>.
1579: * @throws ClassCastException
1580: */
1581: public String getDateShort(int iCol, int iRow) {
1582: java.util.Date oDt = getDate(iCol, iRow);
1583:
1584: if (null == oShortDate)
1585: oShortDate = new SimpleDateFormat("yyyy-MM-dd");
1586:
1587: if (null != oDt)
1588: return oShortDate.format(oDt);
1589: else
1590: return null;
1591:
1592: } // getDateShort()
1593:
1594: // ----------------------------------------------------------
1595:
1596: /**
1597: * <p>Get pre-loaded value for a Date field formated as a DateTime "yyyy-MM-dd HH:mm:ss"</p>
1598: * @param iCol Column position [0..getColumnCount()-1]
1599: * @param iRow Row position [0..getRowCount()-1]
1600: * @return String with format "yyyy-MM-dd HH:mm:ss" or <b>null</b>.
1601: * @throws ClassCastException
1602: * @since 2.1
1603: */
1604:
1605: public String getDateTime24(int iCol, int iRow) {
1606: java.util.Date oDt = getDate(iCol, iRow);
1607:
1608: if (null == oDateTime24)
1609: oDateTime24 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
1610:
1611: if (null != oDt)
1612: return oDateTime24.format(oDt);
1613: else
1614: return null;
1615:
1616: } // getDateTime24()
1617:
1618: // ----------------------------------------------------------
1619:
1620: /**
1621: * <p>Get pre-loaded value for a Date field formated as a DateTime "yyyy-MM-dd hh:mm:ss"</p>
1622: * @param iCol Column position [0..getColumnCount()-1]
1623: * @param iRow Row position [0..getRowCount()-1]
1624: * @throws ClassCastException
1625: * @throws ArrayIndexOutOfBoundsException
1626: * @return String with format "yyyy-MM-dd hh:mm:ss" or <b>null</b>.
1627: */
1628:
1629: public String getDateTime(int iCol, int iRow)
1630: throws ClassCastException, ArrayIndexOutOfBoundsException {
1631:
1632: java.util.Date oDt = getDate(iCol, iRow);
1633:
1634: if (null == oDateTime)
1635: oDateTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
1636:
1637: if (null != oDt)
1638: return oDateTime.format(oDt);
1639: else
1640: return null;
1641: } // getDateShort()
1642:
1643: // ----------------------------------------------------------
1644:
1645: /**
1646: * <p>Get pre-loaded value for a Date field formated with a used defind formar</p>
1647: * @param iCol Column position [0..getColumnCount()-1]
1648: * @param iRow Row position [0..getRowCount()-1]
1649: * @param sFormat Date Format (like "yyyy-MM-dd HH:mm:ss")
1650: * @throws ClassCastException
1651: * @throws ArrayIndexOutOfBoundsException
1652: * @return Date value formated as String.
1653: * @see java.text.SimpleDateFormat
1654: */
1655:
1656: public String getDateFormated(int iCol, int iRow, String sFormat)
1657: throws ArrayIndexOutOfBoundsException, ClassCastException {
1658:
1659: java.util.Date oDt = getDate(iCol, iRow);
1660: SimpleDateFormat oSimpleDate;
1661:
1662: if (null != oDt) {
1663: oSimpleDate = new SimpleDateFormat(sFormat);
1664: return oSimpleDate.format(oDt);
1665: } else
1666: return null;
1667:
1668: } // getDateFormated()
1669:
1670: // ----------------------------------------------------------
1671:
1672: /**
1673: * <p>Get pre-loaded value and tries to convert it into a Short</p>
1674: * @param iCol Column position [0..getColumnCount()-1]
1675: * @param iRow Row position [0..getRowCount()-1]
1676: * @throws NullPointerException If field value is <b>null</b>
1677: * @throws ArrayIndexOutOfBoundsException
1678: */
1679:
1680: public short getShort(int iCol, int iRow)
1681: throws NullPointerException, ArrayIndexOutOfBoundsException {
1682:
1683: Object oVal = (((Vector) oResults.get(iRow)).get(iCol));
1684: Class oCls;
1685: short iRetVal;
1686:
1687: oCls = oVal.getClass();
1688:
1689: try {
1690: if (oCls.equals(Short.TYPE))
1691: iRetVal = ((Short) oVal).shortValue();
1692: else if (oCls.equals(Integer.TYPE))
1693: iRetVal = (short) ((Integer) oVal).intValue();
1694: else if (oCls.equals(Class.forName("java.math.BigDecimal")))
1695: iRetVal = (short) ((java.math.BigDecimal) oVal)
1696: .intValue();
1697: else if (oCls.equals(Float.TYPE))
1698: iRetVal = (short) ((Float) oVal).intValue();
1699: else if (oCls.equals(Double.TYPE))
1700: iRetVal = (short) ((Double) oVal).intValue();
1701: else
1702: iRetVal = new Short(oVal.toString()).shortValue();
1703: } catch (ClassNotFoundException cnfe) { /* never thrown */
1704: iRetVal = (short) 0;
1705: }
1706:
1707: return iRetVal;
1708: } // getShort
1709:
1710: // ----------------------------------------------------------
1711:
1712: /**
1713: * <p>Get pre-loaded value and tries to convert it into a int</p>
1714: * @param iCol Column position [0..getColumnCount()-1]
1715: * @param iRow Row position [0..getRowCount()-1]
1716: * @throws NullPointerException If field value is <b>null</b>
1717: * @throws ArrayIndexOutOfBoundsException
1718: */
1719:
1720: public int getInt(int iCol, int iRow) throws NullPointerException,
1721: ArrayIndexOutOfBoundsException {
1722:
1723: Object oVal = (((Vector) oResults.get(iRow)).get(iCol));
1724:
1725: if (oVal.getClass().equals(Integer.TYPE))
1726: return ((Integer) oVal).intValue();
1727: else
1728: return getInteger(iCol, iRow).intValue();
1729: }
1730:
1731: // ----------------------------------------------------------
1732:
1733: /**
1734: * <p>Get pre-loaded value and tries to convert it into a Short</p>
1735: * @param sCol Column name
1736: * @param iRow Row position [0..getRowCount()-1]
1737: * @throws ArrayIndexOutOfBoundsException if column is not found
1738: * @throws NullPointerException If field value is <b>null</b>
1739: */
1740:
1741: public int getInt(String sCol, int iRow)
1742: throws ArrayIndexOutOfBoundsException, NullPointerException {
1743:
1744: int iCol = getColumnPosition(sCol);
1745:
1746: if (iCol == -1)
1747: throw new ArrayIndexOutOfBoundsException("Column " + sCol
1748: + " not found");
1749:
1750: Object oVal = (((Vector) oResults.get(iRow)).get(iCol));
1751:
1752: if (oVal.getClass().equals(Integer.TYPE))
1753:
1754: return ((Integer) oVal).intValue();
1755:
1756: else
1757:
1758: return getInteger(iCol, iRow).intValue();
1759:
1760: } // getInt
1761:
1762: // ----------------------------------------------------------
1763:
1764: /**
1765: * <p>Get pre-loaded value and tries to convert it into a double</p>
1766: * @param iCol Column position [0..getColumnCount()-1]
1767: * @param iRow Row position [0..getRowCount()-1]
1768: * @throws NullPointerException If field value is <b>null</b>
1769: * @throws ArrayIndexOutOfBoundsException
1770: */
1771:
1772: public double getDouble(int iCol, int iRow)
1773: throws NullPointerException, ArrayIndexOutOfBoundsException {
1774:
1775: Object oVal = (((Vector) oResults.get(iRow)).get(iCol));
1776: Class oCls;
1777: double dRetVal;
1778:
1779: oCls = oVal.getClass();
1780:
1781: try {
1782: if (oCls.equals(Short.TYPE))
1783: dRetVal = (double) ((Short) oVal).shortValue();
1784: else if (oCls.equals(Integer.TYPE))
1785: dRetVal = (double) ((Integer) oVal).intValue();
1786: else if (oCls.equals(Class.forName("java.math.BigDecimal")))
1787: dRetVal = ((java.math.BigDecimal) oVal).doubleValue();
1788: else if (oCls.equals(Float.TYPE))
1789: dRetVal = ((Float) oVal).doubleValue();
1790: else if (oCls.equals(Double.TYPE))
1791: dRetVal = ((Double) oVal).doubleValue();
1792: else
1793: dRetVal = new Double(Gadgets.removeChar(
1794: oVal.toString(), ',')).doubleValue();
1795: } catch (ClassNotFoundException cnfe) { /* never thrown */
1796: dRetVal = 0d;
1797: }
1798:
1799: return dRetVal;
1800: } // getDouble
1801:
1802: // ----------------------------------------------------------
1803:
1804: /**
1805: * <p>Get pre-loaded value and tries to convert it into a float</p>
1806: * @param iCol Column position [0..getColumnCount()-1]
1807: * @param iRow Row position [0..getRowCount()-1]
1808: * @throws NullPointerException If field value is <b>null</b>
1809: * @throws ArrayIndexOutOfBoundsException
1810: */
1811:
1812: public float getFloat(int iCol, int iRow)
1813: throws NullPointerException, ArrayIndexOutOfBoundsException {
1814:
1815: Object oVal = (((Vector) oResults.get(iRow)).get(iCol));
1816: Class oCls;
1817: float fRetVal;
1818:
1819: oCls = oVal.getClass();
1820:
1821: try {
1822: if (oCls.equals(Short.TYPE))
1823: fRetVal = (float) ((Short) oVal).shortValue();
1824: else if (oCls.equals(Integer.TYPE))
1825: fRetVal = (float) ((Integer) oVal).intValue();
1826: else if (oCls.equals(Class.forName("java.math.BigDecimal")))
1827: fRetVal = ((java.math.BigDecimal) oVal).floatValue();
1828: else if (oCls.equals(Float.TYPE))
1829: fRetVal = ((Float) oVal).floatValue();
1830: else if (oCls.equals(Double.TYPE))
1831: fRetVal = ((Double) oVal).floatValue();
1832: else
1833: fRetVal = new Float(Gadgets.removeChar(oVal.toString(),
1834: ',')).floatValue();
1835: } catch (ClassNotFoundException cnfe) { /* never thrown */
1836: fRetVal = 0f;
1837: }
1838:
1839: return fRetVal;
1840: } // getFloat
1841:
1842: // ----------------------------------------------------------
1843:
1844: /**
1845: * <p>Get pre-loaded value and tries to convert it into a Short</p>
1846: * @param sCol Column name
1847: * @param iRow Row position [0..getRowCount()-1]
1848: * @throws ArrayIndexOutOfBoundsException if column is not found
1849: * @throws NullPointerException If field value is <b>null</b>
1850: */
1851:
1852: public float getFloat(String sCol, int iRow)
1853: throws NullPointerException, ArrayIndexOutOfBoundsException {
1854:
1855: int iCol = getColumnPosition(sCol);
1856:
1857: if (iCol == -1)
1858: throw new ArrayIndexOutOfBoundsException("Column " + sCol
1859: + " not found");
1860:
1861: return getFloat(iCol, iRow);
1862: }
1863:
1864: // ----------------------------------------------------------
1865:
1866: /**
1867: * <p>Get pre-loaded value and tries to convert it into a float</p>
1868: * @param iCol Column position [0..getColumnCount()-1]
1869: * @param iRow Row position [0..getRowCount()-1]
1870: * @param iDecimals Decimal places for float value
1871: * @throws ArrayIndexOutOfBoundsException if column is not found
1872: * @throws NullPointerException If field value is <b>null</b>
1873: */
1874:
1875: public float getFloat(int iCol, int iRow, int iDecimals)
1876: throws NullPointerException, ArrayIndexOutOfBoundsException {
1877:
1878: float p, f = getFloat(iCol, iRow);
1879: int i;
1880:
1881: if (0 == iDecimals)
1882:
1883: return (float) ((int) f);
1884:
1885: else {
1886:
1887: p = 10f;
1888: for (int d = 0; d < iDecimals; d++)
1889: p *= 10;
1890: i = (int) (f * p);
1891:
1892: return ((float) i) / p;
1893: }
1894: } // getFloat
1895:
1896: // ----------------------------------------------------------
1897:
1898: /**
1899: * <p>Get pre-loaded value and tries to convert it into a float</p>
1900: * @param sCol Column name
1901: * @param iRow Row position [0..getRowCount()-1]
1902: * @param iDecimals Decimal places for float value
1903: * @throws ArrayIndexOutOfBoundsException if column is not found
1904: * @throws NullPointerException If field value is <b>null</b>
1905: */
1906:
1907: public float getFloat(String sCol, int iRow, int iDecimals)
1908: throws ArrayIndexOutOfBoundsException, NullPointerException {
1909:
1910: int iCol = getColumnPosition(sCol);
1911:
1912: if (iCol == -1)
1913: throw new ArrayIndexOutOfBoundsException("Column " + sCol
1914: + " not found");
1915:
1916: return getFloat(iCol, iRow, iDecimals);
1917: } // getFloat
1918:
1919: // ----------------------------------------------------------
1920:
1921: /**
1922: * <p>Get pre-loaded value and tries to convert it into an Integer</p>
1923: * @param iCol Column position [0..getColumnCount()-1]
1924: * @param iRow Row position [0..getRowCount()-1]
1925: * @return Field value converted to Integer or <b>null</b> if field was NULL.
1926: */
1927:
1928: public Integer getInteger(int iCol, int iRow)
1929: throws ArrayIndexOutOfBoundsException {
1930:
1931: Object oVal = (((Vector) oResults.get(iRow)).get(iCol));
1932: Class oCls;
1933: Integer iRetVal;
1934:
1935: if (null == oVal)
1936: return null;
1937:
1938: oCls = oVal.getClass();
1939:
1940: try {
1941: if (oCls.equals(Short.TYPE))
1942: iRetVal = new Integer(((Short) oVal).intValue());
1943: else if (oCls.equals(Integer.TYPE))
1944: iRetVal = (Integer) oVal;
1945: else if (oCls.equals(Class.forName("java.math.BigDecimal")))
1946: iRetVal = new Integer(((java.math.BigDecimal) oVal)
1947: .intValue());
1948: else if (oCls.equals(Float.TYPE))
1949: iRetVal = new Integer(((Float) oVal).intValue());
1950: else if (oCls.equals(Double.TYPE))
1951: iRetVal = new Integer(((Double) oVal).intValue());
1952: else
1953: iRetVal = new Integer(oVal.toString());
1954: } catch (ClassNotFoundException cnfe) { /* never thrown */
1955: iRetVal = null;
1956: }
1957:
1958: return iRetVal;
1959:
1960: } // getInteger
1961:
1962: // ----------------------------------------------------------
1963:
1964: /**
1965: * <p>Get pre-loaded value and tries to convert it into an Integer</p>
1966: * @param sCol Column name
1967: * @param iRow Row position [0..getRowCount()-1]
1968: * @return Field value converted to Integer or <b>null</b> if field was NULL.
1969: * @throws ArrayIndexOutOfBoundsException if column is not found
1970: */
1971:
1972: public Integer getInteger(String sCol, int iRow)
1973: throws ArrayIndexOutOfBoundsException {
1974:
1975: int iCol = getColumnPosition(sCol);
1976:
1977: if (iCol == -1)
1978: throw new ArrayIndexOutOfBoundsException("Column " + sCol
1979: + " not found");
1980:
1981: return getInteger(iCol, iRow);
1982: }
1983:
1984: // ----------------------------------------------------------
1985:
1986: /**
1987: * <p>Get pre-loaded value and tries to convert it into a BigDecimal</p>
1988: * If column is NULL then <b>null</b> value is returned.<BR>
1989: * If base columnn is of type String then thsi function will try to parse the
1990: * value into a BigDecimal. A single dot '.' is used as decimal delimiter no
1991: * matter which is the current locale. All comma characters ',' are removed
1992: * before parsing String into BigDecimal.
1993: * @param iCol Column position [0..getColumnCount()-1]
1994: * @param iRow Row position [0..getRowCount()-1]
1995: * @return Field value converted to BigDecimal or <b>null</b> if field was NULL.
1996: * @throws java.lang.ClassCastException
1997: * @throws java.lang.NumberFormatException
1998: */
1999:
2000: public BigDecimal getDecimal(int iCol, int iRow)
2001: throws java.lang.ClassCastException,
2002: java.lang.NumberFormatException {
2003: Object oVal = (((Vector) oResults.get(iRow)).get(iCol));
2004: Class oCls;
2005: BigDecimal oDecVal;
2006:
2007: if (oVal == null)
2008: return null;
2009:
2010: oCls = oVal.getClass();
2011:
2012: if (oCls.equals(Short.TYPE))
2013: oDecVal = new BigDecimal(((Short) oVal).doubleValue());
2014: else if (oCls.equals(Integer.TYPE))
2015: oDecVal = new BigDecimal(((Integer) oVal).doubleValue());
2016: else if (oCls.equals(Float.TYPE))
2017: oDecVal = new BigDecimal(((Float) oVal).doubleValue());
2018: else if (oCls.equals(Double.TYPE))
2019: oDecVal = new BigDecimal(((Double) oVal).doubleValue());
2020: else if (oCls.getName().equalsIgnoreCase("java.lang.String"))
2021: oDecVal = new BigDecimal(Gadgets.removeChar((String) oVal,
2022: ','));
2023: else {
2024: try {
2025: oDecVal = (BigDecimal) oVal;
2026: } catch (ClassCastException cce) {
2027: throw new ClassCastException(
2028: "Cannot cast column of type "
2029: + oVal.getClass().getName()
2030: + " to BigDecimal");
2031: }
2032: }
2033:
2034: return oDecVal;
2035: } // getDecimal
2036:
2037: // ----------------------------------------------------------
2038:
2039: /**
2040: * <p>Get pre-loaded value and tries to convert it into a BigDecimal</p>
2041: * @param sCol Column name
2042: * @param iRow Row position [0..getRowCount()-1]
2043: * @return Field value converted to BigDecimal or <b>null</b> if field was NULL.
2044: * @throws ArrayIndexOutOfBoundsException if column is not found
2045: */
2046: public BigDecimal getDecimal(String sCol, int iRow)
2047: throws ArrayIndexOutOfBoundsException {
2048:
2049: int iCol = getColumnPosition(sCol);
2050:
2051: if (iCol == -1)
2052: throw new ArrayIndexOutOfBoundsException("Column " + sCol
2053: + " not found");
2054:
2055: return getDecimal(iCol, iRow);
2056: } // getDecimal
2057:
2058: // ----------------------------------------------------------
2059:
2060: /**
2061: * <p>Get decimal formated as a String using the given pattern and the symbols for the default locale</p>
2062: * @param iCol Column position [0..getColumnCount()-1]
2063: * @param iRow Row position [0..getRowCount()-1]
2064: * @param sPattern A non-localized pattern string, for example: "#0.00"
2065: * @return String decimal value formated according to sPatern or <b>null</b>
2066: * @throws ClassCastException
2067: * @throws NumberFormatException
2068: * @throws NullPointerException if sPattern is <b>null</b>
2069: * @throws IllegalArgumentException if sPattern is invalid
2070: */
2071: public String getDecimalFormated(int iCol, int iRow, String sPattern)
2072: throws java.lang.ClassCastException,
2073: java.lang.NumberFormatException,
2074: java.lang.NullPointerException,
2075: java.lang.IllegalArgumentException {
2076: BigDecimal oDecVal = getDecimal(iCol, iRow);
2077:
2078: if (null == oDecVal) {
2079: return null;
2080: } else {
2081: if (oDecFmt == null) {
2082: oDecFmt = new DecimalFormat(sPattern);
2083: return oDecFmt.format(oDecVal.doubleValue());
2084: } else {
2085: if (oDecFmt.toPattern().equals(sPattern)) {
2086: return oDecFmt.format(oDecVal.doubleValue());
2087: } else {
2088: oDecFmt = new DecimalFormat(sPattern);
2089: return oDecFmt.format(oDecVal.doubleValue());
2090: }
2091: }
2092: }
2093: } // getDecimalFormated
2094:
2095: // ----------------------------------------------------------
2096:
2097: /**
2098: * <p>Get decimal formated as a String using the given pattern and the symbols for the default locale</p>
2099: * @param sCol Column name
2100: * @param iRow Row position [0..getRowCount()-1]
2101: * @param sPattern A non-localized pattern string, for example: "#0.00"
2102: * @return String decimal value formated according to sPatern or <b>null</b>
2103: * @throws ClassCastException
2104: * @throws NumberFormatException
2105: * @throws NullPointerException if sPattern is <b>null</b>
2106: * @throws IllegalArgumentException if sPattern is invalid
2107: * @throws ArrayIndexOutOfBoundsException if column is not found
2108: */
2109: public String getDecimalFormated(String sCol, int iRow,
2110: String sPattern) throws java.lang.ClassCastException,
2111: java.lang.NumberFormatException,
2112: java.lang.NullPointerException,
2113: java.lang.IllegalArgumentException,
2114: java.lang.ArrayIndexOutOfBoundsException {
2115:
2116: int iCol = getColumnPosition(sCol);
2117:
2118: if (iCol == -1)
2119: throw new ArrayIndexOutOfBoundsException("Column " + sCol
2120: + " not found");
2121:
2122: return getDecimalFormated(iCol, iRow, sPattern);
2123: } // getDecimalFormated
2124:
2125: // ----------------------------------------------------------
2126:
2127: /**
2128: * <p>Get value of a VARCHAR field that holds a money+currency amount<p>
2129: * Money values are stored with its currency sign embedded inside,
2130: * like "26.32 USD" or "$48.3" or "35.44 "
2131: * @param iCol int Column position [0..getColumnCount()-1]
2132: * @param iRow int Row position [0..getRowCount()-1]
2133: * @return com.knowgate.math.Money
2134: * @throws ArrayIndexOutOfBoundsException
2135: * @throws NumberFormatException
2136: * @since 3.0
2137: */
2138: public Money getMoney(int iCol, int iRow)
2139: throws ArrayIndexOutOfBoundsException,
2140: NumberFormatException {
2141: Object obj = (((Vector) oResults.get(iRow)).get(iCol));
2142:
2143: if (null != obj)
2144: if (obj.toString().length() > 0)
2145: return Money.parse(obj.toString());
2146: else
2147: return null;
2148: else
2149: return null;
2150: } // getMoney
2151:
2152: // ----------------------------------------------------------
2153:
2154: /**
2155: * <p>Get value of a VARCHAR field that holds a money+currency amount<p>
2156: * Money values are stored with its currency sign embedded inside,
2157: * like "26.32 USD" or "$48.3" or "35.44 "
2158: * @param iCol int Column position [0..getColumnCount()-1]
2159: * @param iRow int Row position [0..getRowCount()-1]
2160: * @return com.knowgate.math.Money
2161: * @throws ArrayIndexOutOfBoundsException if column is not found
2162: * @throws NumberFormatException
2163: * @since 3.0
2164: */
2165: public Money getMoney(String sCol, int iRow)
2166: throws ArrayIndexOutOfBoundsException,
2167: NumberFormatException {
2168: int iCol = getColumnPosition(sCol);
2169:
2170: if (iCol == -1)
2171: throw new ArrayIndexOutOfBoundsException("Column " + sCol
2172: + " not found");
2173:
2174: return getMoney(iCol, iRow);
2175: } // getMoney
2176:
2177: // ----------------------------------------------------------
2178:
2179: /**
2180: * <p>Get toString() form of pre-loaded value</p>
2181: * @param iCol Column position [0..getColumnCount()-1]
2182: * @param iRow Row position [0..getRowCount()-1]
2183: * @return Field value converted to String or <b>null</b> if field was NULL.
2184: * @throws ArrayIndexOutOfBoundsException
2185: */
2186:
2187: public String getString(int iCol, int iRow)
2188: throws ArrayIndexOutOfBoundsException {
2189:
2190: Object obj = (((Vector) oResults.get(iRow)).get(iCol));
2191:
2192: if (null != obj)
2193: return obj.toString();
2194: else
2195: return null;
2196:
2197: } // getString
2198:
2199: // ----------------------------------------------------------
2200:
2201: /**
2202: * <p>Get toString() form of pre-loaded value</p>
2203: * @param iCol Column position [0..getColumnCount()-1]
2204: * @param iRow Row position [0..getRowCount()-1]
2205: * @param sDef Default value
2206: * @return Field value converted to String default value sDef if field was NULL.
2207: */
2208:
2209: public String getStringNull(int iCol, int iRow, String sDef)
2210: throws ArrayIndexOutOfBoundsException {
2211: String str = getString(iCol, iRow);
2212:
2213: return (null != str ? str : sDef);
2214:
2215: } // getStringNull
2216:
2217: // ----------------------------------------------------------
2218:
2219: /**
2220: * <p>Get toString() form of pre-loaded value</p>
2221: * @param sCol Column name
2222: * @param iRow Row position [0..getRowCount()-1]
2223: * @return Field value converted to String or <b>null</b> if field was NULL.
2224: * @throws ArrayIndexOutOfBoundsException if column is not found
2225: */
2226:
2227: public String getString(String sCol, int iRow)
2228: throws ArrayIndexOutOfBoundsException {
2229: int iCol = getColumnPosition(sCol);
2230:
2231: if (iCol == -1)
2232: throw new ArrayIndexOutOfBoundsException("Column " + sCol
2233: + " not found");
2234:
2235: Object obj = (((Vector) oResults.get(iRow)).get(iCol));
2236:
2237: if (null != obj)
2238: return obj.toString();
2239: else
2240: return null;
2241: } // getString
2242:
2243: // ----------------------------------------------------------
2244:
2245: /**
2246: * <p>Get toString() form of pre-loaded value</p>
2247: * @param sCol Column name
2248: * @param iRow Row position [0..getRowCount()-1]
2249: * @param sDef Default value
2250: * @return Field value converted to String default value sDef if field was NULL.
2251: * @throws ArrayIndexOutOfBoundsException if column is not found
2252: */
2253:
2254: public String getStringNull(String sCol, int iRow, String sDef)
2255: throws ArrayIndexOutOfBoundsException {
2256: int iCol = getColumnPosition(sCol);
2257:
2258: if (iCol == -1)
2259: throw new ArrayIndexOutOfBoundsException("Column " + sCol
2260: + " not found");
2261:
2262: String str = getString(iCol, iRow);
2263:
2264: return (null != str ? str : sDef);
2265: } // getStringNull
2266:
2267: // ----------------------------------------------------------
2268:
2269: /**
2270: * Get Time column
2271: * @param iCol Column position [0..getColumnCount()-1]
2272: * @param iRow Row position [0..getRowCount()-1]
2273: * @return java.sql.Time
2274: * @throws ArrayIndexOutOfBoundsException
2275: * @throws ClassCastException
2276: * @since 3.0
2277: */
2278: public Time getTimeOfDay(int iCol, int iRow)
2279: throws ArrayIndexOutOfBoundsException, ClassCastException {
2280:
2281: Object obj = (((Vector) oResults.get(iRow)).get(iCol));
2282:
2283: if (null != obj)
2284: return (Time) obj;
2285: else
2286: return null;
2287: } // getTimeOfDay
2288:
2289: // ----------------------------------------------------------
2290:
2291: /**
2292: * Get Timestamp columnn
2293: * @param iCol Column position [0..getColumnCount()-1]
2294: * @param iRow Row position [0..getRowCount()-1]
2295: * @return java.sql.Timestamp
2296: * @throws ArrayIndexOutOfBoundsException
2297: * @throws ClassCastException
2298: * @since 2.2
2299: */
2300: public Timestamp getTimestamp(int iCol, int iRow)
2301: throws ArrayIndexOutOfBoundsException, ClassCastException {
2302: Object obj = (((Vector) oResults.get(iRow)).get(iCol));
2303:
2304: if (null != obj) {
2305: if (obj instanceof Timestamp)
2306: return (Timestamp) obj;
2307: else if (obj instanceof Date)
2308: return new Timestamp(((Date) obj).getTime());
2309: else
2310: throw new ClassCastException("Cannot cast "
2311: + obj.getClass().getName() + " to Timestamp");
2312: } else
2313: return null;
2314: }
2315:
2316: // ----------------------------------------------------------
2317:
2318: /**
2319: * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
2320: * @param iCol Column position [0..getColumnCount()-1]
2321: * @param iRow Row position [0..getRowCount()-1]
2322: * @return long Miliseconds or zero if column is <b>null</b>
2323: * @throws ArrayIndexOutOfBoundsException
2324: * @throws ClassCastException
2325: * @since 2.2
2326: */
2327: public long getTimeMilis(int iCol, int iRow)
2328: throws ArrayIndexOutOfBoundsException, ClassCastException {
2329: Object obj = (((Vector) oResults.get(iRow)).get(iCol));
2330:
2331: if (null != obj) {
2332: if (obj instanceof Timestamp)
2333: return ((Timestamp) obj).getTime();
2334: else if (obj instanceof Date)
2335: return ((Date) obj).getTime();
2336: else
2337: throw new ClassCastException("Cannot cast "
2338: + obj.getClass().getName() + " to Timestamp");
2339: } else
2340: return 0;
2341: }
2342:
2343: // ----------------------------------------------------------
2344:
2345: /**
2346: * <p>Return interval value in miliseconds</p>
2347: * This method is only for PostgreSQL 8.0 or later
2348: * @param iCol Column position [0..getColumnCount()-1]
2349: * @param iRow Row position [0..getRowCount()-1]
2350: * @return long Interval in miliseconds. If interval is null then zero is returned.<br>
2351: * For Postgres 7.4 and earlier versions this method always return zero
2352: * even if the interval column is not null.
2353: * @throws ArrayIndexOutOfBoundsException
2354: * @throws ClassCastException
2355: * @since v2.2
2356: */
2357: public long getIntervalMilis(int iCol, int iRow)
2358: throws ArrayIndexOutOfBoundsException, ClassCastException {
2359: Object obj = (((Vector) oResults.get(iRow)).get(iCol));
2360:
2361: if (null == obj)
2362: return 0l;
2363: else if (obj.getClass().getName().equals(
2364: "org.postgresql.util.PGInterval")) {
2365: final long SecMilis = 1000l, MinMilis = 60000l, HourMilis = 3600000l, DayMilis = 86400000l;
2366: long lInterval;
2367: String[] aHMS;
2368: String sInt = obj.toString();
2369: int iDays = sInt.indexOf("days");
2370: if (iDays > 0) {
2371: lInterval = Long
2372: .parseLong(sInt.substring(0, iDays - 1));
2373: aHMS = Gadgets.split(sInt.substring(iDays + 5), ':');
2374: } else {
2375: lInterval = 0;
2376: aHMS = Gadgets.split(sInt, ':');
2377: }
2378: lInterval += Long.parseLong(aHMS[0]) * HourMilis
2379: + Long.parseLong(aHMS[1]) * MinMilis
2380: + Long.parseLong(aHMS[2]) * SecMilis;
2381: return lInterval;
2382: } else
2383: throw new ClassCastException("Cannot cast "
2384: + obj.getClass().getName() + " to Timestamp");
2385: } // getIntervalMilis
2386:
2387: // ----------------------------------------------------------
2388:
2389: /**
2390: * Pre-allocate a given number of empty rows and columns
2391: * @param nCols Number of columns per row
2392: * @param nRows Number of rows to allocate
2393: * @since 2.2
2394: */
2395: public void ensureCapacity(int nCols, int nRows) {
2396: if (DebugFile.trace) {
2397: DebugFile.writeln("Begin DBSubset.ensureCapacity("
2398: + String.valueOf(nCols) + ","
2399: + String.valueOf(nRows) + ")");
2400: DebugFile.incIdent();
2401: }
2402:
2403: oResults = new Vector(nRows);
2404: for (int r = 0; r < nRows; r++) {
2405: Vector oNewRow = new Vector(nCols);
2406: for (int c = 0; c < nCols; c++) {
2407: oNewRow.add(null);
2408: }
2409: oResults.add(oNewRow);
2410: }
2411: if (DebugFile.trace) {
2412: DebugFile.decIdent();
2413: DebugFile.writeln("End DBSubset.ensureCapacity()");
2414: }
2415: } // ensureCapacity
2416:
2417: // ----------------------------------------------------------
2418:
2419: /**
2420: * Set an element for a loaded DBSubset
2421: * @param oObj Object Reference
2422: * @param iCol Column Index [0..getColumnCount()-1]
2423: * @param iRow Row Index [0..getRowCount()-1]
2424: * @throws ArrayIndexOutOfBoundsException
2425: */
2426: public void setElementAt(Object oObj, int iCol, int iRow)
2427: throws ArrayIndexOutOfBoundsException {
2428:
2429: if (DebugFile.trace) {
2430: if (oObj == null)
2431: DebugFile.writeln("DBSubset.setElementAt(null,"
2432: + String.valueOf(iCol) + ","
2433: + String.valueOf(iRow) + ")");
2434: else
2435: DebugFile.writeln("DBSubset.setElementAt("
2436: + oObj.toString() + "," + String.valueOf(iCol)
2437: + "," + String.valueOf(iRow) + ")");
2438: DebugFile.incIdent();
2439: }
2440:
2441: if (null == oResults) {
2442: if (DebugFile.trace)
2443: DebugFile.writeln("new Vector("
2444: + String.valueOf(iFetch) + ",1)");
2445: oResults = new Vector(iFetch, 1);
2446: }
2447:
2448: Vector oRow;
2449: Object oRaw = oResults.get(iRow);
2450:
2451: if (null == oRaw) {
2452: if (DebugFile.trace)
2453: DebugFile.writeln("new Vector(" + String.valueOf(iCol)
2454: + ",1)");
2455: oRow = new Vector(iCol, 1);
2456: oResults.add(iRow, oRow);
2457: } else {
2458: oRow = (Vector) oRaw;
2459: }
2460:
2461: oRow.setElementAt(oObj, iCol);
2462:
2463: if (DebugFile.trace) {
2464: DebugFile.decIdent();
2465: DebugFile.writeln("End DBSubset.setElementAt()");
2466: }
2467: } // setElementAt
2468:
2469: // ----------------------------------------------------------
2470:
2471: /**
2472: * Set an element for a loaded DBSubset
2473: * @param oObj Object Reference
2474: * @param sCol Column Name
2475: * @param iRow Row Index [0..getColumnCount()-1]
2476: * @throws ArrayIndexOutOfBoundsException
2477: */
2478: public void setElementAt(Object oObj, String sCol, int iRow)
2479: throws ArrayIndexOutOfBoundsException {
2480: int iCol = getColumnPosition(sCol);
2481: if (-1 == iCol)
2482: throw new ArrayIndexOutOfBoundsException(
2483: "DBSubset.setElementAt() column " + sCol
2484: + " not found");
2485: else
2486: setElementAt(oObj, iCol, iRow);
2487: } // setElementAt
2488:
2489: // ----------------------------------------------------------
2490:
2491: /**
2492: * @param iCol Column position [0..getColumnCount()-1]
2493: * @param iRow Row position [0..getRowCount()-1]
2494: * @return <b>true</b> if pre-load field is <b>null</b>, <b>false</b> otherwise.
2495: * @throws ArrayIndexOutOfBoundsException
2496: */
2497: public boolean isNull(int iCol, int iRow)
2498: throws ArrayIndexOutOfBoundsException {
2499: Object obj = (((Vector) oResults.get(iRow)).get(iCol));
2500:
2501: return (null == obj);
2502:
2503: } // isNull()
2504:
2505: // ----------------------------------------------------------
2506:
2507: /**
2508: * @param sCol Column name
2509: * @param iRow Row position [0..getRowCount()-1]
2510: * @return <b>true</b> if pre-load field is <b>null</b>, <b>false</b> otherwise.
2511: * @throws ArrayIndexOutOfBoundsException if column is not found
2512: */
2513:
2514: public boolean isNull(String sCol, int iRow)
2515: throws ArrayIndexOutOfBoundsException {
2516: int iCol = getColumnPosition(sCol);
2517:
2518: if (iCol == -1)
2519: throw new ArrayIndexOutOfBoundsException("Column " + sCol
2520: + " not found");
2521:
2522: Object obj = (((Vector) oResults.get(iRow)).get(iCol));
2523:
2524: return (null == obj);
2525: } // isNull()
2526:
2527: // ----------------------------------------------------------
2528:
2529: /**
2530: * <p>Write DBSubset to a delimited text string using the column and row delimiters
2531: * stablished at setColumnDelimiter() and setRowDelimiter() properties.</p>
2532: * @return String dump of the whole DBSubset pre-loaded data.
2533: */
2534:
2535: public String toString() {
2536: Vector vRow;
2537: int iCol;
2538: int iRowCount;
2539: StringBuffer strBuff;
2540:
2541: if (oResults == null)
2542: return "";
2543:
2544: iRowCount = oResults.size();
2545:
2546: if (iRowCount == 0)
2547: return "";
2548:
2549: strBuff = new StringBuffer(64 * iRowCount);
2550:
2551: for (int iRow = 0; iRow < iRowCount; iRow++) {
2552: vRow = (Vector) oResults.get(iRow);
2553: iCol = 0;
2554: while (iCol < iColCount) {
2555: strBuff.append(vRow.get(iCol));
2556: if (++iCol < iColCount)
2557: strBuff.append(sColDelim);
2558: }
2559: strBuff.append(sRowDelim);
2560: }
2561:
2562: return strBuff.toString();
2563: } // toString()
2564:
2565: // ----------------------------------------------------------
2566:
2567: /**
2568: * <p>Write DBSubset to an XML string</p>
2569: * @param sIdent Initial space identations on the left for fields
2570: * @param sNode Name of top parent node. If <b>null</b> then main table name
2571: * for this DBSubset is used.
2572: * @param sDateFormat Output format for date values
2573: * @param sDecimalFormat Output format for decimal and floating point values
2574: * @return XML string dump of the whole DBSubset pre-loaded data.
2575: */
2576:
2577: public String toXML(String sIdent, String sNode,
2578: String sDateFormat, String sDecimalFormat) {
2579: Vector vRow;
2580: int iAs;
2581: int iCol;
2582: int iDot;
2583: int iRowCount;
2584: int iTokCount;
2585: StringBuffer strBuff;
2586: StringTokenizer strTok;
2587: String sLabel;
2588: String sNodeName;
2589: Object oColValue;
2590: Class oColClass, ClassString = null, ClassDate = null, ClassBigDecimal = null, ClassDouble = null, ClassFloat = null;
2591: SimpleDateFormat oXMLDate;
2592: DecimalFormat oDecFmt = null;
2593:
2594: if (sDateFormat == null)
2595: oXMLDate = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
2596: else if (sDateFormat.length() == 0)
2597: oXMLDate = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
2598: else
2599: oXMLDate = new SimpleDateFormat(sDateFormat);
2600:
2601: if (null != sDecimalFormat) {
2602: if (sDecimalFormat.length() > 0)
2603: oDecFmt = new DecimalFormat(sDecimalFormat);
2604: } // fi
2605:
2606: if (DebugFile.trace) {
2607: DebugFile.writeln("Begin DBSubset.toXML(" + sNode + ")");
2608: DebugFile.incIdent();
2609: }
2610:
2611: try {
2612: ClassString = Class.forName("java.lang.String");
2613: ClassDate = Class.forName("java.util.Date");
2614: ClassBigDecimal = Class.forName("java.math.BigDecimal");
2615: ClassDouble = Class.forName("java.lang.Double");
2616: ClassFloat = Class.forName("java.lang.Float");
2617: } catch (ClassNotFoundException ignore) {
2618: }
2619:
2620: if (oResults != null) {
2621:
2622: sNodeName = (null != sNode ? sNode : sTable);
2623:
2624: iRowCount = oResults.size();
2625: strBuff = new StringBuffer(256 * iRowCount);
2626:
2627: strTok = new StringTokenizer(sColList, ",");
2628: iTokCount = strTok.countTokens();
2629: String[] Labels = new String[iTokCount];
2630:
2631: for (int iTok = 0; iTok < iTokCount; iTok++) {
2632: sLabel = strTok.nextToken();
2633: iAs = sLabel.toUpperCase().indexOf(" AS ");
2634: if (-1 != iAs)
2635: sLabel = sLabel.substring(iAs + 4);
2636: iDot = sLabel.indexOf('.');
2637: if (-1 != iDot)
2638: sLabel = sLabel.substring(++iDot);
2639: Labels[iTok] = sLabel.trim();
2640: } // next
2641:
2642: for (int iRow = 0; iRow < iRowCount; iRow++) {
2643: vRow = (Vector) oResults.get(iRow);
2644: iCol = 0;
2645: strBuff.append(sIdent + "<" + sNodeName + ">\n");
2646: while (iCol < iColCount) {
2647: strBuff.append(sIdent + " <" + Labels[iCol] + ">");
2648: oColValue = vRow.get(iCol);
2649: if (null != oColValue) {
2650: oColClass = oColValue.getClass();
2651:
2652: if (oColClass.equals(ClassString)
2653: && !Labels[iCol].startsWith("gu_"))
2654: strBuff.append("<![CDATA[" + oColValue
2655: + "]]>");
2656:
2657: else if (oColClass.equals(ClassDate))
2658: strBuff
2659: .append(oXMLDate
2660: .format((java.util.Date) oColValue));
2661:
2662: else if (oColClass.equals(ClassBigDecimal)
2663: && (oDecFmt != null))
2664: strBuff
2665: .append(oDecFmt
2666: .format((java.math.BigDecimal) oColValue));
2667:
2668: else if (oColClass.equals(ClassDouble)
2669: && (oDecFmt != null))
2670: strBuff
2671: .append(oDecFmt
2672: .format(((java.lang.Double) oColValue)
2673: .doubleValue()));
2674:
2675: else if (oColClass.equals(ClassFloat)
2676: && (oDecFmt != null))
2677: strBuff
2678: .append(oDecFmt
2679: .format((double) ((java.lang.Float) oColValue)
2680: .floatValue()));
2681:
2682: else
2683: strBuff.append(oColValue);
2684: }
2685: strBuff.append("</" + Labels[iCol] + ">\n");
2686: iCol++;
2687: }
2688: strBuff.append(sIdent + "</" + sNodeName + ">\n");
2689: } // wend
2690: } else
2691: strBuff = new StringBuffer();
2692:
2693: if (DebugFile.trace) {
2694: DebugFile.writeln("End DBSubset.toXML() : "
2695: + String.valueOf(strBuff.length()));
2696: DebugFile.decIdent();
2697: }
2698:
2699: return strBuff.toString();
2700:
2701: } // toXML()
2702:
2703: /**
2704: * <p>Write DBSubset to an XML string</p>
2705: * Use default output format for date values: yyyy-MM-dd'T'hh:mm:ss
2706: * @param sIdent Initial space identations on the left for fields
2707: * @param sNode Name of top parent node. If <b>null</b> then main table name
2708: * for this DBSubset is used.
2709: * @return XML string dump of the whole DBSubset pre-loaded data.
2710: */
2711:
2712: public String toXML(String sIdent, String sNode) {
2713: return toXML(sIdent, sNode, null, null);
2714: }
2715:
2716: // ----------------------------------------------------------
2717:
2718: /**
2719: * <p>Print DBSubset to an output stream<p>
2720: * This method is quite different in behavior from toString() and toXML().
2721: * In toString() and toXML() methods data is first pre-loaded by invoking
2722: * call() or load() methods and then written to a string buffer.
2723: * For toString() and toXML() memory consumption depends on how many rows
2724: * are pre-loaded in memory.
2725: * print() method directly writes readed data to the output stream without creating
2726: * the bidimimensional internal array for holding readed data.
2727: * This way data is directly piped from database to output stream.
2728: * @param oConn Database Connection
2729: * @param oOutStrm Output Stream
2730: * @throws SQLException
2731: */
2732:
2733: public void print(Connection oConn, OutputStream oOutStrm)
2734: throws SQLException {
2735: String sCol;
2736: int iRows;
2737: int iCol;
2738: short jCol;
2739: float fCol;
2740: double dCol;
2741: Date dtCol;
2742: BigDecimal bdCol;
2743: Object oCol;
2744: boolean bQualify = sTxtQualifier.length() > 0;
2745:
2746: if (DebugFile.trace) {
2747: DebugFile
2748: .writeln("Begin DBSubset.print([Connection], [Object])");
2749: DebugFile.incIdent();
2750: }
2751:
2752: Statement oStmt = oConn
2753: .createStatement(ResultSet.TYPE_FORWARD_ONLY,
2754: ResultSet.CONCUR_READ_ONLY);
2755:
2756: if (DebugFile.trace)
2757: DebugFile
2758: .writeln("Statement.executeQuery(" + sSelect + ")");
2759:
2760: ResultSet oRSet = oStmt.executeQuery(sSelect);
2761:
2762: if (DebugFile.trace)
2763: DebugFile.writeln("ResultSet.getMetaData()");
2764:
2765: ResultSetMetaData oMDat = oRSet.getMetaData();
2766: int iCols = oMDat.getColumnCount();
2767:
2768: if (DebugFile.trace)
2769: DebugFile
2770: .writeln("column count = " + String.valueOf(iCols));
2771:
2772: PrintWriter oWriter = new PrintWriter(oOutStrm);
2773:
2774: iRows = 0;
2775: while (oRSet.next()) {
2776: for (int c = 1; c <= iCols; c++) {
2777: switch (oMDat.getColumnType(c)) {
2778: case Types.VARCHAR:
2779: case Types.CHAR:
2780: sCol = oRSet.getString(c);
2781: if (!oRSet.wasNull()) {
2782: sCol = sCol.replace('\n', ' ');
2783: if (bQualify)
2784: oWriter.print(sTxtQualifier + sCol
2785: + sTxtQualifier);
2786: else
2787: oWriter.print(sCol);
2788: }
2789: break;
2790: case Types.DATE:
2791: dtCol = oRSet.getDate(c);
2792: if (!oRSet.wasNull())
2793: oWriter.write(dtCol.toString());
2794: break;
2795: case Types.INTEGER:
2796: iCol = oRSet.getInt(c);
2797: if (!oRSet.wasNull())
2798: oWriter.print(iCol);
2799: break;
2800: case Types.SMALLINT:
2801: jCol = oRSet.getShort(c);
2802: if (!oRSet.wasNull())
2803: oWriter.print(jCol);
2804: break;
2805: case Types.FLOAT:
2806: fCol = oRSet.getFloat(c);
2807: if (!oRSet.wasNull())
2808: oWriter.print(fCol);
2809: break;
2810: case Types.REAL:
2811: dCol = oRSet.getDouble(c);
2812: if (!oRSet.wasNull())
2813: oWriter.print(dCol);
2814: break;
2815: case Types.DECIMAL:
2816: bdCol = oRSet.getBigDecimal(c);
2817: if (!oRSet.wasNull())
2818: oWriter.print(bdCol.toString());
2819: break;
2820: default:
2821: oCol = oRSet.getObject(c);
2822: if (!oRSet.wasNull())
2823: oWriter.print(oCol.toString());
2824: break;
2825: } // end switch()
2826: if (c < iCols)
2827: oWriter.print(getColumnDelimiter());
2828: } // next (c)
2829: oWriter.print(getRowDelimiter());
2830: iRows++;
2831: } // wend()
2832:
2833: oWriter.flush();
2834: oWriter.close();
2835: oWriter = null;
2836:
2837: oRSet.close();
2838: oRSet = null;
2839: oStmt.close();
2840: oStmt = null;
2841:
2842: if (DebugFile.trace) {
2843: DebugFile.decIdent();
2844: DebugFile.writeln("End DBSubset.print() : "
2845: + String.valueOf(iRows));
2846: }
2847:
2848: } // print()
2849:
2850: // ----------------------------------------------------------
2851:
2852: private static String removeQuotes(String sStr) {
2853: final int iLen = sStr.length();
2854: StringBuffer oStr = new StringBuffer(iLen);
2855: char c;
2856:
2857: for (int i = 0; i < iLen; i++) {
2858: c = sStr.charAt(i);
2859: if (c != '"' && c != ' ' && c != '\n' && c != '\t'
2860: && c != '\r')
2861: oStr.append(c);
2862: } // next (c)
2863:
2864: return oStr.toString();
2865: } // removeQuotes
2866:
2867: // ----------------------------------------------------------
2868:
2869: /**
2870: * <p>Store full contents of this DBSubset at base table</p>
2871: * <p>This method takes all the dat contained in memory for this DBSubsets and
2872: * stores it at the database. For each row, if it does not exist then it is
2873: * inserted, if it exists then it is updated.
2874: * @param oConn JDBC Database Connection
2875: * @param oDBPersistSubclass DBPersist subclass for rows. DBSubset will call the
2876: * proper DBPersist.store() derived method for each row, executing specific code
2877: * for the subclass such as automatic GUID at modification date generation.
2878: * @param bStopOnError <b>true</b> if process should stop if any SQLException is
2879: * thrown, <b>false</b> if process must continue upon an SQLException and leave
2880: * return addional information throught SQLException[] array.
2881: * @return An array with a SQLException object per stored row, if no SQLException
2882: * was trown for a row then the entry at the array for that row is <b>null</b>.<br>
2883: * eof() property is set to <b>true</b> if all rows were inserted successfully,
2884: * and, thus, all entries of the returned SQLException array are null; if any row
2885: * failed to be inserted or updated then eof() is set to <b>false</b>
2886: * @throws SQLException Only if bStopOnError is <b>true</b>
2887: * @trhows ArrayIndexOutOfBoundsException If a table column is not found by its name
2888: * @throws IllegalAccessException
2889: * @throws InstantiationException
2890: */
2891: public SQLException[] store(JDCConnection oConn,
2892: Class oDBPersistSubclass, boolean bStopOnError)
2893: throws SQLException, IllegalAccessException,
2894: InstantiationException, ArrayIndexOutOfBoundsException {
2895:
2896: DBPersist oDBP;
2897: DBTable oTbl;
2898: Object oFld;
2899: Statement oStmt;
2900: ResultSet oRSet;
2901: ResultSetMetaData oMDat;
2902: SQLException[] aExceptions;
2903: int iExceptions = 0;
2904: int iType = Types.NULL;
2905:
2906: if (DebugFile.trace) {
2907: if (null == oDBPersistSubclass)
2908: DebugFile
2909: .writeln("Begin DBSubset.store([Connection],null");
2910: else
2911: DebugFile.writeln("Begin DBSubset.store([Connection],["
2912: + oDBPersistSubclass.getName() + "]");
2913: DebugFile.incIdent();
2914: }
2915:
2916: String[] aCols = Gadgets.split(removeQuotes(sColList), ',');
2917:
2918: iColCount = aCols.length;
2919:
2920: if (oDBPersistSubclass != null) {
2921: oDBP = (DBPersist) oDBPersistSubclass.newInstance();
2922: oTbl = oDBP.getTable();
2923:
2924: sColList = "";
2925: for (int c = 0; c < iColCount; c++)
2926: if (null != oTbl.getColumnByName(aCols[c]))
2927: sColList += (c == 0 ? "" : ",") + aCols[c];
2928: else
2929: sColList += (c == 0 ? "" : ",") + "'void' AS "
2930: + aCols[c];
2931: }
2932:
2933: final int iRowCount = getRowCount();
2934:
2935: if (bStopOnError)
2936: aExceptions = null;
2937: else
2938: aExceptions = new SQLException[iRowCount];
2939:
2940: oStmt = oConn.createStatement();
2941:
2942: if (DebugFile.trace)
2943: DebugFile.writeln("Statement.executeQuery(SELECT "
2944: + sColList + " FROM " + sTable + " WHERE 1=0)");
2945:
2946: oRSet = oStmt.executeQuery("SELECT " + sColList + " FROM "
2947: + sTable + " WHERE 1=0");
2948: oMDat = oRSet.getMetaData();
2949:
2950: int[] aTypes = new int[oMDat.getColumnCount()];
2951:
2952: ColNames = new String[oMDat.getColumnCount()];
2953:
2954: for (int t = 1; t <= iColCount; t++) {
2955: ColNames[t - 1] = oMDat.getColumnName(t).toLowerCase();
2956: aTypes[t - 1] = oMDat.getColumnType(t);
2957: }
2958:
2959: oMDat = null;
2960: oRSet.close();
2961: oStmt.close();
2962:
2963: if (oDBPersistSubclass != null)
2964: oDBP = (DBPersist) oDBPersistSubclass.newInstance();
2965: else
2966: oDBP = new DBPersist(sTable, sTable);
2967:
2968: for (int r = 0; r < iRowCount; r++) {
2969:
2970: if (DebugFile.trace)
2971: DebugFile
2972: .writeln("processing row " + String.valueOf(r));
2973:
2974: for (int c = 0; c < iColCount; c++) {
2975:
2976: oFld = get(c, r);
2977:
2978: if (null != oFld) {
2979: iType = aTypes[c];
2980: if (iType == Types.BLOB)
2981: iType = Types.LONGVARBINARY;
2982: if (iType == Types.CLOB)
2983: iType = Types.LONGVARCHAR;
2984: try {
2985: if (oFld.toString().length() > 0
2986: && !oDBP.AllVals.containsKey(aCols[c])) {
2987: if (oFld.getClass().getName().equals(
2988: "java.util.Date"))
2989: oDBP.put(aCols[c],
2990: (java.util.Date) oFld);
2991: else
2992: oDBP.put(aCols[c], oFld.toString(),
2993: iType);
2994: }
2995: } catch (FileNotFoundException e) { /* never thrown */
2996: }
2997: } // fi (null!=oFld)
2998: } // next (c)
2999:
3000: if (bStopOnError) {
3001:
3002: oDBP.store(oConn);
3003: } else {
3004:
3005: try {
3006:
3007: oDBP.store(oConn);
3008: aExceptions[r] = null;
3009:
3010: } catch (SQLException sqle) {
3011: iExceptions++;
3012: aExceptions[r] = sqle;
3013: }
3014: } // fi (bStopOnError)
3015:
3016: oDBP.clear();
3017: } // next (r)
3018:
3019: ColNames = null;
3020:
3021: aTypes = null;
3022:
3023: bEOF = (0 == iExceptions);
3024:
3025: if (DebugFile.trace) {
3026: DebugFile.decIdent();
3027: DebugFile.writeln("End DBSubset.store() : "
3028: + String.valueOf(iExceptions));
3029: }
3030:
3031: return aExceptions;
3032: } // store
3033:
3034: // ----------------------------------------------------------
3035:
3036: private boolean swapRows(int iRow1, int iRow2)
3037: throws ArrayIndexOutOfBoundsException {
3038: Object oRow1 = oResults.get(iRow1);
3039: Object oRow2 = oResults.get(iRow2);
3040: oResults.setElementAt(oRow2, iRow1);
3041: oResults.setElementAt(oRow1, iRow2);
3042: return true;
3043: }
3044:
3045: /**
3046: * <p>Sort in memory an already loaded ResultSet by a given column</p>
3047: * A modified bubble sort algorithm is used. Resulting in a O(n²) worst case
3048: * and O(n) best case if the ResultSet was already sorted by the given column.
3049: * @param iCol int Column Index [0..getColumnCount()-1]
3050: * @throws ArrayIndexOutOfBoundsException
3051: * @throws ClassCastException
3052: * @since 3.0
3053: */
3054: public void sortBy(int iCol) throws ArrayIndexOutOfBoundsException,
3055: ClassCastException {
3056:
3057: if (DebugFile.trace) {
3058: DebugFile.writeln("Begin DBSubset.sortBy("
3059: + String.valueOf(iCol) + ")");
3060: DebugFile.incIdent();
3061: }
3062:
3063: final int iRows = getRowCount();
3064: final int iRows1 = iRows - 1;
3065: boolean bSwapFlag = true;
3066:
3067: for (int q = 0; q < iRows && bSwapFlag; q++) {
3068: bSwapFlag = false;
3069: for (int r = 0; r < iRows1; r++) {
3070: if (!isNull(iCol, r) || !isNull(iCol, r + 1)) {
3071: if (!isNull(iCol, r) && isNull(iCol, r + 1))
3072: bSwapFlag = swapRows(r, r + 1);
3073: else if (((Comparable) get(iCol, r)).compareTo(get(
3074: iCol, r + 1)) > 0)
3075: bSwapFlag = swapRows(r, r + 1);
3076: } // fi
3077: } // next (r)
3078: } // next (q)
3079:
3080: if (DebugFile.trace) {
3081: DebugFile.decIdent();
3082: DebugFile.writeln("End DBSubset.sortBy("
3083: + String.valueOf(iCol) + ")");
3084: }
3085: } // sortBy
3086:
3087: // ----------------------------------------------------------
3088:
3089: private BigDecimal sumDecimal(int iCol)
3090: throws NumberFormatException,
3091: ArrayIndexOutOfBoundsException {
3092: BigDecimal oRetVal = new BigDecimal(0);
3093: final int iRows = getRowCount();
3094:
3095: for (int r = 0; r < iRows; r++)
3096: if (!isNull(iCol, r))
3097: oRetVal.add(getDecimal(iCol, r));
3098:
3099: return oRetVal;
3100: }
3101:
3102: private Integer sumInteger(int iCol) {
3103: int iRetVal = 0;
3104: final int iRows = getRowCount();
3105:
3106: for (int r = 0; r < iRows; r++)
3107: if (!isNull(iCol, r))
3108: iRetVal += getInt(iCol, r);
3109:
3110: return new Integer(iRetVal);
3111: }
3112:
3113: private Short sumShort(int iCol) {
3114: short iRetVal = 0;
3115: final int iRows = getRowCount();
3116:
3117: for (int r = 0; r < iRows; r++)
3118: if (!isNull(iCol, r))
3119: iRetVal += getShort(iCol, r);
3120:
3121: return new Short(iRetVal);
3122: }
3123:
3124: private Float sumFloat(int iCol) {
3125: float fRetVal = 0;
3126: final int iRows = getRowCount();
3127:
3128: for (int r = 0; r < iRows; r++)
3129: if (!isNull(iCol, r))
3130: fRetVal += getFloat(iCol, r);
3131:
3132: return new Float(fRetVal);
3133: }
3134:
3135: private Double sumDouble(int iCol) {
3136: double dRetVal = 0;
3137: final int iRows = getRowCount();
3138:
3139: for (int r = 0; r < iRows; r++)
3140: if (!isNull(iCol, r))
3141: dRetVal += getDouble(iCol, r);
3142:
3143: return new Double(dRetVal);
3144: }
3145:
3146: public Object sum(int iCol) throws NumberFormatException,
3147: ArrayIndexOutOfBoundsException {
3148: final int iRows = getRowCount();
3149:
3150: if (0 == iRows)
3151: return null;
3152:
3153: Object oFirst = null;
3154: int r = 0;
3155: do
3156: oFirst = get(iCol, 0);
3157: while ((null == oFirst) && (r < iRows));
3158:
3159: if (null == oFirst)
3160: return new BigDecimal(0);
3161:
3162: if (oFirst.getClass().getName().equals("java.math.BigDecimal"))
3163: return sumDecimal(iCol);
3164: else if (oFirst.getClass().getName()
3165: .equals("java.lang.Integer"))
3166: return sumInteger(iCol);
3167: else if (oFirst.getClass().getName().equals("java.lang.Short"))
3168: return sumShort(iCol);
3169: else if (oFirst.getClass().getName().equals("java.lang.Float"))
3170: return sumFloat(iCol);
3171: else if (oFirst.getClass().getName().equals("java.lang.Double"))
3172: return sumDouble(iCol);
3173: else
3174: throw new NumberFormatException("Column "
3175: + String.valueOf(iCol)
3176: + " is not a suitable type for sum()");
3177: }
3178:
3179: // ----------------------------------------------------------
3180:
3181: /**
3182: * <p>Append rows from given DBSubset to this DBSubset</p>
3183: * @param oDbs DBSubset An already loaded DBSubset
3184: * @throws ArrayIndexOutOfBoundsException If both DBSubsets do not have the same number of columns
3185: * @throws NullPointerException If oDbs is <b>null</b>
3186: * @since 3.0
3187: */
3188: public void union(DBSubset oDbs)
3189: throws ArrayIndexOutOfBoundsException, NullPointerException {
3190: if (this .getColumnCount() != oDbs.getColumnCount()) {
3191: throw new ArrayIndexOutOfBoundsException(
3192: "DBSubset.union() subsets to be unified must have the same number of columns");
3193: }
3194: final int iDbsRows = oDbs.getRowCount();
3195: if (iDbsRows > 0) {
3196: oResults.ensureCapacity(getRowCount() + iDbsRows);
3197: for (int r = 0; r < iDbsRows; r++) {
3198: oResults.add(oDbs.oResults.get(r));
3199: } // next
3200: } // fi
3201: } // union
3202:
3203: // ----------------------------------------------------------
3204:
3205: /**
3206: * <p>Parse a delimited text file into DBSubset bi-dimensional array</p>
3207: * The parsed file must have the same column structure as the column list set when the DBSubset constructor was called.
3208: * @param sFilePath File Path
3209: * @param sCharSet Character set encoding for file
3210: * @throws IOException
3211: * @throws FileNotFoundException
3212: * @throws ArrayIndexOutOfBoundsException Delimited values for a file is greater
3213: * than columns specified at descriptor.
3214: * @throws RuntimeException If delimiter is not one of { ',' ';' or '\t' }
3215: * @throws NullPointerException if sFileDescriptor is <b>null</b>
3216: * @throws IllegalArgumentException if sFileDescriptor is ""
3217: */
3218:
3219: public void parseCSV(String sFilePath, String sCharSet)
3220: throws ArrayIndexOutOfBoundsException, IOException,
3221: FileNotFoundException, RuntimeException,
3222: NullPointerException, IllegalArgumentException {
3223:
3224: if (DebugFile.trace) {
3225: DebugFile.writeln("Begin DBSubset.parseCSV(" + sFilePath
3226: + ")");
3227: DebugFile.incIdent();
3228: }
3229:
3230: Vector oRow;
3231:
3232: String[] aCols = Gadgets.split(removeQuotes(sColList), ',');
3233:
3234: iColCount = aCols.length;
3235:
3236: CSVParser oParser = new CSVParser(sCharSet);
3237:
3238: oParser.parseFile(sFilePath, sColList.replace(',', sColDelim
3239: .charAt(0)));
3240:
3241: final int iRowCount = oParser.getLineCount();
3242:
3243: oResults = new Vector(iRowCount, 1);
3244:
3245: for (int r = 0; r < iRowCount; r++) {
3246: oRow = new Vector(iColCount);
3247:
3248: for (int c = 0; c < iColCount; c++)
3249: oRow.add(oParser.getField(c, r));
3250:
3251: oResults.add(oRow);
3252: } // next
3253:
3254: if (DebugFile.trace) {
3255: DebugFile.decIdent();
3256: DebugFile.writeln("End DBSubset.parseCSV()");
3257: }
3258: } // parseCSV()
3259:
3260: // ----------------------------------------------------------
3261:
3262: /**
3263: * <p>Parse a delimited text file into DBSubset bi-dimensional array</p>
3264: * The parsed file must have the same column structure as the column list set when the DBSubset constructor was called.
3265: * @param sFilePath File Path
3266: */
3267:
3268: public void parseCSV(String sFilePath)
3269: throws ArrayIndexOutOfBoundsException, IOException,
3270: FileNotFoundException, RuntimeException,
3271: NullPointerException, IllegalArgumentException {
3272:
3273: parseCSV(sFilePath, null);
3274:
3275: } // parseCSV()
3276:
3277: // ----------------------------------------------------------
3278:
3279: /**
3280: * <p>Parse character data into DBSubset bi-dimensional array</p>
3281: * The parsed file must have the same column structure as the column list set when the DBSubset constructor was called.
3282: * @param sFilePath Character Data to be parsed
3283: * @param sCharSet Character set encoding for file
3284: */
3285:
3286: public void parseCSV(char[] aData, String sCharSet)
3287: throws ArrayIndexOutOfBoundsException, RuntimeException,
3288: NullPointerException, IllegalArgumentException,
3289: UnsupportedEncodingException {
3290:
3291: if (DebugFile.trace) {
3292: DebugFile.writeln("Begin DBSubset.parseCSV(char[], "
3293: + sCharSet + ")");
3294: DebugFile.incIdent();
3295: }
3296:
3297: Vector oRow;
3298:
3299: String[] aCols = Gadgets.split(removeQuotes(sColList), ',');
3300:
3301: CSVParser oParser = new CSVParser(sCharSet);
3302:
3303: oParser.parseData(aData, sColList.replace(',', sColDelim
3304: .charAt(0)));
3305:
3306: final int iRowCount = oParser.getLineCount();
3307: iColCount = aCols.length;
3308:
3309: oResults = new Vector(iRowCount, 1);
3310:
3311: for (int r = 0; r < iRowCount; r++) {
3312: oRow = new Vector(iColCount);
3313:
3314: for (int c = 0; c < iColCount; c++)
3315: oRow.add(oParser.getField(c, r));
3316:
3317: oResults.add(oRow);
3318: } // next
3319:
3320: if (DebugFile.trace) {
3321: DebugFile.decIdent();
3322: DebugFile.writeln("End DBSubset.parseCSV()");
3323: }
3324: } // parseCSV()
3325:
3326: // ----------------------------------------------------------
3327:
3328: /**
3329: * <p>Parse character data into DBSubset bi-dimensional array</p>
3330: * The parsed file must have the same column structure as the column list set when the DBSubset constructor was called.
3331: * @param sFilePath Character Data to be parsed
3332: */
3333:
3334: public void parseCSV(char[] aData)
3335: throws ArrayIndexOutOfBoundsException, RuntimeException,
3336: NullPointerException, IllegalArgumentException,
3337: UnsupportedEncodingException {
3338:
3339: parseCSV(aData, null);
3340: }
3341:
3342: // **********************************************************
3343: // Private Variables
3344:
3345: private static Class getClassForName(String sClassName) {
3346: Class oRetVal;
3347: try {
3348: oRetVal = Class.forName(sClassName);
3349: } catch (ClassNotFoundException cnfe) {
3350: oRetVal = null;
3351: }
3352:
3353: return oRetVal;
3354: }
3355:
3356: // ----------------------------------------------------------
3357:
3358: private static Class ClassLangString = getClassForName("java.lang.String");
3359: private static Class ClassUtilDate = getClassForName("java.util.Date");
3360: private static Class ClassSQLDate = getClassForName("java.sql.Date");
3361: private static Class ClassSQLTime = getClassForName("java.sql.Time");
3362: private static Class ClassTimestamp = getClassForName("java.sql.Timestamp");
3363:
3364: private int iFetch;
3365: private int iTimeOut;
3366: private int iColCount;
3367: private int iMaxRows;
3368: private boolean bEOF;
3369: private String sTable;
3370: private String sColList;
3371: private String sFilter;
3372: private String sSelect;
3373: private String sInsert;
3374: private String sColDelim;
3375: private String sRowDelim;
3376: private String sTxtQualifier;
3377: private Vector oResults;
3378: private String ColNames[];
3379: private SimpleDateFormat oShortDate;
3380: private SimpleDateFormat oDateTime;
3381: private SimpleDateFormat oDateTime24;
3382: private DecimalFormat oDecFmt;
3383:
3384: } // DBSubset
|