db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r1431526 - in /db/derby/code/trunk/java: engine/org/apache/derby/catalog/ testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Thu, 10 Jan 2013 17:48:58 GMT
Author: rhillegas
Date: Thu Jan 10 17:48:58 2013
New Revision: 1431526

URL: http://svn.apache.org/viewvc?rev=1431526&view=rev
Log:
DERBY-6022: Add ability to load/unload custom tool packages via syscs_util.syscs_register_tool().

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolExample.java
  (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/catalog/Java5SystemProcedures.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolsTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/build.xml

Modified: db/derby/code/trunk/java/engine/org/apache/derby/catalog/Java5SystemProcedures.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/catalog/Java5SystemProcedures.java?rev=1431526&r1=1431525&r2=1431526&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/catalog/Java5SystemProcedures.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/catalog/Java5SystemProcedures.java Thu
Jan 10 17:48:58 2013
@@ -50,6 +50,9 @@ public  class   Java5SystemProcedures
     private static  final   int TOOL_NAME = 0;
     private static  final   int TOOL_CLASS_NAME = TOOL_NAME + 1;
 
+    /** Generic name for all user-supplied tools: the first optional arg is the tool class
name */
+    private static  final   String  CUSTOM_TOOL_CLASS_NAME = "customTool";
+
     ///////////////////////////////////////////////////////////////////////////////////
     //
     // STATE
@@ -59,8 +62,8 @@ public  class   Java5SystemProcedures
     /** Mapping of tool names to their implementing classes for use by SYSCS_REGISTER_TOOL
*/
     private static  final   String[][]  OPTIONAL_TOOLS = new String[][]
     {
-        { "dbmd", "org.apache.derby.impl.tools.optional.DBMDWrapper" },
-        { "fdbv", "org.apache.derby.impl.tools.optional.ForeignDBViews" },
+        { "databaseMetaData", "org.apache.derby.impl.tools.optional.DBMDWrapper" },
+        { "foreignViews", "org.apache.derby.impl.tools.optional.ForeignDBViews" },
     };
 
     ///////////////////////////////////////////////////////////////////////////////////
@@ -71,7 +74,9 @@ public  class   Java5SystemProcedures
 
     /**
      * <p>
-     * Load or unload an optional tool package.
+     * Load or unload an optional tool package. If the tool name is the special
+     * CUSTOM_TOOL_CLASS_NAME tool, then the first optionalArg is the name
+     * of a user-supplied class which implements OptionalTool.
      * </p>
      *
      * @param toolName  Name of the tool package.
@@ -90,7 +95,7 @@ public  class   Java5SystemProcedures
 			CompilerContext cc = (CompilerContext) ContextService.getContext( CompilerContext.CONTEXT_ID
);
             ClassFactory    classFactory = cc.getClassFactory();
 
-            String              toolClassName = findToolClassName( toolName );          
 
+            String              toolClassName = findToolClassName( toolName, optionalArgs
);            
             OptionalTool    tool = null;
 
             try {
@@ -100,20 +105,60 @@ public  class   Java5SystemProcedures
             catch (InstantiationException ie) { throw wrap( ie ); }
             catch (IllegalAccessException iae) { throw wrap( iae ); }
 
+            // Strip the custom tool class name from the optional args as necessary
+            if ( CUSTOM_TOOL_CLASS_NAME.equals( toolName ) )
+            {
+                optionalArgs = stripCustomClassName( optionalArgs );
+            }
+
             if ( register ) { tool.loadTool( optionalArgs ); }
             else { tool.unloadTool( optionalArgs ); }
         }
         catch (StandardException se) { throw PublicAPI.wrapStandardException( se ); }
     }
     /** Lookup the class name corresponding to the name of an optional tool */
-    private static  String  findToolClassName( String toolName ) throws StandardException
+    private static  String  findToolClassName( String toolName, String... optionalArgs )
throws StandardException
     {
+        //
+        // For a user-supplied tool, the first optional arg is the name of a user-supplied
class
+        // which implements OptionalTool
+        //
+        if ( CUSTOM_TOOL_CLASS_NAME.equals( toolName ) )
+        {
+            if ( (optionalArgs == null) || (optionalArgs.length == 0) )
+            {
+                throw badTool( "null" );
+            }
+            else { return optionalArgs[ 0 ]; }
+        }
+        
         for ( String[] descriptor : OPTIONAL_TOOLS )
         {
             if ( descriptor[ TOOL_NAME ].equals( toolName ) ) { return descriptor[ TOOL_CLASS_NAME
]; }
         }
 
-        throw StandardException.newException( SQLState.LANG_UNKNOWN_TOOL_NAME,  toolName
);
+        throw badTool( toolName );
+    }
+    private static  StandardException   badTool( String toolName )
+    {
+        return StandardException.newException( SQLState.LANG_UNKNOWN_TOOL_NAME,  toolName
);
+    }
+
+    /**
+     * <p>
+     * For a custom tool, we strip the first arg from the list of optional args. By
+     * the time we get to this method, it has already been determined that there is
+     * at least one arg and it is the name of a class which implements OptionalTool.
+     * </p>
+     */
+    private static  String[]    stripCustomClassName( String... optionalArgs )
+    {
+        int     count = optionalArgs.length - 1;
+        String[]    retval = new String[ count ];
+
+        for ( int i = 0; i < count; i++ ) { retval[ i ] = optionalArgs[ i + 1 ]; }
+
+        return retval;
     }
 
     ///////////////////////////////////////////////////////////////////////////////////

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolExample.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolExample.java?rev=1431526&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolExample.java
(added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolExample.java
Thu Jan 10 17:48:58 2013
@@ -0,0 +1,118 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.tests.lang.OptionalToolExample
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.functionTests.tests.lang;
+
+import org.apache.derby.iapi.sql.dictionary.OptionalTool;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+/**
+ * <p>
+ * Simple OptionalTool.
+ * </p>
+ */
+public class OptionalToolExample implements OptionalTool
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /** 0-arg constructor required by the OptionalTool contract */
+    public  OptionalToolExample() {}
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // OptionalTool BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  void    loadTool( String... configurationParameters )
+        throws SQLException
+    { loadToolMinion( "toString" ); }
+
+    public  void    unloadTool( String... configurationParameters )
+        throws SQLException
+    { unloadToolMinion( "toString" ); }
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // MINIONS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    protected   void    loadToolMinion( String functionName )
+        throws SQLException
+    {
+        getDerbyConnection().prepareStatement
+            (
+             "create function " + functionName + "( intVal int ) returns varchar( 32672 )\n"
+
+             "language java parameter style java no sql\n" +
+             "external name 'java.lang.Integer.toString'"
+             ).execute();
+
+    }
+    
+    protected   void    unloadToolMinion( String functionName )
+        throws SQLException
+    {
+        getDerbyConnection().prepareStatement( "drop function " + functionName ).execute();
+    }
+
+    private Connection  getDerbyConnection() throws SQLException
+    {
+        return DriverManager.getConnection( "jdbc:default:connection" );
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    //  NESTED CLASS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  static  final   class   VariableName    extends OptionalToolExample
+    {
+        public  void    loadTool( String... configurationParameters )
+            throws SQLException
+        { loadToolMinion( configurationParameters[ 0 ] ); }
+
+        public  void    unloadTool( String... configurationParameters )
+            throws SQLException
+        { unloadToolMinion( configurationParameters[ 0 ]  ); }
+    }
+
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolExample.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolsTest.java?rev=1431526&r1=1431525&r2=1431526&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolsTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolsTest.java
Thu Jan 10 17:48:58 2013
@@ -56,6 +56,8 @@ public class OptionalToolsTest  extends 
     protected   static  final   String  NO_SUCH_TABLE_FUNCTION = "42ZB4";
     protected   static  final   String  UNEXPECTED_USER_EXCEPTION = "38000";
     protected   static  final   String  MISSING_SCHEMA = "42Y07";
+    protected   static  final   String  UNKNOWN_TOOL = "X0Y88";
+    protected   static  final   String  UNKNOWN_ROUTINE = "42Y03";
 
     private static  final   String      TEST_DBO = "TEST_DBO";
     private static  final   String      RUTH = "RUTH";
@@ -129,7 +131,7 @@ public class OptionalToolsTest  extends 
             (
              ruthConnection,
              LACK_EXECUTE_PRIV,
-             "call syscs_util.syscs_register_tool( 'dbmd', true )"
+             "call syscs_util.syscs_register_tool( 'databaseMetaData', true )"
              );
 
         // create a dummy table just to force the schema to be created
@@ -139,7 +141,7 @@ public class OptionalToolsTest  extends 
         expectCompilationError( dboConnection, NO_SUCH_TABLE_FUNCTION, getTypeInfo );
 
         // now register the database metadata wrappers
-        goodStatement( dboConnection, "call syscs_util.syscs_register_tool( 'dbmd', true
)" );
+        goodStatement( dboConnection, "call syscs_util.syscs_register_tool( 'databaseMetaData',
true )" );
 
         // now the routine exists
         assertResults
@@ -175,7 +177,7 @@ public class OptionalToolsTest  extends 
              );
 
         // now unregister the database metadata wrappers
-        goodStatement( dboConnection, "call syscs_util.syscs_register_tool( 'dbmd', false
)" );
+        goodStatement( dboConnection, "call syscs_util.syscs_register_tool( 'databaseMetaData',
false )" );
 
         // the routines don't exist anymore
         expectCompilationError( dboConnection, NO_SUCH_TABLE_FUNCTION, getTypeInfo );
@@ -252,7 +254,7 @@ public class OptionalToolsTest  extends 
             (
              dboConnection,
              UNEXPECTED_USER_EXCEPTION,
-             "call syscs_util.syscs_register_tool( 'fdbv', true )"
+             "call syscs_util.syscs_register_tool( 'foreignViews', true )"
              );
 
         // should fail because the view and its schema don't exist
@@ -273,7 +275,7 @@ public class OptionalToolsTest  extends 
         goodStatement
             (
              dboConnection,
-             "call syscs_util.syscs_register_tool( 'fdbv', true, '" + foreignURL + "' )"
+             "call syscs_util.syscs_register_tool( 'foreignViews', true, '" + foreignURL
+ "' )"
              );
 
         // views should have been created against the foreign database
@@ -297,14 +299,14 @@ public class OptionalToolsTest  extends 
             (
              dboConnection,
              UNEXPECTED_USER_EXCEPTION,
-             "call syscs_util.syscs_register_tool( 'fdbv', false )"
+             "call syscs_util.syscs_register_tool( 'foreignViews', false )"
              );
 
         // should work
         goodStatement
             (
              dboConnection,
-             "call syscs_util.syscs_register_tool( 'fdbv', false, '" + foreignURL + "' )"
+             "call syscs_util.syscs_register_tool( 'foreignViews', false, '" + foreignURL
+ "' )"
              );
 
         // should fail because the view and its schema were dropped when the tool was unloaded
@@ -325,14 +327,14 @@ public class OptionalToolsTest  extends 
         goodStatement
             (
              dboConnection,
-             "call syscs_util.syscs_register_tool( 'fdbv', false, '" + foreignURL + "' )"
+             "call syscs_util.syscs_register_tool( 'foreignViews', false, '" + foreignURL
+ "' )"
              );
 
         // register with a schema prefix
         goodStatement
             (
              dboConnection,
-             "call syscs_util.syscs_register_tool( 'fdbv', true, '" + foreignURL + "', 'XYZ_'
)"
+             "call syscs_util.syscs_register_tool( 'foreignViews', true, '" + foreignURL
+ "', 'XYZ_' )"
              );
         employeeSelect = "select * from xyz_frank.employee order by employeeID";
         starSelect = "select * from xyz_alice.stars order by starID";
@@ -357,7 +359,7 @@ public class OptionalToolsTest  extends 
         goodStatement
             (
              dboConnection,
-             "call syscs_util.syscs_register_tool( 'fdbv', false, '" + foreignURL + "', 'XYZ_'
)"
+             "call syscs_util.syscs_register_tool( 'foreignViews', false, '" + foreignURL
+ "', 'XYZ_' )"
              );
         expectCompilationError
             (
@@ -372,6 +374,144 @@ public class OptionalToolsTest  extends 
              starSelect
              );
     }
