001: /**
002: * $RCSfile$
003: * $Revision: 3055 $
004: * $Date: 2005-11-10 21:57:51 -0300 (Thu, 10 Nov 2005) $
005: *
006: * Copyright (C) 2004 Jive Software. All rights reserved.
007: *
008: * This software is published under the terms of the GNU Public License (GPL),
009: * a copy of which is included in this distribution.
010: */package org.jivesoftware.database;
011:
012: import org.jivesoftware.util.Log;
013:
014: import java.util.List;
015: import java.util.ArrayList;
016: import java.sql.Types;
017: import java.sql.PreparedStatement;
018: import java.sql.SQLException;
019:
020: /**
021: * Allows PreparedStatement information to be cached. A prepared statement consists of
022: * a SQL statement containing bind variables as well as variable values. For example,
023: * the SQL statement <tt>"SELECT * FROM person WHERE age > ?"</tt> would have the integer
024: * variable <tt>18</tt> (which replaces the "?" chracter) to find all adults. This class
025: * encapsulates both the SQL string and bind variable values so that actual
026: * PreparedStatement can be created from that information later.
027: *
028: * @author Matt Tucker
029: */
030: public class CachedPreparedStatement {
031:
032: private String sql;
033: private List<Object> params;
034: private List<Integer> types;
035:
036: /**
037: * Constructs a new CachedPreparedStatement.
038: */
039: public CachedPreparedStatement() {
040: params = new ArrayList<Object>();
041: types = new ArrayList<Integer>();
042: }
043:
044: /**
045: * Constructs a new CachedPreparedStatement.
046: *
047: * @param sql the SQL.
048: */
049: public CachedPreparedStatement(String sql) {
050: this ();
051: setSQL(sql);
052: }
053:
054: /**
055: * Returns the SQL.
056: *
057: * @return the SQL.
058: */
059: public String getSQL() {
060: return sql;
061: }
062:
063: /**
064: * Sets the SQL.
065: *
066: * @param sql the SQL.
067: */
068: public void setSQL(String sql) {
069: this .sql = sql;
070: }
071:
072: /**
073: * Adds a boolean parameter to the prepared statement.
074: *
075: * @param value the boolean value.
076: */
077: public void addBoolean(boolean value) {
078: params.add(value);
079: types.add(Types.BOOLEAN);
080: }
081:
082: /**
083: * Adds an integer parameter to the prepared statement.
084: *
085: * @param value the int value.
086: */
087: public void addInt(int value) {
088: params.add(value);
089: types.add(Types.INTEGER);
090: }
091:
092: /**
093: * Adds a long parameter to the prepared statement.
094: *
095: * @param value the long value.
096: */
097: public void addLong(long value) {
098: params.add(value);
099: types.add(Types.BIGINT);
100: }
101:
102: /**
103: * Adds a String parameter to the prepared statement.
104: *
105: * @param value the String value.
106: */
107: public void addString(String value) {
108: params.add(value);
109: types.add(Types.VARCHAR);
110: }
111:
112: /**
113: * Sets all parameters on the given PreparedStatement. The standard code block
114: * for turning a CachedPreparedStatement into a PreparedStatement is as follows:
115: *
116: * <pre>
117: * PreparedStatement pstmt = con.prepareStatement(cachedPstmt.getSQL());
118: * cachedPstmt.setParams(pstmt);
119: * </pre>
120: *
121: * @param pstmt the prepared statement.
122: * @throws java.sql.SQLException if an SQL Exception occurs.
123: */
124: public void setParams(PreparedStatement pstmt) throws SQLException {
125: for (int i = 0; i < params.size(); i++) {
126: Object param = params.get(i);
127: int type = types.get(i);
128: // Set param, noting fact that params start at 1 and not 0.
129: switch (type) {
130: case Types.INTEGER:
131: pstmt.setInt(i + 1, (Integer) param);
132: break;
133: case Types.BIGINT:
134: pstmt.setLong(i + 1, (Long) param);
135: break;
136: case Types.VARCHAR:
137: pstmt.setString(i + 1, (String) param);
138: break;
139: case Types.BOOLEAN:
140: pstmt.setBoolean(i + 1, (Boolean) param);
141: }
142: }
143: }
144:
145: public boolean equals(Object object) {
146: if (object == null) {
147: return false;
148: }
149: if (!(object instanceof CachedPreparedStatement)) {
150: return false;
151: }
152: if (this == object) {
153: return true;
154: }
155: CachedPreparedStatement otherStmt = (CachedPreparedStatement) object;
156: return (sql == null && otherStmt.sql == null) || sql != null
157: && sql.equals(otherStmt.sql)
158: && types.equals(otherStmt.types)
159: && params.equals(otherStmt.params);
160: }
161:
162: public int hashCode() {
163: int hashCode = 1;
164: if (sql != null) {
165: hashCode += sql.hashCode();
166: }
167: hashCode = hashCode * 31 + types.hashCode();
168: hashCode = hashCode * 31 + params.hashCode();
169: return hashCode;
170: }
171:
172: public String toString() {
173: String toStringSql = sql;
174: try {
175: int index = toStringSql.indexOf('?');
176: int count = 0;
177:
178: while (index > -1) {
179: Object param = params.get(count);
180: int type = types.get(count);
181: String val = null;
182:
183: // Get param
184: switch (type) {
185: case Types.INTEGER:
186: val = "" + param;
187: break;
188: case Types.BIGINT:
189: val = "" + param;
190: break;
191: case Types.VARCHAR:
192: val = '\'' + (String) param + '\'';
193: break;
194: case Types.BOOLEAN:
195: val = "" + param;
196: }
197:
198: toStringSql = toStringSql.substring(0, index)
199: + val
200: + ((index == toStringSql.length() - 1) ? ""
201: : toStringSql.substring(index + 1));
202: index = toStringSql.indexOf('?', index + val.length());
203: count++;
204: }
205: } catch (Exception e) {
206: Log.error(e);
207: }
208:
209: return "CachedPreparedStatement{ sql=" + toStringSql + '}';
210: }
211: }
|