db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r1431041 - in /db/derby/code/trunk: java/build/org/apache/derbyBuild/ java/engine/org/apache/derby/catalog/ java/engine/org/apache/derby/impl/sql/compile/ java/engine/org/apache/derby/vti/ java/testing/org/apache/derbyTesting/functionTests/...
Date Wed, 09 Jan 2013 20:23:27 GMT
Author: rhillegas
Date: Wed Jan  9 20:23:27 2013
New Revision: 1431041

URL: http://svn.apache.org/viewvc?rev=1431041&view=rev
Log:
DERBY-6022: Add optional tool for bulk-importing data from foreign databases.

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/vti/ForeignTableVTI.java   (with props)
    db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/optional/ForeignDBViews.java   (with props)
Modified:
    db/derby/code/trunk/java/build/org/apache/derbyBuild/classlister.java
    db/derby/code/trunk/java/engine/org/apache/derby/catalog/Java5SystemProcedures.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/vti/build.xml
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OptionalToolsTest.java
    db/derby/code/trunk/java/tools/org/apache/derby/loc/toolsmessages.properties
    db/derby/code/trunk/tools/jar/extraDBMSclasses.properties
    db/derby/code/trunk/tools/jar/tools.properties
    db/derby/code/trunk/tools/javadoc/publishedapi.ant

