EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.impl.jdbc]

COVERAGE SUMMARY FOR SOURCE FILE [EmbedConnection.java]

nameclass, %method, %block, %line, %
EmbedConnection.java100% (1/1)94%  (74/79)86%  (1279/1487)89%  (341.3/384)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class EmbedConnection100% (1/1)94%  (74/79)86%  (1279/1487)89%  (341.3/384)
<static initializer> 100% (1/1)100% (3/3)100% (1/1)
EmbedConnection (EmbedConnection): void 100% (1/1)100% (37/37)100% (12/12)
EmbedConnection (InternalDriver, String, Properties): void 100% (1/1)100% (154/154)100% (38/38)
addWarning (SQLWarning): void 100% (1/1)100% (12/12)100% (5/5)
bootDatabase (Properties): boolean 100% (1/1)93%  (55/59)95%  (18/19)
checkUserCredentials (String, Properties): void 100% (1/1)73%  (35/48)81%  (8.9/11)
clearWarnings (): void 100% (1/1)100% (4/4)100% (2/2)
close (): void 100% (1/1)84%  (21/25)88%  (7/8)
close (Exception): void 100% (1/1)100% (52/52)100% (15/15)
commit (): void 100% (1/1)100% (35/35)100% (10/10)
commitIfAutoCommit (): void 100% (1/1)69%  (11/16)71%  (5/7)
commitIfNeeded (): void 100% (1/1)74%  (14/19)71%  (5/7)
createBoot (Properties): boolean 100% (1/1)100% (53/53)100% (15/15)
createDatabase (String, Properties): Database 100% (1/1)86%  (30/35)90%  (9/10)
createStatement (): Statement 100% (1/1)100% (7/7)100% (1/1)
createStatement (int, int): Statement 100% (1/1)100% (7/7)100% (1/1)
createStatement (int, int, int): Statement 100% (1/1)100% (19/19)100% (3/3)
filterProperties (Properties): Properties 100% (1/1)97%  (28/29)86%  (6/7)
finalize (): void 100% (1/1)100% (13/13)100% (5/5)
getApplicationConnection (): Connection 100% (1/1)100% (3/3)100% (1/1)
getAutoCommit (): boolean 100% (1/1)100% (3/3)100% (1/1)
getCatalog (): String 100% (1/1)100% (2/2)100% (1/1)
getConnectionSynchronization (): Object 100% (1/1)100% (3/3)100% (1/1)
getContextManager (): ContextManager 100% (1/1)92%  (11/12)96%  (1.9/2)
getDBName (): String 100% (1/1)92%  (11/12)96%  (1.9/2)
getDatabase (): Database 0%   (0/1)0%   (0/12)0%   (0/2)
getEngineType (): int 0%   (0/1)0%   (0/11)0%   (0/4)
getHoldability (): int 100% (1/1)100% (3/3)100% (1/1)
getLanguageConnection (): LanguageConnectionContext 100% (1/1)92%  (11/12)96%  (1.9/2)
getLocalDriver (): InternalDriver 100% (1/1)92%  (11/12)96%  (1.9/2)
getMetaData (): DatabaseMetaData 100% (1/1)100% (20/20)100% (5/5)
getPrepareIsolation (): int 100% (1/1)100% (4/4)100% (1/1)
getResultSetOrderId (): int 100% (1/1)100% (15/15)100% (3/3)
getTR (): TransactionResourceImpl 100% (1/1)100% (4/4)100% (1/1)
getTransactionIsolation (): int 100% (1/1)100% (6/6)100% (1/1)
getTypeMap (): Map 0%   (0/1)0%   (0/2)0%   (0/1)
getWarnings (): SQLWarning 100% (1/1)100% (3/3)100% (1/1)
handleException (Throwable): SQLException 100% (1/1)100% (8/8)100% (1/1)
handleException (Throwable, boolean): SQLException 0%   (0/1)0%   (0/8)0%   (0/1)
isClosed (): boolean 100% (1/1)100% (13/13)100% (5/5)
isReadOnly (): boolean 100% (1/1)100% (4/4)100% (1/1)
nativeSQL (String): String 0%   (0/1)0%   (0/2)0%   (0/1)
needCommit (): void 100% (1/1)100% (7/7)100% (2/2)
newSQLException (String): SQLException 100% (1/1)100% (3/3)100% (1/1)
newSQLException (String, Object): SQLException 100% (1/1)100% (4/4)100% (1/1)
newSQLException (String, Object, Object): SQLException 100% (1/1)100% (5/5)100% (1/1)
prepareCall (String): CallableStatement 100% (1/1)100% (8/8)100% (1/1)
prepareCall (String, int, int): CallableStatement 100% (1/1)100% (8/8)100% (1/1)
prepareCall (String, int, int, int): CallableStatement 100% (1/1)98%  (44/45)100% (6/6)
prepareMetaDataStatement (String): PreparedStatement 100% (1/1)75%  (30/40)85%  (6.8/8)
prepareStatement (String): PreparedStatement 100% (1/1)100% (11/11)100% (1/1)
prepareStatement (String, String []): PreparedStatement 100% (1/1)100% (3/3)100% (1/1)
prepareStatement (String, int []): PreparedStatement 100% (1/1)100% (3/3)100% (1/1)
prepareStatement (String, int): PreparedStatement 100% (1/1)100% (11/11)100% (1/1)
prepareStatement (String, int, int): PreparedStatement 100% (1/1)100% (11/11)100% (1/1)
prepareStatement (String, int, int, int): PreparedStatement 100% (1/1)100% (10/10)100% (1/1)
prepareStatement (String, int, int, int, int, int [], String []): PreparedSta... 100% (1/1)100% (41/41)100% (5/5)
pushConnectionContext (ContextManager): EmbedConnectionContext 100% (1/1)100% (6/6)100% (1/1)
resetFromPool (): void 100% (1/1)53%  (17/32)68%  (6.1/9)
restoreContextStack (): void 100% (1/1)60%  (27/45)82%  (4.9/6)
rollback (): void 100% (1/1)71%  (25/35)77%  (7.7/10)
setApplicationConnection (Connection): void 100% (1/1)100% (4/4)100% (2/2)
setAutoCommit (boolean): void 100% (1/1)70%  (14/20)71%  (5/7)
setCatalog (String): void 100% (1/1)100% (1/1)100% (1/1)
setDrdaID (String): void 100% (1/1)100% (5/5)100% (2/2)
setHoldability (int): void 100% (1/1)100% (4/4)100% (2/2)
setInactive (): void 100% (1/1)75%  (18/24)82%  (5.7/7)
setPrepareIsolation (int): void 100% (1/1)61%  (20/33)74%  (6.7/9)
setReadOnly (boolean): void 100% (1/1)100% (33/33)100% (9/9)
setResultSetConcurrency (int, int): int 100% (1/1)100% (14/14)100% (4/4)
setResultSetType (int): int 100% (1/1)100% (11/11)100% (4/4)
setTransactionIsolation (int): void 100% (1/1)87%  (52/60)95%  (20/21)
setTypeMap (Map): void 100% (1/1)100% (14/14)100% (5/5)
setupContextStack (): void 100% (1/1)100% (9/9)100% (4/4)
toString (): String 100% (1/1)100% (12/12)100% (3/3)
transactionIsIdle (): boolean 100% (1/1)100% (4/4)100% (1/1)
xa_commit (boolean): void 100% (1/1)55%  (18/33)68%  (6.1/9)
xa_prepare (): int 100% (1/1)67%  (30/45)69%  (7.6/11)
xa_rollback (): void 100% (1/1)53%  (17/32)68%  (6.1/9)

