001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.GenericStorablePreparedStatement
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql;
023:
024: import org.apache.derby.iapi.services.monitor.ModuleFactory;
025: import org.apache.derby.iapi.services.monitor.Monitor;
026:
027: import org.apache.derby.iapi.services.sanity.SanityManager;
028:
029: import org.apache.derby.catalog.UUID;
030: import org.apache.derby.iapi.services.uuid.UUIDFactory;
031: import org.apache.derby.iapi.util.ByteArray;
032:
033: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
034:
035: import org.apache.derby.iapi.sql.Activation;
036: import org.apache.derby.iapi.sql.ResultColumnDescriptor;
037: import org.apache.derby.iapi.sql.ResultDescription;
038: import org.apache.derby.iapi.sql.ResultSet;
039: import org.apache.derby.iapi.sql.PreparedStatement;
040: import org.apache.derby.iapi.sql.Statement;
041: import org.apache.derby.iapi.sql.StorablePreparedStatement;
042:
043: import org.apache.derby.iapi.sql.execute.ConstantAction;
044: import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
045:
046: import org.apache.derby.iapi.error.StandardException;
047:
048: import org.apache.derby.iapi.reference.SQLState;
049:
050: import org.apache.derby.iapi.services.loader.GeneratedClass;
051: import org.apache.derby.iapi.services.loader.ClassFactory;
052: import org.apache.derby.iapi.services.context.ContextService;
053:
054: import org.apache.derby.iapi.services.io.StoredFormatIds;
055: import org.apache.derby.iapi.services.io.FormatIdUtil;
056: import org.apache.derby.iapi.services.io.ArrayUtil;
057: import org.apache.derby.iapi.services.io.Formatable;
058:
059: import org.apache.derby.iapi.services.monitor.Monitor;
060:
061: import java.sql.Timestamp;
062: import java.io.ObjectOutput;
063: import java.io.ObjectInput;
064: import java.io.IOException;
065:
066: import org.apache.derby.iapi.services.loader.ClassFactory;
067: import org.apache.derby.iapi.services.loader.GeneratedClass;
068: import org.apache.derby.iapi.services.loader.GeneratedMethod;
069:
070: /**
071: * Prepared statement that can be made persistent.
072: * @author jamie
073: */
074: public class GenericStorablePreparedStatement extends
075: GenericPreparedStatement implements Formatable,
076: StorablePreparedStatement {
077:
078: // formatable
079: private ByteArray byteCode;
080: private String className;
081:
082: /**
083: * Niladic constructor, for formatable
084: * only.
085: */
086: public GenericStorablePreparedStatement() {
087: super ();
088: }
089:
090: GenericStorablePreparedStatement(Statement stmt) {
091: super (stmt);
092: }
093:
094: /**
095: * Get our byte code array. Used
096: * by others to save off our byte
097: * code for us.
098: *
099: * @return the byte code saver
100: */
101: ByteArray getByteCodeSaver() {
102: if (byteCode == null) {
103: byteCode = new ByteArray();
104: }
105: return byteCode;
106: }
107:
108: /**
109: * Get and load the activation class. Will always
110: * return a loaded/valid class or null if the class
111: * cannot be loaded.
112: *
113: * @return the generated class, or null if the
114: * class cannot be loaded
115: *
116: * @exception StandardException on error
117: */
118: public GeneratedClass getActivationClass() throws StandardException {
119: if (activationClass == null)
120: loadGeneratedClass();
121:
122: return activationClass;
123: }
124:
125: void setActivationClass(GeneratedClass ac) {
126:
127: super .setActivationClass(ac);
128: if (ac != null) {
129: className = ac.getName();
130:
131: // see if this is an pre-compiled class
132: if (byteCode != null && byteCode.getArray() == null)
133: byteCode = null;
134: }
135: }
136:
137: /////////////////////////////////////////////////////////////
138: //
139: // STORABLEPREPAREDSTATEMENT INTERFACE
140: //
141: /////////////////////////////////////////////////////////////
142:
143: /**
144: * Load up the class from the saved bytes.
145: *
146: * @exception StandardException on error
147: */
148: public void loadGeneratedClass() throws StandardException {
149: LanguageConnectionContext lcc = (LanguageConnectionContext) ContextService
150: .getContext(LanguageConnectionContext.CONTEXT_ID);
151: ClassFactory classFactory = lcc.getLanguageConnectionFactory()
152: .getClassFactory();
153:
154: GeneratedClass gc = classFactory.loadGeneratedClass(className,
155: byteCode);
156:
157: /*
158: ** No special try catch logic to write out bad classes
159: ** here. We don't expect any problems, and in any
160: ** event, we don't have the class builder available
161: ** here.
162: */
163: setActivationClass(gc);
164: }
165:
166: /////////////////////////////////////////////////////////////
167: //
168: // EXTERNALIZABLE INTERFACE
169: //
170: /////////////////////////////////////////////////////////////
171: /**
172: *
173: * @exception IOException on error
174: */
175: public void writeExternal(ObjectOutput out) throws IOException {
176: out.writeObject(getCursorInfo());
177: out.writeBoolean(needsSavepoint());
178: out.writeBoolean(isAtomic);
179: out.writeObject(executionConstants);
180: out.writeObject(resultDesc);
181:
182: // savedObjects may be null
183: if (savedObjects == null) {
184: out.writeBoolean(false);
185: } else {
186: out.writeBoolean(true);
187: ArrayUtil.writeArrayLength(out, savedObjects);
188: ArrayUtil.writeArrayItems(out, savedObjects);
189: }
190:
191: /*
192: ** Write out the class name and byte code
193: ** if we have them. They might be null if
194: ** we don't want to write out the plan, and
195: ** would prefer it just write out null (e.g.
196: ** we know the plan is invalid).
197: */
198: out.writeObject(className);
199: out.writeBoolean(byteCode != null);
200: if (byteCode != null)
201: byteCode.writeExternal(out);
202: }
203:
204: /**
205: * @see java.io.Externalizable#readExternal
206: *
207: * @exception IOException on error
208: * @exception ClassNotFoundException on error
209: */
210: public void readExternal(ObjectInput in) throws IOException,
211: ClassNotFoundException {
212: setCursorInfo((CursorInfo) in.readObject());
213: setNeedsSavepoint(in.readBoolean());
214: isAtomic = (in.readBoolean());
215: executionConstants = (ConstantAction) in.readObject();
216: resultDesc = (ResultDescription) in.readObject();
217:
218: if (in.readBoolean()) {
219: savedObjects = new Object[ArrayUtil.readArrayLength(in)];
220: ArrayUtil.readArrayItems(in, savedObjects);
221: }
222:
223: className = (String) in.readObject();
224: if (in.readBoolean()) {
225: byteCode = new ByteArray();
226: byteCode.readExternal(in);
227: } else
228: byteCode = null;
229: }
230:
231: /////////////////////////////////////////////////////////////
232: //
233: // FORMATABLE INTERFACE
234: //
235: /////////////////////////////////////////////////////////////
236: /**
237: * Get the formatID which corresponds to this class.
238: *
239: * @return the formatID of this class
240: */
241: public int getTypeFormatId() {
242: return StoredFormatIds.STORABLE_PREPARED_STATEMENT_V01_ID;
243: }
244:
245: /////////////////////////////////////////////////////////////
246: //
247: // MISC
248: //
249: /////////////////////////////////////////////////////////////
250: public boolean isStorable() {
251: return true;
252: }
253:
254: public String toString() {
255: if (SanityManager.DEBUG) {
256: String acn;
257: if (activationClass == null)
258: acn = "null";
259: else
260: acn = activationClass.getName();
261:
262: return "GSPS " + System.identityHashCode(this )
263: + " activationClassName=" + acn + " className="
264: + className;
265: } else {
266: return "";
267: }
268: }
269: }
|