Modified: db/derby/code/trunk/java/build/org/apache/derbyBuild/classlister.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/build/org/apache/derbyBuild/classlister.java?rev=1431041&r1=1431040&r2=1431041&view=diff
==============================================================================
--- db/derby/code/trunk/java/build/org/apache/derbyBuild/classlister.java (original)
+++ db/derby/code/trunk/java/build/org/apache/derbyBuild/classlister.java Wed Jan  9 20:23:27 2013
@@ -485,6 +485,7 @@ public class classlister {
 				|| className.startsWith("org.apache.derby.jdbc.")
 				|| className.startsWith("org.apache.derby.vti.")
 				|| className.startsWith("org.apache.derby.iapi.sql.dictionary.")
+				|| className.startsWith("org.apache.derby.iapi.util.")
 				)
 			{
 				return;

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=1431041&r1=1431040&r2=1431041&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 Wed Jan  9 20:23:27 2013
@@ -60,6 +60,7 @@ public  class   Java5SystemProcedures
     private static  final   String[][]  OPTIONAL_TOOLS = new String[][]
     {
         { "dbmd", "org.apache.derby.impl.tools.optional.DBMDWrapper" },
+        { "fdbv", "org.apache.derby.impl.tools.optional.ForeignDBViews" },
     };
 
     ///////////////////////////////////////////////////////////////////////////////////

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java?rev=1431041&r1=1431040&r2=1431041&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java Wed Jan  9 20:23:27 2013
@@ -328,7 +328,8 @@ public class StaticMethodCallNode extend
             // A special exception is made for the optional tools methods.
             if (
                 javaClassName.startsWith( "org.apache.derby." ) &&
-                !javaClassName.startsWith( "org.apache.derby.impl.tools.optional." )
+                !javaClassName.startsWith( "org.apache.derby.impl.tools.optional." ) &&
+                !javaClassName.startsWith( "org.apache.derby.vti." )
                 )
             {
                 if (!sd.isSystemSchema())

Added: db/derby/code/trunk/java/engine/org/apache/derby/vti/ForeignTableVTI.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/vti/ForeignTableVTI.java?rev=1431041&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/vti/ForeignTableVTI.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/vti/ForeignTableVTI.java Wed Jan  9 20:23:27 2013
@@ -0,0 +1,431 @@
+/*
+
+   Derby - Class org.apache.derby.vti.ForeignTableVTI
+
+   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.derby.vti;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.derby.iapi.util.IdUtil;
+
+/**
+ * <p>
+ * This class contains a table function which can be used to bulk-import data
+ * from a foreign database. Because the table function is a RestrictedVTI, it
+ * can also be used to periodically and efficiently integrate data streams from
+ * a foreign database.
+ * </p>
+ *
+ * <p>
+ * If you need to siphon data out of the foreign database on an ongoing basis, you
+ * can restrict the data you SELECT. Note that the local views are backed by
+ * RestrictedVTIs. That means that the actual query sent to the foreign database
+ * will only involve the columns you SELECT. In addition, the query will include the WHERE clause,
+ * provided that it is simple enough (see the javadoc for RestrictedVTI):
+ * </p>
+ *
+ * <p>
+ * The following script shows how to use this table function:
+ * </p>
+ *
+ * <pre>
+ * -- create a foreign database with a table in it
+ * connect 'jdbc:derby:memory:db;create=true;user=test_dbo;password=test_dbopassword';
+ * 
+ * call syscs_util.syscs_create_user( 'test_dbo', 'test_dbopassword' );
+ * 
+ * create table employee
+ * (
+ *     firstName   varchar( 50 ),
+ *     lastName    varchar( 50 ),
+ *     employeeID  int primary key
+ * );
+ * 
+ * insert into employee values ( 'Billy', 'Goatgruff', 1 );
+ * insert into employee values ( 'Mary', 'Hadalittlelamb', 2 );
+ * 
+ * connect 'jdbc:derby:memory:db;shutdown=true';
+ * 
+ * -- now create the database where we will do our work
+ * connect 'jdbc:derby:memory:db1;create=true';
+ * 
+ * -- register a table function with the shape of the foreign table
+ * create function employeeFunction
+ * (
+ *     schemaName  varchar( 32672 ),
+ *     tableName   varchar( 32672 ),
+ *     connectionURL        varchar( 32672 )
+ * )
+ * returns table
+ * (
+ *     firstName   varchar( 50 ),
+ *     lastName    varchar( 50 ),
+ *     employeeID  int    
+ * )
+ * language java parameter style derby_jdbc_result_set no sql
+ * external name 'org.apache.derby.vti.ForeignTableVTI.readForeignTable'
+ * ;
+ * 
+ * -- create a convenience view to factor out the function parameters
+ * create view foreignEmployee
+ * as select firstName, lastName, employeeID
+ * from table
+ * (
+ *     employeeFunction
+ *     (
+ *         'TEST_DBO',
+ *         'EMPLOYEE',
+ *         'jdbc:derby:memory:db;user=test_dbo;password=test_dbopassword'
+ *     )
+ * ) s;
+ * 
+ * -- now select from the view as though it were a local table
+ * select * from foreignEmployee;
+ * select lastName from foreignEmployee where employeeID = 2;
+ * </pre>
+ */
+public	class   ForeignTableVTI extends VTITemplate implements  RestrictedVTI
+{
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	CONSTANTS
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	STATE
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    private static  HashMap _connections = new HashMap();
+
+    private String  _foreignSchemaName;
+    private String  _foreignTableName;
+    private String  _connectionURL;
+
+    private String[]    _columnNames;
+    private Restriction _restriction;
+
+    // this maps Derby columns (0-based) to foreign column numbers (1-based) in
+    // the actual query
+    private int[]               _columnNumberMap;
+    private PreparedStatement   _foreignPreparedStatement;
+    private ResultSet           _foreignResultSet;
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	CONSTRUCTOR
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    protected  ForeignTableVTI
+        (
+         String foreignSchemaName,
+         String foreignTableName,
+         String connectionURL
+         )
+    {
+        _foreignSchemaName = foreignSchemaName;
+        _foreignTableName = foreignTableName;
+        _connectionURL = connectionURL;
+    }
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	TABLE FUNCTION
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Table function to read a table in a foreign database.
+     * </p>
+     *
+     * @param   foreignSchemaName   Case-sensitive name of foreign schema
+     * @param   foreignTableName    Case-sensitive name of foreign table
+     * @param   connectionURL       URL for connecting to foreign database via DriverManager.getConnection()
+     */
+    public  static  ForeignTableVTI readForeignTable
+        (
+         String foreignSchemaName,
+         String foreignTableName,
+         String connectionURL
+         )
+    {
+        return new ForeignTableVTI( foreignSchemaName, foreignTableName, connectionURL );
+    }
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	ResultSet BEHAVIOR
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    public  void    close() throws SQLException
+    {
+        if ( !isClosed() )
+        {
+            _foreignSchemaName = null;
+            _foreignTableName = null;
+            _connectionURL = null;
+            _columnNames = null;
+            _restriction = null;
+            _columnNumberMap = null;
+
+            if ( _foreignResultSet != null ) { _foreignResultSet.close(); }
+            if ( _foreignPreparedStatement != null ) { _foreignPreparedStatement.close(); }
+
+            _foreignResultSet = null;
+            _foreignPreparedStatement = null;
+        }
+    }
+
+    public  boolean next()  throws SQLException
+    {
+        if ( !isClosed() && (_foreignResultSet == null) )
+        {
+            _foreignPreparedStatement = prepareStatement
+                ( getForeignConnection( _connectionURL ), makeQuery() );
+            _foreignResultSet = _foreignPreparedStatement.executeQuery();
+        }
+
+        return _foreignResultSet.next();
+    }
+
+    public boolean isClosed() { return (_connectionURL == null); }
+
+    public  boolean wasNull()   throws SQLException
+    { return _foreignResultSet.wasNull(); }
+
+    public  ResultSetMetaData   getMetaData()   throws SQLException
+    { return _foreignResultSet.getMetaData(); }
+
+    public  InputStream 	getAsciiStream(int i) throws SQLException
+    { return _foreignResultSet.getAsciiStream( mapColumnNumber( i ) ); }
+    
+    public  BigDecimal 	getBigDecimal(int i) throws SQLException
+    { return _foreignResultSet.getBigDecimal( mapColumnNumber( i ) ); }
+    
+    public  BigDecimal 	getBigDecimal(int i, int scale) throws SQLException
+    { return _foreignResultSet.getBigDecimal( mapColumnNumber( i ), scale ); }
+    
+    public  InputStream 	getBinaryStream(int i)  throws SQLException
+    { return _foreignResultSet.getBinaryStream( mapColumnNumber( i ) ); }
+    
+    public  Blob 	getBlob(int i)  throws SQLException
+    { return _foreignResultSet.getBlob( mapColumnNumber( i ) ); }
+    
+    public  boolean 	getBoolean(int i) throws SQLException
+    { return _foreignResultSet.getBoolean( mapColumnNumber( i ) ); }
+    
+    public  byte 	getByte(int i)    throws SQLException
+    { return _foreignResultSet.getByte( mapColumnNumber( i ) ); }
+    
+    public  byte[] 	getBytes(int i) throws SQLException
+    { return _foreignResultSet.getBytes( mapColumnNumber( i ) ); }
+    
+    public  Reader 	getCharacterStream(int i) throws SQLException
+    { return _foreignResultSet.getCharacterStream( mapColumnNumber( i ) ); }
+
+    public  Clob 	getClob(int i)  throws SQLException
+    { return _foreignResultSet.getClob( mapColumnNumber( i ) ); }
+
+    public  Date 	getDate(int i)  throws SQLException
+    { return _foreignResultSet.getDate( mapColumnNumber( i ) ); }
+
+    public  Date 	getDate(int i, Calendar cal)    throws SQLException
+    { return _foreignResultSet.getDate( mapColumnNumber( i ), cal ); }
+
+    public  double 	getDouble(int i)    throws SQLException
+    { return _foreignResultSet.getDouble( mapColumnNumber( i ) ); }
+
+    public  float 	getFloat(int i) throws SQLException
+    { return _foreignResultSet.getFloat( mapColumnNumber( i ) ); }
+
+    public  int 	getInt(int i)   throws SQLException
+    { return _foreignResultSet.getInt( mapColumnNumber( i ) ); }
+
+    public  long 	getLong(int i)  throws SQLException
+    { return _foreignResultSet.getLong( mapColumnNumber( i ) ); }
+
+    public  Object 	getObject(int i)    throws SQLException
+    { return _foreignResultSet.getObject( mapColumnNumber( i ) ); }
+
+    public  short 	getShort(int i) throws SQLException
+    { return _foreignResultSet.getShort( mapColumnNumber( i ) ); }
+
+    public  String 	getString(int i)    throws SQLException
+    { return _foreignResultSet.getString( mapColumnNumber( i ) ); }
+
+    public  Time 	getTime(int i)  throws SQLException
+    { return _foreignResultSet.getTime( mapColumnNumber( i ) ); }
+
+    public  Time 	getTime(int i, Calendar cal)    throws SQLException
+    { return _foreignResultSet.getTime( mapColumnNumber( i ), cal ); }
+
+    public  Timestamp 	getTimestamp(int i) throws SQLException
+    { return _foreignResultSet.getTimestamp( mapColumnNumber( i ) ); }
+
+    public  Timestamp 	getTimestamp(int i, Calendar cal)   throws SQLException
+    { return _foreignResultSet.getTimestamp( mapColumnNumber( i ), cal ); }
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	RestrictedVTI BEHAVIOR
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    public  void    initScan
+        ( String[] columnNames, Restriction restriction )
+        throws SQLException
+    {
+        _columnNames = columnNames;
+        _restriction = restriction;
+
+        int columnCount = _columnNames.length;
+
+        _columnNumberMap = new int[ columnCount ];
+        int foreignColumnID = 1;
+        for ( int i = 0; i < columnCount; i++ )
+        {
+            if ( columnNames[ i ] != null ) { _columnNumberMap[ i ] = foreignColumnID++; }
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	Connection MANAGEMENT
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    private static  Connection  getForeignConnection
+        ( String connectionURL )
+        throws SQLException
+    {
+        Connection  conn = (Connection) _connections.get( connectionURL );
+
+        if ( conn == null )
+        {
+            conn = DriverManager.getConnection( connectionURL );
+
+            if ( conn != null ) { _connections.put( connectionURL, conn ); }
+        }
+
+        return conn;
+    }
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	QUERY FACTORY
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Build the query which will be sent to the foreign database.
+     * </p>
+     */
+    private String  makeQuery()
+    {
+        StringBuilder    buffer = new StringBuilder();
+
+        buffer.append( "select " );
+
+        int possibleCount = _columnNames.length;
+        int actualCount = 0;
+        for ( int i = 0; i < possibleCount; i++ )
+        {
+            String  rawName = _columnNames[ i ];
+            if ( rawName == null ) { continue; }
+
+            if ( actualCount > 0 ) { buffer.append( ", " ); }
+            actualCount++;
+            
+            buffer.append( delimitedID( rawName ) );
+        }
+
+        buffer.append( "\nfrom " );
+        buffer.append( delimitedID( _foreignSchemaName ) );
+        buffer.append( '.' );
+        buffer.append( delimitedID( _foreignTableName ) );
+
+        if ( _restriction != null )
+        {
+            String  clause = _restriction.toSQL();
+
+            if (clause != null)
+            {
+                clause = clause.trim();
+                if ( clause.length() != 0 )
+                {
+                    buffer.append( "\nwhere " + clause );
+                }
+            }
+        }
+
+        return buffer.toString();
+    }
+
+    private static  String  delimitedID( String text )  { return IdUtil.normalToDelimited( text ); }
+
+    private static  PreparedStatement   prepareStatement
+        ( Connection conn, String text )
+        throws SQLException
+    {
+        return conn.prepareStatement( text );
+    }
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	UTILITY METHODS
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Map a 1-based Derby column number to a 1-based column number in the
+     * foreign query.
+     * </p>
+     */
+    private int mapColumnNumber( int derbyNumber )
+    {
+        return _columnNumberMap[ derbyNumber - 1 ];
+    }
+}
+

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/vti/ForeignTableVTI.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/vti/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/vti/build.xml?rev=1431041&r1=1431040&r2=1431041&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/vti/build.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/vti/build.xml Wed Jan  9 20:23:27 2013
@@ -58,6 +58,7 @@
       <exclude name="${derby.dir}/vti/VTITemplate.java"/>
       <exclude name="${derby.dir}/vti/VTITemplateBase.java"/>
       <exclude name="${derby.dir}/vti/StringColumnVTI.java"/>
+      <exclude name="${derby.dir}/vti/ForeignTableVTI.java"/>
 
     </javac>
     <javac
@@ -80,6 +81,7 @@
     	<include name="${derby.dir}/vti/VTITemplate.java"/>
     	<include name="${derby.dir}/vti/VTITemplateBase.java"/>
     	<include name="${derby.dir}/vti/StringColumnVTI.java"/>
+    	<include name="${derby.dir}/vti/ForeignTableVTI.java"/>
     </javac>
   </target>
 

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=1431041&r1=1431040&r2=1431041&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 Wed Jan  9 20:23:27 2013
@@ -34,6 +34,8 @@ import java.util.HashMap;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
+import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
+import org.apache.derbyTesting.junit.DatabasePropertyTestSetup;
 import org.apache.derbyTesting.junit.Decorator;
 import org.apache.derbyTesting.junit.TestConfiguration;
 import org.apache.derbyTesting.junit.JDBC;
@@ -51,7 +53,17 @@ public class OptionalToolsTest  extends 
     //
     ///////////////////////////////////////////////////////////////////////////////////
 
-    protected static final    String NO_SUCH_TABLE_FUNCTION = "42ZB4";
+    protected   static  final   String  NO_SUCH_TABLE_FUNCTION = "42ZB4";
+    protected   static  final   String  UNEXPECTED_USER_EXCEPTION = "38000";
+    protected   static  final   String  MISSING_SCHEMA = "42Y07";
+
+    private static  final   String      TEST_DBO = "TEST_DBO";
+    private static  final   String      RUTH = "RUTH";
+    private static  final   String      ALICE = "ALICE";
+    private static  final   String      FRANK = "FRANK";
+    private static  final   String[]    LEGAL_USERS = { TEST_DBO, ALICE, RUTH, FRANK  };
+
+    private static  final   String      FOREIGN_DB = "foreignDB";
 
     ///////////////////////////////////////////////////////////////////////////////////
     //
@@ -85,11 +97,14 @@ public class OptionalToolsTest  extends 
      */
     public static Test suite()
     {
-        TestSuite       suite = new TestSuite( "OptionalToolsTest" );
+        TestSuite suite = (TestSuite) TestConfiguration.embeddedSuite(OptionalToolsTest.class);        
+        Test        test = DatabasePropertyTestSetup.builtinAuthentication
+            ( suite, LEGAL_USERS, "optionalToolsPermissions" );
 
-        suite.addTest( TestConfiguration.defaultSuite(OptionalToolsTest.class) );
+        test = TestConfiguration.sqlAuthorizationDecorator( test );
+        test = TestConfiguration.additionalDatabaseDecorator( test, FOREIGN_DB );
 
-        return suite;
+        return test;
     }
 
     ///////////////////////////////////////////////////////////////////////////////////
@@ -105,19 +120,31 @@ public class OptionalToolsTest  extends 
      */
     public void test_01_dbmdWrapper() throws Exception
     {
-        Connection conn = getConnection();
+        Connection  dboConnection = openUserConnection( TEST_DBO );
+        Connection  ruthConnection = openUserConnection( RUTH );
         String  getTypeInfo = "select type_name, minimum_scale, maximum_scale from table( getTypeInfo() ) s";
 
+        // only the dbo can register tools
+        expectExecutionError
+            (
+             ruthConnection,
+             LACK_EXECUTE_PRIV,
+             "call syscs_util.syscs_register_tool( 'dbmd', true )"
+             );
+
+        // create a dummy table just to force the schema to be created
+        goodStatement( dboConnection, "create table t( a int )" );
+
         // the routines don't exist unless you register them
-        expectCompilationError( NO_SUCH_TABLE_FUNCTION, getTypeInfo );
+        expectCompilationError( dboConnection, NO_SUCH_TABLE_FUNCTION, getTypeInfo );
 
         // now register the database metadata wrappers
-        goodStatement( conn, "call syscs_util.syscs_register_tool( 'dbmd', true )" );
+        goodStatement( dboConnection, "call syscs_util.syscs_register_tool( 'dbmd', true )" );
 
         // now the routine exists
         assertResults
             (
-             conn,
+             dboConnection,
              getTypeInfo,
              new String[][]
              {
@@ -148,10 +175,202 @@ public class OptionalToolsTest  extends 
              );
 
         // now unregister the database metadata wrappers
-        goodStatement( conn, "call syscs_util.syscs_register_tool( 'dbmd', false )" );
+        goodStatement( dboConnection, "call syscs_util.syscs_register_tool( 'dbmd', false )" );
 
         // the routines don't exist anymore
-        expectCompilationError( NO_SUCH_TABLE_FUNCTION, getTypeInfo );
+        expectCompilationError( dboConnection, NO_SUCH_TABLE_FUNCTION, getTypeInfo );
+    }
+    
+    /**
+     * <p>
+     * Test the optional package of views on an external database.
+     * </p>
+     */
+    public void test_02_foreignDBViews() throws Exception
+    {
+        Connection  dboConnection = openUserConnection( TEST_DBO );
+        Connection  foreignFrankConnection = getTestConfiguration().openConnection( FOREIGN_DB, FRANK, FRANK );
+        Connection  foreignAliceConnection = getTestConfiguration().openConnection( FOREIGN_DB, ALICE, ALICE );
+
+        //
+        // Create the foreign database.
+        //
+        goodStatement
+            (
+             foreignFrankConnection,
+             "create table employee\n" +
+             "(\n" +
+             "    firstName   varchar( 50 ),\n" +
+             "    lastName    varchar( 50 ),\n" +
+             "    employeeID  int primary key\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             foreignFrankConnection,
+             "insert into employee values ( 'Billy', 'Goatgruff', 1 )\n"
+             );
+        goodStatement
+            (
+             foreignFrankConnection,
+             "insert into employee values ( 'Mary', 'Hadalittlelamb', 2 )\n"
+             );
+        goodStatement
+            (
+             foreignAliceConnection,
+             "create table stars\n" +
+             "(\n" +
+             "    name   varchar( 50 ),\n" +
+             "    magnitude int,\n" +
+             "    starID  int primary key\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             foreignAliceConnection,
+             "insert into stars values ( 'Polaris', 100, 1 )\n"
+             );
+        
+        // now work in the database where we will create views
+        String      foreignURL = "jdbc:derby:" +
+            getTestConfiguration().getPhysicalDatabaseName( FOREIGN_DB ) +
+            ";user=" + TEST_DBO + ";password=" + TEST_DBO;
+        String      employeeSelect = "select * from frank.employee order by employeeID";
+        String      starSelect = "select * from alice.stars order by starID";
+        String[][]   employeeResult = new String[][]
+            {
+                { "Billy", "Goatgruff", "1" },
+                { "Mary", "Hadalittlelamb", "2" },
+            };
+        String[][]  starResult = new String[][]
+            {
+                { "Polaris", "100", "1" },
+            };
+
+        // wrong number of arguments
+        expectExecutionError
+            (
+             dboConnection,
+             UNEXPECTED_USER_EXCEPTION,
+             "call syscs_util.syscs_register_tool( 'fdbv', true )"
+             );
+
+        // should fail because the view and its schema don't exist
+        expectCompilationError
+            (
+             dboConnection,
+             MISSING_SCHEMA,
+             employeeSelect
+             );
+        expectCompilationError
+            (
+             dboConnection,
+             MISSING_SCHEMA,
+             starSelect
+             );
+
+        // should work
+        goodStatement
+            (
+             dboConnection,
+             "call syscs_util.syscs_register_tool( 'fdbv', true, '" + foreignURL + "' )"
+             );
+
+        // views should have been created against the foreign database
+        assertResults
+            (
+             dboConnection,
+             employeeSelect,
+             employeeResult,
+             false
+             );
+        assertResults
+            (
+             dboConnection,
+             starSelect,
+             starResult,
+             false
+             );
+        
+        // wrong number of arguments
+        expectExecutionError
+            (
+             dboConnection,
+             UNEXPECTED_USER_EXCEPTION,
+             "call syscs_util.syscs_register_tool( 'fdbv', false )"
+             );
+
+        // should work
+        goodStatement
+            (
+             dboConnection,
+             "call syscs_util.syscs_register_tool( 'fdbv', false, '" + foreignURL + "' )"
+             );
+
+        // should fail because the view and its schema were dropped when the tool was unloaded
+        expectCompilationError
+            (
+             dboConnection,
+             MISSING_SCHEMA,
+             employeeSelect
+             );
+        expectCompilationError
+            (
+             dboConnection,
+             MISSING_SCHEMA,
+             starSelect
+             );
+
+        // unregistration should be idempotent
+        goodStatement
+            (
+             dboConnection,
+             "call syscs_util.syscs_register_tool( 'fdbv', false, '" + foreignURL + "' )"
+             );
+
+        // register with a schema prefix
+        goodStatement
+            (
+             dboConnection,
+             "call syscs_util.syscs_register_tool( 'fdbv', true, '" + foreignURL + "', 'XYZ_' )"
+             );
+        employeeSelect = "select * from xyz_frank.employee order by employeeID";
+        starSelect = "select * from xyz_alice.stars order by starID";
+
+        // views should have been created against the foreign database
+        assertResults
+            (
+             dboConnection,
+             employeeSelect,
+             employeeResult,
+             false
+             );
+        assertResults
+            (
+             dboConnection,
+             starSelect,
+             starResult,
+             false
+             );
+
+        // drop the views
+        goodStatement
+            (
+             dboConnection,
+             "call syscs_util.syscs_register_tool( 'fdbv', false, '" + foreignURL + "', 'XYZ_' )"
+             );
+        expectCompilationError
+            (
+             dboConnection,
+             MISSING_SCHEMA,
+             employeeSelect
+             );
+        expectCompilationError
+            (
+             dboConnection,
+             MISSING_SCHEMA,
+             starSelect
+             );
     }
     
 }

Added: db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/optional/ForeignDBViews.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/optional/ForeignDBViews.java?rev=1431041&view=auto
==============================================================================
--- db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/optional/ForeignDBViews.java (added)
+++ db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/optional/ForeignDBViews.java Wed Jan  9 20:23:27 2013
@@ -0,0 +1,516 @@
+/*
+
+   Derby - Class org.apache.derby.impl.tools.optional.ForeignDBViews
+
+   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.derby.impl.tools.optional;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.HashSet;
+
+import org.apache.derby.iapi.sql.dictionary.OptionalTool;
+import org.apache.derby.iapi.tools.i18n.LocalizedResource;
+import org.apache.derby.iapi.util.IdUtil;
+import org.apache.derby.iapi.util.StringUtil;
+
+/**
+ * <p>
+ * OptionalTool to create wrapper functions and views for all of the user tables
+ * in a foreign database.
+ * </p>
+ */
+public	class   ForeignDBViews  implements OptionalTool
+{
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	CONSTANTS
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    private static  final   int XML_TYPE = 2009;    // needed if you aren't compiling against Java 6
+
+    //
+    // It's ok to get these SQLStates when trying to drop an object on behalf
+    // of unloadTool(). The idea is to make unloadTool() idempotent.
+    //
+    private static  final   String[]    SAFE_DROP_SQLSTATES =
+    {
+        org.apache.derby.shared.common.reference.SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION,
+        org.apache.derby.shared.common.reference.SQLState.LANG_OBJECT_DOES_NOT_EXIST,
+        org.apache.derby.shared.common.reference.SQLState.LANG_SCHEMA_DOES_NOT_EXIST,
+    };
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	STATE
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	CONSTRUCTOR
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    /** 0-arg constructor required by the OptionalTool contract */
+    public  ForeignDBViews() {}
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // OptionalTool BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Creates a local Derby schema for every foreign schema which contains
+     * a user table. Then creates a table function and convenience view for every
+     * user table found in the foreign database. The parameters to this method are:
+     * </p>
+     *
+     * <ul>
+     * <li>foreignConnectionURL (required) - URL to connect to the foreign database</li>
+     * <li>schemaPrefix (optional) - If not specified, then the local Derby schema which is
+     * created has the same name as the foreign schema. Otherwise, this prefix is prepended
+     * to the names of the local Derby schemas which are created.</li>
+     * </ul>
+     */
+    public  void    loadTool( String... configurationParameters )
+        throws SQLException
+    {
+        if ( (configurationParameters == null) || (configurationParameters.length < 1) )
+        {
+            throw wrap( LocalizedResource.getMessage( "OT_BadLoadUnloadArgs" ) );
+        }
+
+        String              foreignConnectionURL = configurationParameters[ 0 ];
+        String              schemaPrefix = (configurationParameters.length == 1) ? null : configurationParameters[ 1 ];
+        Connection          foreignConn = getForeignConnection( foreignConnectionURL );
+        Connection          derbyConn = getDerbyConnection();
+        DatabaseMetaData    foreignDBMD = foreignConn.getMetaData();
+        ResultSet           tableCursor = getForeignTables( foreignDBMD );
+
+        while( tableCursor.next() )
+        {
+            registerForeignTable
+                (
+                 foreignDBMD,
+                 tableCursor.getString( 2 ),
+                 tableCursor.getString( 3 ),
+                 foreignConnectionURL,
+                 schemaPrefix,
+                 derbyConn
+                 );
+        }
+
+        tableCursor.close();
+        foreignConn.close();
+    }
+
+    /**
+     * <p>
+     * Removes the schemas, table functions, and views created by loadTool().
+     * </p>
+     *
+     * <ul>
+     * <li>connectionURL (required) - URL to connect to the foreign database</li>
+     * <li>schemaPrefix (optional) - See loadTool() for more information on this argument.</li>
+     * </ul>
+     */
+    public  void    unloadTool( String... configurationParameters )
+        throws SQLException
+    {
+        if ( (configurationParameters == null) || (configurationParameters.length < 1) )
+        {
+            throw wrap( LocalizedResource.getMessage( "OT_BadLoadUnloadArgs" ) );
+        }
+
+        String              foreignConnectionURL = configurationParameters[ 0 ];
+        String              schemaPrefix = (configurationParameters.length == 1) ? null : configurationParameters[ 1 ];
+        Connection          foreignConn = getForeignConnection( foreignConnectionURL );
+        Connection          derbyConn = getDerbyConnection();
+        DatabaseMetaData    foreignDBMD = foreignConn.getMetaData();
+        ResultSet           tableCursor = getForeignTables( foreignDBMD );
+        HashSet<String> schemas = new HashSet<String>();
+
+        while( tableCursor.next() )
+        {
+            String          derbySchemaName = getDerbySchemaName( schemaPrefix, tableCursor.getString( 2 ) );
+            String          objectName = tableCursor.getString( 3 );
+
+            if ( derbySchemaName != null ) { schemas.add( derbySchemaName ); }
+            
+            dropObject( derbyConn, derbySchemaName, objectName, "view", false );
+            dropObject( derbyConn, derbySchemaName, objectName, "function", false );
+        }
+
+        tableCursor.close();
+        foreignConn.close();
+
+        // now drop the schemas created by loadTool()
+        for ( String schemaName : schemas ) { dropDerbySchema( derbyConn, schemaName ); }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // REGISTRATION MINIONS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    private void    registerForeignTable
+        (
+         DatabaseMetaData   foreignDBMD,
+         String             foreignSchemaName,
+         String             foreignTableName,
+         String             foreignConnectionURL,
+         String             schemaPrefix,
+         Connection     derbyConn
+        )
+        throws SQLException
+    {
+        //
+        // Create DDL string for registering the table function
+        //
+        StringBuilder       tfBuffer = new StringBuilder();
+        String              derbySchemaName = getDerbySchemaName( schemaPrefix, foreignSchemaName );
+        String              dotSchemaName = dotSeparatedSchemaName( derbySchemaName );
+
+        createDerbySchema( derbyConn, derbySchemaName );
+
+        tfBuffer.append( "create function " + dotSchemaName + delimitedID( foreignTableName ) );
+        tfBuffer.append( "\n(" );
+        tfBuffer.append( "\n\tforeignSchemaName varchar( 32672 )," );
+        tfBuffer.append( "\n\tforeignTableName varchar( 32672 )," );
+        tfBuffer.append( "\n\tconnectionURL varchar( 32672 )" );
+        tfBuffer.append( "\n)\nreturns table\n(" );
+        
+        ResultSet           columnCursor = foreignDBMD.getColumns( null, foreignSchemaName, foreignTableName, "%" );
+        int                 columnCount = 0;
+        while( columnCursor.next() )
+        {
+            tfBuffer.append( "\n\t" );
+            if ( columnCount > 0 ) { tfBuffer.append( ", " ); }
+            columnCount++;
+
+            tfBuffer.append( delimitedID( columnCursor.getString( 4 ) ) );
+            tfBuffer.append( " " );
+            tfBuffer.append
+                (
+                 mapType
+                 (
+                  columnCursor.getInt( 5 ),
+                  columnCursor.getInt( 7 ),
+                  columnCursor.getInt( 9 ),
+                  columnCursor.getString( 6 )
+                  )
+                 );
+        }
+        columnCursor.close();
+
+        tfBuffer.append( "\n)" );
+        tfBuffer.append( "\nlanguage java parameter style derby_jdbc_result_set no sql" );
+        tfBuffer.append( "\nexternal name 'org.apache.derby.vti.ForeignTableVTI.readForeignTable'" );
+
+        String          tfDDL = tfBuffer.toString();
+        
+        //
+        // Create DDL string for registering the view
+        //
+        StringBuilder   viewBuffer = new StringBuilder();
+
+        viewBuffer.append( "create view " + dotSchemaName + delimitedID( foreignTableName ) );
+        viewBuffer.append( "\nas select *" );
+        viewBuffer.append( "\nfrom table" );
+        viewBuffer.append( "\n(\n" );
+        viewBuffer.append( "\t" + dotSchemaName + delimitedID( foreignTableName ) );
+        viewBuffer.append( "\n\t(" );
+        viewBuffer.append( "\n\t\t" + stringLiteral( foreignSchemaName ) + "," );
+        viewBuffer.append( "\n\t\t" + stringLiteral( foreignTableName ) + "," );
+        viewBuffer.append( "\n\t\t" + stringLiteral( foreignConnectionURL ) );
+        viewBuffer.append( "\n\t)" );
+        viewBuffer.append( "\n) s" );
+
+        String          viewDDL = viewBuffer.toString();
+
+        //
+        // Now create the table function and view.
+        //
+        executeDDL( derbyConn, tfDDL );
+        executeDDL( derbyConn, viewDDL );
+    }
+
+    /**
+     * <p>
+     * Get a cursor through the user tables in the foreign database.
+     * </p>
+     */
+    private ResultSet   getForeignTables( DatabaseMetaData foreignDBMD )
+        throws SQLException
+    {
+        return foreignDBMD.getTables( null, null, "%", new String[] { "TABLE" } );
+    }
+
+    /**
+     * <p>
+     * Create a Derby schema if it does not already exist.
+     * </p>
+     */
+    private void    createDerbySchema
+        (
+         Connection derbyConn,
+         String     derbySchemaName
+         )
+        throws SQLException
+    {
+        if ( derbySchemaName == null ) { return; }
+        
+        PreparedStatement   existsPS = prepareStatement
+            ( derbyConn, "select count(*) from sys.sysschemas where schemaname = ?" );
+        existsPS.setString( 1, derbySchemaName );
+        ResultSet   existsRS = existsPS.executeQuery();
+        existsRS.next();
+        boolean exists = existsRS.getInt( 1 ) > 0;
+        existsRS.close();
+        existsPS.close();
+
+        if ( !exists )
+        {
+            executeDDL
+                ( derbyConn, "create schema " + delimitedID( derbySchemaName ) );
+        }
+    }
+
+    /**
+     * <p>
+     * Drop a Derby schema.
+     * </p>
+     */
+    private void    dropDerbySchema
+        (
+         Connection derbyConn,
+         String     derbySchemaName
+         )
+        throws SQLException
+    {
+        if ( derbySchemaName == null ) { return; }
+
+        dropObject( derbyConn, null, derbySchemaName, "schema", true );
+    }
+        
+    /**
+     * <p>
+     * Get the name of the local Derby schema corresponding to a foreign schema name.
+     * Returns null if the default (current) schema is to be used.
+     * </p>
+     */
+    private String  getDerbySchemaName
+        (
+         String schemaPrefix,
+         String foreignSchemaName
+         )
+    {
+        if ( foreignSchemaName == null ) { return null; }
+        else if ( schemaPrefix == null ) { return foreignSchemaName; }
+        else { return schemaPrefix + foreignSchemaName; }
+    }
+
+    /**
+     * <p>
+     * Turn a Derby schema name into a schema name suitable for use
+     * in a dot-separated object name.
+     * </p>
+     */
+    private String  dotSeparatedSchemaName( String rawName )
+    {
+        if ( rawName == null ) { return ""; }
+        else { return delimitedID( rawName ) + "."; }
+    }
+    
+    /**
+     * <p>
+     * Get the type of an external database's column as a Derby type name.
+     * </p>
+     *
+     */
+    private String    mapType( int jdbcType, int precision, int scale, String foreignTypeName )
+        throws SQLException
+    {
+        switch( jdbcType )
+        {
+        case    Types.BIGINT:           return "bigint";
+        case    Types.BINARY:           return "char " + precisionToLength( precision ) + "  for bit data";
+        case    Types.BIT:              return "boolean";
+        case    Types.BLOB:             return "blob";
+        case    Types.BOOLEAN:          return "boolean";
+        case    Types.CHAR:             return "char" + precisionToLength( precision );
+        case    Types.CLOB:             return "clob";
+        case    Types.DATE:             return "date";
+        case    Types.DECIMAL:          return "decimal" + precisionAndScale( precision, scale );
+        case    Types.DOUBLE:           return "double";
+        case    Types.FLOAT:            return "float";
+        case    Types.INTEGER:          return "integer";
+        case    Types.LONGVARBINARY:    return "long varchar for bit data";
+        case    Types.LONGVARCHAR:      return "long varchar";
+        case    Types.NUMERIC:          return "numeric" + precisionAndScale( precision, scale );
+        case    Types.REAL:             return "real";
+        case    Types.SMALLINT:         return "smallint";
+        case    Types.TIME:             return "time";
+        case    Types.TIMESTAMP:        return "timestamp";
+        case    Types.TINYINT:          return "smallint";
+        case    Types.VARBINARY:        return "varchar " + precisionToLength( precision ) + "  for bit data";
+        case    Types.VARCHAR:          return "varchar" + precisionToLength( precision );
+        case    XML_TYPE:               return "xml";
+ 
+        default:
+            throw wrap
+                (
+                 LocalizedResource.getMessage
+                 (
+                  "OT_UnknownForeignDataType",
+                  Integer.toString( jdbcType ),
+                  foreignTypeName
+                 )
+                );
+        }
+    }
+
+    /**
+     * <p>
+     * Turns precision into a length designator.
+     * </p>
+     *
+     */
+    private String  precisionToLength( int precision )
+    {
+        return "( " + precision + " )";
+    }
+
+    /**
+     * <p>
+     * Build a precision and scale designator.
+     * </p>
+     *
+     */
+    private String  precisionAndScale( int precision, int scale )
+    {
+        return "( " + precision + ", " + scale + " )";
+    }
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	UNREGISTRATION MINIONS
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Drop a schema object. If the object does not exist, silently
+     * swallow the error.
+     * </p>
+     */
+    private void    dropObject
+        (
+         Connection         conn,
+         String             schemaName,
+         String             objectName,
+         String             objectType,
+         boolean        restrict
+        )
+        throws SQLException
+    {
+        String              dotSchemaName = dotSeparatedSchemaName( schemaName );
+        String              restrictString = restrict ? " restrict" : "";
+
+        try {
+            executeDDL
+                (
+                 conn,
+                 "drop " + objectType + " " + dotSchemaName + delimitedID( objectName ) + restrictString
+                 );
+        }
+        catch (SQLException se)
+        {
+            String  actualSQLState = se.getSQLState();
+
+            for ( String safeSQLState : SAFE_DROP_SQLSTATES )
+            {
+                if ( actualSQLState.startsWith( safeSQLState ) ) { return; }
+            }
+
+            throw se;
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	Connection MANAGEMENT
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    private Connection  getForeignConnection( String connectionURL )
+        throws SQLException
+    {
+        return DriverManager.getConnection( connectionURL );
+    }
+
+    private Connection  getDerbyConnection() throws SQLException
+    {
+        return DriverManager.getConnection( "jdbc:default:connection" );
+    }
+
+    ////////////////////////////////////////////////////////////////////////
+    //
+    //	SQL MINIONS
+    //
+    ////////////////////////////////////////////////////////////////////////
+
+    private String  delimitedID( String text )  { return IdUtil.normalToDelimited( text ); }
+    private String  stringLiteral( String text )  { return StringUtil.quoteStringLiteral( text ); }
+
+    private void    executeDDL
+        ( Connection conn, String text )
+        throws SQLException
+    {
+        PreparedStatement   ddl = prepareStatement( conn, text );
+        ddl.execute();
+        ddl.close();
+    }
+    
+    private PreparedStatement   prepareStatement
+        ( Connection conn, String text )
+        throws SQLException
+    {
+        return conn.prepareStatement( text );
+    }
+
+    private SQLException    wrap( String errorMessage )
+    {
+        String  sqlState = org.apache.derby.shared.common.reference.SQLState.JAVA_EXCEPTION.substring( 0, 5 );
+
+        return new SQLException( errorMessage, sqlState );
+    }
+
+}
+

Propchange: db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/optional/ForeignDBViews.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/tools/org/apache/derby/loc/toolsmessages.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/tools/org/apache/derby/loc/toolsmessages.properties?rev=1431041&r1=1431040&r2=1431041&view=diff
==============================================================================
--- db/derby/code/trunk/java/tools/org/apache/derby/loc/toolsmessages.properties (original)
+++ db/derby/code/trunk/java/tools/org/apache/derby/loc/toolsmessages.properties Wed Jan  9 20:23:27 2013
@@ -397,3 +397,13 @@ SC_NO_CONN=Could not get a connection.
 SC_FOUND_MATCH=Found a matching method for: {0}
 SC_UNRESOLVABLE=Unresolvable routine: {0}. Detailed reason: {1}
 
+#
+# Messages for the OptionalTools
+#
+
+OT_BadLoadUnloadArgs=Bad arguments passed to SYSCS_UTIL.SYSCS_REGISTER_TOOL(). Please consult the Reference Manual section which describes this system procedure.
+
+# arg0 = a JDBC type ID from java.sql.Types
+# arg1 = the name of a foreign data type returned by java.sql.DatabaseMetaData.getColumns().getString( 6 )
+OT_UnknownForeignDataType=Unknown external data type. JDBC type = {0}, external type name = {1}.
+

Modified: db/derby/code/trunk/tools/jar/extraDBMSclasses.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/tools/jar/extraDBMSclasses.properties?rev=1431041&r1=1431040&r2=1431041&view=diff
==============================================================================
--- db/derby/code/trunk/tools/jar/extraDBMSclasses.properties (original)
+++ db/derby/code/trunk/tools/jar/extraDBMSclasses.properties Wed Jan  9 20:23:27 2013
@@ -33,7 +33,7 @@ derby.module.jndi.LDAPSchemeImpl=org.apa
 
 derby.module.vti.locktable=org.apache.derby.diag.LockTable
 derby.module.vti.metadata.template=org.apache.derby.vti.VTIMetaDataTemplate
-derby.module.vti.template=org.apache.derby.vti.VTITemplate
+derby.module.vti.ForeignTableVTI=org.apache.derby.vti.ForeignTableVTI
 derby.module.vti.StringColumnVTI=org.apache.derby.vti.StringColumnVTI
 derby.module.vti.updatabletemplate=org.apache.derby.vti.UpdatableVTITemplate
 derby.module.vti.transactiontable=org.apache.derby.diag.TransactionTable

Modified: db/derby/code/trunk/tools/jar/tools.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/tools/jar/tools.properties?rev=1431041&r1=1431040&r2=1431041&view=diff
==============================================================================
--- db/derby/code/trunk/tools/jar/tools.properties (original)
+++ db/derby/code/trunk/tools/jar/tools.properties Wed Jan  9 20:23:27 2013
@@ -30,5 +30,6 @@ derby.module.sysinfo=org.apache.derby.to
 derby.module.SignatureChecker=org.apache.derby.tools.SignatureChecker
 derby.module.planexporter=org.apache.derby.tools.PlanExporter
 derby.module.dbmdwrapper=org.apache.derby.impl.tools.optional.DBMDWrapper
+derby.module.fdbv=org.apache.derby.impl.tools.optional.ForeignDBViews
 
 

Modified: db/derby/code/trunk/tools/javadoc/publishedapi.ant
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/tools/javadoc/publishedapi.ant?rev=1431041&r1=1431040&r2=1431041&view=diff
==============================================================================
--- db/derby/code/trunk/tools/javadoc/publishedapi.ant (original)
+++ db/derby/code/trunk/tools/javadoc/publishedapi.ant Wed Jan  9 20:23:27 2013
@@ -54,6 +54,7 @@ org/apache/derby/tools/dblook.java
 
 # package: org.apache.derby.vti
 
+org/apache/derby/vti/ForeignTableVTI.java
 org/apache/derby/vti/RestrictedVTI.java
 org/apache/derby/vti/Restriction.java
 org/apache/derby/vti/StringColumnVTI.java



Mime
View raw message