0001: //** Copyright Statement ***************************************************
0002: //The Salmon Open Framework for Internet Applications (SOFIA)
0003: // Copyright (C) 1999 - 2002, Salmon LLC
0004: //
0005: // This program is free software; you can redistribute it and/or
0006: // modify it under the terms of the GNU General Public License version 2
0007: // as published by the Free Software Foundation;
0008: //
0009: // This program is distributed in the hope that it will be useful,
0010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
0011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0012: // GNU General Public License for more details.
0013: //
0014: // You should have received a copy of the GNU General Public License
0015: // along with this program; if not, write to the Free Software
0016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0017: //
0018: // For more information please visit http://www.salmonllc.com
0019: //** End Copyright Statement ***************************************************
0020: package com.salmonllc.sql;
0021:
0022: import java.io.*;
0023: import java.sql.*;
0024: import java.text.SimpleDateFormat;
0025: import java.util.Enumeration;
0026: import java.util.StringTokenizer;
0027: import java.util.Vector;
0028: import java.util.Hashtable;
0029: import com.salmonllc.util.MessageLog;
0030: import com.salmonllc.util.Util;
0031:
0032: /**
0033: * This type was created in VisualAge.
0034: */
0035: abstract class DSDataSourceJDBC implements DataSourceIn, DataSourceOut,
0036: Serializable {
0037: public static final int SEL_GEN_SELECT = 0;
0038: public static final int SEL_GEN_PROC = 1;
0039: public static final int SEL_STATIC = 2;
0040: public static final int SEL_PREP_STMT = 3;
0041: //fc 06/24/04
0042: public static final int SEL_GEN_PREP_STMT = 4;
0043:
0044: protected int _selType = SEL_GEN_SELECT;
0045: protected Statement _st;
0046: protected ResultSet _res;
0047: protected String _sql, _proc;
0048: protected StoredProcedureParms _parms;
0049: protected String _tables[];
0050: protected StringBuffer _sqlb;
0051: protected int _autoIncrementCol;
0052: protected boolean _fixDashes = false;
0053:
0054: protected SimpleDateFormat _dateTimeFormat;
0055:
0056: private boolean _enableCancel = false; //Added by FC on 2/21/03. Was added
0057: // to handle JDBC drivers which have
0058: // problems with the cancel() method
0059: // being called. Example Driver:
0060: // JSQLDriver from NetDirect.
0061: //fc 06/11/04 Hashtable used in handling the DataStores with a one to many
0062: // relationship (Master/Detail mode).
0063: private Hashtable _htinsertedmasterkeydata;
0064: private Hashtable _batchedInserts;
0065: private DataStoreBuffer.TablesRelationshipDescription _dsbTableRelationshipsInserts;
0066: private DataStoreBuffer.TablesRelationshipDescription _dsbTableRelationshipsDeletes;
0067:
0068: /**
0069: * DSSQLDataSource constructor comment.
0070: */
0071: public DSDataSourceJDBC() {
0072: super ();
0073: _dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
0074: }
0075:
0076: /**
0077: * This method was created in VisualAge.
0078: */
0079: public void cancel() throws Exception {
0080: //Modified by FC on 2/21/03. Was changed to handle JDBC drivers which
0081: // have problems with the cancel() method being called.
0082: //Example Driver: JSQLDriver from NetDirect.
0083: if (_enableCancel) {
0084: if (_st != null)
0085: _st.cancel();
0086: } else {
0087: if (_res != null)
0088: _res.close();
0089: if (_st != null)
0090: _st.close();
0091: _res = null;
0092: _st = null;
0093: }
0094: }
0095:
0096: //fc 06/11/04: This returns the foreign key data of a detail row in a
0097: // vector stored as String Repesentations for SQL purposes. Used for one to
0098: // many relationship models.
0099: private Vector getDetailRowForeignKey(DataStore dsData,
0100: DataStoreBuffer dsTables, DataStoreRow row, int iTableRow,
0101: DBConnection conn) throws DataStoreException {
0102: String sDetailColumns = dsTables
0103: .getString(
0104: iTableRow,
0105: DataStoreBuffer.TablesRelationshipDescription.DETAILKEYCOLUMNS);
0106: String[] saColumns = Util.split(sDetailColumns, (","));
0107: Vector vKey = new Vector();
0108: Object oData;
0109: DSDataStoreDescriptor desc = dsData.getDescriptor();
0110: DSColumnDescriptor column;
0111: int iType;
0112: String sValue;
0113: for (int i = 0; i < saColumns.length; i++) {
0114: oData = row.getOriginalData(saColumns[i]);
0115: column = desc
0116: .getColumn(dsData.getColumnIndex(saColumns[i]));
0117: iType = column.getType();
0118: if (oData == null)
0119: sValue = "";
0120: else if (iType == DataStore.DATATYPE_DATETIME) {
0121: sValue = "{ts '"
0122: + formatDateTime((Timestamp) oData,
0123: _dateTimeFormat, conn) + "'}";
0124: } else if (iType == DataStore.DATATYPE_DATE) {
0125: sValue = "{d '"
0126: + DataStore.fixQuote(oData.toString(), iType,
0127: conn.getDBMS()) + "'}";
0128: } else if (iType == DataStore.DATATYPE_TIME) {
0129: sValue = "{t '"
0130: + DataStore.fixQuote(oData.toString(), iType,
0131: conn.getDBMS()) + "'}";
0132: } else if (iType == DataStore.DATATYPE_STRING) {
0133: sValue = "'"
0134: + DataStore.fixQuote(oData.toString(), iType,
0135: conn.getDBMS()) + "'";
0136: } else {
0137: sValue = oData.toString();
0138: }
0139: vKey.addElement(sValue);
0140: }
0141: return vKey;
0142: }
0143:
0144: //fc 06/14/04: This returns the primary key data of a detail row in a
0145: // vector. Used for one to many relationship models.
0146: private Vector getDetailRowPrimaryKey(DataStore dsData,
0147: DataStoreBuffer dsTables, DataStoreRow row, int iTableRow)
0148: throws DataStoreException {
0149: String sTable = dsTables.getString(iTableRow,
0150: DataStoreBuffer.TablesRelationshipDescription.TABLE)
0151: + ".";
0152: String[] saColumnList = dsData.getColumnList();
0153: DSDataStoreDescriptor desc = dsData.getDescriptor();
0154: DSColumnDescriptor column;
0155: Object oData;
0156: Vector vKey = new Vector();
0157: for (int i = 0; i < saColumnList.length; i++) {
0158: if (saColumnList[i].startsWith(sTable)) {
0159: column = desc.getColumn(dsData
0160: .getColumnIndex(saColumnList[i]));
0161: if (column.isPrimaryKey()) {
0162: oData = row.getOriginalData(saColumnList[i]);
0163: if (oData == null)
0164: vKey.addElement("");
0165: else
0166: vKey.addElement(oData);
0167: }
0168: }
0169: }
0170: return vKey;
0171: }
0172:
0173: //fc 08/13/04: This returns whether the primary key data of a detail row in
0174: // a vector is valid. Used for one to many relationship models.
0175: private boolean isValidPrimaryKey(DataStore dsData,
0176: DataStoreBuffer dsTables, DataStoreRow row, int iTableRow)
0177: throws DataStoreException {
0178: Vector vKey = getDetailRowPrimaryKey(dsData, dsTables, row,
0179: iTableRow);
0180: boolean bValid = false;
0181: for (int i = 0; i < vKey.size(); i++) {
0182: Object oKey = vKey.elementAt(i);
0183: if (!oKey.toString().equals("")) {
0184: bValid = true;
0185: break;
0186: }
0187: }
0188: return bValid;
0189: }
0190:
0191: //fc 08/13/04: This returns whether columns have been modified in master
0192: // table for a particular row.
0193: private boolean areTableValuesModified(DataStore dsData,
0194: DataStoreRow row, String sTable) throws DataStoreException {
0195: sTable = sTable + ".";
0196: String[] saColumnList = dsData.getColumnList();
0197: boolean bModified = false;
0198: for (int i = 0; i < saColumnList.length; i++) {
0199: if (saColumnList[i].startsWith(sTable)) {
0200: int iStatus = row.getColumnStatus(dsData
0201: .getColumnIndex(saColumnList[i]));
0202: if (iStatus != DataStoreBuffer.STATUS_NOT_MODIFIED) {
0203: bModified = true;
0204: break;
0205: }
0206: }
0207: }
0208: return bModified;
0209: }
0210:
0211: //fc 06/11/04: This returns the key data of a master row in a vector stored
0212: // as the actual object. Used for one to many relationship models.
0213: private Vector getMasterRowKeyData(
0214: DataStoreBuffer.TablesRelationshipDescription dsTables,
0215: DataStoreRow row, int iTableRow) throws DataStoreException {
0216: String sMasterColumns = dsTables
0217: .getString(
0218: iTableRow,
0219: DataStoreBuffer.TablesRelationshipDescription.MASTERKEYCOLUMNS);
0220: String[] saColumns = Util.split(sMasterColumns, ",");
0221: Vector vKey = new Vector();
0222: Object oData;
0223: for (int i = 0; i < saColumns.length; i++) {
0224: oData = row.getData(saColumns[i]);
0225: if (oData != null)
0226: vKey.addElement(oData);
0227: else
0228: vKey.addElement("");
0229: }
0230: return vKey;
0231: }
0232:
0233: //fc 06/11/04: Copies the master key values to the foreign keys in the
0234: // detail row. Used for one to many relationship models.
0235: private void copyMasterValuesToDetail(
0236: DataStoreBuffer.TablesRelationshipDescription dsTables,
0237: DataStoreRow row, int iTableRow) throws DataStoreException {
0238: String sMasterColumns = dsTables
0239: .getString(
0240: iTableRow,
0241: DataStoreBuffer.TablesRelationshipDescription.MASTERKEYCOLUMNS);
0242: String sDetailColumns = dsTables
0243: .getString(
0244: iTableRow,
0245: DataStoreBuffer.TablesRelationshipDescription.DETAILKEYCOLUMNS);
0246: String[] saDetailColumns = Util.split(sDetailColumns, ",");
0247: String[] saMasterColumns = Util.split(sMasterColumns, ",");
0248: for (int i = 0; i < saDetailColumns.length; i++) {
0249: row.setData(saDetailColumns[i], row
0250: .getData(saMasterColumns[i]));
0251: }
0252: }
0253:
0254: //fc 06/11/04: Copies key values to master column to a specified row. Used
0255: // for one to many relationship models.
0256: private void copyKeyToMasterColumns(
0257: DataStoreBuffer.TablesRelationshipDescription dsTables,
0258: DataStoreRow row, int iTableRow, Vector vKeyData)
0259: throws DataStoreException {
0260: String sMasterColumns = dsTables
0261: .getString(
0262: iTableRow,
0263: DataStoreBuffer.TablesRelationshipDescription.MASTERKEYCOLUMNS);
0264: String[] saMasterColumns = Util.split(sMasterColumns, ",");
0265: Object oData;
0266: for (int i = 0; i < saMasterColumns.length; i++) {
0267: oData = vKeyData.elementAt(i);
0268: if (!oData.equals(""))
0269: row.setData(saMasterColumns[i], oData);
0270: else
0271: row.setData(saMasterColumns[i], null);
0272: }
0273: }
0274:
0275: //fc 06/11/04: Gets the detail row count from the database. Used for one to
0276: // many relationship models.
0277: private int getDetailRowCountFromDB(DataStore dsData,
0278: DataStoreBuffer.TablesRelationshipDescription dsTables,
0279: DataStoreRow row, int iTableRow, DBConnection conn)
0280: throws DataStoreException, SQLException {
0281: String sDetailColumns = dsTables
0282: .getString(
0283: iTableRow,
0284: DataStoreBuffer.TablesRelationshipDescription.DETAILKEYCOLUMNS);
0285: String[] saColumns = Util.split(sDetailColumns, (","));
0286: StringBuffer sbSQL = new StringBuffer();
0287: Vector vKey = getDetailRowForeignKey(dsData, dsTables, row,
0288: iTableRow, conn);
0289: for (int i = 0; i < saColumns.length; i++) {
0290: sbSQL.append(saColumns[i]);
0291: String sValue = (String) vKey.elementAt(i);
0292: if (sValue != null && !sValue.equals("")) {
0293: sbSQL.append(" = ");
0294: sbSQL.append(vKey.elementAt(i));
0295: } else {
0296: sbSQL.append(" is null");
0297: }
0298: sbSQL.append(" and ");
0299: }
0300: sbSQL.setLength(sbSQL.length() - 5);
0301: String[] saTableColumn = Util.split(saColumns[0], ".");
0302: String sTable = saTableColumn[0];
0303: sbSQL.insert(0, "select count(*) from " + sTable + " where ");
0304: Statement st = null;
0305: int iRowCount = 0;
0306: try {
0307: st = conn.createStatement();
0308: ResultSet rs = st.executeQuery(sbSQL.toString());
0309: if (rs.next())
0310: iRowCount = rs.getInt(1);
0311: st.close();
0312: } finally {
0313: if (st != null) {
0314: st.close();
0315: }
0316: }
0317: return iRowCount;
0318: }
0319:
0320: /**
0321: * deleteRow method comment.
0322: */
0323: public boolean deleteRow(DataStore ds, DataStoreRow row,
0324: DBConnection conn) throws Exception {
0325: //fc 06/11/04: Updated to handle One to Many Relationship model deletes
0326: DataStoreBuffer.TablesRelationshipDescription dsb = _dsbTableRelationshipsDeletes;
0327: String sTable;
0328: for (int i = 0; i < dsb.getRowCount(); i++) {
0329: sTable = dsb
0330: .getString(
0331: i,
0332: DataStoreBuffer.TablesRelationshipDescription.TABLE);
0333: int iRelType = dsb
0334: .getInt(
0335: i,
0336: DataStoreBuffer.TablesRelationshipDescription.RELATIONSHIPTYPE);
0337: _sql = "";
0338: PreparedStatement p = null;
0339: try {
0340: int iDetailRowCount = 0;
0341: if (iRelType == DataStoreBuffer.RELATION_ONE_TO_MANY) {
0342: iDetailRowCount = getDetailRowCountFromDB(ds, dsb,
0343: row, i, conn);
0344: if (iDetailRowCount > 0) {
0345: continue;
0346: } else {
0347: if (!ds.getAllowMasterRowDelete())
0348: continue;
0349: }
0350: }
0351: if (iRelType == DataStoreBuffer.RELATION_MANY_TO_ONE) {
0352: if (!isValidPrimaryKey(ds, dsb, row, i))
0353: continue;
0354: }
0355: p = prepareDelete(ds, row, sTable, conn, _sqlb);
0356: _sql = _sqlb.toString();
0357: if (p != null && p.executeUpdate() == 0)
0358: throw new DirtyDataException(
0359: "Error: Deleted row changed between retrieve and update.");
0360: } finally {
0361: if (p != null)
0362: p.close();
0363: }
0364: }
0365: return true;
0366:
0367: }
0368:
0369: public String generateProc(DBConnection conn, DataStore ds)
0370: throws Exception {
0371: StringBuffer sql = new StringBuffer(256);
0372: sql.append("{call ");
0373: sql.append(_proc);
0374: if (_parms != null) {
0375: if (_parms.getParmCount() > 0) {
0376: sql.append(" (");
0377: for (int i = 0; i < _parms.getParmCount(); i++) {
0378: sql.append("?,");
0379: }
0380: sql.setCharAt(sql.length() - 1, ' ');
0381: sql.append(")");
0382: }
0383: }
0384: sql.append('}');
0385:
0386: String sqlSt = sql.toString();
0387: CallableStatement cst = null;
0388:
0389: cst = conn.prepareCall(sqlSt);
0390: if (_parms != null) {
0391: for (int i = 0; i < _parms.getParmCount(); i++)
0392: prepareForType(ds, cst, _parms.getParm(i), _parms
0393: .getDataType(i), i + 1);
0394: }
0395: _res = cst.executeQuery();
0396: _st = cst;
0397:
0398: return sqlSt;
0399: }
0400:
0401: public abstract String generateSelect(DataStore ds,
0402: String criteria, boolean countOnly)
0403: throws DataStoreException;
0404:
0405: /**
0406: * This method was created in VisualAge.
0407: *
0408: * @return java.sql.ResultSetMetaData
0409: */
0410: public ResultSetMetaData getMetaData() throws Exception {
0411: return _res.getMetaData();
0412: }
0413:
0414: /**
0415: * This method was created in VisualAge.
0416: *
0417: * @return java.lang.String
0418: */
0419: public String getSelect() {
0420: return _sql;
0421: }
0422:
0423: /**
0424: * insertRow method comment.
0425: */
0426: public boolean insertRow(DataStore ds, DataStoreRow row,
0427: DBConnection conn) throws Exception {
0428: //fc 06/11/04: Updated to handle One to Many Relationship model inserts
0429: DataStoreBuffer.TablesRelationshipDescription dsb = _dsbTableRelationshipsInserts;
0430: String sTable;
0431: for (int i = 0; i < dsb.getRowCount(); i++) {
0432: sTable = dsb
0433: .getString(
0434: i,
0435: DataStoreBuffer.TablesRelationshipDescription.TABLE);
0436: int iRelType = dsb
0437: .getInt(
0438: i,
0439: DataStoreBuffer.TablesRelationshipDescription.RELATIONSHIPTYPE);
0440: _sql = "";
0441: PreparedStatement p = null;
0442: try {
0443: _autoIncrementCol = -1;
0444: if (iRelType == DataStoreBuffer.RELATION_ONE_TO_MANY) {
0445: Vector vMasterRowKeyData = getMasterRowKeyData(dsb,
0446: row, i);
0447: Vector vKey = (Vector) _htinsertedmasterkeydata
0448: .get(sTable);
0449: if (vKey != null) {
0450: Object oData = vMasterRowKeyData.elementAt(0);
0451: if (oData.equals("")) {
0452: copyKeyToMasterColumns(dsb, row, i, vKey);
0453: }
0454: continue;
0455: } else {
0456: DataStoreRow firstrow = new DataStoreRow(ds,
0457: null, ds.getDescriptor());
0458: DSDataRow dsdrFirstRow = (DSDataRow) ((Vector) ds
0459: .getRows().elementAt(0)).elementAt(0);
0460: firstrow.setDSDataRow(dsdrFirstRow);
0461: Vector vFirstRowMasterRowKeyData = getMasterRowKeyData(
0462: dsb, firstrow, 0);
0463: if (firstrow.getDSDataRow().getRowStatus() == DataStoreBuffer.STATUS_NOT_MODIFIED
0464: || !areTableValuesModified(ds, row,
0465: sTable)) {
0466: _htinsertedmasterkeydata.put(sTable,
0467: vFirstRowMasterRowKeyData);
0468: ds.copyMasterKeyValuesToRow(dsb, firstrow,
0469: row, i);
0470: continue;
0471: }
0472: }
0473: }
0474: if (iRelType == DataStoreBuffer.RELATION_MANY_TO_ONE) {
0475: copyMasterValuesToDetail(dsb, row, i);
0476: }
0477: boolean updateHash = false;
0478: if (ds.getBatchInserts()) {
0479: p = getInsertBatch(sTable);
0480: if (p == null)
0481: updateHash = true;
0482: }
0483: p = prepareInsert(ds, row, sTable, conn, _sqlb, p);
0484: if (updateHash)
0485: setInsertBatch(sTable, p);
0486:
0487: _sql = _sqlb.toString();
0488: if (p != null) {
0489: if (ds.getBatchInserts()) {
0490: p.addBatch();
0491: } else if (p.executeUpdate() == 0)
0492: throw new SQLException(
0493: "Error: Duplicate key on insert.");
0494: }
0495:
0496: if (_autoIncrementCol != -1)
0497: populateAutoIncrementValue(row, conn,
0498: _autoIncrementCol);
0499: if (p != null
0500: && iRelType == DataStoreBuffer.RELATION_ONE_TO_MANY) {
0501: Vector vMasterRowKeyData = getMasterRowKeyData(dsb,
0502: row, i);
0503: Vector vKey = (Vector) _htinsertedmasterkeydata
0504: .get(sTable);
0505: if (vKey == null)
0506: _htinsertedmasterkeydata.put(sTable,
0507: vMasterRowKeyData);
0508: }
0509: } finally {
0510: if (p != null && !ds.getBatchInserts())
0511: p.close();
0512: }
0513: }
0514: return true;
0515: }
0516:
0517: /**
0518: * postRetrieve method comment.
0519: */
0520: public void postRetrieve(DataStore ds) throws Exception {
0521: if (_res != null) {
0522: _res.close();
0523: _res = null;
0524: }
0525: if (_st != null) {
0526: _st.close();
0527: _st = null;
0528: }
0529:
0530: }
0531:
0532: /**
0533: * postUpdate method comment.
0534: */
0535: public void postUpdate(DataStore ds, DBConnection conn,
0536: boolean handleTrans, boolean updateSuccessful)
0537: throws Exception {
0538: Exception ex = null;
0539: try {
0540: if (_batchedInserts != null && updateSuccessful) {
0541: Enumeration en = _batchedInserts.elements();
0542: while (en.hasMoreElements()) {
0543: PreparedStatement st = (PreparedStatement) en
0544: .nextElement();
0545: st.executeBatch();
0546: st.close();
0547: }
0548: }
0549: } catch (Exception e) {
0550: updateSuccessful = false;
0551: ex = e;
0552: }
0553:
0554: if (handleTrans) {
0555: if (updateSuccessful)
0556: conn.commit();
0557: else
0558: conn.rollback();
0559: }
0560:
0561: _tables = null;
0562: _sqlb = null;
0563: _batchedInserts = null;
0564: _dsbTableRelationshipsDeletes = null;
0565: _dsbTableRelationshipsInserts = null;
0566: if (ex != null)
0567: throw (ex);
0568:
0569: }
0570:
0571: private PreparedStatement prepareDelete(DataStore ds,
0572: DataStoreRow row, String tableIn, DBConnection conn,
0573: StringBuffer sqlb) throws java.sql.SQLException,
0574: DataStoreException {
0575:
0576: DSColumnDescriptor col;
0577: String table;
0578: String name, value;
0579: int type;
0580: Object data;
0581: boolean useBind = false;
0582:
0583: SimpleDateFormat df = _dateTimeFormat;
0584: DSDataStoreDescriptor desc = ds.getDescriptor();
0585:
0586: sqlb.setLength(0);
0587: for (int i = 0; i < desc.getColumnCount(); i++) {
0588: col = desc.getColumn(i);
0589: table = col.getTable();
0590: if (table == null)
0591: table = desc.getDefaultTable();
0592: if (table == null)
0593: continue;
0594:
0595: if (table.equals(tableIn)) {
0596: data = row.getOriginalData(i);
0597:
0598: type = col.getType();
0599: name = col.getColumn();
0600: value = "";
0601:
0602: if (useBind(col, ds)) {
0603: if (data == null)
0604: value = " IS NULL";
0605: else
0606: value = " = ?";
0607: } else if (type == DataStore.DATATYPE_DATETIME) {
0608: if (data == null)
0609: value = " IS NULL";
0610: else
0611: value = " = {ts '"
0612: + formatDateTime((Timestamp) data, df,
0613: conn) + "'}";
0614: } else if (type == DataStore.DATATYPE_DATE) {
0615: if (data == null)
0616: value = " IS NULL";
0617: else
0618: value = " = {d '"
0619: + DataStore.fixQuote(data.toString(),
0620: type, conn.getDBMS()) + "'}";
0621: } else if (type == DataStore.DATATYPE_TIME) {
0622: if (data == null)
0623: value = " IS NULL";
0624: else
0625: value = " = {t '"
0626: + DataStore.fixQuote(data.toString(),
0627: type, conn.getDBMS()) + "'}";
0628: } else if (type == DataStore.DATATYPE_STRING) {
0629: if (data == null)
0630: value = " IS NULL";
0631: else
0632: value = " = '"
0633: + DataStore.fixQuote(data.toString(),
0634: type, conn.getDBMS()) + "'";
0635: } else {
0636: if (data == null)
0637: value = " IS NULL";
0638: else
0639: value = " = " + data.toString();
0640: }
0641:
0642: if (col.isPrimaryKey()
0643: || (col.getConcurrency() && ds
0644: .getCheckConcurrency())) {
0645: if (useBind(col, ds))
0646: useBind = true;
0647:
0648: if (sqlb.length() == 0)
0649: sqlb.append(" ");
0650: else
0651: sqlb.append(" AND ");
0652: sqlb.append(fixDashes(name));
0653: sqlb.append(value);
0654: }
0655: }
0656: }
0657:
0658: PreparedStatement p = null;
0659:
0660: if (sqlb.length() > 0) {
0661: sqlb
0662: .insert(0, "DELETE FROM "
0663: + fixDashes(desc.resolveTable(tableIn))
0664: + " WHERE ");
0665: p = conn.prepareStatement(sqlb.toString());
0666: if (useBind) {
0667: int pos = 0;
0668: for (int i = 0; i < desc.getColumnCount(); i++) {
0669: table = desc.getDefaultTable();
0670: col = desc.getColumn(i);
0671: if (col.getTable() != null)
0672: table = col.getTable();
0673: if (table == null)
0674: continue;
0675: if (table.equals(tableIn)
0676: && useBind(col, ds)
0677: && (col.isPrimaryKey() || (col
0678: .getConcurrency() && ds
0679: .getCheckConcurrency()))) {
0680: data = row.getOriginalData(i);
0681: if (data != null) {
0682: pos++;
0683: prepareForType(ds, p, data, col.getType(),
0684: pos);
0685: }
0686: }
0687: }
0688: }
0689: }
0690:
0691: return p;
0692:
0693: }
0694:
0695: /**
0696: * This method was created in VisualAge.
0697: *
0698: * @param pst
0699: * java.sql.PreparedStatement
0700: * @param data
0701: * java.lang.Object
0702: * @param type
0703: * int
0704: */
0705: static void prepareForType(DataStore ds, PreparedStatement pst,
0706: Object data, int type, int pos)
0707: throws java.sql.SQLException {
0708: //fc 06/24/04
0709: if (type == DataStore.DATATYPE_ANY) {
0710: if (ds == null)
0711: ds = new DataStore();
0712: type = ds.getObjectType(data);
0713: }
0714:
0715: switch (type) {
0716: case DataStore.DATATYPE_STRING:
0717: if (data == null)
0718: pst.setNull(pos, java.sql.Types.VARCHAR);
0719: else {
0720: String sData = (String) data;
0721: if (sData.length() > 255) {
0722: StringBufferInputStream is = new StringBufferInputStream(
0723: sData);
0724: InputStreamReader isr = new InputStreamReader(is);
0725: pst.setCharacterStream(pos, isr, sData.length());
0726: } else
0727: pst.setString(pos, sData);
0728: }
0729: break;
0730: case DataStore.DATATYPE_INT:
0731: if (data == null)
0732: pst.setNull(pos, java.sql.Types.INTEGER);
0733: else
0734: pst.setInt(pos, ((Integer) data).intValue());
0735: break;
0736: case DataStore.DATATYPE_DATETIME:
0737: if (data == null)
0738: pst.setNull(pos, java.sql.Types.TIMESTAMP);
0739: else
0740: pst.setTimestamp(pos, (java.sql.Timestamp) data);
0741: break;
0742: case DataStore.DATATYPE_DATE:
0743: if (data == null)
0744: pst.setNull(pos, java.sql.Types.DATE);
0745: else
0746: pst.setDate(pos, (java.sql.Date) data);
0747: break;
0748: case DataStore.DATATYPE_TIME:
0749: if (data == null)
0750: pst.setNull(pos, java.sql.Types.TIME);
0751: else
0752: pst.setTime(pos, (java.sql.Time) data);
0753: break;
0754: case DataStore.DATATYPE_DOUBLE:
0755: if (data == null)
0756: pst.setNull(pos, java.sql.Types.DOUBLE);
0757: else
0758: pst.setDouble(pos, ((Double) data).doubleValue());
0759: break;
0760: case DataStore.DATATYPE_BYTEARRAY:
0761: pst.setBytes(pos, (byte[]) data);
0762: break;
0763: case DataStore.DATATYPE_SHORT:
0764: if (data == null)
0765: pst.setNull(pos, java.sql.Types.SMALLINT);
0766: else
0767: pst.setShort(pos, ((Short) data).shortValue());
0768: break;
0769: case DataStore.DATATYPE_LONG:
0770: if (data == null)
0771: pst.setNull(pos, java.sql.Types.BIGINT);
0772: else
0773: pst.setLong(pos, ((Long) data).longValue());
0774: break;
0775: case DataStore.DATATYPE_FLOAT:
0776: if (data == null)
0777: pst.setNull(pos, java.sql.Types.FLOAT);
0778: else
0779: pst.setFloat(pos, ((Float) data).floatValue());
0780: break;
0781: case DataStore.DATATYPE_ANY:
0782: pst.setNull(pos, java.sql.Types.VARCHAR);
0783:
0784: }
0785:
0786: }
0787:
0788: private PreparedStatement prepareInsert(DataStore ds,
0789: DataStoreRow row, String tableIn, DBConnection conn,
0790: StringBuffer sqlb, PreparedStatement pin)
0791: throws java.sql.SQLException, DataStoreException {
0792: DSColumnDescriptor col;
0793: Object data;
0794: int type;
0795: String value = "";
0796: StringBuffer columnList = new StringBuffer(256);
0797: StringBuffer values = new StringBuffer(256);
0798: boolean colUpdated = false;
0799: boolean useBind = false;
0800: DSDataStoreDescriptor desc = ds.getDescriptor();
0801:
0802: SimpleDateFormat df = _dateTimeFormat;
0803:
0804: for (int j = 0; j < desc.getColumnCount(); j++) {
0805: String table = desc.getDefaultTable();
0806: col = desc.getColumn(j);
0807: if (col.getTable() != null)
0808: table = col.getTable();
0809: if (table == null)
0810: continue;
0811:
0812: if (table.equals(tableIn)) {
0813: if (col.isAutoIncrement())
0814: _autoIncrementCol = j;
0815: if (col.isUpdateable()) {
0816: colUpdated = true;
0817: if (pin != null)
0818: useBind = true;
0819: else {
0820: data = row.getData(j);
0821: type = col.getType();
0822: if (ds.getBatchInserts() || useBind(col, ds)) {
0823: useBind = true;
0824: value = "?";
0825: } else if (data == null)
0826: value = "null";
0827: else if (type == DataStore.DATATYPE_DATETIME)
0828: value = "{ts '"
0829: + formatDateTime((Timestamp) data,
0830: df, conn) + "'}";
0831: else if (type == DataStore.DATATYPE_DATE)
0832: value = "{d '"
0833: + DataStore.fixQuote(data
0834: .toString(), type, conn
0835: .getDBMS()) + "'}";
0836: else if (type == DataStore.DATATYPE_TIME)
0837: value = "{t '"
0838: + DataStore.fixQuote(data
0839: .toString(), type, conn
0840: .getDBMS()) + "'}";
0841: else if (type == DataStore.DATATYPE_STRING)
0842: value = "'"
0843: + DataStore.fixQuote(data
0844: .toString(), type, conn
0845: .getDBMS()) + "'";
0846: else
0847: value = data.toString();
0848:
0849: if (columnList.length() == 0) {
0850: columnList
0851: .append(fixDashes(col.getColumn()));
0852: values.append(value);
0853: } else {
0854: columnList.append(","
0855: + fixDashes(col.getColumn()));
0856: values.append("," + value);
0857: }
0858: }
0859: }
0860:
0861: }
0862: }
0863:
0864: if (pin == null) {
0865: sqlb.setLength(0);
0866: sqlb.append("INSERT INTO ");
0867: sqlb.append(fixDashes(desc.resolveTable(tableIn)));
0868: sqlb.append("(");
0869: sqlb.append(columnList.toString());
0870: sqlb.append(") VALUES (");
0871: sqlb.append(values.toString());
0872: sqlb.append(")");
0873: }
0874: if (colUpdated) {
0875: PreparedStatement p = (pin == null) ? conn
0876: .prepareStatement(sqlb.toString()) : pin;
0877: if (useBind) {
0878: int pos = 0;
0879: for (int j = 0; j < desc.getColumnCount(); j++) {
0880: String table = desc.getDefaultTable();
0881: col = desc.getColumn(j);
0882: if (col.getTable() != null)
0883: table = col.getTable();
0884: if (table == null)
0885: continue;
0886: if (table.equals(tableIn)
0887: && col.isUpdateable()
0888: && (useBind(col, ds) || ds
0889: .getBatchInserts())) {
0890: pos++;
0891: prepareForType(ds, p, row.getData(j), col
0892: .getType(), pos);
0893: }
0894: }
0895: }
0896: return p;
0897: } else
0898: return null;
0899: }
0900:
0901: private PreparedStatement prepareUpdate(DataStore ds,
0902: DataStoreRow row, String tableIn, DBConnection conn,
0903: StringBuffer sqlb) throws java.sql.SQLException,
0904: DataStoreException {
0905:
0906: DSColumnDescriptor col;
0907: String table, name;
0908: String value, value2;
0909: int type;
0910: Object data, curData;
0911: boolean colUpdated = false;
0912: boolean useBind = false;
0913: StringBuffer where = new StringBuffer(256);
0914: StringBuffer set = new StringBuffer(256);
0915: SimpleDateFormat df = _dateTimeFormat;
0916: DSDataStoreDescriptor desc = ds.getDescriptor();
0917:
0918: for (int i = 0; i < desc.getColumnCount(); i++) {
0919: col = desc.getColumn(i);
0920: table = col.getTable();
0921: if (table == null)
0922: table = desc.getDefaultTable();
0923: if (table == null)
0924: continue;
0925:
0926: if (table.equals(tableIn)) {
0927: data = row.getOriginalData(i);
0928: curData = row.getData(i);
0929:
0930: type = col.getType();
0931: name = col.getColumn();
0932: value = "";
0933: value2 = "";
0934:
0935: if (name == null) {
0936: continue;
0937: } else if (useBind(col, ds)) {
0938: if (data == null)
0939: value = " IS NULL ";
0940: else
0941: value = " = ? ";
0942:
0943: value2 = " = ?";
0944: } else if (type == DataStore.DATATYPE_DATETIME) {
0945: if (data == null)
0946: value = " IS NULL";
0947: else
0948: value = " = {ts '"
0949: + formatDateTime((Timestamp) data, df,
0950: conn) + "'}";
0951:
0952: if (curData == null)
0953: value2 = " = NULL";
0954: else
0955: value2 = " = {ts '"
0956: + formatDateTime((Timestamp) curData,
0957: df, conn) + "'}";
0958:
0959: } else if (type == DataStore.DATATYPE_DATE) {
0960: if (data == null)
0961: value = " IS NULL";
0962: else
0963: value = " = {d '"
0964: + DataStore.fixQuote(data.toString(),
0965: type, conn.getDBMS()) + "'}";
0966:
0967: if (curData == null)
0968: value2 = " = NULL";
0969: else
0970: value2 = " = {d '"
0971: + DataStore.fixQuote(
0972: curData.toString(), type, conn
0973: .getDBMS()) + "'}";
0974:
0975: } else if (type == DataStore.DATATYPE_TIME) {
0976: if (data == null)
0977: value = " IS NULL";
0978: else
0979: value = " = {t '"
0980: + DataStore.fixQuote(data.toString(),
0981: type, conn.getDBMS()) + "'}";
0982:
0983: if (curData == null)
0984: value2 = " = NULL";
0985: else
0986: value2 = " = {t '"
0987: + DataStore.fixQuote(
0988: curData.toString(), type, conn
0989: .getDBMS()) + "'}";
0990:
0991: } else if (type == DataStore.DATATYPE_STRING) {
0992: if (data == null)
0993: value = " IS NULL";
0994: else
0995: value = " = '"
0996: + DataStore.fixQuote(data.toString(),
0997: type, conn.getDBMS()) + "'";
0998:
0999: if (curData == null)
1000: value2 = " = NULL";
1001: else
1002: value2 = " = '"
1003: + DataStore.fixQuote(
1004: curData.toString(), type, conn
1005: .getDBMS()) + "'";
1006: } else {
1007: if (data == null)
1008: value = " IS NULL";
1009: else
1010: value = " = " + data.toString();
1011:
1012: if (curData == null)
1013: value2 = " = NULL";
1014: else
1015: value2 = " = " + curData.toString();
1016:
1017: }
1018:
1019: if ((col.isPrimaryKey() || (col.getConcurrency() && ds
1020: .getCheckConcurrency()))) {
1021: if (where.length() == 0)
1022: where.append(" ");
1023: else
1024: where.append(" AND ");
1025:
1026: where.append(fixDashes(name));
1027: where.append(value);
1028:
1029: if (useBind(col, ds))
1030: useBind = true;
1031:
1032: }
1033:
1034: if (col.isUpdateable()) {
1035: if (row.isColumnModified(i)) {
1036: colUpdated = true;
1037:
1038: if (set.length() == 0)
1039: set.append(" SET ");
1040: else
1041: set.append(",");
1042:
1043: set.append(fixDashes(name));
1044:
1045: if (useBind(col, ds))
1046: useBind = true;
1047:
1048: set.append(value2);
1049: }
1050: }
1051: }
1052: }
1053:
1054: if (!colUpdated)
1055: return null;
1056: else {
1057: sqlb.setLength(0);
1058: sqlb.append("UPDATE ");
1059: sqlb.append(fixDashes(desc.resolveTable(tableIn)));
1060: sqlb.append(set.toString());
1061: sqlb.append(" WHERE ");
1062: sqlb.append(where.toString());
1063: PreparedStatement p = conn
1064: .prepareStatement(sqlb.toString());
1065: if (useBind) {
1066: int pos = 0;
1067: for (int i = 0; i < desc.getColumnCount(); i++) {
1068: table = desc.getDefaultTable();
1069: col = desc.getColumn(i);
1070: if (col.getTable() != null)
1071: table = col.getTable();
1072: if (table == null)
1073: continue;
1074: if (table.equals(tableIn) && useBind(col, ds)
1075: && col.isUpdateable()
1076: && row.isColumnModified(i)) {
1077: pos++;
1078: prepareForType(ds, p, row.getData(i), col
1079: .getType(), pos);
1080: }
1081: }
1082:
1083: for (int i = 0; i < desc.getColumnCount(); i++) {
1084: table = desc.getDefaultTable();
1085: col = desc.getColumn(i);
1086: if (col.getTable() != null)
1087: table = col.getTable();
1088: if (table == null)
1089: continue;
1090: if (table.equals(tableIn)
1091: && useBind(col, ds)
1092: && (col.isPrimaryKey() || (col
1093: .getConcurrency() && ds
1094: .getCheckConcurrency()))) {
1095: curData = row.getOriginalData(i);
1096: if (curData != null) {
1097: pos++;
1098: prepareForType(ds, p, curData, col
1099: .getType(), pos);
1100: }
1101: }
1102: }
1103:
1104: }
1105: return p;
1106: }
1107:
1108: }
1109:
1110: /**
1111: * preRetrieve method comment.
1112: */
1113: public boolean preRetrieve(DataStore ds, String criteria,
1114: boolean countOnly, DBConnection conn) throws Exception {
1115: //Modified by FC on 2/21/03. Was changed to handle JDBC drivers which
1116: // have problems with the cancel() method being called.
1117: //Example Driver: JSQLDriver from NetDirect.
1118: _enableCancel = ds.getEnableCancel();
1119: if (_selType == SEL_GEN_PROC)
1120: _sql = generateProc(conn, ds);
1121: else if (_selType == SEL_PREP_STMT)
1122: _sql = generatePrepStmt(conn, ds);
1123: //fc 06/24/04
1124: else if (_selType == SEL_GEN_PREP_STMT) {
1125: _proc = generateSelect(ds, criteria, countOnly);
1126: _sql = generatePrepStmt(conn, ds);
1127: } else {
1128: if (_selType == SEL_GEN_SELECT)
1129: _sql = generateSelect(ds, criteria, countOnly);
1130: _st = conn.createStatement();
1131: _res = _st.executeQuery(_sql);
1132: }
1133: return true;
1134: }
1135:
1136: /**
1137: * preUpdate method comment.
1138: */
1139: public boolean preUpdate(DataStore ds, DBConnection conn,
1140: boolean handleTrans) throws Exception {
1141: _tables = ds.getTableList(true);
1142: _sqlb = new StringBuffer(256);
1143: //fc 06/11/04: Creates the hashtables for One to Many Relationship
1144: // checks
1145: // _htdeletedrowcount = new Hashtable();
1146: _htinsertedmasterkeydata = new Hashtable();
1147: if (_tables.length == 0)
1148: throw new DataStoreException(
1149: "This datastore cannot be updated because there are either no updateable columns or the table(s) primary keys are not included");
1150: _dsbTableRelationshipsInserts = ds
1151: .getTablesRelationshipDescription(ds);
1152: _dsbTableRelationshipsDeletes = ds
1153: .getTablesRelationshipDescription(ds);
1154: _dsbTableRelationshipsInserts
1155: .sort(
1156: DataStoreBuffer.TablesRelationshipDescription.RELATIONSHIPTYPE,
1157: DataStoreBuffer.SORT_DES);
1158: _dsbTableRelationshipsDeletes
1159: .sort(
1160: DataStoreBuffer.TablesRelationshipDescription.RELATIONSHIPTYPE,
1161: DataStoreBuffer.SORT_ASC);
1162:
1163: if (handleTrans)
1164: conn.beginTransaction();
1165:
1166: return true;
1167: }
1168:
1169: /**
1170: * retrieveRow method comment.
1171: */
1172: public boolean retrieveRow(DataStore ds, DataStoreRow row)
1173: throws Exception {
1174: if (_res == null) {
1175: MessageLog
1176: .writeAssertionMessage(
1177: "*******Result Set is null, make datastore not threaded.******",
1178: this );
1179: return false;
1180: }
1181: if (_res.next()) {
1182: row.populateFromResultSet(_res);
1183: return true;
1184: } else
1185: return false;
1186: }
1187:
1188: void setSelType(int iSelType) {
1189: _selType = iSelType;
1190: }
1191:
1192: void setParms(StoredProcedureParms p) {
1193: _parms = p;
1194: }
1195:
1196: public void setProc(String proc, StoredProcedureParms p) {
1197: if (p instanceof PreparedStatementParms)
1198: _selType = SEL_PREP_STMT;
1199: else
1200: _selType = SEL_GEN_PROC;
1201: _proc = proc;
1202: _parms = p;
1203: }
1204:
1205: public void setSelect(String sel) {
1206: _selType = SEL_STATIC;
1207: _sql = sel;
1208: }
1209:
1210: public boolean updateRow(DataStore ds, DataStoreRow row,
1211: DBConnection conn) throws Exception {
1212: //fc 06/11/04: Updated to handle One to Many Relationship model updates
1213: DataStoreBuffer.TablesRelationshipDescription dsb = _dsbTableRelationshipsInserts;
1214: String sTable;
1215: for (int i = 0; i < dsb.getRowCount(); i++) {
1216: sTable = dsb
1217: .getString(
1218: i,
1219: DataStoreBuffer.TablesRelationshipDescription.TABLE);
1220: int iRelType = dsb
1221: .getInt(
1222: i,
1223: DataStoreBuffer.TablesRelationshipDescription.RELATIONSHIPTYPE);
1224: _sql = "";
1225: PreparedStatement p = null;
1226: try {
1227: if (iRelType == DataStoreBuffer.RELATION_ONE_TO_MANY) {
1228: Vector vKey = (Vector) _htinsertedmasterkeydata
1229: .get(sTable);
1230: if (vKey != null) {
1231: continue;
1232: } else {
1233: DataStoreRow firstrow = new DataStoreRow(ds,
1234: null, ds.getDescriptor());
1235: DSDataRow dsdrFirstRow = (DSDataRow) ((Vector) ds
1236: .getRows().elementAt(0)).elementAt(0);
1237: firstrow.setDSDataRow(dsdrFirstRow);
1238: Vector vFirstRowMasterRowKeyData = getMasterRowKeyData(
1239: dsb, firstrow, i);
1240: if (firstrow.getDSDataRow().getRowStatus() == DataStoreBuffer.STATUS_NOT_MODIFIED) {
1241: _htinsertedmasterkeydata.put(sTable,
1242: vFirstRowMasterRowKeyData);
1243: ds.copyMasterKeyValuesToRow(dsb, firstrow,
1244: row, i);
1245: continue;
1246: }
1247: }
1248: }
1249: if (iRelType == DataStoreBuffer.RELATION_MANY_TO_ONE) {
1250: copyMasterValuesToDetail(dsb, row, i);
1251: //fc 06/14/04: if the detail row primary key is null then
1252: // use insert instead of update.
1253: Vector vKey = getDetailRowPrimaryKey(ds, dsb, row,
1254: i);
1255: boolean bNewRow = false;
1256: for (int j = 0; j < vKey.size(); j++) {
1257: if (vKey.elementAt(j).equals("")) {
1258: bNewRow = true;
1259: break;
1260: }
1261: }
1262: if (bNewRow)
1263: p = prepareInsert(ds, row, sTable, conn, _sqlb,
1264: null);
1265:
1266: }
1267: if (p == null)
1268: p = prepareUpdate(ds, row, sTable, conn, _sqlb);
1269: _sql = _sqlb.toString();
1270: if (p != null && p.executeUpdate() == 0)
1271: throw new DirtyDataException(
1272: "Operation Failed: The data you are working on is out of date, another user had already updated or deleted the information, please reload the information and perform the action again.");
1273: if (p != null
1274: && iRelType == DataStoreBuffer.RELATION_ONE_TO_MANY) {
1275: Vector vMasterRowKeyData = getMasterRowKeyData(dsb,
1276: row, i);
1277: Vector vKey = (Vector) _htinsertedmasterkeydata
1278: .get(sTable);
1279: if (vKey == null)
1280: _htinsertedmasterkeydata.put(sTable,
1281: vMasterRowKeyData);
1282: }
1283: } finally {
1284: if (p != null)
1285: p.close();
1286: }
1287: }
1288: return true;
1289: }
1290:
1291: private boolean useBind(DSColumnDescriptor ds, DataStore d) {
1292: if (ds.getUseBind() == DataStore.BIND_DEFAULT)
1293: return d.getUseBindForUpdate();
1294: else if (ds.getUseBind() == DataStore.BIND_TRUE)
1295: return true;
1296: else
1297: return false;
1298: }
1299:
1300: /**
1301: * This method takes the SQL INSERT statements that would have been
1302: * generated to add these rows to the database, and, rather than executing
1303: * them, returns them as a string that can be written to a SQL script file.
1304: */
1305:
1306: public String exportAsSQL(DataStore ds, DBConnection conn,
1307: String separator) {
1308: String s = "";
1309: try {
1310: PreparedStatement p = null;
1311: DataStoreRow row = new DataStoreRow(ds, null, ds
1312: .getDescriptor());
1313: Vector rows = (Vector) (ds.getRows().elementAt(0));
1314: int rowCount = ds.getRowCount();
1315: String[] tables = ds.getTableList(true);
1316: StringBuffer sb = new StringBuffer(256);
1317: for (int rowNo = 0; rowNo < rowCount; rowNo++) {
1318: row.setDSDataRow((DSDataRow) rows.elementAt(rowNo));
1319: for (int i = 0; i < tables.length; i++) {
1320: p = prepareInsert(ds, row, tables[i], conn, sb,
1321: null);
1322: s += fixCRLF(sb.toString(), "||") + separator;
1323: }
1324: p.close();
1325: }
1326: } catch (Exception e) {
1327: MessageLog.writeErrorMessage(e, "Error in exportAsSQL");
1328: }
1329: return s;
1330: }
1331:
1332: public String fixCRLF(String s, String concatOperator) {
1333: int i = -1;
1334: String ss = "' " + concatOperator + " chr(10) "
1335: + concatOperator + " chr(13) " + concatOperator + " '";
1336: int j = ss.length();
1337: while ((i = s.indexOf("\r\n", i)) >= 0) {
1338: s = s.substring(0, i) + ss + s.substring(i + 2);
1339: i = i + j;
1340: }
1341: return s;
1342: }
1343:
1344: /**
1345: * Called by SOFIA to find an auto-generated Primary Key after it does an
1346: * Insert. Note that you must call setAutoIncrement(pkey_col, true) and
1347: * setUpdatable(pkey_col, false) for autogenerated pkeys to work. The
1348: * default implementation of this method is null, and must be overridden on
1349: * a per-database basis because of the lamentable lack of standardization on
1350: * how to retrieve the pkey of an autonumbered row after inserting it.
1351: */
1352:
1353: protected void populateAutoIncrementValue(DataStoreRow row,
1354: DBConnection conn, int colNo) {
1355: }
1356:
1357: protected String generatePrepStmt(DBConnection conn, DataStore ds)
1358: throws Exception {
1359:
1360: PreparedStatement pst = null;
1361:
1362: pst = conn.prepareStatement(_proc);
1363: if (_parms != null) {
1364: for (int i = 0; i < _parms.getParmCount(); i++)
1365: prepareForType(ds, pst, _parms.getParm(i), _parms
1366: .getDataType(i), i + 1);
1367: }
1368: _res = pst.executeQuery();
1369: _st = pst;
1370:
1371: return _proc;
1372: }
1373:
1374: SimpleDateFormat getDateTimeFormat() {
1375: return _dateTimeFormat;
1376: }
1377:
1378: static String formatDateTime(Timestamp t, SimpleDateFormat f,
1379: DBConnection conn) {
1380: String ret = f.format(t);
1381:
1382: if (t.getNanos() == 0)
1383: return ret;
1384:
1385: String nanosString;
1386: String zeros = "000000000";
1387:
1388: nanosString = Integer.toString(t.getNanos());
1389:
1390: // Add leading zeros
1391: nanosString = zeros.substring(0, (9 - nanosString.length()))
1392: + nanosString;
1393:
1394: // Truncate trailing zeros
1395: char[] nanosChar = new char[nanosString.length()];
1396: nanosString.getChars(0, nanosString.length(), nanosChar, 0);
1397: int truncIndex = 8;
1398: while (nanosChar[truncIndex] == '0') {
1399: truncIndex--;
1400: }
1401: nanosString = new String(nanosChar, 0, truncIndex + 1);
1402:
1403: if (conn.getDBMS() == DBConnection.SYBASE_CONNECTION
1404: && nanosString.length() > 3)
1405: nanosString = nanosString.substring(0, 3);
1406:
1407: return ret + "." + nanosString;
1408: }
1409:
1410: protected String fixDashes(String source) {
1411: if (!_fixDashes)
1412: return source;
1413: if (source == null)
1414: return source;
1415: if (source.indexOf("-") == -1)
1416: return source;
1417: StringTokenizer st = new StringTokenizer(source, " .,", true);
1418: StringBuffer sb = new StringBuffer(source.length());
1419: while (st.hasMoreTokens()) {
1420: String tok = st.nextToken();
1421: char c = tok.charAt(0);
1422: if (c == ' ' || c == '.' || c == ',')
1423: sb.append(c);
1424: else if (tok.indexOf("-") > -1) {
1425: sb.append("`");
1426: sb.append(tok);
1427: sb.append("`");
1428: } else
1429: sb.append(tok);
1430: }
1431: return sb.toString();
1432: }
1433:
1434: private void setInsertBatch(String table, PreparedStatement st) {
1435: if (_batchedInserts == null)
1436: _batchedInserts = new Hashtable();
1437: _batchedInserts.put(table, st);
1438: }
1439:
1440: private PreparedStatement getInsertBatch(String table) {
1441: if (_batchedInserts == null)
1442: return null;
1443: return (PreparedStatement) _batchedInserts.get(table);
1444:
1445: }
1446: }
|