You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by kr...@apache.org on 2009/11/26 13:32:34 UTC
svn commit: r884542 - in /db/derby/code/trunk/java:
engine/org/apache/derby/iapi/reference/
engine/org/apache/derby/iapi/services/monitor/
engine/org/apache/derby/impl/db/ engine/org/apache/derby/impl/jdbc/
engine/org/apache/derby/loc/ shared/org/apach...
Author: kristwaa
Date: Thu Nov 26 12:32:33 2009
New Revision: 884542
URL: http://svn.apache.org/viewvc?rev=884542&view=rev
Log:
DERBY-4428: Add proper delete mechanism for in-memory databases
This patch adds the final pieces to enable the drop attribute for in-memory
databases. Usage: 'jdbc:derby:memory:myDB;drop=true[;user=...;password=...]'
If successful, an exception with SQL state 08006 is raised.
* EmbedConnection
Added parsing of the drop attribute. 'true' yields true, everything else
results in false (i.e. non-boolean values are accepted and silently ignored).
Added code to drop a database.
Introduced XJ048, raised when drop is combined with shutdown.
Added code to check for attribute conflicts (create, restore).
Added utility method to put the current thread to sleep.
* DatabaseContextImpl
Added a comment.
* Monitor
Added code to disallow dropping databases not using the in-memory back end.
* Attribute
Added constant for the 'drop' JDBC connection URL attribute.
* SQLState, messages.xml, lang.ErrorCodeTest
Added two new messages: 08006 (database dropped) and XJ048 (conflicting
boot attributes)
* Other tests
Enabled drop functionality and tests using it.
Patch file: derby-4428-2b-generic_db_drop.diff
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java
db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/Monitor.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/db/DatabaseContextImpl.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/BasicInMemoryDbTest.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/MemoryDbManager.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/MogTest.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java?rev=884542&r1=884541&r2=884542&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java Thu Nov 26 12:32:33 2009
@@ -163,6 +163,11 @@
*/
String CREATE_ATTR = "create";
+ /**
+ The attribute that is used to request a drop database.
+ */
+ String DROP_ATTR = "drop";
+
/**
The attribute that is used to set the user name.
*/
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/Monitor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/Monitor.java?rev=884542&r1=884541&r2=884542&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/Monitor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/Monitor.java Thu Nov 26 12:32:33 2009
@@ -598,6 +598,14 @@
public static void removePersistentService(String name)
throws StandardException
{
+ // For now we only allow dropping in-memory databases.
+ // This is mostly due to the fact that the current implementation for
+ // the on-disk back end doesn't handle logDevice when dropping.
+ // Security is another concern.
+ if (!name.startsWith(PersistentService.INMEMORY)) {
+ throw StandardException.newException(
+ SQLState.SERVICE_DIRECTORY_REMOVE_ERROR, name);
+ }
monitor.removePersistentService(name);
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/db/DatabaseContextImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/db/DatabaseContextImpl.java?rev=884542&r1=884541&r2=884542&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/db/DatabaseContextImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/db/DatabaseContextImpl.java Thu Nov 26 12:32:33 2009
@@ -57,6 +57,8 @@
if (se.getSeverity() == ExceptionSeverity.DATABASE_SEVERITY) {
ContextService.getFactory().notifyAllActiveThreads(this);
+ // This may be called multiple times, but is short-circuited
+ // in the monitor.
Monitor.getMonitor().shutdown(db);
}
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java?rev=884542&r1=884541&r2=884542&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java Thu Nov 26 12:32:33 2009
@@ -270,6 +270,14 @@
boolean isFailoverMasterBoot = false;
boolean isFailoverSlaveBoot = false;
+ final boolean dropDatabase = isDropDatabase(info);
+
+ // Don't allow both the shutdown and the drop attribute.
+ if (shutdown && dropDatabase) {
+ throw newSQLException(
+ SQLState.CONFLICTING_BOOT_ATTRIBUTES,
+ Attribute.SHUTDOWN_ATTR + ", " + Attribute.DROP_ATTR);
+ }
// check that a replication operation is not combined with
// other operations
@@ -277,6 +285,7 @@
if (replicationOp!= null) {
if (createBoot ||
shutdown ||
+ dropDatabase ||
isTwoPhaseEncryptionBoot ||
isTwoPhaseUpgradeBoot) {
throw StandardException.
@@ -379,7 +388,7 @@
}
}
- if (createBoot && !shutdown)
+ if (createBoot && !shutdown && !dropDatabase)
{
// if we are shutting down don't attempt to boot or create the
// database
@@ -555,6 +564,39 @@
throw tr.shutdownDatabaseException();
}
+ // Drop the database at this point, if that is requested.
+ if (dropDatabase) {
+ if (!usingNoneAuth &&
+ getLanguageConnection().usesSqlAuthorization()) {
+ // Only the database owner is allowed to drop the database.
+ // NOTE: Reusing the message for shutdown, as drop database
+ // includes a shutdown. May want to change this later
+ // if/when we add system privileges.
+ checkIsDBOwner(OP_SHUTDOWN);
+ }
+
+ // TODO: If system privileges is turned on, we need to check
+ // that the user has the shutdown/drop privilege. Waiting for
+ // Derby-2109
+
+ String dbName = tr.getDBName(); // Save before shutdown
+ // TODO: Should block database access and sleep for a while here
+ // Shut down the database.
+ handleException(tr.shutdownDatabaseException());
+ // Give running threads a chance to detect the shutdown.
+ // Removing the service, or rather its conglomerates, too early
+ // may cause a number of errors to be thrown. Try to make the
+ // shutdown/drop as clean as possible.
+ sleep(500L);
+ Monitor.removePersistentService(dbName);
+ // Generate the drop database exception here, as this is the
+ // only place it will be thrown.
+ StandardException se = StandardException.newException(
+ SQLState.DROP_DATABASE, dbName);
+ se.setReport(StandardException.REPORT_NEVER);
+ throw se;
+ }
+
// Raise a warning in sqlAuthorization mode if authentication is not ON
if (usingNoneAuth && getLanguageConnection().usesSqlAuthorization())
addWarning(SQLWarningFactory.newSQLWarning(SQLState.SQL_AUTHORIZATION_WITH_NO_AUTHENTICATION));
@@ -664,6 +706,16 @@
//
if (createCount > 1) throw newSQLException(SQLState.CONFLICTING_CREATE_ATTRIBUTES);
+ // Don't allow combinations of create/restore and drop.
+ if (createCount == 1 && isDropDatabase(p)) {
+ // See whether we have conflicting create or restore attributes.
+ String sqlState = SQLState.CONFLICTING_CREATE_ATTRIBUTES;
+ if (restoreCount > 0) {
+ sqlState = SQLState.CONFLICTING_RESTORE_ATTRIBUTES;
+ }
+ throw newSQLException(sqlState);
+ }
+
//retuns true only for the create flag not for restore flags
return (createCount - restoreCount) == 1;
}
@@ -676,6 +728,19 @@
throw newSQLException(SQLState.DATABASE_NOT_FOUND, dbname);
}
+ /**
+ * Examines the boot properties and determines if the given attributes
+ * would entail dropping the database.
+ *
+ * @param p the attribute set
+ * @return {@code true} if the drop database operation is requested,
+ * {@code false} if not.
+ */
+ private boolean isDropDatabase(Properties p) {
+ return (Boolean.valueOf(
+ p.getProperty(Attribute.DROP_ATTR)).booleanValue());
+ }
+
/**
* Examine boot properties and determine if a boot with the given
* attributes would entail an encryption operation.
@@ -2525,6 +2590,25 @@
}
/**
+ * Puts the current thread to sleep and sets the interrupt flag of the
+ * thread if an {@code InterruptedException} is thrown while sleeping.
+ * <p>
+ * <em>NOTE</em>: This method does not guarantee that the thread sleeps at
+ * least {@code millis} milliseconds.
+ *
+ * @param millis milliseconds to sleep
+ */
+ private static void sleep(long millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException ie) {
+ // Set the interrupt flag of the thread to allow code higher up the
+ // stack to detect the interruption.
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ /**
* Strips any sub-sub-protocol prefix from a database name.
*
* @param dbname a database name
Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=884542&r1=884541&r2=884542&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Thu Nov 26 12:32:33 2009
@@ -458,6 +458,12 @@
<arg>databaseName</arg>
</msg>
+ <msg>
+ <name>08006.D.1</name>
+ <text>Database '{0}' dropped.</text>
+ <arg>databaseName</arg>
+ </msg>
+
</family>
@@ -4365,6 +4371,12 @@
</msg>
<msg>
+ <name>XJ048.C</name>
+ <text>Conflicting boot attributes specified: {0}</text>
+ <arg>attributes</arg>
+ </msg>
+
+ <msg>
<name>XJ049.C</name>
<text>Conflicting create attributes specified.</text>
</msg>
Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=884542&r1=884541&r2=884542&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Thu Nov 26 12:32:33 2009
@@ -1613,6 +1613,7 @@
String MALFORMED_URL = "XJ028.C";
String BOOT_DATABASE_FAILED = "XJ040.C";
String CREATE_DATABASE_FAILED = "XJ041.C";
+ String CONFLICTING_BOOT_ATTRIBUTES = "XJ048.C";
String CONFLICTING_CREATE_ATTRIBUTES = "XJ049.C";
String CONFLICTING_RESTORE_ATTRIBUTES = "XJ081.C";
String INVALID_ATTRIBUTE = "XJ05B.C";
@@ -1685,8 +1686,9 @@
String NET_PASSWORD_TOO_LONG = "08001.C.12";
- // system severity
+ // database severity
String SHUTDOWN_DATABASE = "08006.D";
+ String DROP_DATABASE = "08006.D.1";
//the following 2 exceptions are internal and never get seen by the user.
String CLOSE_REQUEST = "close.C.1"; // no message in messages.properties as it is never printed
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java?rev=884542&r1=884541&r2=884542&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java Thu Nov 26 12:32:33 2009
@@ -135,6 +135,7 @@
{"08006","Attempt to fully materialize lob data that is too large for the JVM. The connection has been terminated.","40000"},
{"08006","A network protocol error was encountered and the connection has been terminated: {0}","40000"},
{"08006","Database '{0}' shutdown.","45000"},
+ {"08006","Database '{0}' dropped.","45000"},
{"0A000","The DRDA command {0} is not currently implemented. The connection has been terminated.","40000"},
{"57017","There is no available conversion for the source code page, {0}, to the target code page, {1}. The connection has been terminated.","40000"},
{"58009","Network protocol exception: only one of the VCM, VCS length can be greater than 0. The connection has been terminated.","40000"},
@@ -187,6 +188,7 @@
{"XJ028","The URL '{0}' is not properly formed.","40000"},
{"XJ040","Failed to start database '{0}', see the next exception for details.","40000"},
{"XJ041","Failed to create database '{0}', see the next exception for details.","40000"},
+ {"XJ048","Conflicting boot attributes specified: {0}","40000"},
{"XJ049","Conflicting create attributes specified.","40000"},
{"XJ05B","JDBC attribute '{0}' has an invalid value '{1}', valid values are '{2}'.","40000"},
{"XJ081","Conflicting create/restore/recovery attributes specified.","40000"},
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/BasicInMemoryDbTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/BasicInMemoryDbTest.java?rev=884542&r1=884541&r2=884542&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/BasicInMemoryDbTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/BasicInMemoryDbTest.java Thu Nov 26 12:32:33 2009
@@ -257,8 +257,7 @@
*
* @throws SQLException if something else goes wrong
*/
- // DISABLED because the feature isn't implemented yet (see DERBY-4428)
- public void DISABLED_testDelete()
+ public void testDelete()
throws SQLException {
Connection conCreate = DriverManager.getConnection(
"jdbc:derby:memory:deleteDbSimple;create=true");
@@ -291,7 +290,7 @@
// Delete the database.
try {
DriverManager.getConnection(
- "jdbc:derby:memory:deleteDbSimple;delete=true");
+ "jdbc:derby:memory:deleteDbSimple;drop=true");
fail("Dropping database should have raised exception.");
} catch (SQLException sqle) {
assertSQLState("08006", sqle);
@@ -307,8 +306,7 @@
* @throws IOException if something goes wrong
* @throws SQLException if something goes wrong
*/
- // DISABLED because the feature isn't implemented yet (see DERBY-4428)
- public void DISABLED_testDeleteWhenInUse()
+ public void testDeleteWhenInUse()
throws IOException, SQLException {
Connection con = DriverManager.getConnection(
"jdbc:derby:memory:deleteDb;create=true");
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/MemoryDbManager.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/MemoryDbManager.java?rev=884542&r1=884541&r2=884542&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/MemoryDbManager.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/MemoryDbManager.java Thu Nov 26 12:32:33 2009
@@ -148,10 +148,6 @@
*/
public void dropDatabase(String dbNameAndAttributes)
throws SQLException {
- // DISABLED because the feature isn't implemented yet (see DERBY-4428)
- if (true) {
- return;
- }
String url = JDBC_PREFIX + dbNameAndAttributes + ";drop=true";
try {
DriverManager.getConnection(url);
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/MogTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/MogTest.java?rev=884542&r1=884541&r2=884542&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/MogTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/memorydb/MogTest.java Thu Nov 26 12:32:33 2009
@@ -77,8 +77,7 @@
} catch (SQLException sqle) {
// Ignore exceptions during close.
}
- // DISABLED because the feature isn't implemented yet (see DERBY-4428)
- //dropInMemoryDb();
+ dropInMemoryDb();
}
println("duration-in-memory: " + (System.currentTimeMillis() - start));
}