001: /**
002: * Sequoia: Database clustering technology.
003: * Copyright (C) 2005 Continuent, Inc.
004: * Contact: sequoia@continuent.org
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: * Initial developer(s): Emmanuel Cecchet.
019: * Contributor(s): ______________________.
020: */package org.continuent.sequoia.common.sql;
021:
022: import java.io.IOException;
023:
024: import org.continuent.sequoia.common.stream.DriverBufferedInputStream;
025: import org.continuent.sequoia.common.stream.DriverBufferedOutputStream;
026: import org.continuent.sequoia.driver.Connection;
027:
028: /**
029: * This class defines a Request object. This basically carries the SQL statement
030: * and the SQL template if this is a PreparedStatement.
031: *
032: * @author <a href="mailto:emmanuel.cecchet@continuent.com">Emmanuel Cecchet</a>
033: * @version 1.0
034: */
035: public class Request {
036: /**
037: * SQL query if this is a statement (should be set in constructor) or query
038: * template if this is a PreparedStatement.
039: */
040: private String sqlQueryOrTemplate;
041:
042: /**
043: * PreparedStatement parameters
044: */
045: private String preparedStatementParameters = null;
046:
047: //
048: // Connection related parameters
049: //
050:
051: /** True if the connection has been set to read-only */
052: private boolean isReadOnly = false;
053:
054: /**
055: * Whether this request has been sent in <code>autocommit</code> mode or
056: * not.
057: */
058: private boolean isAutoCommit = true;
059:
060: /**
061: * Transaction isolation level to use when executing the query inside a
062: * transaction. The value is set by the VirtualDatabaseWorkerThread.
063: */
064: private int transactionIsolation;
065:
066: /**
067: * Timeout for this request in seconds, value 0 means no timeout (should be
068: * set in constructor). This timeout is in seconds, reflecting the jdbc-spec,
069: * and is passed as-is to the backends jdbc-driver. Internally converted to ms
070: * via getTimeoutMs().
071: */
072: private int timeoutInSeconds;
073:
074: /**
075: * Should the backend driver do escape processing before sending to the
076: * database? Simply forwarded to backend driver. No setter for this member,
077: * should be set in constructor.
078: *
079: * @see java.sql.Statement#setEscapeProcessing(boolean)
080: */
081: private boolean escapeProcessing = true;
082:
083: /**
084: * Request identifier only used for failover purposes. This id is sent back by
085: * the controller.
086: */
087: private long id;
088:
089: //
090: // Constructors
091: //
092:
093: /**
094: * Creates a new <code>Request</code> object
095: *
096: * @param sqlTemplate the SQL template (using ? as parameter placeholders) or
097: * null
098: * @param parameters the prepared statement parameters
099: * @param escapeProcessing Should the backend driver do escape processing
100: * before sending to the database?
101: * @param timeoutInSeconds Timeout for this request in seconds, value 0 means
102: * no timeout
103: */
104: public Request(String sqlTemplate, String parameters,
105: boolean escapeProcessing, int timeoutInSeconds) {
106: this .sqlQueryOrTemplate = sqlTemplate;
107: this .preparedStatementParameters = parameters;
108: this .escapeProcessing = escapeProcessing;
109: this .timeoutInSeconds = timeoutInSeconds;
110: }
111:
112: //
113: // Serialization
114: //
115:
116: /**
117: * Creates a new <code>Request</code> object, deserializing it from an input
118: * stream. Has to mirror the serialization method below.
119: *
120: * @param in the input stream to read from
121: * @throws IOException if a network error occurs
122: */
123:
124: public Request(DriverBufferedInputStream in) throws IOException {
125: this .sqlQueryOrTemplate = in.readLongUTF();
126: this .escapeProcessing = in.readBoolean();
127: this .timeoutInSeconds = in.readInt();
128:
129: this .isAutoCommit = in.readBoolean();
130:
131: // Does this request has a template with question marks "?"
132: // true for PreparedStatements
133: // (AND did we ask for them at connection time?)
134: if (in.readBoolean())
135: this .preparedStatementParameters = in.readLongUTF();
136:
137: // success, we received it all
138: }
139:
140: /**
141: * Serialize the request on the output stream by sending only the needed
142: * parameters to reconstruct it on the controller. Has to mirror the
143: * deserialization method above.
144: *
145: * @param out destination DriverBufferedOutputStream
146: * @throws IOException if fails
147: */
148:
149: public void sendToStream(DriverBufferedOutputStream out)
150: throws IOException {
151: out.writeLongUTF(sqlQueryOrTemplate);
152: out.writeBoolean(escapeProcessing);
153: out.writeInt(timeoutInSeconds);
154:
155: out.writeBoolean(isAutoCommit);
156:
157: // Send the "un-"PreparedStatement if the controller wants it:
158: // - either for better parsing
159: // - or to process it
160: // - && this is a PreparedStatement (of course)
161: if (preparedStatementParameters != null) {
162: out.writeBoolean(true);
163: out.writeLongUTF(preparedStatementParameters);
164: } else
165: out.writeBoolean(false);
166: }
167:
168: //
169: // Getters/Setters
170: //
171:
172: /**
173: * Returns the escapeProcessing value.
174: *
175: * @return Returns the escapeProcessing.
176: */
177: public final boolean isEscapeProcessing() {
178: return escapeProcessing;
179: }
180:
181: /**
182: * Sets the escapeProcessing value.
183: *
184: * @param escapeProcessing The escapeProcessing to set.
185: */
186: public final void setEscapeProcessing(boolean escapeProcessing) {
187: this .escapeProcessing = escapeProcessing;
188: }
189:
190: /**
191: * Returns the isAutoCommit value.
192: *
193: * @return Returns the isAutoCommit.
194: */
195: public final boolean isAutoCommit() {
196: return isAutoCommit;
197: }
198:
199: /**
200: * Sets the isAutoCommit value.
201: *
202: * @param isAutoCommit The isAutoCommit to set.
203: */
204: public final void setIsAutoCommit(boolean isAutoCommit) {
205: this .isAutoCommit = isAutoCommit;
206: }
207:
208: /**
209: * Returns the isReadOnly value.
210: *
211: * @return Returns the isReadOnly.
212: */
213: public final boolean isReadOnly() {
214: return isReadOnly;
215: }
216:
217: /**
218: * Sets the isReadOnly value.
219: *
220: * @param isReadOnly The isReadOnly to set.
221: */
222: public final void setIsReadOnly(boolean isReadOnly) {
223: this .isReadOnly = isReadOnly;
224: }
225:
226: /**
227: * Returns the id value.
228: *
229: * @return Returns the id.
230: */
231: public long getId() {
232: return id;
233: }
234:
235: /**
236: * Sets the id value.
237: *
238: * @param id The id to set.
239: */
240: public void setId(long id) {
241: this .id = id;
242: }
243:
244: /**
245: * Returns the sqlQuery value.
246: *
247: * @return Returns the sqlQuery.
248: */
249: public final String getSqlQueryOrTemplate() {
250: return sqlQueryOrTemplate;
251: }
252:
253: /**
254: * Get a short form of this request if the SQL statement exceeds
255: * nbOfCharacters.
256: *
257: * @param nbOfCharacters number of characters to include in the short form.
258: * @return the nbOfCharacters first characters of the SQL statement
259: */
260: public String getSqlShortForm(int nbOfCharacters) {
261: if ((nbOfCharacters == 0)
262: || (sqlQueryOrTemplate.length() < nbOfCharacters))
263: return sqlQueryOrTemplate;
264: else
265: return sqlQueryOrTemplate.substring(0, nbOfCharacters)
266: + "...";
267: }
268:
269: /**
270: * Returns the sqlTemplate value.
271: *
272: * @return Returns the sqlTemplate.
273: */
274: public final String getPreparedStatementParameters() {
275: return preparedStatementParameters;
276: }
277:
278: /**
279: * Returns the timeoutInSeconds value.
280: *
281: * @return Returns the timeoutInSeconds.
282: */
283: public final int getTimeoutInSeconds() {
284: return timeoutInSeconds;
285: }
286:
287: /**
288: * Sets the timeoutInSeconds value.
289: *
290: * @param timeoutInSeconds The timeoutInSeconds to set.
291: */
292: public final void setTimeoutInSeconds(int timeoutInSeconds) {
293: this .timeoutInSeconds = timeoutInSeconds;
294: }
295:
296: /**
297: * Returns the transactionIsolation value.
298: *
299: * @return Returns the transactionIsolation.
300: */
301: public final int getTransactionIsolation() {
302: return transactionIsolation;
303: }
304:
305: /**
306: * Sets the transactionIsolation value.
307: *
308: * @param transactionIsolation The transactionIsolation to set.
309: */
310: public final void setTransactionIsolation(int transactionIsolation) {
311: this.transactionIsolation = transactionIsolation;
312: }
313: }
|