1/*
2 
3   Derby - Class org.apache.derby.impl.jdbc.EmbedConnection
4 
5   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21package org.apache.derby.impl.jdbc;
22 
23import org.apache.derby.jdbc.InternalDriver;
24 
25import org.apache.derby.iapi.reference.Attribute;
26import org.apache.derby.iapi.reference.JDBC20Translation;
27import org.apache.derby.iapi.reference.JDBC30Translation;
28import org.apache.derby.iapi.reference.MessageId;
29import org.apache.derby.iapi.reference.Property;
30import org.apache.derby.iapi.reference.SQLState;
31 
32import org.apache.derby.iapi.services.context.ContextManager;
33import org.apache.derby.iapi.services.memory.LowMemory;
34import org.apache.derby.iapi.services.monitor.Monitor;
35import org.apache.derby.iapi.services.sanity.SanityManager;
36 
37import org.apache.derby.iapi.jdbc.AuthenticationService;
38import org.apache.derby.iapi.jdbc.EngineConnection;
39 
40import org.apache.derby.iapi.db.Database;
41import org.apache.derby.iapi.error.StandardException;
42import org.apache.derby.iapi.services.i18n.MessageService;
43import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
44import org.apache.derby.iapi.sql.execute.ExecutionContext;
45import org.apache.derby.iapi.sql.dictionary.DataDictionary;
46import org.apache.derby.iapi.store.access.XATransactionController;
47 
48/* can't import due to name overlap:
49import java.sql.Connection;
50import java.sql.ResultSet;
51*/
52import java.sql.PreparedStatement;
53import java.sql.CallableStatement;
54import java.sql.DatabaseMetaData;
55import java.sql.SQLException;
56import java.sql.SQLWarning;
57import java.sql.Statement;
58 
59import java.util.Properties;
60 
61/**
62 * Local implementation of Connection for a JDBC driver in 
63 * the same process as the database.
64 * <p> 
65 * There is always a single root (parent) connection.  The
66 * initial JDBC connection is the root connection. A
67 * call to <I>getCurrentConnection()</I> or with the URL 
68 * <I>jdbc:default:connection</I> yields a nested connection that shares
69 * the same root connection as the parent.  A nested connection
70 * is implemented using this class.  The nested connection copies the 
71 * state of the parent connection and shares some of the same 
72 * objects (e.g. ContextManager) that are shared across all
73 * nesting levels.  The proxy also maintains its own
74 * state that is distinct from its parent connection (e.g.
75 * autocommit or warnings).
76 * <p>
77 * <B>SYNCHRONIZATION</B>: Just about all JDBC actions are
78 * synchronized across all connections stemming from the
79 * same root connection.  The synchronization is upon
80 * the a synchronized object return by the rootConnection.
81   <P><B>Supports</B>
82   <UL>
83  <LI> JDBC 2.0
84   </UL>
85 * 
86 *        @author djd
87 *
88 * @see TransactionResourceImpl
89 *
90 */
91public class EmbedConnection implements EngineConnection
92{
93 
94        private static final StandardException exceptionClose = StandardException.closeException();
95    
96    /**
97     * Static exception to be thrown when a Connection request can not
98     * be fulfilled due to lack of memory. A static exception as the lack
99     * of memory would most likely cause another OutOfMemoryException and
100     * if there is not enough memory to create the OOME exception then something
101     * like the VM dying could occur. Simpler just to throw a static.
102     */
103    public static final SQLException NO_MEM =
104        Util.generateCsSQLException(SQLState.LOGIN_FAILED, "java.lang.OutOfMemoryError");
105    
106    /**
107     * Low memory state object for connection requests.
108     */
109    public static final LowMemory memoryState = new LowMemory();
110 
111        //////////////////////////////////////////////////////////
112        // OBJECTS SHARED ACROSS CONNECTION NESTING
113        //////////////////////////////////////////////////////////
114        DatabaseMetaData dbMetadata;
115 
116        final TransactionResourceImpl tr; // always access tr thru getTR()
117 
118 
119        //////////////////////////////////////////////////////////
120        // STATE (copied to new nested connections, but nesting
121        // specific)
122        //////////////////////////////////////////////////////////
123        private boolean        active;
124        boolean        autoCommit = true;
125        boolean        needCommit;
126        /*
127     following is a new feature in JDBC3.0 where you can specify the holdability
128     of a resultset at the end of the transaction. This gets set by the
129         new method setHoldability(int) in JDBC3.0
130     * 
131         */
132        private int        connectionHoldAbility = JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
133 
134 
135        //////////////////////////////////////////////////////////
136        // NESTING SPECIFIC OBJECTS
137        //////////////////////////////////////////////////////////
138        /*
139        ** The root connection is the base connection upon
140        ** which all actions are synchronized.  By default,
141        ** we are the root connection unless we are created
142        ** by copying the state from another connection.
143        */
144        final EmbedConnection rootConnection;
145        private SQLWarning                 topWarning;
146        /**        
147                Factory for JDBC objects to be created.
148        */
149        private InternalDriver factory;
150 
151        /**
152                The Connection object the application is using when accessing the
153                database through this connection. In most cases this will be equal
154                to this. When Connection pooling is being used, then it will
155                be set to the Connection object handed to the application.
156                It is used for the getConnection() methods of various JDBC objects.
157        */
158        private java.sql.Connection applicationConnection;
159 
160        /**
161                An increasing counter to assign to a ResultSet on its creation.
162                Used for ordering ResultSets returned from a procedure, always
163                returned in order of their creation. Is maintained at the root connection.
164        */
165        private int resultSetId;
166    
167    /** Cached string representation of the connection id */
168    private String connString;
169 
170 
171        //////////////////////////////////////////////////////////
172        // CONSTRUCTORS
173        //////////////////////////////////////////////////////////
174 
175        // create a new Local Connection, using a new context manager
176        //
177        public EmbedConnection(InternalDriver driver, String url, Properties info)
178                 throws SQLException
179        {
180                // Create a root connection.
181                applicationConnection = rootConnection = this;
182                factory = driver;
183 
184 
185                tr = new TransactionResourceImpl(driver, url, info);
186 
187                active = true;
188 
189                // register this thread and its context manager with
190                // the global context service
191                setupContextStack();
192 
193                try {
194 
195                        // stick my context into the context manager
196                        EmbedConnectionContext context = pushConnectionContext(tr.getContextManager());
197 
198                        // if we are shutting down don't attempt to boot or create the database
199                        boolean shutdown = Boolean.valueOf(info.getProperty(Attribute.SHUTDOWN_ATTR)).booleanValue();
200 
201                        // see if database is already booted
202                        Database database = (Database) Monitor.findService(Property.DATABASE_MODULE, tr.getDBName());
203 
204                        // See if user wants to create a new database.
205                        boolean        createBoot = createBoot(info);        
206                        if (database != null)
207                        {
208                                // database already booted by someone else
209                                tr.setDatabase(database);
210                        }
211                        else if (!shutdown)
212                        {
213                                // Return false iff the monitor cannot handle a service of the type
214                                // indicated by the proptocol within the name.  If that's the case
215                                // then we are the wrong driver.
216                                if (!bootDatabase(info))
217                                {
218                                        tr.clearContextInError();
219                                        setInactive();
220                                        return;
221                                }
222                        }
223 
224 
225                        if (createBoot && !shutdown)
226                        {
227                                // if we are shutting down don't attempt to boot or create the database
228 
229                                if (tr.getDatabase() != null) {
230                                        addWarning(EmbedSQLWarning.newEmbedSQLWarning(SQLState.DATABASE_EXISTS, getDBName()));
231                                } else {
232 
233                                        // check for user's credential and authenticate the user
234                                        // with system level authentication service.
235                                        // FIXME: We should also check for CREATE DATABASE operation
236                                        //                  authorization for the user if authorization was
237                                        //                  set at the system level.
238                                        //                  Right now, the authorization service does not
239                                        //                  restrict/account for Create database op.
240                                        checkUserCredentials(null, info);
241                                        
242                                        // Process with database creation
243                                        database = createDatabase(tr.getDBName(), info);
244                                        tr.setDatabase(database);
245                                }
246                        }
247 
248 
249                        if (tr.getDatabase() == null) {
250                                String dbname = tr.getDBName();
251                                // do not clear the TransactionResource context. It will be restored
252                // as part of the finally clause below.
253                                this.setInactive();
254                                throw newSQLException(SQLState.DATABASE_NOT_FOUND, dbname);
255                        }
256 
257 
258                        // Check User's credentials and if it is a valid user of
259                        // the database
260                        //
261                        checkUserCredentials(tr.getDBName(), info);
262 
263                        // Make a real connection into the database, setup lcc, tc and all
264                        // the rest.
265                        tr.startTransaction();
266 
267                        // now we have the database connection, we can shut down
268                        if (shutdown) {
269                                throw tr.shutdownDatabaseException();
270                        }
271 
272                }
273        catch (OutOfMemoryError noMemory)
274                {
275                        //System.out.println("freeA");
276                        restoreContextStack();
277                        tr.lcc = null;
278                        tr.cm = null;
279                        
280                        //System.out.println("free");
281                        //System.out.println(Runtime.getRuntime().freeMemory());
282            memoryState.setLowMemory();
283                        
284                        //noMemory.printStackTrace();
285                        // throw Util.generateCsSQLException(SQLState.LOGIN_FAILED, noMemory.getMessage(), noMemory);
286                        throw NO_MEM;
287                }
288                catch (Throwable t) {
289                        throw handleException(t);
290                } finally {
291                        restoreContextStack();
292                }
293        }
294 
295 
296        /**
297          Examine the attributes set provided and determine if this is a create
298          boot. A boot is a create boot iff.
299 
300          <OL>
301          <LI>create=true - This means create a standard database.
302          <LI> createFrom = Path - creates database from backup if it does not exist.
303          <LI> restoreFrom = Path - database is restored completley from backup.
304           if a database exists in the same place it is replaced by the version
305                   in the backup otherwise a new one is created using the backup copy.
306      <LI> rollForwardRecoveryFrom = Path  - rollforward is performed 
307      using the version backup and any active and archived log files.
308          </OL>
309 
310          @param p the attribute set.
311 
312          @exception SQLException Ooops.
313          */
314        private boolean createBoot(Properties p) throws SQLException
315        {
316                int createCount = 0;
317 
318                if (Boolean.valueOf(p.getProperty(Attribute.CREATE_ATTR)).booleanValue())
319                        createCount++;
320 
321                int restoreCount=0;
322                //check if the user has specified any /create/restore/recover from backup attributes.
323                if (p.getProperty(Attribute.CREATE_FROM) != null)
324                        restoreCount++;
325                if (p.getProperty(Attribute.RESTORE_FROM) != null)
326                        restoreCount++;
327                if (p.getProperty(Attribute.ROLL_FORWARD_RECOVERY_FROM)!=null)
328                        restoreCount++;
329                if(restoreCount > 1)
330                        throw newSQLException(SQLState.CONFLICTING_RESTORE_ATTRIBUTES);
331        
332                //add the restore count to create count to make sure 
333                //user has not specified and restore together by mistake.
334                createCount = createCount + restoreCount ;
335 
336                //
337                if (createCount > 1) throw newSQLException(SQLState.CONFLICTING_CREATE_ATTRIBUTES);
338                
339                //retuns true only for the  create flag not for restore flags
340                return (createCount - restoreCount) == 1;
341        }
342 
343        /**
344         * Create a new connection based off of the 
345         * connection passed in.  Initializes state
346         * based on input connection, and copies 
347         * appropriate object pointers. This is only used
348           for nested connections.
349         *
350         * @param inputConnection the input connection
351         */
352        public EmbedConnection(EmbedConnection inputConnection) 
353        {
354                if (SanityManager.DEBUG)
355                {
356                        SanityManager.ASSERT(inputConnection.active, 
357                        "trying to create a proxy for an inactive conneciton");
358                }
359 
360                // Proxy connections are always autocommit false
361                // thus needCommit is irrelavent.
362                autoCommit = false;
363 
364 
365                /*
366                ** Nesting specific state we are copying from 
367                ** the inputConnection
368                */
369 
370                /*
371                ** Objects we are sharing across nestings
372                */
373                // set it to null to allow it to be final.
374                tr = null;                        // a proxy connection has no direct
375                                                                // pointer to the tr.  Every call has to go
376                                                                // thru the rootConnection's tr.
377                active = true;
378                this.rootConnection = inputConnection.rootConnection;
379                this.applicationConnection = this;
380                this.factory = inputConnection.factory;
381 
382                //if no holdability specified for the resultset, use the holability
383                //defined for the connection
384                this.connectionHoldAbility = inputConnection.connectionHoldAbility;
385 
386                //RESOLVE: although it looks like the right
387                // thing to share the metadata object, if
388                // we do we'll get the wrong behavior on
389                // getCurrentConnection().getMetaData().isReadOnly()
390                // so don't try to be smart and uncomment the
391                // following.  Ultimately, the metadata should
392                // be shared by all connections anyway.
393                //dbMetadata = inputConnection.dbMetadata;
394        }
395 
396        //
397        // Check passed-in user's credentials.
398        //
399        private void checkUserCredentials(String dbname,
400                                                                          Properties userInfo)
401          throws SQLException
402        {
403                if (SanityManager.DEBUG)
404                        SanityManager.ASSERT(!isClosed(), "connection is closed");
405 
406                // If a database name was passed-in then check user's credential
407                // in that database using the database's authentication service,
408                // otherwise check if it is a valid user in the JBMS system.
409                //
410                // NOTE: We always expect an authentication service per database
411                // and one at the system level.
412                //
413                AuthenticationService authenticationService = null;
414 
415                // Retrieve appropriate authentication service handle
416                if (dbname == null)
417                        authenticationService = getLocalDriver().getAuthenticationService();
418                else
419                        authenticationService = getTR().getDatabase().getAuthenticationService();
420 
421                // check that we do have a authentication service
422                // it is _always_ expected.
423                if (authenticationService == null)
424                {
425                        String failedString = MessageService.getTextMessage(
426                                (dbname == null) ? MessageId.AUTH_NO_SERVICE_FOR_SYSTEM : MessageId.AUTH_NO_SERVICE_FOR_DB);
427 
428                        throw newSQLException(SQLState.LOGIN_FAILED, failedString);
429                }
430                
431                // Let's authenticate now
432                        
433                if (!authenticationService.authenticate(
434                                                                                           dbname,
435                                                                                           userInfo
436                                                                                           )) {
437 
438                        throw newSQLException(SQLState.LOGIN_FAILED, MessageService.getTextMessage(MessageId.AUTH_INVALID));
439 
440                }
441        }
442 
443    /**
444     * Gets the EngineType of the connected database.
445     *
446     * @return 0 if there is no database, the engine type otherwise. @see org.apache.derby.iapi.reference.EngineType
447     */
448    public int getEngineType()
449    {
450        Database db = getDatabase();
451 
452        if( null == db)
453            return 0;
454        return db.getEngineType();
455    }
456    
457        /*
458        ** Methods from java.sql.Connection
459        */
460 
461    /**
462         * SQL statements without parameters are normally
463     * executed using Statement objects. If the same SQL statement 
464     * is executed many times, it is more efficient to use a 
465     * PreparedStatement
466     *
467     * JDBC 2.0
468     *
469     * Result sets created using the returned Statement will have
470     * forward-only type, and read-only concurrency, by default.
471     *
472     * @return a new Statement object 
473     * @exception SQLException if a database-access error occurs.
474     */
475        public final Statement createStatement() throws SQLException 
476        {
477                return createStatement(JDBC20Translation.TYPE_FORWARD_ONLY,
478                                                           JDBC20Translation.CONCUR_READ_ONLY,
479                                                           connectionHoldAbility);
480        }
481 
482    /**
483     * JDBC 2.0
484     *
485     * Same as createStatement() above, but allows the default result set
486     * type and result set concurrency type to be overridden.
487     *
488     * @param resultSetType a result set type, see ResultSet.TYPE_XXX
489     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
490     * @return a new Statement object 
491      * @exception SQLException if a database-access error occurs.
492    */
493    public final Statement createStatement(int resultSetType,
494                                                                     int resultSetConcurrency) 
495                                                throws SQLException
496        {
497                return createStatement(resultSetType, resultSetConcurrency,
498                            connectionHoldAbility);
499        }
500 
501    /**
502     * JDBC 3.0
503     *
504     * Same as createStatement() above, but allows the default result set
505     * type, result set concurrency type and result set holdability type to
506     * be overridden.
507     *
508     * @param resultSetType a result set type, see ResultSet.TYPE_XXX
509     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
510     * @param resultSetHoldability a holdability type,
511     *  ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT
512     * @return a new Statement object
513     * @exception SQLException if a database-access error occurs.
514     */
515    public final Statement createStatement(int resultSetType,
516                                                                     int resultSetConcurrency,
517                                                                     int resultSetHoldability)
518                                                throws SQLException
519        {
520                checkIfClosed();
521 
522                return factory.newEmbedStatement(this, false,
523                        setResultSetType(resultSetType), resultSetConcurrency,
524                        resultSetHoldability);
525        }
526 
527    /**
528     * A SQL statement with or without IN parameters can be
529     * pre-compiled and stored in a PreparedStatement object. This
530     * object can then be used to efficiently execute this statement
531     * multiple times.
532     *
533     * <P><B>Note:</B> This method is optimized for handling
534     * parametric SQL statements that benefit from precompilation. If
535     * the driver supports precompilation, prepareStatement will send
536     * the statement to the database for precompilation. Some drivers
537     * may not support precompilation. In this case, the statement may
538     * not be sent to the database until the PreparedStatement is
539     * executed.  This has no direct affect on users; however, it does
540     * affect which method throws certain SQLExceptions.
541     *
542     * JDBC 2.0
543     *
544     * Result sets created using the returned PreparedStatement will have
545     * forward-only type, and read-only concurrency, by default.
546     *
547     * @param sql a SQL statement that may contain one or more '?' IN
548     * parameter placeholders
549     * @return a new PreparedStatement object containing the
550     * pre-compiled statement 
551     * @exception SQLException if a database-access error occurs.
552     */
553    public final PreparedStatement prepareStatement(String sql)
554            throws SQLException
555        {
556                return prepareStatement(sql,JDBC20Translation.TYPE_FORWARD_ONLY,
557                        JDBC20Translation.CONCUR_READ_ONLY,
558                        connectionHoldAbility,
559                        JDBC30Translation.NO_GENERATED_KEYS,
560                        null,
561                        null);
562        }
563 
564 
565    /**
566     * JDBC 2.0
567     *
568     * Same as prepareStatement() above, but allows the default result set
569     * type and result set concurrency type to be overridden.
570     *
571     * @param resultSetType a result set type, see ResultSet.TYPE_XXX
572     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
573     * @return a new PreparedStatement object containing the
574     * pre-compiled SQL statement
575     * @exception SQLException if a database-access error occurs.
576     */
577    public final PreparedStatement prepareStatement(String sql, int resultSetType,
578                                        int resultSetConcurrency)
579            throws SQLException
580        {
581                return prepareStatement(sql,
582                        resultSetType,
583                        resultSetConcurrency,
584                        connectionHoldAbility,
585                        JDBC30Translation.NO_GENERATED_KEYS,
586                        null,
587                        null);
588        }
589 
590    /**
591     * JDBC 3.0
592     *
593     * Same as prepareStatement() above, but allows the default result set
594     * type, result set concurrency type and result set holdability
595     * to be overridden.
596     *
597     * @param resultSetType a result set type, see ResultSet.TYPE_XXX
598     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
599     * @param resultSetHoldability - one of the following ResultSet constants:
600     *  ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT
601     * @return a new PreparedStatement object containing the
602     *  pre-compiled SQL statement
603     * @exception SQLException if a database-access error occurs.
604     */
605    public final PreparedStatement prepareStatement(String sql, int resultSetType,
606                                        int resultSetConcurrency, int resultSetHoldability)
607            throws SQLException
608        {
609                return prepareStatement(sql,
610                        resultSetType,
611                        resultSetConcurrency,
612                        resultSetHoldability,
613                        JDBC30Translation.NO_GENERATED_KEYS,
614                        null,
615                        null);
616        }
617 
618 
619        /**
620         * Creates a default PreparedStatement object capable of returning
621         * the auto-generated keys designated by the given array. This array contains
622         * the indexes of the columns in the target table that contain the auto-generated
623         * keys that should be made available. This array is ignored if the SQL statement
624         * is not an INSERT statement
625 
626                JDBC 3.0
627         *
628         *
629         * @param sql  An SQL statement that may contain one or more ? IN parameter placeholders
630         * @param columnIndexes  An array of column indexes indicating the columns
631         *  that should be returned from the inserted row or rows
632         *
633         * @return  A new PreparedStatement object, containing the pre-compiled
634         *  SQL statement, that will have the capability of returning auto-generated keys
635         *  designated by the given array of column indexes
636         *
637         * @exception SQLException  Feature not implemented for now.
638         */
639        public final PreparedStatement prepareStatement(
640                        String sql,
641                        int[] columnIndexes)
642    throws SQLException
643        {
644                 throw Util.notImplemented("prepareStatement(String, int[])");
645        }
646 
647        /**
648         * Creates a default PreparedStatement object capable of returning
649         * the auto-generated keys designated by the given array. This array contains
650         * the names of the columns in the target table that contain the auto-generated
651         * keys that should be returned. This array is ignored if the SQL statement
652         * is not an INSERT statement
653         *
654                JDBC 3.0
655         *
656         * @param sql  An SQL statement that may contain one or more ? IN parameter placeholders
657         * @param columnNames  An array of column names indicating the columns
658         *  that should be returned from the inserted row or rows
659         *
660         * @return  A new PreparedStatement object, containing the pre-compiled
661         *  SQL statement, that will have the capability of returning auto-generated keys
662         *  designated by the given array of column names
663         *
664         * @exception SQLException  Feature not implemented for now.
665         */
666        public final PreparedStatement prepareStatement(
667                        String sql,
668                        String[] columnNames)
669    throws SQLException
670        {
671                 throw Util.notImplemented("prepareStatement(String, String[])");
672        }
673 
674        /**
675         * Creates a default PreparedStatement object that has the capability to
676         * retieve auto-generated keys. The given constant tells the driver
677         * whether it should make auto-generated keys available for retrieval.
678         * This parameter is ignored if the SQL statement is not an INSERT statement.
679         * JDBC 3.0
680         *
681         * @param sql  A SQL statement that may contain one or more ? IN parameter placeholders
682         * @param autoGeneratedKeys  A flag indicating whether auto-generated keys
683         *  should be returned
684         *
685         * @return  A new PreparedStatement object, containing the pre-compiled
686         *  SQL statement, that will have the capability of returning auto-generated keys
687         *
688         * @exception SQLException  Feature not implemented for now.
689         */
690        public final PreparedStatement prepareStatement(
691                        String sql,
692                        int autoGeneratedKeys)
693    throws SQLException
694        {
695                return prepareStatement(sql,
696                        JDBC20Translation.TYPE_FORWARD_ONLY,
697                        JDBC20Translation.CONCUR_READ_ONLY,
698                        connectionHoldAbility,
699                        autoGeneratedKeys,
700                        null,
701                        null);
702        }
703    
704        private PreparedStatement prepareStatement(String sql, int resultSetType,
705                                        int resultSetConcurrency, int resultSetHoldability,
706                                        int autoGeneratedKeys, int[] columnIndexes, String[] columnNames)
707       throws SQLException
708         {
709                synchronized (getConnectionSynchronization()) {
710                        setupContextStack();
711                        try {
712                            return factory.newEmbedPreparedStatement(this, sql, false,
713                                                                                           setResultSetType(resultSetType),
714                                                                                           resultSetConcurrency,
715                                                                                           resultSetHoldability,
716                                                                                           autoGeneratedKeys,
717                                                                                           columnIndexes,
718                                                                                           columnNames);
719                        } finally {
720                            restoreContextStack();
721                        }
722                }
723     }
724 
725    /**
726     * A SQL stored procedure call statement is handled by creating a
727     * CallableStatement for it. The CallableStatement provides
728     * methods for setting up its IN and OUT parameters, and
729     * methods for executing it.
730     *
731     * <P><B>Note:</B> This method is optimized for handling stored
732     * procedure call statements. Some drivers may send the call
733     * statement to the database when the prepareCall is done; others
734     * may wait until the CallableStatement is executed. This has no
735     * direct affect on users; however, it does affect which method
736     * throws certain SQLExceptions.
737     *
738     * JDBC 2.0
739     *
740     * Result sets created using the returned CallableStatement will have
741     * forward-only type, and read-only concurrency, by default.
742     *
743     * @param sql a SQL statement that may contain one or more '?'
744     * parameter placeholders. Typically this  statement is a JDBC
745     * function call escape string.
746     * @return a new CallableStatement object containing the
747     * pre-compiled SQL statement 
748     * @exception SQLException if a database-access error occurs.
749     */
750        public final CallableStatement prepareCall(String sql) 
751                throws SQLException 
752        {
753                return prepareCall(sql, JDBC20Translation.TYPE_FORWARD_ONLY,
754                                                   JDBC20Translation.CONCUR_READ_ONLY,
755                                                   connectionHoldAbility);
756        }
757 
758    /**
759     * JDBC 2.0
760     *
761     * Same as prepareCall() above, but allows the default result set
762     * type and result set concurrency type to be overridden.
763     *
764     * @param resultSetType a result set type, see ResultSet.TYPE_XXX
765     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
766     * @return a new CallableStatement object containing the
767     * pre-compiled SQL statement 
768     * @exception SQLException if a database-access error occurs.
769     */
770    public final CallableStatement prepareCall(String sql, int resultSetType,
771                                 int resultSetConcurrency)
772                throws SQLException 
773        {
774                return prepareCall(sql, resultSetType, resultSetConcurrency,
775                                                   connectionHoldAbility);
776        }
777 
778    /**
779     * JDBC 3.0
780     *
781     * Same as prepareCall() above, but allows the default result set
782     * type, result set concurrency type and result set holdability
783     * to be overridden.
784     *
785     * @param resultSetType a result set type, see ResultSet.TYPE_XXX
786     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
787     * @param resultSetHoldability - one of the following ResultSet constants:
788     *  ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT
789     * @return a new CallableStatement object containing the
790     * pre-compiled SQL statement 
791     * @exception SQLException if a database-access error occurs.
792     */
793    public final CallableStatement prepareCall(String sql, int resultSetType, 
794                                 int resultSetConcurrency, int resultSetHoldability)
795                throws SQLException 
796        {
797                checkIfClosed();
798 
799                synchronized (getConnectionSynchronization())
800                {
801            setupContextStack();
802                        try 
803                        {
804                            return factory.newEmbedCallableStatement(this, sql,
805                                                                                           setResultSetType(resultSetType),
806                                                                                           resultSetConcurrency,
807                                                                                           resultSetHoldability);
808                        } 
809                        finally 
810                        {
811                            restoreContextStack();
812                        }
813                }
814        }
815 
816    /**
817     * A driver may convert the JDBC sql grammar into its system's
818     * native SQL grammar prior to sending it; nativeSQL returns the
819     * native form of the statement that the driver would have sent.
820     *
821     * @param sql a SQL statement that may contain one or more '?'
822     * parameter placeholders
823     * @return the native form of this statement
824     */
825    public String nativeSQL(String sql) throws SQLException {
826        checkIfClosed();
827                // we don't massage the strings at all, so this is easy:
828                return sql;
829        }
830 
831    /**
832     * If a connection is in auto-commit mode, then all its SQL
833     * statements will be executed and committed as individual
834     * transactions.  Otherwise, its SQL statements are grouped into
835     * transactions that are terminated by either commit() or
836     * rollback().  By default, new connections are in auto-commit
837     * mode.
838     *
839     * The commit occurs when the statement completes or the next
840     * execute occurs, whichever comes first. In the case of
841     * statements returning a ResultSet, the statement completes when
842     * the last row of the ResultSet has been retrieved or the
843     * ResultSet has been closed. In advanced cases, a single
844     * statement may return multiple results as well as output
845     * parameter values. Here the commit occurs when all results and
846     * output param values have been retrieved.
847     *
848     * @param autoCommit true enables auto-commit; false disables
849     * auto-commit.  
850     * @exception SQLException if a database-access error occurs.
851     */
852        public void setAutoCommit(boolean autoCommit) throws SQLException {
853                checkIfClosed();
854 
855                // Is this a nested connection
856                if (rootConnection != this) {
857                        if (autoCommit)
858                                throw newSQLException(SQLState.NO_AUTO_COMMIT_ON);
859                }
860 
861                if (this.autoCommit != autoCommit)
862                        commit();
863 
864                this.autoCommit = autoCommit;
865        }
866 
867    /**
868     * Get the current auto-commit state.
869     *
870     * @return Current state of auto-commit mode.
871     * @see #setAutoCommit 
872     */
873    public boolean getAutoCommit() throws SQLException {
874        checkIfClosed();
875                return autoCommit;
876        }
877 
878    /**
879     * Commit makes all changes made since the previous
880     * commit/rollback permanent and releases any database locks
881     * currently held by the Connection. This method should only be
882     * used when auto commit has been disabled.
883     *
884     * @exception SQLException if a database-access error occurs.
885     * @see #setAutoCommit 
886     */
887    public void commit() throws SQLException {
888                synchronized (getConnectionSynchronization())
889                {
890                        /*
891                        ** Note that the context stack is
892                        ** needed even for rollback & commit
893                        */
894            setupContextStack();
895 
896                        try
897                        {
898                            getTR().commit();
899                        }
900            catch (Throwable t)
901                        {
902                                throw handleException(t);
903                        }
904                        finally 
905                        {
906                                restoreContextStack();
907                        }
908 
909                        needCommit = false;
910                }
911        }
912 
913    /**
914     * Rollback drops all changes made since the previous
915     * commit/rollback and releases any database locks currently held
916     * by the Connection. This method should only be used when auto
917     * commit has been disabled.
918     *
919     * @exception SQLException if a database-access error occurs.
920     * @see #setAutoCommit 
921     */
922    public void rollback() throws SQLException {
923 
924                synchronized (getConnectionSynchronization())
925                {
926                        /*
927                        ** Note that the context stack is
928                        ** needed even for rollback & commit
929                        */
930            setupContextStack();
931                        try
932                        {
933                            getTR().rollback();
934                        } catch (Throwable t) {
935                                throw handleException(t);
936                        }
937                        finally 
938                        {
939                                restoreContextStack();
940                        }
941                        needCommit = false;
942                } 
943        }
944 
945    /**
946     * In some cases, it is desirable to immediately release a
947     * Connection's database and JDBC resources instead of waiting for
948     * them to be automatically released; the close method provides this
949     * immediate release. 
950     *
951     * <P><B>Note:</B> A Connection is automatically closed when it is
952     * garbage collected. Certain fatal errors also result in a closed
953     * Connection.
954     *
955     * @exception SQLException if a database-access error occurs.
956     */
957    public void close() throws SQLException {
958                // JDK 1.4 javadoc indicates close on a closed connection is a no-op
959                if (isClosed())
960                           return;
961 
962 
963                if (rootConnection == this)
964                {
965                        /* Throw error to match DB2/JDBC if a tran is pending in non-autocommit mode */
966                        if (!autoCommit && !transactionIsIdle()) {
967                                throw newSQLException(SQLState.LANG_INVALID_TRANSACTION_STATE);
968                        }
969 
970                        close(exceptionClose);
971                }
972                else
973                        setInactive(); // nested connection
974        }
975 
976        // This inner close takes the exception and calls 
977        // the context manager to make the connection close.
978        // The exception must be a session severity exception.
979        //
980        // NOTE: This method is not part of JDBC specs.
981        //
982    private void close(StandardException e) throws SQLException {
983                
984                synchronized(getConnectionSynchronization())
985                {
986                        if (rootConnection == this)
987                        {
988                                /*
989                                 * If it isn't active, it's already been closed.
990                                 */
991                                if (active) {
992                                        setupContextStack();
993                                        try {
994                                                tr.rollback();
995 
996                                                // Let go of lcc reference so it can be GC'ed after
997                                                // cleanupOnError, the tr will stay around until the
998                                                // rootConnection itself is GC'ed, which is dependent
999                                                // on how long the client program wants to hold on to
1000                                                // the Connection object.
1001                                                tr.clearLcc(); 
1002                                                tr.cleanupOnError(e);
1003 
1004                                        } catch (Throwable t) {
1005                                                throw handleException(t);
1006                                        } finally {
1007                                                restoreContextStack();
1008                                        }
1009                                }
1010                        }
1011 
1012                        if (!isClosed())
1013                                setInactive();
1014                }
1015        }
1016 
1017    /**
1018     * Tests to see if a Connection is closed.
1019     *
1020     * @return true if the connection is closed; false if it's still open
1021     */
1022    public final boolean isClosed() {
1023                if (active) {
1024 
1025                        // I am attached, check the database state
1026                        if (getTR().isActive()) {
1027                                return false;
1028                        }
1029 
1030                        setInactive();
1031 
1032                }
1033                return true;
1034        }
1035 
1036    /**
1037     * A Connection's database is able to provide information
1038     * describing its tables, its supported SQL grammar, its stored
1039     * procedures, the capabilities of this connection, etc. This
1040     * information is made available through a DatabaseMetaData
1041     * object.
1042     *
1043     * @return a DatabaseMetaData object for this Connection 
1044     * @exception SQLException if a database-access error occurs.
1045     */
1046    public DatabaseMetaData getMetaData() throws SQLException {
1047        checkIfClosed();
1048 
1049                if (dbMetadata == null) {
1050 
1051                         // There is a case where dbname can be null.
1052                        // Replication client of this method does not have a
1053                        // JDBC connection; therefore dbname is null and this
1054                        // is expected.
1055                        //
1056                        dbMetadata = factory.newEmbedDatabaseMetaData(this, getTR().getUrl());
1057                }
1058                return dbMetadata;
1059        }
1060 
1061        /**
1062                JDBC 3.0
1063         * Retrieves the current holdability of ResultSet objects created using this
1064         * Connection object.
1065         *
1066         *
1067         * @return  The holdability, one of ResultSet.HOLD_CURSORS_OVER_COMMIT
1068         * or ResultSet.CLOSE_CURSORS_AT_COMMIT
1069         *
1070         */
1071        public final int getHoldability() throws SQLException {
1072                checkIfClosed();
1073                return connectionHoldAbility;
1074        }
1075 
1076        /**
1077                JDBC 3.0
1078         * Changes the holdability of ResultSet objects created using this
1079         * Connection object to the given holdability.
1080         *
1081         *
1082         * @param holdability  A ResultSet holdability constant, one of ResultSet.HOLD_CURSORS_OVER_COMMIT
1083         * or ResultSet.CLOSE_CURSORS_AT_COMMIT
1084         *
1085         */
1086        public final void setHoldability(int holdability) throws SQLException {
1087                checkIfClosed();
1088                connectionHoldAbility = holdability;
1089        }
1090 
1091    /**
1092     * You can put a connection in read-only mode as a hint to enable 
1093     * database optimizations.
1094     *
1095     * <P><B>Note:</B> setReadOnly cannot be called while in the
1096     * middle of a transaction.
1097     *
1098     * @param readOnly true enables read-only mode; false disables
1099     * read-only mode.  
1100     * @exception SQLException if a database-access error occurs.
1101     */
1102    public final void setReadOnly(boolean readOnly) throws SQLException
1103        {
1104                synchronized(getConnectionSynchronization())
1105                {
1106                        setupContextStack();
1107                        try {
1108                                getLanguageConnection().setReadOnly(readOnly);
1109                        } catch (StandardException e) {
1110                                throw handleException(e);
1111                        } finally {
1112                                restoreContextStack();
1113                        }
1114                }
1115        }
1116 
1117    /**
1118     * Tests to see if the connection is in read-only mode.
1119     *
1120     * @return true if connection is read-only
1121     * @exception SQLException if a database-access error occurs.
1122     */
1123    public final boolean isReadOnly() throws SQLException
1124        {
1125                checkIfClosed();
1126                return getLanguageConnection().isReadOnly();
1127        }
1128 
1129    /**
1130     * A sub-space of this Connection's database may be selected by setting a
1131     * catalog name. If the driver does not support catalogs it will
1132     * silently ignore this request.
1133     *
1134     * @exception SQLException if a database-access error occurs.
1135     */
1136    public void setCatalog(String catalog) throws SQLException {
1137        checkIfClosed();
1138                // silently ignoring this request like the javadoc said.
1139                return;
1140        }
1141 
1142    /**
1143     * Return the Connection's current catalog name.
1144     *
1145     * @return the current catalog name or null
1146     * @exception SQLException if a database-access error occurs.
1147     */
1148        public String getCatalog() throws SQLException {
1149                checkIfClosed();
1150                // we do not have support for Catalog, just return null as
1151                // the JDBC specs mentions then.
1152                return null;
1153        }
1154 
1155    /**
1156     * You can call this method to try to change the transaction
1157     * isolation level using one of the TRANSACTION_* values.
1158     *
1159     * <P><B>Note:</B> setTransactionIsolation causes the current
1160     * transaction to commit
1161     *
1162     * @param level one of the TRANSACTION_* isolation values with the
1163     * exception of TRANSACTION_NONE; some databases may not support
1164     * other values
1165     * @exception SQLException if a database-access error occurs.
1166     * @see DatabaseMetaData#supportsTransactionIsolationLevel 
1167     */
1168    public void setTransactionIsolation(int level) throws SQLException {
1169 
1170                if (level == getTransactionIsolation())
1171                        return;
1172 
1173                // Convert the isolation level to the internal one
1174                int iLevel;
1175                switch (level)
1176                {
1177                case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:
1178                        iLevel = ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL;
1179                        break;
1180 
1181                case java.sql.Connection.TRANSACTION_READ_COMMITTED:
1182                        iLevel = ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL;
1183                        break;
1184 
1185                case java.sql.Connection.TRANSACTION_REPEATABLE_READ:
1186            iLevel = ExecutionContext.REPEATABLE_READ_ISOLATION_LEVEL;
1187            break;
1188 
1189                case java.sql.Connection.TRANSACTION_SERIALIZABLE:
1190                        iLevel = ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL;
1191                        break;
1192                default:
1193                        throw newSQLException(SQLState.UNIMPLEMENTED_ISOLATION_LEVEL, new Integer(level));
1194                }
1195 
1196                synchronized(getConnectionSynchronization())
1197                {
1198            setupContextStack();
1199                        try {
1200                                getLanguageConnection().setIsolationLevel(iLevel);
1201                        } catch (StandardException e) {
1202                                throw handleException(e);
1203                        } finally {
1204                                restoreContextStack();
1205                        }
1206                }
1207        }
1208 
1209 
1210    /**
1211     * Get this Connection's current transaction isolation mode.
1212     *
1213     * @return the current TRANSACTION_* mode value
1214     * @exception SQLException if a database-access error occurs.
1215     */
1216    public final int getTransactionIsolation() throws SQLException {
1217        checkIfClosed();
1218                return ExecutionContext.CS_TO_JDBC_ISOLATION_LEVEL_MAP[getLanguageConnection().getCurrentIsolationLevel()];
1219        }
1220 
1221    /**
1222     * The first warning reported by calls on this Connection is
1223     * returned.  
1224     *
1225     * <P><B>Note:</B> Subsequent warnings will be chained to this
1226     * SQLWarning.
1227     *
1228     * @return the first SQLWarning or null 
1229     *
1230         * Synchronization note: Warnings are synchronized 
1231         * on nesting level
1232     */
1233        public final synchronized SQLWarning getWarnings() throws SQLException {
1234                checkIfClosed();
1235                   return topWarning;
1236        }
1237 
1238    /**
1239     * After this call, getWarnings returns null until a new warning is
1240     * reported for this Connection.  
1241     *
1242         * Synchronization node: Warnings are synchonized 
1243         * on nesting level
1244     */
1245    public final synchronized void clearWarnings() throws SQLException {
1246        checkIfClosed();
1247                topWarning = null;
1248        }
1249 
1250         /////////////////////////////////////////////////////////////////////////
1251        //
1252        //        JDBC 2.0        -        New public methods
1253        //
1254        /////////////////////////////////////////////////////////////////////////
1255 
1256    /**
1257     *
1258         * Get the type-map object associated with this connection.
1259         * By default, the map returned is empty.
1260         * JDBC 2.0 - java.util.Map requires JDK 1
1261     *
1262     */
1263    public java.util.Map getTypeMap() throws SQLException {
1264        checkIfClosed();
1265                // just return an immuntable empty map
1266                return java.util.Collections.EMPTY_MAP;
1267    }
1268 
1269    /** 
1270         * Install a type-map object as the default type-map for
1271         * this connection.
1272         * JDBC 2.0 - java.util.Map requires JDK 1
1273     *
1274     * @exception SQLException Feature not implemented for now.
1275         */
1276    public final void setTypeMap(java.util.Map map) throws SQLException {
1277        checkIfClosed();
1278        if( map == null)
1279            throw Util.generateCsSQLException(SQLState.INVALID_API_PARAMETER,map,"map",
1280                                              "java.sql.Connection.setTypeMap");
1281        if(!(map.isEmpty()))
1282            throw Util.notImplemented();
1283    }
1284 
1285        /////////////////////////////////////////////////////////////////////////
1286        //
1287        //        Implementation specific methods        
1288        //
1289        /////////////////////////////////////////////////////////////////////////
1290 
1291        /**
1292                Add a warning to the current list of warnings, to follow
1293                this note from Connection.getWarnings.
1294                Note: Subsequent warnings will be chained to this SQLWarning. 
1295 
1296                @see java.sql.Connection#getWarnings
1297        */
1298         public final synchronized void addWarning(SQLWarning newWarning) {
1299                if (topWarning == null) {
1300                        topWarning = newWarning;
1301                        return;
1302                }
1303 
1304                topWarning.setNextWarning(newWarning);
1305        }
1306 
1307        /**
1308         * Return the dbname for this connection.
1309         *
1310         * @return String        The dbname for this connection.
1311         */
1312        public String getDBName()
1313        {
1314                if (SanityManager.DEBUG)
1315                        SanityManager.ASSERT(!isClosed(), "connection is closed");
1316 
1317                return getTR().getDBName();
1318        }
1319 
1320        public final LanguageConnectionContext getLanguageConnection() {
1321 
1322                if (SanityManager.DEBUG)
1323                        SanityManager.ASSERT(!isClosed(), "connection is closed");
1324 
1325                return getTR().getLcc();
1326        }
1327 
1328    /**
1329     * Raises an exception if the connection is closed.
1330     *
1331     * @exception SQLException if the connection is closed
1332     */
1333    protected final void checkIfClosed() throws SQLException {
1334        if (isClosed()) {
1335            throw Util.noCurrentConnection();
1336        }
1337    }
1338 
1339        //EmbedConnection30 overrides this method so it can release the savepoints array if
1340        //the exception severity is transaction level
1341        SQLException handleException(Throwable thrownException)
1342                        throws SQLException
1343        {
1344                /*
1345                ** By default, rollback the connection on if autocommit
1346                 ** is on.
1347                */
1348                return getTR().handleException(thrownException, 
1349                                                                  autoCommit,
1350                                                                  true // Rollback xact on auto commit
1351                                                                  );
1352        }
1353 
1354        /**
1355                Handle any type of Exception.
1356                <UL>
1357                <LI> Inform the contexts of the error
1358                <LI> Throw an Util based upon the thrown exception.
1359                </UL>
1360 
1361                REMIND: now that we know all the exceptions from our driver
1362                are Utils, would it make sense to shut down the system
1363                for unknown SQLExceptions? At present, we do not.
1364 
1365                Because this is the last stop for exceptions,
1366                it will catch anything that occurs in it and try
1367                to cleanup before re-throwing them.
1368        
1369                @param thrownException the exception
1370                @param rollbackOnAutoCommit rollback the xact on if autocommit is
1371                                on, otherwise rollback stmt but leave xact open (and
1372                                continue to hold on to locks).  Most of the time, this
1373                                will be true, excepting operations on result sets, like
1374                                getInt().
1375        */
1376        final SQLException handleException(Throwable thrownException, 
1377                                                                           boolean rollbackOnAutoCommit) 
1378                        throws SQLException 
1379        {
1380                return getTR().handleException(thrownException, autoCommit,
1381                                                                  rollbackOnAutoCommit); 
1382 
1383        }
1384 
1385        /*
1386           This is called from the EmbedConnectionContext to
1387           close on errors.  We assume all handling of the connectin
1388           is dealt with via the context stack, and our only role
1389           is to mark ourself as closed.
1390         */
1391 
1392        /**
1393                Close the connection when processing errors, or when
1394                 closing a nested connection.
1395                <p>
1396                This only marks it as closed and frees up its resources;
1397                any closing of the underlying connection or commit work
1398                is assumed to be done elsewhere.
1399 
1400                Called from EmbedConnectionContext's cleanup routine,        
1401                and by proxy.close().
1402         */
1403 
1404        public final void setInactive() {
1405 
1406                if (active == false)
1407                        return;
1408                // active = false
1409                // tr = null !-> active = false
1410 
1411                synchronized (getConnectionSynchronization()) {
1412                        active = false;
1413                        // tr = null; cleanupOnerror sets inactive but still needs tr to
1414                        // restore context later
1415                        dbMetadata = null;
1416                }
1417        }
1418 
1419        /**
1420                @exception Throwable        standard error policy
1421         */
1422        protected void finalize() throws Throwable 
1423        {
1424                if (rootConnection == this)
1425                {
1426                        super.finalize();
1427                        if (!isClosed())
1428                            close(exceptionClose);
1429                }
1430        }
1431 
1432        /**
1433         * if auto commit is on, remember that we need to commit
1434         * the current statement.
1435         */
1436    protected void needCommit() {
1437                if (!needCommit) needCommit = true;
1438        }
1439 
1440        /**
1441         * if a commit is needed, perform it.
1442     *
1443     * Must have connection synchonization and context set up already.
1444     *
1445         * @exception SQLException if commit returns error
1446         */
1447        protected void commitIfNeeded() throws SQLException 
1448    {
1449                if (autoCommit && needCommit) 
1450        {
1451            try
1452            {
1453                getTR().commit();
1454            } 
1455            catch (Throwable t)
1456            {
1457                throw handleException(t);
1458            }
1459            needCommit = false;
1460                }
1461        }
1462 
1463        /**
1464         * If in autocommit, then commit.
1465     * 
1466     * Used to force a commit after a result set closes in autocommit mode.
1467     * The needCommit mechanism does not work correctly as there are times
1468     * with cursors (like a commit, followed by a next, followed by a close)
1469     * where the system does not think it needs a commit but we need to 
1470     * force the commit on close.  It seemed safer to just force a commit
1471     * on close rather than count on keeping the needCommit flag correct for
1472     * all cursor cases.
1473     *
1474     * Must have connection synchonization and context set up already.
1475     *
1476         * @exception SQLException if commit returns error
1477         */
1478        protected void commitIfAutoCommit() throws SQLException 
1479    {
1480                if (autoCommit) 
1481        {
1482            try
1483            {
1484                getTR().commit();
1485            } 
1486            catch (Throwable t)
1487            {
1488                throw handleException(t);
1489            }
1490            needCommit = false;
1491                }
1492        }
1493 
1494 
1495        final protected Object getConnectionSynchronization()
1496  {
1497                return rootConnection;
1498  }
1499 
1500        /**
1501                Install the context manager for this thread.  Check connection status here.
1502                 @exception SQLException if fails
1503         */
1504        protected final void  setupContextStack() throws SQLException {
1505 
1506                /*
1507                        Track this entry, then throw an exception
1508                        rather than doing the quiet return.  Need the
1509                        track before the throw because the backtrack
1510                        is in a finally block.
1511                 */
1512 
1513                checkIfClosed();
1514 
1515                getTR().setupContextStack();
1516 
1517        }
1518 
1519        protected final void restoreContextStack() throws SQLException {
1520 
1521                if (SanityManager.DEBUG)
1522                Util.ASSERT(this, (active) || getTR().getCsf() !=null, "No context service to do restore");
1523 
1524                TransactionResourceImpl tr = getTR();
1525 
1526                //REMIND: someone is leaving an incorrect manager on when they
1527                // are exiting the system in the nested case.
1528                if (SanityManager.DEBUG)
1529                {
1530                        if ((tr.getCsf() != null) && (tr.getCsf().getCurrentContextManager() !=
1531                                tr.getContextManager()))
1532                        {
1533                                Util.THROWASSERT(this, 
1534                                        "Current Context Manager not the one was expected: " +
1535                                         tr.getCsf().getCurrentContextManager() + " " + 
1536                                         tr.getContextManager());
1537                        }
1538                }
1539 
1540                tr.restoreContextStack();
1541        }
1542 
1543        /*
1544        ** Create database methods.
1545        */
1546 
1547        /**
1548                Create a new database.
1549                @param dbname the database name
1550                @param info the properties
1551 
1552                @return        Database The newly created database or null.
1553 
1554                 @exception SQLException if fails to create database
1555        */
1556 
1557        private Database createDatabase(String dbname, Properties info)
1558                throws SQLException {
1559 
1560                info = filterProperties(info);
1561 
1562                try {
1563                        if (Monitor.createPersistentService(Property.DATABASE_MODULE, dbname, info) == null) 
1564                        {
1565                                // service already exists, create a warning
1566                                addWarning(EmbedSQLWarning.newEmbedSQLWarning(SQLState.DATABASE_EXISTS, dbname));
1567                        }
1568                } catch (StandardException mse) {
1569 
1570                        SQLException se = newSQLException(SQLState.CREATE_DATABASE_FAILED, dbname);
1571                        se.setNextException(handleException(mse));
1572                        throw se;
1573                }
1574 
1575                // clear these values as some modules hang onto
1576                // the properties set corresponding to service.properties
1577                // and they shouldn't be interested in these JDBC attributes.
1578                info.clear();
1579 
1580                return (Database) Monitor.findService(Property.DATABASE_MODULE, dbname);
1581        }
1582 
1583 
1584        /**
1585                Return false iff the monitor cannot handle a service
1586                of the type indicated by the protocol within the name.
1587                If that's the case then we are the wrong driver.
1588 
1589                Throw exception if anything else is wrong.
1590         */
1591 
1592        private boolean bootDatabase(Properties info) throws Throwable
1593        {
1594                String dbname = tr.getDBName();
1595 
1596                // boot database now
1597                try {
1598 
1599                        info = filterProperties(info);
1600                        
1601                        // try to start the service if it doesn't already exist
1602                        if (!Monitor.startPersistentService(dbname, info)) {
1603                                // a false indicates the monitor cannot handle a service
1604                                // of the type indicated by the protocol within the name.
1605                                // If that's the case then we are the wrong driver
1606                                // so just return null.
1607                                return false;
1608                        }
1609 
1610                        // clear these values as some modules hang onto
1611                        // the properties set corresponding to service.properties
1612                        // and they shouldn't be interested in these JDBC attributes.
1613                        info.clear();
1614 
1615                        Database database = (Database) Monitor.findService(Property.DATABASE_MODULE, dbname);
1616                        tr.setDatabase(database);
1617 
1618                } catch (StandardException mse) {
1619                        SQLException se = newSQLException(SQLState.BOOT_DATABASE_FAILED, dbname);
1620 
1621                        Throwable ne = mse.getNestedException();
1622                        SQLException nse;
1623 
1624                        /*
1625                          If there is a next exception, assume
1626                          that the first one is just a redundant "see the
1627                          next exception" message.
1628                          if it is a BEI, treat it as a database exception.
1629                          If there isn't a BEI, treat it as a java exception.
1630 
1631                          In general we probably want to walk the chain
1632                          and return all of them, but empirically, this
1633                          is all we need to do for now.
1634                          */
1635                        if (ne instanceof StandardException)
1636                                nse = Util.generateCsSQLException((StandardException)ne);
1637                        else if (ne != null)
1638                                nse = Util.javaException(ne);
1639                        else
1640                                nse = Util.generateCsSQLException(mse);
1641 
1642                        se.setNextException(nse);
1643                        throw se;
1644                }
1645 
1646                // If database exists, getDatabase() will return the database object.
1647                // If any error occured while booting an existing database, an
1648                // exception would have been thrown already.
1649                return true;
1650 
1651        }
1652 
1653        /*
1654         * Class interface methods used by database metadata to ensure
1655         * good relations with autocommit.
1656         */
1657 
1658    PreparedStatement prepareMetaDataStatement(String sql)
1659            throws SQLException {
1660                synchronized (getConnectionSynchronization()) {
1661                        setupContextStack();
1662                        PreparedStatement s = null;
1663                        try {
1664                            s = factory.newEmbedPreparedStatement(this, sql, true,
1665                                                                                          JDBC20Translation.TYPE_FORWARD_ONLY,
1666                                                                                          JDBC20Translation.CONCUR_READ_ONLY,
1667                                                                                          connectionHoldAbility,
1668                                                                                          JDBC30Translation.NO_GENERATED_KEYS,
1669                                                                                          null,
1670                                                                                          null);
1671                        } finally {
1672                            restoreContextStack();
1673                        }
1674                        return s;
1675                }
1676        }
1677 
1678        public final InternalDriver getLocalDriver()
1679        {
1680                if (SanityManager.DEBUG)
1681                        SanityManager.ASSERT(!isClosed(), "connection is closed");
1682 
1683                return getTR().getDriver();
1684        }
1685 
1686        /**
1687                Return the context manager for this connection.
1688        */
1689        public final ContextManager getContextManager() {
1690 
1691                if (SanityManager.DEBUG)
1692                        SanityManager.ASSERT(!isClosed(), "connection is closed");
1693 
1694                return getTR().getContextManager();
1695        }
1696 
1697        /**
1698         * Filter out properties from the passed in set of JDBC attributes
1699         * to remove any derby.* properties. This is to ensure that setting
1700         * derby.* properties does not work this way, it's not a defined way
1701         * to set such properties and could be a secuirty hole in allowing
1702         * remote connections to override system, application or database settings.
1703         * 
1704         * @return a new Properties set copied from the parameter but with no
1705         * derby.* properties.
1706         */
1707        private Properties filterProperties(Properties inputSet) {
1708                Properties limited = new Properties();
1709 
1710                // filter out any derby.* properties, only
1711                // JDBC attributes can be set this way
1712                for (java.util.Enumeration e = inputSet.propertyNames(); e.hasMoreElements(); ) {
1713 
1714                        String key = (String) e.nextElement();
1715 
1716                        // we don't allow properties to be set this way
1717                        if (key.startsWith("derby."))
1718                                continue;
1719                        limited.put(key, inputSet.getProperty(key));
1720                }
1721                return limited;
1722        }
1723 
1724        /*
1725        ** methods to be overridden by subimplementations wishing to insert
1726        ** their classes into the mix.
1727        */
1728 
1729        protected Database getDatabase() 
1730        {
1731                if (SanityManager.DEBUG)
1732                        SanityManager.ASSERT(!isClosed(), "connection is closed");
1733 
1734                return getTR().getDatabase();
1735        }
1736 
1737        final protected TransactionResourceImpl getTR()
1738        {
1739                return rootConnection.tr;
1740        }
1741 
1742        private EmbedConnectionContext pushConnectionContext(ContextManager cm) {
1743                return new EmbedConnectionContext(cm, this);
1744        }
1745 
1746        public final void setApplicationConnection(java.sql.Connection applicationConnection) {
1747                this.applicationConnection = applicationConnection;
1748        }
1749 
1750        public final java.sql.Connection getApplicationConnection() {
1751                return applicationConnection;
1752        }
1753 
1754        public void setDrdaID(String drdaID) {
1755                getLanguageConnection().setDrdaID(drdaID);
1756        }
1757 
1758        /**
1759                Reset the connection before it is returned from a PooledConnection
1760                to a new application request (wrapped by a BrokeredConnection).
1761                Examples of reset covered here is dropping session temporary tables
1762                and reseting IDENTITY_VAL_LOCAL.
1763                Most JDBC level reset is handled by calling standard java.sql.Connection
1764                methods from EmbedPooledConnection.
1765         */
1766        public void resetFromPool() throws SQLException {
1767                synchronized (getConnectionSynchronization())
1768                {
1769                        setupContextStack();
1770                        try {
1771                                getLanguageConnection().resetFromPool();
1772                        } catch (StandardException t) {
1773                                throw handleException(t);
1774                        }
1775                        finally
1776                        {
1777                                restoreContextStack();
1778                        }
1779                }
1780        }
1781 
1782        /*
1783        ** methods to be overridden by subimplementations wishing to insert
1784        ** their classes into the mix.
1785        ** The reason we need to override them is because we want to create a
1786        ** Local20/LocalStatment object (etc) rather than a Local/LocalStatment
1787        ** object (etc).
1788        */
1789 
1790 
1791        /*
1792        ** XA support
1793        */
1794 
1795        public final int xa_prepare() throws SQLException {
1796 
1797                synchronized (getConnectionSynchronization())
1798                {
1799            setupContextStack();
1800                        try
1801                        {
1802                                XATransactionController tc = 
1803                                        (XATransactionController) getLanguageConnection().getTransactionExecute();
1804 
1805                                int ret = tc.xa_prepare();
1806 
1807                                if (ret == XATransactionController.XA_RDONLY)
1808                                {
1809                                        // On a prepare call, xa allows an optimization that if the
1810                                        // transaction is read only, the RM can just go ahead and
1811                                        // commit it.  So if store returns this read only status -
1812                                        // meaning store has taken the liberty to commit already - we
1813                                        // needs to turn around and call internalCommit (without
1814                                        // committing the store again) to make sure the state is
1815                                        // consistent.  Since the transaction is read only, there is
1816                                        // probably not much that needs to be done.
1817 
1818                                        getLanguageConnection().internalCommit(false /* don't commitStore again */);
1819                                }
1820                                return ret;
1821                        } catch (StandardException t)
1822                        {
1823                                throw handleException(t);
1824                        }
1825                        finally
1826                        {
1827                                restoreContextStack();
1828                        }
1829                }
1830        }
1831 
1832 
1833        public final void xa_commit(boolean onePhase) throws SQLException {
1834 
1835                synchronized (getConnectionSynchronization())
1836                {
1837            setupContextStack();
1838                        try
1839                        {
1840                            getLanguageConnection().xaCommit(onePhase);
1841                        } catch (StandardException t)
1842                        {
1843                                throw handleException(t);
1844                        }
1845                        finally 
1846                        {
1847                                restoreContextStack();
1848                        }
1849                }
1850        }
1851        public final void xa_rollback() throws SQLException {
1852 
1853                synchronized (getConnectionSynchronization())
1854                {
1855            setupContextStack();
1856                        try
1857                        {
1858                            getLanguageConnection().xaRollback();
1859                        } catch (StandardException t)
1860                        {
1861                                throw handleException(t);
1862                        }
1863                        finally 
1864                        {
1865                                restoreContextStack();
1866                        }
1867                }
1868        }
1869        /**
1870         * returns false if there is an underlying transaction and that transaction
1871         * has done work.  True if there is no underlying transaction or that
1872         * underlying transaction is idle
1873         */
1874        public final boolean transactionIsIdle()
1875        {
1876                return getTR().isIdle();
1877        }
1878        private int setResultSetType(int resultSetType) {
1879 
1880                /* Add warning if scroll sensitive cursor
1881                 * and downgrade to scroll insensitive cursor.
1882                 */
1883                if (resultSetType == JDBC20Translation.TYPE_SCROLL_SENSITIVE)
1884                {
1885                        addWarning(EmbedSQLWarning.newEmbedSQLWarning(SQLState.NO_SCROLL_SENSITIVE_CURSORS));
1886                        resultSetType = JDBC20Translation.TYPE_SCROLL_INSENSITIVE;
1887                }
1888                return resultSetType;
1889        }
1890        
1891 
1892        /** 
1893         * Set the transaction isolation level that will be used for the 
1894         * next prepare.  Used by network server to implement DB2 style 
1895         * isolation levels.
1896         * @param level Isolation level to change to.  level is the DB2 level
1897         *               specified in the package names which happen to correspond
1898         *               to our internal levels. If 
1899         *               level == ExecutionContext.UNSPECIFIED_ISOLATION,
1900         *               the statement won't be prepared with an isolation level.
1901         * 
1902         * 
1903         */
1904        public void setPrepareIsolation(int level) throws SQLException
1905        {
1906                if (level == getPrepareIsolation())
1907                        return;
1908 
1909                switch (level)
1910                {
1911                        case ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL:
1912                        case ExecutionContext.REPEATABLE_READ_ISOLATION_LEVEL:
1913                        case ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL:
1914                        case ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL:
1915                        case ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL:
1916                                break;
1917                        default:
1918                                throw Util.generateCsSQLException(
1919                                                                                                                           SQLState.UNIMPLEMENTED_ISOLATION_LEVEL, new Integer(level));
1920                }
1921                
1922                synchronized(getConnectionSynchronization())
1923                {
1924                        getLanguageConnection().setPrepareIsolationLevel(level);
1925                }
1926        }
1927 
1928        /**
1929         * Return prepare isolation 
1930         */
1931        public int getPrepareIsolation()
1932        {
1933                return getLanguageConnection().getPrepareIsolationLevel();
1934        }
1935 
1936        /**
1937                Return a unique order number for a result set.
1938                A unique value is only needed if the result set is
1939                being created within procedure and thus must be using
1940                a nested connection.
1941        */
1942        final int getResultSetOrderId() {
1943 
1944                if (this == rootConnection) {
1945                        return 0;
1946                } else {
1947                        return rootConnection.resultSetId++;
1948                }
1949        }
1950 
1951        protected SQLException newSQLException(String messageId) {
1952                return Util.generateCsSQLException(messageId);
1953        }
1954        protected SQLException newSQLException(String messageId, Object arg1) {
1955                return Util.generateCsSQLException(messageId, arg1);
1956        }
1957        protected SQLException newSQLException(String messageId, Object arg1, Object arg2) {
1958                return Util.generateCsSQLException(messageId, arg1, arg2);
1959        }
1960 
1961        /////////////////////////////////////////////////////////////////////////
1962        //
1963        //        OBJECT OVERLOADS
1964        //
1965        /////////////////////////////////////////////////////////////////////////
1966 
1967    /**
1968     * Get a String representation that uniquely identifies
1969     * this connection.  Include the same information that is
1970     * printed in the log for various trace and error messages.
1971     *
1972     * In Derby the "physical" connection is a LanguageConnectionContext, 
1973     * or LCC.
1974     * The JDBC Connection is an JDBC-specific layer on top of this.  Rather
1975     * than create a new id here, we simply use the id of the underlying LCC.
1976     * Note that this is a big aid in debugging, because much of the
1977     * engine trace and log code prints the LCC id. 
1978     *
1979     * @return a string representation for this connection
1980     */
1981    public String toString()
1982    {
1983        if ( connString == null )
1984        {
1985            
1986            LanguageConnectionContext lcc = getLanguageConnection();
1987 
1988            connString = 
1989              this.getClass().getName() + "@" + this.hashCode() + " " +
1990                lcc.xidStr +                  
1991                    lcc.getTransactionExecute().getTransactionIdString() + 
1992                    "), " +
1993                lcc.lccStr + 
1994                    Integer.toString(lcc.getInstanceNumber()) + "), " +
1995                lcc.dbnameStr + lcc.getDbname() + "), " +
1996                lcc.drdaStr + lcc.getDrdaID() + ") ";
1997        }       
1998        
1999        return connString;
2000    }
2001 
2002 
2003}

[all classes][org.apache.derby.impl.jdbc]
EMMA 2.0.5312 (C) Vladimir Roubtsov