+
+    /**
+     * <p>
+     * Test loading custom, user-supplied tools.
+     * </p>
+     */
+    public void test_03_customTool() throws Exception
+    {
+        Connection  dboConnection = openUserConnection( TEST_DBO );
+
+        // unknown tool name
+        expectExecutionError
+            (
+             dboConnection,
+             UNKNOWN_TOOL,
+             "call syscs_util.syscs_register_tool( 'uknownToolName', true )"
+             );
+
+        // no custom class name supplied
+        expectExecutionError
+            (
+             dboConnection,
+             UNKNOWN_TOOL,
+             "call syscs_util.syscs_register_tool( 'customTool', true )"
+             );
+
+        // supplied class does not implement OptionalTool
+        expectExecutionError
+            (
+             dboConnection,
+             UNEXPECTED_USER_EXCEPTION,
+             "call syscs_util.syscs_register_tool( 'customTool', true, 'java.lang.String'
)"
+             );
+
+        //
+        // Register a custom tool.
+        //
+
+        // first verify that the tool hasn't been run yet
+        expectCompilationError
+            (
+             dboConnection,
+             UNKNOWN_ROUTINE,
+             "values toString( 100 )"
+             );
+
+        // now register the tool
+        goodStatement
+            (
+             dboConnection,
+             "call syscs_util.syscs_register_tool( 'customTool', true, 'org.apache.derbyTesting.functionTests.tests.lang.OptionalToolExample'
)"
+             );
+
+        // run it
+        assertResults
+            (
+             dboConnection,
+             "values toString( 100 )",
+             new String[][]
+             {
+                 { "100" },
+             },
+             false
+             );
+
+        // unregister the tool
+        goodStatement
+            (
+             dboConnection,
+             "call syscs_util.syscs_register_tool( 'customTool', false, 'org.apache.derbyTesting.functionTests.tests.lang.OptionalToolExample'
)"
+             );
+
+        // verify that the tool was unregistered
+        expectCompilationError
+            (
+             dboConnection,
+             UNKNOWN_ROUTINE,
+             "values toString( 100 )"
+             );
+
+        //
+        // Register a custom tool with a custom parameter.
+        //
+
+        // first verify that the tool hasn't been run yet
+        expectCompilationError
+            (
+             dboConnection,
+             UNKNOWN_ROUTINE,
+             "values foobar( 100 )"
+             );
+
+        // now register the tool
+        goodStatement
+            (
+             dboConnection,
+             "call syscs_util.syscs_register_tool\n" +
+             "(\n" +
+             "    'customTool',\n" +
+             "    true,\n" +
+             "    'org.apache.derbyTesting.functionTests.tests.lang.OptionalToolExample$VariableName',\n"
+
+             "    'foobar'\n" +
+             ")\n"
+             );
+
+        // run it
+        assertResults
+            (
+             dboConnection,
+             "values foobar( 100 )",
+             new String[][]
+             {
+                 { "100" },
+             },
+             false
+             );
+
+        // unregister the tool
+        goodStatement
+            (
+             dboConnection,
+             "call syscs_util.syscs_register_tool\n" +
+             "(\n" +
+             "    'customTool',\n" +
+             "    false,\n" +
+             "    'org.apache.derbyTesting.functionTests.tests.lang.OptionalToolExample$VariableName',\n"
+
+             "    'foobar'\n" +
+             ")\n"
+             );
+
+        // verify that the tool was unregistered
+        expectCompilationError
+            (
+             dboConnection,
+             UNKNOWN_ROUTINE,
+             "values foobar( 100 )"
+             );
+
+    }
     
 }
-

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/build.xml?rev=1431526&r1=1431525&r2=1431526&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/build.xml
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/build.xml
Thu Jan 10 17:48:58 2013
@@ -100,6 +100,7 @@
       <exclude name="${this.dir}/unaryArithmeticDynamicParameter.java"/>
       <exclude name="${this.dir}/_Suite.java"/>
       <exclude name="${this.dir}/VarargsRoutines.java"/>
+      <exclude name="${this.dir}/OptionalToolExample.java"/>
     </javac>
   </target>
   <target name="compilet2" depends="compilet1">
@@ -174,6 +175,7 @@
       <include name="${this.dir}/ModeAggregate.java"/>
       <include name="${this.dir}/LobMode.java"/>
       <include name="${this.dir}/VarargsRoutines.java"/>
+      <include name="${this.dir}/OptionalToolExample.java"/>
     </javac>
   </target> 
 



Mime
View raw message