Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / impl / jdbc / EmbedConnection.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
new file mode 100644 (file)
index 0000000..4ba3945
--- /dev/null
@@ -0,0 +1,2439 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.jdbc.EmbedConnection\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.jdbc;\r
+\r
+import org.apache.derby.iapi.error.ExceptionSeverity;\r
+import org.apache.derby.jdbc.InternalDriver;\r
+\r
+import org.apache.derby.iapi.reference.Attribute;\r
+import org.apache.derby.iapi.reference.JDBC20Translation;\r
+import org.apache.derby.iapi.reference.JDBC30Translation;\r
+import org.apache.derby.iapi.reference.MessageId;\r
+import org.apache.derby.iapi.reference.Property;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.iapi.services.context.ContextManager;\r
+import org.apache.derby.iapi.services.memory.LowMemory;\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.jdbc.AuthenticationService;\r
+import org.apache.derby.iapi.jdbc.EngineConnection;\r
+\r
+import org.apache.derby.iapi.db.Database;\r
+import org.apache.derby.iapi.error.ExceptionSeverity;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.services.i18n.MessageService;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+import org.apache.derby.iapi.sql.execute.ExecutionContext;\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.store.access.XATransactionController;\r
+\r
+/* can't import due to name overlap:\r
+import java.sql.Connection;\r
+import java.sql.ResultSet;\r
+*/\r
+import java.sql.PreparedStatement;\r
+import java.sql.CallableStatement;\r
+import java.sql.Blob;\r
+import java.sql.Clob;\r
+import java.sql.DatabaseMetaData;\r
+import java.sql.SQLException;\r
+import java.sql.SQLWarning;\r
+import java.sql.Statement;\r
+\r
+import java.util.Map;\r
+import java.util.WeakHashMap;\r
+import java.util.HashMap;\r
+import java.util.Properties;\r
+import java.util.Iterator;\r
+\r
+import org.apache.derby.iapi.jdbc.EngineLOB;\r
+import org.apache.derby.impl.jdbc.authentication.NoneAuthenticationServiceImpl;\r
+\r
+/**\r
+ * Local implementation of Connection for a JDBC driver in \r
+ * the same process as the database.\r
+ * <p> \r
+ * There is always a single root (parent) connection.  The\r
+ * initial JDBC connection is the root connection. A\r
+ * call to <I>getCurrentConnection()</I> or with the URL \r
+ * <I>jdbc:default:connection</I> yields a nested connection that shares\r
+ * the same root connection as the parent.  A nested connection\r
+ * is implemented using this class.  The nested connection copies the \r
+ * state of the parent connection and shares some of the same \r
+ * objects (e.g. ContextManager) that are shared across all\r
+ * nesting levels.  The proxy also maintains its own\r
+ * state that is distinct from its parent connection (e.g.\r
+ * autocommit or warnings).\r
+ * <p>\r
+ * <B>SYNCHRONIZATION</B>: Just about all JDBC actions are\r
+ * synchronized across all connections stemming from the\r
+ * same root connection.  The synchronization is upon\r
+ * the a synchronized object return by the rootConnection.\r
+   <P><B>Supports</B>\r
+   <UL>\r
+  <LI> JDBC 2.0\r
+   </UL>\r
+ * \r
+ *\r
+ * @see TransactionResourceImpl\r
+ *\r
+ */\r
+public abstract class EmbedConnection implements EngineConnection\r
+{\r
+\r
+       private static final StandardException exceptionClose = StandardException.closeException();\r
+    \r
+    /**\r
+     * Static exception to be thrown when a Connection request can not\r
+     * be fulfilled due to lack of memory. A static exception as the lack\r
+     * of memory would most likely cause another OutOfMemoryException and\r
+     * if there is not enough memory to create the OOME exception then something\r
+     * like the VM dying could occur. Simpler just to throw a static.\r
+     */\r
+    public static final SQLException NO_MEM =\r
+        Util.generateCsSQLException(SQLState.LOGIN_FAILED, "java.lang.OutOfMemoryError");\r
+    \r
+    /**\r
+     * Low memory state object for connection requests.\r
+     */\r
+    public static final LowMemory memoryState = new LowMemory();\r
+\r
+       //////////////////////////////////////////////////////////\r
+       // OBJECTS SHARED ACROSS CONNECTION NESTING\r
+       //////////////////////////////////////////////////////////\r
+       DatabaseMetaData dbMetadata;\r
+\r
+       TransactionResourceImpl tr; // always access tr thru getTR()\r
+\r
+       private HashMap lobHashMap = null;\r
+       private int lobHMKey = 0;\r
+\r
+    /**\r
+     * Map to keep track of all the lobs associated with this\r
+     * connection. These lobs will be cleared after the transaction\r
+     * is no longer valid or when connection is closed\r
+     */\r
+    private WeakHashMap lobReferences = null;\r
+\r
+       //////////////////////////////////////////////////////////\r
+       // STATE (copied to new nested connections, but nesting\r
+       // specific)\r
+       //////////////////////////////////////////////////////////\r
+       private boolean active;\r
+       boolean autoCommit = true;\r
+       boolean needCommit;\r
+\r
+       // Set to true if NONE authentication is being used\r
+       private boolean usingNoneAuth;\r
+\r
+       /*\r
+     following is a new feature in JDBC3.0 where you can specify the holdability\r
+     of a resultset at the end of the transaction. This gets set by the\r
+        new method setHoldability(int) in JDBC3.0\r
+     * \r
+        */\r
+       private int     connectionHoldAbility = JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;\r
+\r
+\r
+       //////////////////////////////////////////////////////////\r
+       // NESTING SPECIFIC OBJECTS\r
+       //////////////////////////////////////////////////////////\r
+       /*\r
+       ** The root connection is the base connection upon\r
+       ** which all actions are synchronized.  By default,\r
+       ** we are the root connection unless we are created\r
+       ** by copying the state from another connection.\r
+       */\r
+       final EmbedConnection rootConnection;\r
+       private SQLWarning              topWarning;\r
+       /**     \r
+               Factory for JDBC objects to be created.\r
+       */\r
+       private InternalDriver factory;\r
+\r
+       /**\r
+               The Connection object the application is using when accessing the\r
+               database through this connection. In most cases this will be equal\r
+               to this. When Connection pooling is being used, then it will\r
+               be set to the Connection object handed to the application.\r
+               It is used for the getConnection() methods of various JDBC objects.\r
+       */\r
+       private java.sql.Connection applicationConnection;\r
+\r
+       /**\r
+               An increasing counter to assign to a ResultSet on its creation.\r
+               Used for ordering ResultSets returned from a procedure, always\r
+               returned in order of their creation. Is maintained at the root connection.\r
+       */\r
+       private int resultSetId;\r
+    \r
+    /** Cached string representation of the connection id */\r
+    private String connString;\r
+\r
+\r
+       //////////////////////////////////////////////////////////\r
+       // CONSTRUCTORS\r
+       //////////////////////////////////////////////////////////\r
+\r
+       // create a new Local Connection, using a new context manager\r
+       //\r
+       public EmbedConnection(InternalDriver driver, String url, Properties info)\r
+                throws SQLException\r
+       {\r
+               // Create a root connection.\r
+               applicationConnection = rootConnection = this;\r
+               factory = driver;\r
+\r
+\r
+               tr = new TransactionResourceImpl(driver, url, info);\r
+\r
+               active = true;\r
+\r
+               // register this thread and its context manager with\r
+               // the global context service\r
+               setupContextStack();\r
+\r
+               try {\r
+\r
+                       // stick my context into the context manager\r
+                       EmbedConnectionContext context = pushConnectionContext(tr.getContextManager());\r
+\r
+                       // if we are shutting down don't attempt to boot or create the database\r
+                       boolean shutdown = Boolean.valueOf(info.getProperty(Attribute.SHUTDOWN_ATTR)).booleanValue();\r
+\r
+                       // see if database is already booted\r
+                       Database database = (Database) Monitor.findService(Property.DATABASE_MODULE, tr.getDBName());\r
+\r
+                       // See if user wants to create a new database.\r
+                       boolean createBoot = createBoot(info);  \r
+\r
+                       // DERBY-2264: keeps track of whether we do a plain boot before an\r
+                       // (re)encryption or hard upgrade boot to (possibly) authenticate\r
+                       // first. We can not authenticate before we have booted, so in\r
+                       // order to enforce data base owner powers over encryption or\r
+                       // upgrade, we need a plain boot, then authenticate, then, if all\r
+                       // is well, boot with (re)encryption or upgrade.  Encryption at\r
+                       // create time is not checked.\r
+                       boolean isTwoPhaseEncryptionBoot = (!createBoot &&\r
+                                                                                               isEncryptionBoot(info));\r
+                       boolean isTwoPhaseUpgradeBoot = (!createBoot &&\r
+                                                                                        isHardUpgradeBoot(info));\r
+\r
+                       // Save original properties if we modified them for\r
+                       // two phase encryption or upgrade boot.\r
+                       Properties savedInfo = null;\r
+\r
+                       if (database != null)\r
+                       {\r
+                               // database already booted by someone else\r
+                               tr.setDatabase(database);\r
+                               isTwoPhaseEncryptionBoot = false;\r
+                               isTwoPhaseUpgradeBoot = false;\r
+                       }\r
+                       else if (!shutdown)\r
+                       {\r
+                               if (isTwoPhaseEncryptionBoot || isTwoPhaseUpgradeBoot) {\r
+                                       savedInfo = info;\r
+                                       info = removePhaseTwoProps((Properties)info.clone());\r
+                               }\r
+\r
+                               // Return false iff the monitor cannot handle a service of the\r
+                               // type indicated by the proptocol within the name.  If that's\r
+                               // the case then we are the wrong driver.\r
+\r
+                               if (!bootDatabase(info, isTwoPhaseUpgradeBoot))\r
+                               {\r
+                                       tr.clearContextInError();\r
+                                       setInactive();\r
+                                       return;\r
+                               }\r
+                       }\r
+\r
+\r
+                       if (createBoot && !shutdown)\r
+                       {\r
+                               // if we are shutting down don't attempt to boot or create the\r
+                               // database\r
+\r
+                               if (tr.getDatabase() != null) {\r
+                                       addWarning(EmbedSQLWarning.newEmbedSQLWarning(SQLState.DATABASE_EXISTS, getDBName()));\r
+                               } else {\r
+\r
+                                       // check for user's credential and authenticate the user\r
+                                       // with system level authentication service.\r
+                                       // FIXME: We should also check for CREATE DATABASE operation\r
+                                       //                authorization for the user if authorization was\r
+                                       //                set at the system level.\r
+                                       //                Right now, the authorization service does not\r
+                                       //                restrict/account for Create database op.\r
+                                       checkUserCredentials(null, info);\r
+                                       \r
+                                       // Process with database creation\r
+                                       database = createDatabase(tr.getDBName(), info);\r
+                                       tr.setDatabase(database);\r
+                               }\r
+                       }\r
+\r
+\r
+                       if (tr.getDatabase() == null) {\r
+                               String dbname = tr.getDBName();\r
+                               // do not clear the TransactionResource context. It will be restored\r
+                // as part of the finally clause below.\r
+                               this.setInactive();\r
+                               throw newSQLException(SQLState.DATABASE_NOT_FOUND, dbname);\r
+                       }\r
+\r
+\r
+                       // Check User's credentials and if it is a valid user of\r
+                       // the database\r
+                       //\r
+                       checkUserCredentials(tr.getDBName(), info);\r
+\r
+                       // Make a real connection into the database, setup lcc, tc and all\r
+                       // the rest.\r
+                       tr.startTransaction();\r
+\r
+                       if (isTwoPhaseEncryptionBoot || isTwoPhaseUpgradeBoot) {\r
+\r
+                               // DERBY-2264: shutdown and boot again with encryption or\r
+                               // upgrade attributes active. This is restricted to the\r
+                               // database owner if authentication and sqlAuthorization is on.\r
+                               if (!usingNoneAuth &&\r
+                                               getLanguageConnection().usesSqlAuthorization()) {\r
+                                       // a failure here leaves database booted, but no\r
+                                       // (re)encryption has taken place and the connection is\r
+                                       // rejected.\r
+                                       checkIsDBOwner(isTwoPhaseEncryptionBoot? OP_ENCRYPT :\r
+                                                                  OP_HARD_UPGRADE);\r
+                               }\r
+\r
+                               // shutdown and reboot using saved properties which\r
+                               // include the (re)encyption or upgrade attribute(s)\r
+                               info = savedInfo;\r
+                               handleException(tr.shutdownDatabaseException());\r
+                               restoreContextStack();\r
+                               tr = new TransactionResourceImpl(driver, url, info);\r
+                               active = true;\r
+                               setupContextStack();\r
+                               context = pushConnectionContext(tr.getContextManager());\r
+\r
+                               if (!bootDatabase(info, false))\r
+                               {\r
+                                       if (SanityManager.DEBUG) {\r
+                                               SanityManager.THROWASSERT(\r
+                                                       "bootDatabase failed after initial plain boot " +\r
+                                                       "for (re)encryption or upgrade");\r
+                                       }\r
+                                       tr.clearContextInError();\r
+                                       setInactive();\r
+                                       return;\r
+                               }\r
+                               // don't need to check user credentials again, did\r
+                               // that on first plain boot, so just start\r
+                               tr.startTransaction();\r
+                       }\r
+\r
+                       // now we have the database connection, we can shut down\r
+                       if (shutdown) {\r
+                               if (!usingNoneAuth &&\r
+                                               getLanguageConnection().usesSqlAuthorization()) {\r
+                                       // DERBY-2264: Only allow database owner to shut down if\r
+                                       // authentication and sqlAuthorization is on.\r
+                                       checkIsDBOwner(OP_SHUTDOWN);\r
+                               }\r
+                               throw tr.shutdownDatabaseException();\r
+                       }\r
+\r
+                       // Raise a warning in sqlAuthorization mode if authentication is not ON\r
+                       if (usingNoneAuth && getLanguageConnection().usesSqlAuthorization())\r
+                               addWarning(EmbedSQLWarning.newEmbedSQLWarning(SQLState.SQL_AUTHORIZATION_WITH_NO_AUTHENTICATION));\r
+               }\r
+        catch (OutOfMemoryError noMemory)\r
+               {\r
+                       //System.out.println("freeA");\r
+                       restoreContextStack();\r
+                       tr.lcc = null;\r
+                       tr.cm = null;\r
+                       \r
+                       //System.out.println("free");\r
+                       //System.out.println(Runtime.getRuntime().freeMemory());\r
+            memoryState.setLowMemory();\r
+                       \r
+                       //noMemory.printStackTrace();\r
+                       // throw Util.generateCsSQLException(SQLState.LOGIN_FAILED, noMemory.getMessage(), noMemory);\r
+                       throw NO_MEM;\r
+               }\r
+               catch (Throwable t) {\r
+            if (t instanceof StandardException)\r
+            {\r
+                StandardException se = (StandardException) t;\r
+                if (se.getSeverity() < ExceptionSeverity.SESSION_SEVERITY)\r
+                    se.setSeverity(ExceptionSeverity.SESSION_SEVERITY);\r
+            }\r
+                       tr.cleanupOnError(t);\r
+                       throw handleException(t);\r
+               } finally {\r
+                       restoreContextStack();\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+         Examine the attributes set provided for illegal boot\r
+         combinations and determine if this is a create boot.\r
+\r
+         @return true iff the attribute <em>create=true</em> is provided. This\r
+         means create a standard database.  In other cases, returns\r
+         false.\r
+\r
+         @param p the attribute set.\r
+\r
+         @exception SQLException Throw if more than one of\r
+         <em>create</em>, <em>createFrom</em>, <em>restoreFrom</em> and\r
+         <em>rollForwardRecoveryFrom</em> is used simultaneously. <br>\r
+\r
+         Also, throw if (re)encryption is attempted with one of\r
+         <em>createFrom</em>, <em>restoreFrom</em> and\r
+         <em>rollForwardRecoveryFrom</em>.\r
+\r
+       */\r
+       private boolean createBoot(Properties p) throws SQLException\r
+       {\r
+               int createCount = 0;\r
+\r
+               if (Boolean.valueOf(p.getProperty(Attribute.CREATE_ATTR)).booleanValue())\r
+                       createCount++;\r
+\r
+               int restoreCount=0;\r
+               //check if the user has specified any /create/restore/recover from backup attributes.\r
+               if (p.getProperty(Attribute.CREATE_FROM) != null)\r
+                       restoreCount++;\r
+               if (p.getProperty(Attribute.RESTORE_FROM) != null)\r
+                       restoreCount++;\r
+               if (p.getProperty(Attribute.ROLL_FORWARD_RECOVERY_FROM)!=null)\r
+                       restoreCount++;\r
+               if(restoreCount > 1)\r
+                       throw newSQLException(SQLState.CONFLICTING_RESTORE_ATTRIBUTES);\r
+       \r
+        // check if user has specified re-encryption attributes in\r
+        // combination with createFrom/restoreFrom/rollForwardRecoveryFrom\r
+        // attributes.  Re-encryption is not\r
+        // allowed when restoring from backup.\r
+        if (restoreCount != 0 && isEncryptionBoot(p)) {\r
+                       throw newSQLException(SQLState.CONFLICTING_RESTORE_ATTRIBUTES);\r
+        }\r
+\r
+\r
+               //add the restore count to create count to make sure \r
+               //user has not specified and restore together by mistake.\r
+               createCount = createCount + restoreCount ;\r
+\r
+               //\r
+               if (createCount > 1) throw newSQLException(SQLState.CONFLICTING_CREATE_ATTRIBUTES);\r
+               \r
+               //retuns true only for the  create flag not for restore flags\r
+               return (createCount - restoreCount) == 1;\r
+       }\r
+\r
+       /**\r
+        * Examine boot properties and determine if a boot with the given\r
+        * attributes would entail an encryption operation.\r
+        *\r
+        * @param p the attribute set\r
+        * @return true if a boot will encrypt or re-encrypt the database\r
+        */\r
+       private boolean isEncryptionBoot(Properties p)\r
+       {\r
+               return ((Boolean.valueOf(\r
+                                        p.getProperty(Attribute.DATA_ENCRYPTION)).booleanValue()) ||\r
+                               (p.getProperty(Attribute.NEW_BOOT_PASSWORD) != null)           ||\r
+                               (p.getProperty(Attribute.NEW_CRYPTO_EXTERNAL_KEY) != null));\r
+       }\r
+\r
+       /**\r
+        * Examine boot properties and determine if a boot with the given\r
+        * attributes would entail a hard upgrade.\r
+        *\r
+        * @param p the attribute set\r
+        * @return true if a boot will hard upgrade the database\r
+        */\r
+       private boolean isHardUpgradeBoot(Properties p)\r
+       {\r
+               return Boolean.valueOf(\r
+                       p.getProperty(Attribute.UPGRADE_ATTR)).booleanValue();\r
+       }\r
+\r
+       /**\r
+        * Remove any encryption or upgarde properties from the given properties\r
+        *\r
+        * @param p the attribute set\r
+        * @return clone sans encryption properties\r
+        */\r
+       private Properties removePhaseTwoProps(Properties p)\r
+       {\r
+               p.remove(Attribute.DATA_ENCRYPTION);\r
+               p.remove(Attribute.NEW_BOOT_PASSWORD);\r
+               p.remove(Attribute.NEW_CRYPTO_EXTERNAL_KEY);\r
+               p.remove(Attribute.UPGRADE_ATTR);\r
+               return p;\r
+       }\r
+\r
+\r
+       /**\r
+        * Create a new connection based off of the \r
+        * connection passed in.  Initializes state\r
+        * based on input connection, and copies \r
+        * appropriate object pointers. This is only used\r
+          for nested connections.\r
+        *\r
+        * @param inputConnection the input connection\r
+        */\r
+       public EmbedConnection(EmbedConnection inputConnection) \r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(inputConnection.active, \r
+                       "trying to create a proxy for an inactive conneciton");\r
+               }\r
+\r
+               // Proxy connections are always autocommit false\r
+               // thus needCommit is irrelavent.\r
+               autoCommit = false;\r
+\r
+\r
+               /*\r
+               ** Nesting specific state we are copying from \r
+               ** the inputConnection\r
+               */\r
+\r
+               /*\r
+               ** Objects we are sharing across nestings\r
+               */\r
+               // set it to null to allow it to be final.\r
+               tr = null;                      // a proxy connection has no direct\r
+                                                               // pointer to the tr.  Every call has to go\r
+                                                               // thru the rootConnection's tr.\r
+               active = true;\r
+               this.rootConnection = inputConnection.rootConnection;\r
+               this.applicationConnection = this;\r
+               this.factory = inputConnection.factory;\r
+\r
+               //if no holdability specified for the resultset, use the holability\r
+               //defined for the connection\r
+               this.connectionHoldAbility = inputConnection.connectionHoldAbility;\r
+\r
+               //RESOLVE: although it looks like the right\r
+               // thing to share the metadata object, if\r
+               // we do we'll get the wrong behavior on\r
+               // getCurrentConnection().getMetaData().isReadOnly()\r
+               // so don't try to be smart and uncomment the\r
+               // following.  Ultimately, the metadata should\r
+               // be shared by all connections anyway.\r
+               //dbMetadata = inputConnection.dbMetadata;\r
+       }\r
+\r
+       //\r
+       // Check passed-in user's credentials.\r
+       //\r
+       private void checkUserCredentials(String dbname,\r
+                                                                         Properties userInfo)\r
+         throws SQLException\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClosed(), "connection is closed");\r
+\r
+               // If a database name was passed-in then check user's credential\r
+               // in that database using the database's authentication service,\r
+               // otherwise check if it is a valid user in the JBMS system.\r
+               //\r
+               // NOTE: We always expect an authentication service per database\r
+               // and one at the system level.\r
+               //\r
+               AuthenticationService authenticationService = null;\r
+\r
+               // Retrieve appropriate authentication service handle\r
+               if (dbname == null)\r
+                       authenticationService = getLocalDriver().getAuthenticationService();\r
+               else\r
+                       authenticationService = getTR().getDatabase().getAuthenticationService();\r
+\r
+               // check that we do have a authentication service\r
+               // it is _always_ expected.\r
+               if (authenticationService == null)\r
+               {\r
+                       String failedString = MessageService.getTextMessage(\r
+                               (dbname == null) ? MessageId.AUTH_NO_SERVICE_FOR_SYSTEM : MessageId.AUTH_NO_SERVICE_FOR_DB);\r
+\r
+                       throw newSQLException(SQLState.LOGIN_FAILED, failedString);\r
+               }\r
+               \r
+               // Let's authenticate now\r
+                       \r
+               if (!authenticationService.authenticate(\r
+                                                                                          dbname,\r
+                                                                                          userInfo\r
+                                                                                          )) {\r
+\r
+                       throw newSQLException(SQLState.LOGIN_FAILED, MessageService.getTextMessage(MessageId.AUTH_INVALID));\r
+\r
+               }\r
+\r
+               // If authentication is not on, we have to raise a warning if sqlAuthorization is ON\r
+               // Since NoneAuthenticationService is the default for Derby, it should be ok to refer\r
+               // to its implementation here, since it will always be present.\r
+               if (authenticationService instanceof NoneAuthenticationServiceImpl)\r
+                       usingNoneAuth = true;\r
+       }\r
+\r
+       /* Enumerate operations controlled by database owner powers */\r
+       private static final int OP_ENCRYPT = 0;\r
+       private static final int OP_SHUTDOWN = 1;\r
+       private static final int OP_HARD_UPGRADE = 2;\r
+       /**\r
+        * Check if actual authenticationId is equal to the database owner's.\r
+        *\r
+        * @param operation attempted operation which needs database owner powers\r
+        * @throws SQLException if actual authenticationId is different\r
+        * from authenticationId of database owner.\r
+        */\r
+       private void checkIsDBOwner(int operation) throws SQLException\r
+       {\r
+               final LanguageConnectionContext lcc = getLanguageConnection();\r
+               final String actualId = lcc.getAuthorizationId();\r
+               final String dbOwnerId = lcc.getDataDictionary().\r
+                       getAuthorizationDatabaseOwner();\r
+               if (!actualId.equals(dbOwnerId)) {\r
+                       switch (operation) {\r
+                       case OP_ENCRYPT:\r
+                               throw newSQLException(SQLState.AUTH_ENCRYPT_NOT_DB_OWNER,\r
+                                                                         actualId, tr.getDBName());\r
+                       case OP_SHUTDOWN:\r
+                               throw newSQLException(SQLState.AUTH_SHUTDOWN_NOT_DB_OWNER,\r
+                                                                         actualId, tr.getDBName());\r
+                       case OP_HARD_UPGRADE:\r
+                               throw newSQLException(SQLState.AUTH_HARD_UPGRADE_NOT_DB_OWNER,\r
+                                                                         actualId, tr.getDBName());\r
+                       default:\r
+                               if (SanityManager.DEBUG) {\r
+                                       SanityManager.THROWASSERT(\r
+                                               "illegal checkIsDBOwner operation");\r
+                               }\r
+                               throw newSQLException(\r
+                                       SQLState.AUTH_DATABASE_CONNECTION_REFUSED);\r
+                       }\r
+               }\r
+       }\r
+\r
+    /**\r
+     * Gets the EngineType of the connected database.\r
+     *\r
+     * @return 0 if there is no database, the engine type otherwise. @see org.apache.derby.iapi.reference.EngineType\r
+     */\r
+    public int getEngineType()\r
+    {\r
+        Database db = getDatabase();\r
+\r
+        if( null == db)\r
+            return 0;\r
+        return db.getEngineType();\r
+    }\r
+    \r
+       /*\r
+       ** Methods from java.sql.Connection\r
+       */\r
+\r
+    /**\r
+        * SQL statements without parameters are normally\r
+     * executed using Statement objects. If the same SQL statement \r
+     * is executed many times, it is more efficient to use a \r
+     * PreparedStatement\r
+     *\r
+     * JDBC 2.0\r
+     *\r
+     * Result sets created using the returned Statement will have\r
+     * forward-only type, and read-only concurrency, by default.\r
+     *\r
+     * @return a new Statement object \r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+       public final Statement createStatement() throws SQLException \r
+       {\r
+               return createStatement(JDBC20Translation.TYPE_FORWARD_ONLY,\r
+                                                          JDBC20Translation.CONCUR_READ_ONLY,\r
+                                                          connectionHoldAbility);\r
+       }\r
+\r
+    /**\r
+     * JDBC 2.0\r
+     *\r
+     * Same as createStatement() above, but allows the default result set\r
+     * type and result set concurrency type to be overridden.\r
+     *\r
+     * @param resultSetType a result set type, see ResultSet.TYPE_XXX\r
+     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX\r
+     * @return a new Statement object \r
+      * @exception SQLException if a database-access error occurs.\r
+    */\r
+    public final Statement createStatement(int resultSetType,\r
+                                                                int resultSetConcurrency) \r
+                                               throws SQLException\r
+       {\r
+               return createStatement(resultSetType, resultSetConcurrency,\r
+                           connectionHoldAbility);\r
+       }\r
+\r
+    /**\r
+     * JDBC 3.0\r
+     *\r
+     * Same as createStatement() above, but allows the default result set\r
+     * type, result set concurrency type and result set holdability type to\r
+     * be overridden.\r
+     *\r
+     * @param resultSetType a result set type, see ResultSet.TYPE_XXX\r
+     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX\r
+     * @param resultSetHoldability a holdability type,\r
+     *  ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT\r
+     * @return a new Statement object\r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public final Statement createStatement(int resultSetType,\r
+                                                                int resultSetConcurrency,\r
+                                                                int resultSetHoldability)\r
+                                               throws SQLException\r
+       {\r
+               checkIfClosed();\r
+\r
+               return factory.newEmbedStatement(this, false,\r
+                       setResultSetType(resultSetType), resultSetConcurrency,\r
+                       resultSetHoldability);\r
+       }\r
+\r
+    /**\r
+     * A SQL statement with or without IN parameters can be\r
+     * pre-compiled and stored in a PreparedStatement object. This\r
+     * object can then be used to efficiently execute this statement\r
+     * multiple times.\r
+     *\r
+     * <P><B>Note:</B> This method is optimized for handling\r
+     * parametric SQL statements that benefit from precompilation. If\r
+     * the driver supports precompilation, prepareStatement will send\r
+     * the statement to the database for precompilation. Some drivers\r
+     * may not support precompilation. In this case, the statement may\r
+     * not be sent to the database until the PreparedStatement is\r
+     * executed.  This has no direct affect on users; however, it does\r
+     * affect which method throws certain SQLExceptions.\r
+     *\r
+     * JDBC 2.0\r
+     *\r
+     * Result sets created using the returned PreparedStatement will have\r
+     * forward-only type, and read-only concurrency, by default.\r
+     *\r
+     * @param sql a SQL statement that may contain one or more '?' IN\r
+     * parameter placeholders\r
+     * @return a new PreparedStatement object containing the\r
+     * pre-compiled statement \r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public final PreparedStatement prepareStatement(String sql)\r
+           throws SQLException\r
+       {\r
+               return prepareStatement(sql,JDBC20Translation.TYPE_FORWARD_ONLY,\r
+                       JDBC20Translation.CONCUR_READ_ONLY,\r
+                       connectionHoldAbility,\r
+                       JDBC30Translation.NO_GENERATED_KEYS,\r
+                       null,\r
+                       null);\r
+       }\r
+\r
+\r
+    /**\r
+     * JDBC 2.0\r
+     *\r
+     * Same as prepareStatement() above, but allows the default result set\r
+     * type and result set concurrency type to be overridden.\r
+     *\r
+     * @param resultSetType a result set type, see ResultSet.TYPE_XXX\r
+     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX\r
+     * @return a new PreparedStatement object containing the\r
+     * pre-compiled SQL statement\r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public final PreparedStatement prepareStatement(String sql, int resultSetType,\r
+                                       int resultSetConcurrency)\r
+           throws SQLException\r
+       {\r
+               return prepareStatement(sql,\r
+                       resultSetType,\r
+                       resultSetConcurrency,\r
+                       connectionHoldAbility,\r
+                       JDBC30Translation.NO_GENERATED_KEYS,\r
+                       null,\r
+                       null);\r
+       }\r
+\r
+    /**\r
+     * JDBC 3.0\r
+     *\r
+     * Same as prepareStatement() above, but allows the default result set\r
+     * type, result set concurrency type and result set holdability\r
+     * to be overridden.\r
+     *\r
+     * @param resultSetType a result set type, see ResultSet.TYPE_XXX\r
+     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX\r
+     * @param resultSetHoldability - one of the following ResultSet constants:\r
+     *  ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT\r
+     * @return a new PreparedStatement object containing the\r
+     *  pre-compiled SQL statement\r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public final PreparedStatement prepareStatement(String sql, int resultSetType,\r
+                                       int resultSetConcurrency, int resultSetHoldability)\r
+           throws SQLException\r
+       {\r
+               return prepareStatement(sql,\r
+                       resultSetType,\r
+                       resultSetConcurrency,\r
+                       resultSetHoldability,\r
+                       JDBC30Translation.NO_GENERATED_KEYS,\r
+                       null,\r
+                       null);\r
+       }\r
+\r
+\r
+       /**\r
+        * Creates a default PreparedStatement object capable of returning\r
+        * the auto-generated keys designated by the given array. This array contains\r
+        * the indexes of the columns in the target table that contain the auto-generated\r
+        * keys that should be made available. This array is ignored if the SQL statement\r
+        * is not an INSERT statement\r
+\r
+               JDBC 3.0\r
+        *\r
+        *\r
+        * @param sql  An SQL statement that may contain one or more ? IN parameter placeholders\r
+        * @param columnIndexes  An array of column indexes indicating the columns\r
+        *  that should be returned from the inserted row or rows\r
+        *\r
+        * @return  A new PreparedStatement object, containing the pre-compiled\r
+        *  SQL statement, that will have the capability of returning auto-generated keys\r
+        *  designated by the given array of column indexes\r
+        *\r
+        * @exception SQLException  Thrown on error.\r
+        */\r
+       public final PreparedStatement prepareStatement(\r
+                       String sql,\r
+                       int[] columnIndexes)\r
+    throws SQLException\r
+       {\r
+               return prepareStatement(sql,\r
+                       JDBC20Translation.TYPE_FORWARD_ONLY,\r
+                       JDBC20Translation.CONCUR_READ_ONLY,\r
+                       connectionHoldAbility,\r
+                       columnIndexes == null\r
+                               ? JDBC30Translation.NO_GENERATED_KEYS\r
+                               : JDBC30Translation.RETURN_GENERATED_KEYS,\r
+                       columnIndexes,\r
+                       null);\r
+       }\r
+\r
+       /**\r
+        * Creates a default PreparedStatement object capable of returning\r
+        * the auto-generated keys designated by the given array. This array contains\r
+        * the names of the columns in the target table that contain the auto-generated\r
+        * keys that should be returned. This array is ignored if the SQL statement\r
+        * is not an INSERT statement\r
+        *\r
+               JDBC 3.0\r
+        *\r
+        * @param sql  An SQL statement that may contain one or more ? IN parameter placeholders\r
+        * @param columnNames  An array of column names indicating the columns\r
+        *  that should be returned from the inserted row or rows\r
+        *\r
+        * @return  A new PreparedStatement object, containing the pre-compiled\r
+        *  SQL statement, that will have the capability of returning auto-generated keys\r
+        *  designated by the given array of column names\r
+        *\r
+        * @exception SQLException Thrown on error.\r
+        */\r
+       public final PreparedStatement prepareStatement(\r
+                       String sql,\r
+                       String[] columnNames)\r
+    throws SQLException\r
+       {\r
+               return prepareStatement(sql,\r
+                       JDBC20Translation.TYPE_FORWARD_ONLY,\r
+                       JDBC20Translation.CONCUR_READ_ONLY,\r
+                       connectionHoldAbility,\r
+                       columnNames == null\r
+                               ? JDBC30Translation.NO_GENERATED_KEYS\r
+                               : JDBC30Translation.RETURN_GENERATED_KEYS,\r
+                       null,\r
+                       columnNames);\r
+       }\r
+\r
+       /**\r
+        * Creates a default PreparedStatement object that has the capability to\r
+        * retieve auto-generated keys. The given constant tells the driver\r
+        * whether it should make auto-generated keys available for retrieval.\r
+        * This parameter is ignored if the SQL statement is not an INSERT statement.\r
+        * JDBC 3.0\r
+        *\r
+        * @param sql  A SQL statement that may contain one or more ? IN parameter placeholders\r
+        * @param autoGeneratedKeys  A flag indicating whether auto-generated keys\r
+        *  should be returned\r
+        *\r
+        * @return  A new PreparedStatement object, containing the pre-compiled\r
+        *  SQL statement, that will have the capability of returning auto-generated keys\r
+        *\r
+        * @exception SQLException  Feature not implemented for now.\r
+        */\r
+       public final PreparedStatement prepareStatement(\r
+                       String sql,\r
+                       int autoGeneratedKeys)\r
+    throws SQLException\r
+       {\r
+               return prepareStatement(sql,\r
+                       JDBC20Translation.TYPE_FORWARD_ONLY,\r
+                       JDBC20Translation.CONCUR_READ_ONLY,\r
+                       connectionHoldAbility,\r
+                       autoGeneratedKeys,\r
+                       null,\r
+                       null);\r
+       }\r
+    \r
+       private PreparedStatement prepareStatement(String sql, int resultSetType,\r
+                                       int resultSetConcurrency, int resultSetHoldability,\r
+                                       int autoGeneratedKeys, int[] columnIndexes, String[] columnNames)\r
+       throws SQLException\r
+        {\r
+               synchronized (getConnectionSynchronization()) {\r
+                        setupContextStack();\r
+                       try {\r
+                           return factory.newEmbedPreparedStatement(this, sql, false,\r
+                                                                                          setResultSetType(resultSetType),\r
+                                                                                          resultSetConcurrency,\r
+                                                                                          resultSetHoldability,\r
+                                                                                          autoGeneratedKeys,\r
+                                                                                          columnIndexes,\r
+                                                                                          columnNames);\r
+                       } finally {\r
+                           restoreContextStack();\r
+                       }\r
+               }\r
+     }\r
+\r
+    /**\r
+     * A SQL stored procedure call statement is handled by creating a\r
+     * CallableStatement for it. The CallableStatement provides\r
+     * methods for setting up its IN and OUT parameters, and\r
+     * methods for executing it.\r
+     *\r
+     * <P><B>Note:</B> This method is optimized for handling stored\r
+     * procedure call statements. Some drivers may send the call\r
+     * statement to the database when the prepareCall is done; others\r
+     * may wait until the CallableStatement is executed. This has no\r
+     * direct affect on users; however, it does affect which method\r
+     * throws certain SQLExceptions.\r
+     *\r
+     * JDBC 2.0\r
+     *\r
+     * Result sets created using the returned CallableStatement will have\r
+     * forward-only type, and read-only concurrency, by default.\r
+     *\r
+     * @param sql a SQL statement that may contain one or more '?'\r
+     * parameter placeholders. Typically this  statement is a JDBC\r
+     * function call escape string.\r
+     * @return a new CallableStatement object containing the\r
+     * pre-compiled SQL statement \r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+       public final CallableStatement prepareCall(String sql) \r
+               throws SQLException \r
+       {\r
+               return prepareCall(sql, JDBC20Translation.TYPE_FORWARD_ONLY,\r
+                                                  JDBC20Translation.CONCUR_READ_ONLY,\r
+                                                  connectionHoldAbility);\r
+       }\r
+\r
+    /**\r
+     * JDBC 2.0\r
+     *\r
+     * Same as prepareCall() above, but allows the default result set\r
+     * type and result set concurrency type to be overridden.\r
+     *\r
+     * @param resultSetType a result set type, see ResultSet.TYPE_XXX\r
+     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX\r
+     * @return a new CallableStatement object containing the\r
+     * pre-compiled SQL statement \r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public final CallableStatement prepareCall(String sql, int resultSetType,\r
+                                int resultSetConcurrency)\r
+               throws SQLException \r
+       {\r
+               return prepareCall(sql, resultSetType, resultSetConcurrency,\r
+                                                  connectionHoldAbility);\r
+       }\r
+\r
+    /**\r
+     * JDBC 3.0\r
+     *\r
+     * Same as prepareCall() above, but allows the default result set\r
+     * type, result set concurrency type and result set holdability\r
+     * to be overridden.\r
+     *\r
+     * @param resultSetType a result set type, see ResultSet.TYPE_XXX\r
+     * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX\r
+     * @param resultSetHoldability - one of the following ResultSet constants:\r
+     *  ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT\r
+     * @return a new CallableStatement object containing the\r
+     * pre-compiled SQL statement \r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public final CallableStatement prepareCall(String sql, int resultSetType, \r
+                                int resultSetConcurrency, int resultSetHoldability)\r
+               throws SQLException \r
+       {\r
+               checkIfClosed();\r
+\r
+               synchronized (getConnectionSynchronization())\r
+               {\r
+            setupContextStack();\r
+                       try \r
+                       {\r
+                           return factory.newEmbedCallableStatement(this, sql,\r
+                                                                                          setResultSetType(resultSetType),\r
+                                                                                          resultSetConcurrency,\r
+                                                                                          resultSetHoldability);\r
+                       } \r
+                       finally \r
+                       {\r
+                           restoreContextStack();\r
+                       }\r
+               }\r
+       }\r
+\r
+    /**\r
+     * A driver may convert the JDBC sql grammar into its system's\r
+     * native SQL grammar prior to sending it; nativeSQL returns the\r
+     * native form of the statement that the driver would have sent.\r
+     *\r
+     * @param sql a SQL statement that may contain one or more '?'\r
+     * parameter placeholders\r
+     * @return the native form of this statement\r
+     */\r
+    public String nativeSQL(String sql) throws SQLException {\r
+        checkIfClosed();\r
+               // we don't massage the strings at all, so this is easy:\r
+               return sql;\r
+       }\r
+\r
+    /**\r
+     * If a connection is in auto-commit mode, then all its SQL\r
+     * statements will be executed and committed as individual\r
+     * transactions.  Otherwise, its SQL statements are grouped into\r
+     * transactions that are terminated by either commit() or\r
+     * rollback().  By default, new connections are in auto-commit\r
+     * mode.\r
+     *\r
+     * The commit occurs when the statement completes or the next\r
+     * execute occurs, whichever comes first. In the case of\r
+     * statements returning a ResultSet, the statement completes when\r
+     * the last row of the ResultSet has been retrieved or the\r
+     * ResultSet has been closed. In advanced cases, a single\r
+     * statement may return multiple results as well as output\r
+     * parameter values. Here the commit occurs when all results and\r
+     * output param values have been retrieved.\r
+     *\r
+     * @param autoCommit true enables auto-commit; false disables\r
+     * auto-commit.  \r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+       public void setAutoCommit(boolean autoCommit) throws SQLException {\r
+               checkIfClosed();\r
+\r
+               // Is this a nested connection\r
+               if (rootConnection != this) {\r
+                       if (autoCommit)\r
+                               throw newSQLException(SQLState.NO_AUTO_COMMIT_ON);\r
+               }\r
+\r
+               if (this.autoCommit != autoCommit)\r
+                       commit();\r
+\r
+               this.autoCommit = autoCommit;\r
+       }\r
+\r
+    /**\r
+     * Get the current auto-commit state.\r
+     *\r
+     * @return Current state of auto-commit mode.\r
+     * @see #setAutoCommit \r
+     */\r
+    public boolean getAutoCommit() throws SQLException {\r
+        checkIfClosed();\r
+               return autoCommit;\r
+       }\r
+\r
+    /**\r
+     * Commit makes all changes made since the previous\r
+     * commit/rollback permanent and releases any database locks\r
+     * currently held by the Connection. This method should only be\r
+     * used when auto commit has been disabled.\r
+     *\r
+     * @exception SQLException if a database-access error occurs.\r
+     * @see #setAutoCommit \r
+     */\r
+    public void commit() throws SQLException {\r
+               synchronized (getConnectionSynchronization())\r
+               {\r
+                       /*\r
+                       ** Note that the context stack is\r
+                       ** needed even for rollback & commit\r
+                       */\r
+            setupContextStack();\r
+\r
+                       try\r
+                       {\r
+                       getTR().commit();\r
+                       clearLOBMapping();\r
+                       }\r
+            catch (Throwable t)\r
+                       {\r
+                               throw handleException(t);\r
+                       }\r
+                       finally \r
+                       {\r
+                               restoreContextStack();\r
+                       }\r
+\r
+                       needCommit = false;\r
+               }\r
+       }\r
+\r
+    /**\r
+     * Rollback drops all changes made since the previous\r
+     * commit/rollback and releases any database locks currently held\r
+     * by the Connection. This method should only be used when auto\r
+     * commit has been disabled.\r
+     *\r
+     * @exception SQLException if a database-access error occurs.\r
+     * @see #setAutoCommit \r
+     */\r
+    public void rollback() throws SQLException {\r
+\r
+               synchronized (getConnectionSynchronization())\r
+               {\r
+                       /*\r
+                       ** Note that the context stack is\r
+                       ** needed even for rollback & commit\r
+                       */\r
+            setupContextStack();\r
+                       try\r
+                       {\r
+                       getTR().rollback();\r
+                       clearLOBMapping();\r
+                       } catch (Throwable t) {\r
+                               throw handleException(t);\r
+                       }\r
+                       finally \r
+                       {\r
+                               restoreContextStack();\r
+                       }\r
+                       needCommit = false;\r
+               } \r
+       }\r
+\r
+    /**\r
+     * In some cases, it is desirable to immediately release a\r
+     * Connection's database and JDBC resources instead of waiting for\r
+     * them to be automatically released; the close method provides this\r
+     * immediate release. \r
+     *\r
+     * <P><B>Note:</B> A Connection is automatically closed when it is\r
+     * garbage collected. Certain fatal errors also result in a closed\r
+     * Connection.\r
+     *\r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public void close() throws SQLException {\r
+               // JDK 1.4 javadoc indicates close on a closed connection is a no-op\r
+               if (!isClosed() &&\r
+                               (rootConnection == this) && \r
+                               (!autoCommit && !transactionIsIdle())) {\r
+                       throw newSQLException(\r
+                               SQLState.LANG_INVALID_TRANSACTION_STATE);\r
+               }\r
+               \r
+               close(exceptionClose);\r
+       }\r
+\r
+       // This inner close takes the exception and calls \r
+       // the context manager to make the connection close.\r
+       // The exception must be a session severity exception.\r
+       //\r
+       // NOTE: This method is not part of JDBC specs.\r
+       //\r
+    private void close(StandardException e) throws SQLException {\r
+               \r
+               synchronized(getConnectionSynchronization())\r
+               {\r
+                       if (rootConnection == this)\r
+                       {\r
+                               /*\r
+                                * If it isn't active, it's already been closed.\r
+                                */\r
+                               if (active) {\r
+                                       if (tr.isActive()) {\r
+                                               setupContextStack();\r
+                                               try {\r
+                                                       tr.rollback();\r
+                                                       \r
+                                                       // Let go of lcc reference so it can be GC'ed after\r
+                                                       // cleanupOnError, the tr will stay around until the\r
+                                                       // rootConnection itself is GC'ed, which is dependent\r
+                                                       // on how long the client program wants to hold on to\r
+                                                       // the Connection object.\r
+                                                       tr.clearLcc(); \r
+                                                       tr.cleanupOnError(e);\r
+                                                       \r
+                                               } catch (Throwable t) {\r
+                                                       throw handleException(t);\r
+                                               } finally {\r
+                                                       restoreContextStack();\r
+                                               }\r
+                                       } else {\r
+                                               // DERBY-1947: If another connection has closed down\r
+                                               // the database, the transaction is not active, but\r
+                                               // the cleanup has not been done yet.\r
+                                               tr.clearLcc(); \r
+                                               tr.cleanupOnError(e);\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       if (!isClosed())\r
+                               setInactive();\r
+               }\r
+       }\r
+\r
+    /**\r
+     * Tests to see if a Connection is closed.\r
+     *\r
+     * @return true if the connection is closed; false if it's still open\r
+     */\r
+    public final boolean isClosed() {\r
+               if (active) {\r
+\r
+                       // I am attached, check the database state\r
+                       if (getTR().isActive()) {\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+\r
+    /**\r
+     * A Connection's database is able to provide information\r
+     * describing its tables, its supported SQL grammar, its stored\r
+     * procedures, the capabilities of this connection, etc. This\r
+     * information is made available through a DatabaseMetaData\r
+     * object.\r
+     *\r
+     * @return a DatabaseMetaData object for this Connection \r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public DatabaseMetaData getMetaData() throws SQLException {\r
+        checkIfClosed();\r
+\r
+               if (dbMetadata == null) {\r
+\r
+                       // There is a case where dbname can be null.\r
+                       // Replication client of this method does not have a\r
+                       // JDBC connection; therefore dbname is null and this\r
+                       // is expected.\r
+                       //\r
+                       dbMetadata = factory.newEmbedDatabaseMetaData(this, getTR().getUrl());\r
+               }\r
+               return dbMetadata;\r
+       }\r
+\r
+       /**\r
+               JDBC 3.0\r
+        * Retrieves the current holdability of ResultSet objects created using this\r
+        * Connection object.\r
+        *\r
+        *\r
+        * @return  The holdability, one of ResultSet.HOLD_CURSORS_OVER_COMMIT\r
+        * or ResultSet.CLOSE_CURSORS_AT_COMMIT\r
+        *\r
+        */\r
+       public final int getHoldability() throws SQLException {\r
+               checkIfClosed();\r
+               return connectionHoldAbility;\r
+       }\r
+\r
+       /**\r
+               JDBC 3.0\r
+        * Changes the holdability of ResultSet objects created using this\r
+        * Connection object to the given holdability.\r
+        *\r
+        *\r
+        * @param holdability  A ResultSet holdability constant, one of ResultSet.HOLD_CURSORS_OVER_COMMIT\r
+        * or ResultSet.CLOSE_CURSORS_AT_COMMIT\r
+        *\r
+        */\r
+       public final void setHoldability(int holdability) throws SQLException {\r
+               checkIfClosed();\r
+               connectionHoldAbility = holdability;\r
+       }\r
+\r
+    /**\r
+     * You can put a connection in read-only mode as a hint to enable \r
+     * database optimizations.\r
+     *\r
+     * <P><B>Note:</B> setReadOnly cannot be called while in the\r
+     * middle of a transaction.\r
+     *\r
+     * @param readOnly true enables read-only mode; false disables\r
+     * read-only mode.  \r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public final void setReadOnly(boolean readOnly) throws SQLException\r
+       {\r
+               synchronized(getConnectionSynchronization())\r
+               {\r
+                        setupContextStack();\r
+                       try {\r
+                               getLanguageConnection().setReadOnly(readOnly);\r
+                       } catch (StandardException e) {\r
+                               throw handleException(e);\r
+                       } finally {\r
+                               restoreContextStack();\r
+                       }\r
+               }\r
+       }\r
+\r
+    /**\r
+     * Tests to see if the connection is in read-only mode.\r
+     *\r
+     * @return true if connection is read-only\r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public final boolean isReadOnly() throws SQLException\r
+       {\r
+               checkIfClosed();\r
+               return getLanguageConnection().isReadOnly();\r
+       }\r
+\r
+    /**\r
+     * A sub-space of this Connection's database may be selected by setting a\r
+     * catalog name. If the driver does not support catalogs it will\r
+     * silently ignore this request.\r
+     *\r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public void setCatalog(String catalog) throws SQLException {\r
+        checkIfClosed();\r
+               // silently ignoring this request like the javadoc said.\r
+               return;\r
+       }\r
+\r
+    /**\r
+     * Return the Connection's current catalog name.\r
+     *\r
+     * @return the current catalog name or null\r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+       public String getCatalog() throws SQLException {\r
+               checkIfClosed();\r
+               // we do not have support for Catalog, just return null as\r
+               // the JDBC specs mentions then.\r
+               return null;\r
+       }\r
+\r
+    /**\r
+     * You can call this method to try to change the transaction\r
+     * isolation level using one of the TRANSACTION_* values.\r
+     *\r
+     * <P><B>Note:</B> setTransactionIsolation causes the current\r
+     * transaction to commit if the isolation level is changed. Otherwise, if\r
+     * the requested isolation level is the same as the current isolation\r
+     * level, this method is a no-op.\r
+     *\r
+     * @param level one of the TRANSACTION_* isolation values with the\r
+     * exception of TRANSACTION_NONE; some databases may not support\r
+     * other values\r
+     * @exception SQLException if a database-access error occurs.\r
+     * @see DatabaseMetaData#supportsTransactionIsolationLevel \r
+     */\r
+    public void setTransactionIsolation(int level) throws SQLException {\r
+\r
+               if (level == getTransactionIsolation())\r
+                       return;\r
+\r
+               // Convert the isolation level to the internal one\r
+               int iLevel;\r
+               switch (level)\r
+               {\r
+               case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:\r
+                       iLevel = ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL;\r
+                       break;\r
+\r
+               case java.sql.Connection.TRANSACTION_READ_COMMITTED:\r
+                       iLevel = ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL;\r
+                       break;\r
+\r
+               case java.sql.Connection.TRANSACTION_REPEATABLE_READ:\r
+            iLevel = ExecutionContext.REPEATABLE_READ_ISOLATION_LEVEL;\r
+            break;\r
+\r
+               case java.sql.Connection.TRANSACTION_SERIALIZABLE:\r
+                       iLevel = ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL;\r
+                       break;\r
+               default:\r
+                       throw newSQLException(SQLState.UNIMPLEMENTED_ISOLATION_LEVEL, new Integer(level));\r
+               }\r
+\r
+               synchronized(getConnectionSynchronization())\r
+               {\r
+            setupContextStack();\r
+                       try {\r
+                               getLanguageConnection().setIsolationLevel(iLevel);\r
+                       } catch (StandardException e) {\r
+                               throw handleException(e);\r
+                       } finally {\r
+                               restoreContextStack();\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+    /**\r
+     * Get this Connection's current transaction isolation mode.\r
+     *\r
+     * @return the current TRANSACTION_* mode value\r
+     * @exception SQLException if a database-access error occurs.\r
+     */\r
+    public final int getTransactionIsolation() throws SQLException {\r
+        checkIfClosed();\r
+               return ExecutionContext.CS_TO_JDBC_ISOLATION_LEVEL_MAP[getLanguageConnection().getCurrentIsolationLevel()];\r
+       }\r
+\r
+    /**\r
+     * The first warning reported by calls on this Connection is\r
+     * returned.  \r
+     *\r
+     * <P><B>Note:</B> Subsequent warnings will be chained to this\r
+     * SQLWarning.\r
+     *\r
+     * @return the first SQLWarning or null \r
+     *\r
+        * Synchronization note: Warnings are synchronized \r
+        * on nesting level\r
+     */\r
+       public final synchronized SQLWarning getWarnings() throws SQLException {\r
+               checkIfClosed();\r
+               return topWarning;\r
+       }\r
+\r
+    /**\r
+     * After this call, getWarnings returns null until a new warning is\r
+     * reported for this Connection.  \r
+     *\r
+        * Synchronization node: Warnings are synchonized \r
+        * on nesting level\r
+     */\r
+    public final synchronized void clearWarnings() throws SQLException {\r
+        checkIfClosed();\r
+               topWarning = null;\r
+       }\r
+\r
+       /////////////////////////////////////////////////////////////////////////\r
+       //\r
+       //      JDBC 2.0        -       New public methods\r
+       //\r
+       /////////////////////////////////////////////////////////////////////////\r
+\r
+    /**\r
+     *\r
+        * Get the type-map object associated with this connection.\r
+        * By default, the map returned is empty.\r
+        * JDBC 2.0 - java.util.Map requires JDK 1\r
+     *\r
+     */\r
+    public java.util.Map getTypeMap() throws SQLException {\r
+        checkIfClosed();\r
+               // just return an immuntable empty map\r
+               return java.util.Collections.EMPTY_MAP;\r
+    }\r
+\r
+    /** \r
+        * Install a type-map object as the default type-map for\r
+        * this connection.\r
+        * JDBC 2.0 - java.util.Map requires JDK 1\r
+     *\r
+     * @exception SQLException Feature not implemented for now.\r
+        */\r
+    public final void setTypeMap(java.util.Map map) throws SQLException {\r
+        checkIfClosed();\r
+        if( map == null)\r
+            throw Util.generateCsSQLException(SQLState.INVALID_API_PARAMETER,map,"map",\r
+                                              "java.sql.Connection.setTypeMap");\r
+        if(!(map.isEmpty()))\r
+            throw Util.notImplemented();\r
+    }\r
+\r
+       /////////////////////////////////////////////////////////////////////////\r
+       //\r
+       //      Implementation specific methods \r
+       //\r
+       /////////////////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+               Add a warning to the current list of warnings, to follow\r
+               this note from Connection.getWarnings.\r
+               Note: Subsequent warnings will be chained to this SQLWarning. \r
+\r
+               @see java.sql.Connection#getWarnings\r
+       */\r
+        public final synchronized void addWarning(SQLWarning newWarning) {\r
+               if (topWarning == null) {\r
+                       topWarning = newWarning;\r
+                       return;\r
+               }\r
+\r
+               topWarning.setNextWarning(newWarning);\r
+       }\r
+\r
+       /**\r
+        * Return the dbname for this connection.\r
+        *\r
+        * @return String       The dbname for this connection.\r
+        */\r
+       public String getDBName()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClosed(), "connection is closed");\r
+\r
+               return getTR().getDBName();\r
+       }\r
+\r
+       public final LanguageConnectionContext getLanguageConnection() {\r
+\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClosed(), "connection is closed");\r
+\r
+               return getTR().getLcc();\r
+       }\r
+\r
+    /**\r
+     * Raises an exception if the connection is closed.\r
+     *\r
+     * @exception SQLException if the connection is closed\r
+     */\r
+    protected final void checkIfClosed() throws SQLException {\r
+        if (isClosed()) {\r
+            throw Util.noCurrentConnection();\r
+        }\r
+    }\r
+\r
+       //EmbedConnection30 overrides this method so it can release the savepoints array if\r
+       //the exception severity is transaction level\r
+       SQLException handleException(Throwable thrownException)\r
+                       throws SQLException\r
+       {\r
+               //assume in case of SQLException cleanup is \r
+               //done already. This assumption is inline with\r
+               //TR's assumption. In case no rollback was \r
+               //called lob objects will remain valid.\r
+               if (thrownException instanceof StandardException) {\r
+                       if (((StandardException) thrownException)\r
+                               .getSeverity() \r
+                               >= ExceptionSeverity.TRANSACTION_SEVERITY) {\r
+                               clearLOBMapping();\r
+                       }\r
+               }\r
+\r
+               /*\r
+               ** By default, rollback the connection on if autocommit\r
+               ** is on.\r
+               */\r
+               return getTR().handleException(thrownException, \r
+                                                                 autoCommit,\r
+                                                                 true // Rollback xact on auto commit\r
+                                                                 );\r
+       }\r
+\r
+       /**\r
+               Handle any type of Exception.\r
+               <UL>\r
+               <LI> Inform the contexts of the error\r
+               <LI> Throw an Util based upon the thrown exception.\r
+               </UL>\r
+\r
+               REMIND: now that we know all the exceptions from our driver\r
+               are Utils, would it make sense to shut down the system\r
+               for unknown SQLExceptions? At present, we do not.\r
+\r
+               Because this is the last stop for exceptions,\r
+               it will catch anything that occurs in it and try\r
+               to cleanup before re-throwing them.\r
+       \r
+               @param thrownException the exception\r
+               @param rollbackOnAutoCommit rollback the xact on if autocommit is\r
+                               on, otherwise rollback stmt but leave xact open (and\r
+                               continue to hold on to locks).  Most of the time, this\r
+                               will be true, excepting operations on result sets, like\r
+                               getInt().\r
+       */\r
+       final SQLException handleException(Throwable thrownException, \r
+                                                                          boolean rollbackOnAutoCommit) \r
+                       throws SQLException \r
+       {\r
+               //assume in case of SQLException cleanup is \r
+               //done already. This assumption is inline with\r
+               //TR's assumption. In case no rollback was \r
+               //called lob objects will remain valid.\r
+               if (thrownException instanceof StandardException) {\r
+                       if (((StandardException) thrownException)\r
+                               .getSeverity() \r
+                               >= ExceptionSeverity.TRANSACTION_SEVERITY) {\r
+                               clearLOBMapping();\r
+                       }\r
+               }\r
+               return getTR().handleException(thrownException, autoCommit,\r
+                                                                 rollbackOnAutoCommit); \r
+\r
+       }\r
+\r
+       /*\r
+          This is called from the EmbedConnectionContext to\r
+          close on errors.  We assume all handling of the connectin\r
+          is dealt with via the context stack, and our only role\r
+          is to mark ourself as closed.\r
+        */\r
+\r
+       /**\r
+               Close the connection when processing errors, or when\r
+               closing a nested connection.\r
+               <p>\r
+               This only marks it as closed and frees up its resources;\r
+               any closing of the underlying connection or commit work\r
+               is assumed to be done elsewhere.\r
+\r
+               Called from EmbedConnectionContext's cleanup routine,   \r
+               and by proxy.close().\r
+        */\r
+\r
+       public final void setInactive() {\r
+\r
+               if (active == false)\r
+                       return;\r
+               // active = false\r
+               // tr = null !-> active = false\r
+\r
+               synchronized (getConnectionSynchronization()) {\r
+                       active = false;\r
+                       // tr = null; cleanupOnerror sets inactive but still needs tr to\r
+                       // restore context later\r
+                       dbMetadata = null;\r
+               }\r
+       }\r
+\r
+       /**\r
+               @exception Throwable    standard error policy\r
+        */\r
+       protected void finalize() throws Throwable \r
+       {\r
+               try {\r
+                       // Only close root connections, since for nested\r
+                       // connections, it is not strictly necessary and close()\r
+                       // synchronizes on the root connection which can cause\r
+                       // deadlock with the call to runFinalization from\r
+                       // GenericPreparedStatement#prepareToInvalidate (see\r
+                       // DERBY-1947) on SUN VMs.\r
+                       if (rootConnection == this) {\r
+                               close(exceptionClose);\r
+                       }\r
+               }\r
+               finally {\r
+                       super.finalize();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * if auto commit is on, remember that we need to commit\r
+        * the current statement.\r
+        */\r
+    protected void needCommit() {\r
+               if (!needCommit) needCommit = true;\r
+       }\r
+\r
+       /**\r
+        * if a commit is needed, perform it.\r
+     *\r
+     * Must have connection synchonization and context set up already.\r
+     *\r
+        * @exception SQLException if commit returns error\r
+        */\r
+       protected void commitIfNeeded() throws SQLException \r
+    {\r
+               if (autoCommit && needCommit) \r
+        {\r
+            try\r
+            {\r
+                getTR().commit();\r
+                clearLOBMapping();\r
+            } \r
+            catch (Throwable t)\r
+            {\r
+                throw handleException(t);\r
+            }\r
+            needCommit = false;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * If in autocommit, then commit.\r
+     * \r
+     * Used to force a commit after a result set closes in autocommit mode.\r
+     * The needCommit mechanism does not work correctly as there are times\r
+     * with cursors (like a commit, followed by a next, followed by a close)\r
+     * where the system does not think it needs a commit but we need to \r
+     * force the commit on close.  It seemed safer to just force a commit\r
+     * on close rather than count on keeping the needCommit flag correct for\r
+     * all cursor cases.\r
+     *\r
+     * Must have connection synchonization and context set up already.\r
+     *\r
+        * @exception SQLException if commit returns error\r
+        */\r
+       protected void commitIfAutoCommit() throws SQLException \r
+    {\r
+               if (autoCommit) \r
+        {\r
+            try\r
+            {\r
+                getTR().commit();\r
+                clearLOBMapping();\r
+            } \r
+            catch (Throwable t)\r
+            {\r
+                throw handleException(t);\r
+            }\r
+            needCommit = false;\r
+               }\r
+       }\r
+\r
+\r
+       final protected Object getConnectionSynchronization()\r
+  {\r
+               return rootConnection;\r
+  }\r
+\r
+       /**\r
+               Install the context manager for this thread.  Check connection status here.\r
+               @exception SQLException if fails\r
+        */\r
+       protected final void  setupContextStack() throws SQLException {\r
+\r
+               /*\r
+                       Track this entry, then throw an exception\r
+                       rather than doing the quiet return.  Need the\r
+                       track before the throw because the backtrack\r
+                       is in a finally block.\r
+                */\r
+\r
+               checkIfClosed();\r
+\r
+               getTR().setupContextStack();\r
+\r
+       }\r
+\r
+       protected final void restoreContextStack() throws SQLException {\r
+\r
+               if (SanityManager.DEBUG)\r
+               Util.ASSERT(this, (active) || getTR().getCsf() !=null, "No context service to do restore");\r
+\r
+               TransactionResourceImpl tr = getTR();\r
+\r
+               //REMIND: someone is leaving an incorrect manager on when they\r
+               // are exiting the system in the nested case.\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (tr.getCsf() != null) {\r
+                               ContextManager cm1 = tr.getCsf().getCurrentContextManager();\r
+                               ContextManager cm2 = tr.getContextManager();\r
+                               // If the system has been shut down, cm1 can be null.\r
+                               // Otherwise, cm1 and cm2 should be identical.\r
+                               Util.ASSERT(this, (cm1 == cm2 || cm1 == null),\r
+                                       "Current Context Manager not the one was expected: " +\r
+                                        cm1 + " " + cm2);\r
+                       }\r
+               }\r
+\r
+               tr.restoreContextStack();\r
+       }\r
+\r
+       /*\r
+       ** Create database methods.\r
+       */\r
+\r
+       /**\r
+               Create a new database.\r
+               @param dbname the database name\r
+               @param info the properties\r
+\r
+               @return Database The newly created database or null.\r
+\r
+               @exception SQLException if fails to create database\r
+       */\r
+\r
+       private Database createDatabase(String dbname, Properties info)\r
+               throws SQLException {\r
+\r
+               info = filterProperties(info);\r
+\r
+               try {\r
+                       if (Monitor.createPersistentService(Property.DATABASE_MODULE, dbname, info) == null) \r
+                       {\r
+                               // service already exists, create a warning\r
+                               addWarning(EmbedSQLWarning.newEmbedSQLWarning(SQLState.DATABASE_EXISTS, dbname));\r
+                       }\r
+               } catch (StandardException mse) {\r
+            throw Util.seeNextException(SQLState.CREATE_DATABASE_FAILED,\r
+                                        new Object[] { dbname },\r
+                                        handleException(mse));\r
+               }\r
+\r
+               // clear these values as some modules hang onto\r
+               // the properties set corresponding to service.properties\r
+               // and they shouldn't be interested in these JDBC attributes.\r
+               info.clear();\r
+\r
+               return (Database) Monitor.findService(Property.DATABASE_MODULE, dbname);\r
+       }\r
+\r
+\r
+       /**\r
+        * Boot database.\r
+        *\r
+        * @param info boot properties\r
+        *\r
+        * @param softAuthenticationBoot If true, don't fail soft upgrade due\r
+        * to missing features (phase one of two phased hard upgrade boot).\r
+        *\r
+        * @return false iff the monitor cannot handle a service\r
+        * of the type indicated by the protocol within the name.\r
+        * If that's the case then we are the wrong driver.\r
+        *\r
+        * @throws Throwable if anything else is wrong.\r
+        */\r
+\r
+       private boolean bootDatabase(Properties info,\r
+                                                                boolean softAuthenticationBoot\r
+                                                                ) throws Throwable\r
+       {\r
+               String dbname = tr.getDBName();\r
+\r
+               // boot database now\r
+               try {\r
+\r
+                       info = filterProperties(info);\r
+\r
+                       if (softAuthenticationBoot) {\r
+                               info.setProperty(Attribute.SOFT_UPGRADE_NO_FEATURE_CHECK,\r
+                                                                "true");\r
+                       } else {\r
+                               info.remove(Attribute.SOFT_UPGRADE_NO_FEATURE_CHECK);\r
+                       }\r
+                       \r
+                       // try to start the service if it doesn't already exist\r
+                       if (!Monitor.startPersistentService(dbname, info)) {\r
+                               // a false indicates the monitor cannot handle a service\r
+                               // of the type indicated by the protocol within the name.\r
+                               // If that's the case then we are the wrong driver\r
+                               // so just return null.\r
+                               return false;\r
+                       }\r
+\r
+                       // clear these values as some modules hang onto\r
+                       // the properties set corresponding to service.properties\r
+                       // and they shouldn't be interested in these JDBC attributes.\r
+                       info.clear();\r
+\r
+                       Database database = (Database) Monitor.findService(Property.DATABASE_MODULE, dbname);\r
+                       tr.setDatabase(database);\r
+\r
+               } catch (StandardException mse) {\r
+\r
+                       Throwable ne = mse.getCause();\r
+                       SQLException nse;\r
+\r
+                       /*\r
+                         If there is a next exception, assume\r
+                         that the first one is just a redundant "see the\r
+                         next exception" message.\r
+                         if it is a BEI, treat it as a database exception.\r
+                         If there isn't a BEI, treat it as a java exception.\r
+\r
+                         In general we probably want to walk the chain\r
+                         and return all of them, but empirically, this\r
+                         is all we need to do for now.\r
+                         */\r
+                       if (ne instanceof StandardException)\r
+                               nse = Util.generateCsSQLException((StandardException)ne);\r
+                       else if (ne != null)\r
+                               nse = Util.javaException(ne);\r
+                       else\r
+                               nse = Util.generateCsSQLException(mse);\r
+\r
+            throw Util.seeNextException(SQLState.BOOT_DATABASE_FAILED,\r
+                                        new Object[] { dbname }, nse);\r
+               }\r
+\r
+               // If database exists, getDatabase() will return the database object.\r
+               // If any error occured while booting an existing database, an\r
+               // exception would have been thrown already.\r
+               return true;\r
+\r
+       }\r
+\r
+       /*\r
+        * Class interface methods used by database metadata to ensure\r
+        * good relations with autocommit.\r
+        */\r
+\r
+    PreparedStatement prepareMetaDataStatement(String sql)\r
+           throws SQLException {\r
+               synchronized (getConnectionSynchronization()) {\r
+                        setupContextStack();\r
+                       PreparedStatement s = null;\r
+                       try {\r
+                           s = factory.newEmbedPreparedStatement(this, sql, true,\r
+                                                                                         JDBC20Translation.TYPE_FORWARD_ONLY,\r
+                                                                                         JDBC20Translation.CONCUR_READ_ONLY,\r
+                                                                                         connectionHoldAbility,\r
+                                                                                         JDBC30Translation.NO_GENERATED_KEYS,\r
+                                                                                         null,\r
+                                                                                         null);\r
+                       } finally {\r
+                           restoreContextStack();\r
+                       }\r
+                       return s;\r
+               }\r
+       }\r
+\r
+       public final InternalDriver getLocalDriver()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClosed(), "connection is closed");\r
+\r
+               return getTR().getDriver();\r
+       }\r
+\r
+       /**\r
+               Return the context manager for this connection.\r
+       */\r
+       public final ContextManager getContextManager() {\r
+\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClosed(), "connection is closed");\r
+\r
+               return getTR().getContextManager();\r
+       }\r
+\r
+       /**\r
+        * Filter out properties from the passed in set of JDBC attributes\r
+        * to remove any derby.* properties. This is to ensure that setting\r
+        * derby.* properties does not work this way, it's not a defined way\r
+        * to set such properties and could be a secuirty hole in allowing\r
+        * remote connections to override system, application or database settings.\r
+        * \r
+        * @return a new Properties set copied from the parameter but with no\r
+        * derby.* properties.\r
+        */\r
+       private Properties filterProperties(Properties inputSet) {\r
+               Properties limited = new Properties();\r
+\r
+               // filter out any derby.* properties, only\r
+               // JDBC attributes can be set this way\r
+               for (java.util.Enumeration e = inputSet.propertyNames(); e.hasMoreElements(); ) {\r
+\r
+                       String key = (String) e.nextElement();\r
+\r
+                       // we don't allow properties to be set this way\r
+                       if (key.startsWith("derby."))\r
+                               continue;\r
+                       limited.put(key, inputSet.getProperty(key));\r
+               }\r
+               return limited;\r
+       }\r
+\r
+       /*\r
+       ** methods to be overridden by subimplementations wishing to insert\r
+       ** their classes into the mix.\r
+       */\r
+\r
+       protected Database getDatabase() \r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(!isClosed(), "connection is closed");\r
+\r
+               return getTR().getDatabase();\r
+       }\r
+\r
+       final protected TransactionResourceImpl getTR()\r
+       {\r
+               return rootConnection.tr;\r
+       }\r
+\r
+       private EmbedConnectionContext pushConnectionContext(ContextManager cm) {\r
+               return new EmbedConnectionContext(cm, this);\r
+       }\r
+\r
+       public final void setApplicationConnection(java.sql.Connection applicationConnection) {\r
+               this.applicationConnection = applicationConnection;\r
+       }\r
+\r
+       public final java.sql.Connection getApplicationConnection() {\r
+               return applicationConnection;\r
+       }\r
+\r
+       public void setDrdaID(String drdaID) {\r
+               getLanguageConnection().setDrdaID(drdaID);\r
+       }\r
+\r
+       /**\r
+               Reset the connection before it is returned from a PooledConnection\r
+               to a new application request (wrapped by a BrokeredConnection).\r
+               Examples of reset covered here is dropping session temporary tables\r
+               and reseting IDENTITY_VAL_LOCAL.\r
+               Most JDBC level reset is handled by calling standard java.sql.Connection\r
+               methods from EmbedPooledConnection.\r
+        */\r
+       public void resetFromPool() throws SQLException {\r
+               synchronized (getConnectionSynchronization())\r
+               {\r
+                       setupContextStack();\r
+                       try {\r
+                               getLanguageConnection().resetFromPool();\r
+                       } catch (StandardException t) {\r
+                               throw handleException(t);\r
+                       }\r
+                       finally\r
+                       {\r
+                               restoreContextStack();\r
+                       }\r
+               }\r
+       }\r
+\r
+       /*\r
+       ** methods to be overridden by subimplementations wishing to insert\r
+       ** their classes into the mix.\r
+       ** The reason we need to override them is because we want to create a\r
+       ** Local20/LocalStatment object (etc) rather than a Local/LocalStatment\r
+       ** object (etc).\r
+       */\r
+\r
+\r
+       /*\r
+       ** XA support\r
+       */\r
+\r
+    /**\r
+     * Do not use this method directly use XATransactionState.xa_prepare\r
+     * instead because it also maintains/cancels the timout task which is\r
+     * scheduled to cancel/rollback the global transaction.\r
+     */\r
+       public final int xa_prepare() throws SQLException {\r
+\r
+               synchronized (getConnectionSynchronization())\r
+               {\r
+            setupContextStack();\r
+                       try\r
+                       {\r
+                               XATransactionController tc = \r
+                                       (XATransactionController) getLanguageConnection().getTransactionExecute();\r
+\r
+                               int ret = tc.xa_prepare();\r
+\r
+                               if (ret == XATransactionController.XA_RDONLY)\r
+                               {\r
+                                       // On a prepare call, xa allows an optimization that if the\r
+                                       // transaction is read only, the RM can just go ahead and\r
+                                       // commit it.  So if store returns this read only status -\r
+                                       // meaning store has taken the liberty to commit already - we\r
+                                       // needs to turn around and call internalCommit (without\r
+                                       // committing the store again) to make sure the state is\r
+                                       // consistent.  Since the transaction is read only, there is\r
+                                       // probably not much that needs to be done.\r
+\r
+                                       getLanguageConnection().internalCommit(false /* don't commitStore again */);\r
+                               }\r
+                               return ret;\r
+                       } catch (StandardException t)\r
+                       {\r
+                               throw handleException(t);\r
+                       }\r
+                       finally\r
+                       {\r
+                               restoreContextStack();\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+    /**\r
+     * Do not use this method directly use XATransactionState.xa_commit\r
+     * instead because it also maintains/cancels the timout task which is\r
+     * scheduled to cancel/rollback the global transaction.\r
+     */\r
+       public final void xa_commit(boolean onePhase) throws SQLException {\r
+\r
+               synchronized (getConnectionSynchronization())\r
+               {\r
+            setupContextStack();\r
+                       try\r
+                       {\r
+                       getLanguageConnection().xaCommit(onePhase);\r
+                       } catch (StandardException t)\r
+                       {\r
+                               throw handleException(t);\r
+                       }\r
+                       finally \r
+                       {\r
+                               restoreContextStack();\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+    /**\r
+     * Do not use this method directly use XATransactionState.xa_rollback\r
+     * instead because it also maintains/cancels the timout task which is\r
+     * scheduled to cancel/rollback the global transaction.\r
+     */\r
+       public final void xa_rollback() throws SQLException {\r
+               synchronized (getConnectionSynchronization())\r
+               {\r
+            setupContextStack();\r
+                       try\r
+                       {\r
+                       getLanguageConnection().xaRollback();\r
+                       } catch (StandardException t)\r
+                       {\r
+                               throw handleException(t);\r
+                       }\r
+                       finally \r
+                       {\r
+                               restoreContextStack();\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+        * returns false if there is an underlying transaction and that transaction\r
+        * has done work.  True if there is no underlying transaction or that\r
+        * underlying transaction is idle\r
+        */\r
+       public final boolean transactionIsIdle()\r
+       {\r
+               return getTR().isIdle();\r
+       }\r
+       private int setResultSetType(int resultSetType) {\r
+\r
+               /* Add warning if scroll sensitive cursor\r
+                * and downgrade to scroll insensitive cursor.\r
+                */\r
+               if (resultSetType == JDBC20Translation.TYPE_SCROLL_SENSITIVE)\r
+               {\r
+                       addWarning(EmbedSQLWarning.newEmbedSQLWarning(SQLState.NO_SCROLL_SENSITIVE_CURSORS));\r
+                       resultSetType = JDBC20Translation.TYPE_SCROLL_INSENSITIVE;\r
+               }\r
+               return resultSetType;\r
+       }\r
+       \r
+\r
+       /** \r
+        * Set the transaction isolation level that will be used for the \r
+        * next prepare.  Used by network server to implement DB2 style \r
+        * isolation levels.\r
+        * @param level Isolation level to change to.  level is the DB2 level\r
+        *               specified in the package names which happen to correspond\r
+        *               to our internal levels. If \r
+        *               level == ExecutionContext.UNSPECIFIED_ISOLATION,\r
+        *               the statement won't be prepared with an isolation level.\r
+        * \r
+        * \r
+        */\r
+       public void setPrepareIsolation(int level) throws SQLException\r
+       {\r
+               if (level == getPrepareIsolation())\r
+                       return;\r
+\r
+               switch (level)\r
+               {\r
+                       case ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL:\r
+                       case ExecutionContext.REPEATABLE_READ_ISOLATION_LEVEL:\r
+                       case ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL:\r
+                       case ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL:\r
+                       case ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL:\r
+                               break;\r
+                       default:\r
+                               throw Util.generateCsSQLException(\r
+                                                                                                                          SQLState.UNIMPLEMENTED_ISOLATION_LEVEL, new Integer(level));\r
+               }\r
+               \r
+               synchronized(getConnectionSynchronization())\r
+               {\r
+                       getLanguageConnection().setPrepareIsolationLevel(level);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Return prepare isolation \r
+        */\r
+       public int getPrepareIsolation()\r
+       {\r
+               return getLanguageConnection().getPrepareIsolationLevel();\r
+       }\r
+\r
+       /**\r
+               Return a unique order number for a result set.\r
+               A unique value is only needed if the result set is\r
+               being created within procedure and thus must be using\r
+               a nested connection.\r
+       */\r
+       final int getResultSetOrderId() {\r
+\r
+               if (this == rootConnection) {\r
+                       return 0;\r
+               } else {\r
+                       return rootConnection.resultSetId++;\r
+               }\r
+       }\r
+\r
+       protected SQLException newSQLException(String messageId) {\r
+               return Util.generateCsSQLException(messageId);\r
+       }\r
+       protected SQLException newSQLException(String messageId, Object arg1) {\r
+               return Util.generateCsSQLException(messageId, arg1);\r
+       }\r
+       protected SQLException newSQLException(String messageId, Object arg1, Object arg2) {\r
+               return Util.generateCsSQLException(messageId, arg1, arg2);\r
+       }\r
+\r
+       /////////////////////////////////////////////////////////////////////////\r
+       //\r
+       //      OBJECT OVERLOADS\r
+       //\r
+       /////////////////////////////////////////////////////////////////////////\r
+\r
+    /**\r
+     * Get a String representation that uniquely identifies\r
+     * this connection.  Include the same information that is\r
+     * printed in the log for various trace and error messages.\r
+     *\r
+     * In Derby the "physical" connection is a LanguageConnectionContext, \r
+     * or LCC.\r
+     * The JDBC Connection is an JDBC-specific layer on top of this.  Rather\r
+     * than create a new id here, we simply use the id of the underlying LCC.\r
+     * Note that this is a big aid in debugging, because much of the\r
+     * engine trace and log code prints the LCC id. \r
+     *\r
+     * @return a string representation for this connection\r
+     */\r
+    public String toString()\r
+    {\r
+        if ( connString == null )\r
+        {\r
+            \r
+            LanguageConnectionContext lcc = getLanguageConnection();\r
+\r
+            connString = \r
+              this.getClass().getName() + "@" + this.hashCode() + " " +\r
+                lcc.xidStr +                  \r
+                    lcc.getTransactionExecute().getTransactionIdString() + \r
+                    "), " +\r
+                lcc.lccStr + \r
+                    Integer.toString(lcc.getInstanceNumber()) + "), " +\r
+                lcc.dbnameStr + lcc.getDbname() + "), " +\r
+                lcc.drdaStr + lcc.getDrdaID() + ") ";\r
+        }       \r
+        \r
+        return connString;\r
+    }\r
+\r
+\r
+       /**\r
+       *\r
+       * Constructs an object that implements the <code>Clob</code> interface. The object\r
+       * returned initially contains no data.  The <code>setAsciiStream</code>,\r
+       * <code>setCharacterStream</code> and <code>setString</code> methods of\r
+       * the <code>Clob</code> interface may be used to add data to the <code>Clob</code>.\r
+       *\r
+       * @return An object that implements the <code>Clob</code> interface\r
+       * @throws SQLException if an object that implements the\r
+       * <code>Clob</code> interface can not be constructed, this method is\r
+       * called on a closed connection or a database access error occurs.\r
+       *\r
+       */\r
+       public Clob createClob() throws SQLException {\r
+               checkIfClosed();\r
+               return new EmbedClob(this);\r
+       }\r
+\r
+       /**\r
+       *\r
+       * Constructs an object that implements the <code>Blob</code> interface. The object\r
+       * returned initially contains no data.  The <code>setBinaryStream</code> and\r
+       * <code>setBytes</code> methods of the <code>Blob</code> interface may be used to add data to\r
+       * the <code>Blob</code>.\r
+       *\r
+       * @return  An object that implements the <code>Blob</code> interface\r
+       * @throws SQLException if an object that implements the\r
+       * <code>Blob</code> interface can not be constructed, this method is\r
+       * called on a closed connection or a database access error occurs.\r
+       *\r
+       */\r
+       public Blob createBlob() throws SQLException {\r
+               checkIfClosed();\r
+               return new EmbedBlob(new byte[0], this);\r
+       }\r
+\r
+       /**\r
+       * Add the locator and the corresponding LOB object into the\r
+       * HashMap\r
+       *\r
+       * @param LOBReference The object which contains the LOB object that\r
+       *                     that is added to the HashMap.\r
+       * @return an integer that represents the locator that has been\r
+       *         allocated to this LOB.\r
+       */\r
+       public int addLOBMapping(Object LOBReference) {\r
+               int loc = getIncLOBKey();\r
+               getlobHMObj().put(new Integer(loc), LOBReference);\r
+               return loc;\r
+       }\r
+\r
+       /**\r
+       * Remove the key(LOCATOR) from the hash table.\r
+       * @param key an integer that represents the locator that needs to be\r
+       *            removed from the table.\r
+       */\r
+       public void removeLOBMapping(int key) {\r
+               getlobHMObj().remove(new Integer(key));\r
+       }\r
+\r
+       /**\r
+       * Get the LOB reference corresponding to the locator.\r
+       * @param key the integer that represents the LOB locator value.\r
+       * @return the LOB Object corresponding to this locator.\r
+       */\r
+       public Object getLOBMapping(int key) {\r
+               return getlobHMObj().get(new Integer(key));\r
+       }\r
+\r
+       /**\r
+       * Clear the HashMap of all entries.\r
+       * Called when a commit or rollback of the transaction\r
+       * happens.\r
+       */\r
+       public void clearLOBMapping() throws SQLException {\r
+\r
+               //free all the lob resources in the HashMap\r
+               //initialize the locator value to 0 and\r
+               //the hash table object to null.\r
+               Map map = rootConnection.lobReferences;\r
+               if (map != null) {\r
+            Iterator it = map.keySet ().iterator ();\r
+            while (it.hasNext()) {\r
+                ((EngineLOB)it.next()).free();\r
+                       }\r
+                       map.clear();\r
+               }\r
+        if (rootConnection.lobHashMap != null) {\r
+            rootConnection.lobHashMap.clear ();\r
+        }\r
+       }\r
+\r
+       /**\r
+       * Return the current locator value/\r
+        * 0x800x values are not  valid values as they are used to indicate the BLOB \r
+        * is being sent by value, so we skip those values (DERBY-3243)\r
+        * \r
+       * @return an integer that represents the most recent locator value.\r
+       */\r
+       private int getIncLOBKey() {\r
+                int newKey = ++rootConnection.lobHMKey;\r
+                // Skip 0x8000, 0x8002, 0x8004, 0x8006, for DERBY-3243\r
+                // Earlier versions of the Derby Network Server (<10.3) didn't\r
+                // support locators and would send an extended length field\r
+                // with one of the above mentioned values instead of a\r
+                // locator, even when locators were requested. To enable the\r
+                // client driver to detect that locators aren't supported,\r
+                // we don't use any of them as locator values.\r
+                if (newKey == 0x8000 || newKey == 0x8002 ||  newKey == 0x8004 ||\r
+                     newKey == 0x8006 || newKey == 0x8008)\r
+                    newKey = ++rootConnection.lobHMKey;\r
+                // Also roll over when the high bit of four byte locator is set.\r
+                // This will prevent us from sending a negative locator to the\r
+                // client. Don't allow zero since it is not a valid locator for the \r
+                // client.\r
+                if (newKey == 0x80000000 || newKey == 0)\r
+                    newKey = rootConnection.lobHMKey = 1;\r
+                return newKey;\r
+       }\r
+\r
+    /**\r
+     * Adds an entry of the lob in WeakHashMap. These entries are used\r
+     * for cleanup during commit/rollback or close.\r
+     * @param lobReference LOB Object\r
+     */\r
+    void addLOBReference (Object lobReference) {\r
+        if (rootConnection.lobReferences == null) {\r
+            rootConnection.lobReferences = new WeakHashMap ();\r
+        }\r
+        rootConnection.lobReferences.put (lobReference, null);\r
+    }\r
+\r
+       /**\r
+       * Return the Hash Map in the root connection\r
+       * @return the HashMap that contains the locator to LOB object mapping\r
+       */\r
+       public HashMap getlobHMObj() {\r
+               if (rootConnection.lobHashMap == null) {\r
+                       rootConnection.lobHashMap = new HashMap();\r
+               }\r
+               return rootConnection.lobHashMap;\r
+       }\r
+\r
+    /** Cancels the current running statement. */\r
+    public void cancelRunningStatement() {\r
+        getLanguageConnection().getStatementContext().cancel();\r
+    }\r
+}\r