public class ForeignTableVTI extends VTITemplate implements RestrictedVTI
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.
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):
The following script shows how to use this table function:
-- 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;
| Modifier and Type | Field and Description |
|---|---|
private java.lang.String[] |
_columnNames |
private int[] |
_columnNumberMap |
private static java.util.HashMap |
_connections |
private java.lang.String |
_connectionURL |
private java.sql.PreparedStatement |
_foreignPreparedStatement |
private java.sql.ResultSet |
_foreignResultSet |
private java.lang.String |
_foreignSchemaName |
private java.lang.String |
_foreignTableName |
private Restriction |
_restriction |
| Modifier | Constructor and Description |
|---|---|
protected |
ForeignTableVTI(java.lang.String foreignSchemaName,
java.lang.String foreignTableName,
java.lang.String connectionURL) |
| Modifier and Type | Method and Description |
|---|---|
void |
close() |
private static java.lang.String |
delimitedID(java.lang.String text) |
java.io.InputStream |
getAsciiStream(int i) |
java.math.BigDecimal |
getBigDecimal(int i) |
java.math.BigDecimal |
getBigDecimal(int i,
int scale) |
java.io.InputStream |
getBinaryStream(int i) |
java.sql.Blob |
getBlob(int i) |
boolean |
getBoolean(int i) |
byte |
getByte(int i) |
byte[] |
getBytes(int i) |
java.io.Reader |
getCharacterStream(int i) |
java.sql.Clob |
getClob(int i) |
java.sql.Date |
getDate(int i) |
java.sql.Date |
getDate(int i,
java.util.Calendar cal) |
double |
getDouble(int i) |
float |
getFloat(int i) |
private static java.sql.Connection |
getForeignConnection(java.lang.String connectionURL) |
int |
getInt(int i) |
long |
getLong(int i) |
java.sql.ResultSetMetaData |
getMetaData() |
java.lang.Object |
getObject(int i) |
short |
getShort(int i) |
java.lang.String |
getString(int i) |
java.sql.Time |
getTime(int i) |
java.sql.Time |
getTime(int i,
java.util.Calendar cal) |
java.sql.Timestamp |
getTimestamp(int i) |
java.sql.Timestamp |
getTimestamp(int i,
java.util.Calendar cal) |
void |
initScan(java.lang.String[] columnNames,
Restriction restriction)
Initialize a scan of a ResultSet.
|
boolean |
isClosed() |
private java.lang.String |
makeQuery()
Build the query which will be sent to the foreign database.
|
private int |
mapColumnNumber(int derbyNumber)
Map a 1-based Derby column number to a 1-based column number in the
foreign query.
|
boolean |
next() |
private static java.sql.PreparedStatement |
prepareStatement(java.sql.Connection conn,
java.lang.String text) |
static ForeignTableVTI |
readForeignTable(java.lang.String foreignSchemaName,
java.lang.String foreignTableName,
java.lang.String connectionURL)
Table function to read a table in a foreign database.
|
boolean |
wasNull() |
getBigDecimal, getBigDecimal, getBoolean, getByte, getBytes, getDate, getDouble, getFloat, getInt, getLong, getObject, getShort, getString, getTime, getTimestampabsolute, afterLast, beforeFirst, cancelRowUpdates, clearWarnings, deleteRow, findColumn, first, getArray, getArray, getAsciiStream, getBinaryStream, getBlob, getCharacterStream, getClob, getConcurrency, getCursorName, getDate, getFetchDirection, getFetchSize, getObject, getObject, getRef, getRef, getRow, getStatement, getTime, getTimestamp, getType, getUnicodeStream, getUnicodeStream, getURL, getURL, getWarnings, insertRow, isAfterLast, isBeforeFirst, isFirst, isLast, last, moveToCurrentRow, moveToInsertRow, notImplemented, previous, refreshRow, relative, rowDeleted, rowInserted, rowUpdated, setFetchDirection, setFetchSize, updateArray, updateArray, updateAsciiStream, updateAsciiStream, updateBigDecimal, updateBigDecimal, updateBinaryStream, updateBinaryStream, updateBlob, updateBlob, updateBoolean, updateBoolean, updateByte, updateByte, updateBytes, updateBytes, updateCharacterStream, updateCharacterStream, updateClob, updateClob, updateDate, updateDate, updateDouble, updateDouble, updateFloat, updateFloat, updateInt, updateInt, updateLong, updateLong, updateNull, updateNull, updateObject, updateObject, updateObject, updateObject, updateRef, updateRef, updateRow, updateShort, updateShort, updateString, updateString, updateTime, updateTime, updateTimestamp, updateTimestampclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitgetHoldability, getNCharacterStream, getNCharacterStream, getNClob, getNClob, getNString, getNString, getObject, getObject, getRowId, getRowId, getSQLXML, getSQLXML, updateAsciiStream, updateAsciiStream, updateAsciiStream, updateAsciiStream, updateBinaryStream, updateBinaryStream, updateBinaryStream, updateBinaryStream, updateBlob, updateBlob, updateBlob, updateBlob, updateCharacterStream, updateCharacterStream, updateCharacterStream, updateCharacterStream, updateClob, updateClob, updateClob, updateClob, updateNCharacterStream, updateNCharacterStream, updateNCharacterStream, updateNCharacterStream, updateNClob, updateNClob, updateNClob, updateNClob, updateNClob, updateNClob, updateNString, updateNString, updateObject, updateObject, updateObject, updateObject, updateRowId, updateRowId, updateSQLXML, updateSQLXMLprivate static java.util.HashMap _connections
private java.lang.String _foreignSchemaName
private java.lang.String _foreignTableName
private java.lang.String _connectionURL
private java.lang.String[] _columnNames
private Restriction _restriction
private int[] _columnNumberMap
private java.sql.PreparedStatement _foreignPreparedStatement
private java.sql.ResultSet _foreignResultSet
protected ForeignTableVTI(java.lang.String foreignSchemaName,
java.lang.String foreignTableName,
java.lang.String connectionURL)
public static ForeignTableVTI readForeignTable(java.lang.String foreignSchemaName, java.lang.String foreignTableName, java.lang.String connectionURL)
Table function to read a table in a foreign database.
foreignSchemaName - Case-sensitive name of foreign schemaforeignTableName - Case-sensitive name of foreign tableconnectionURL - URL for connecting to foreign database via DriverManager.getConnection()public void close()
throws java.sql.SQLException
close in interface java.lang.AutoCloseableclose in interface java.sql.ResultSetclose in class VTITemplatejava.sql.SQLExceptionpublic boolean next()
throws java.sql.SQLException
next in interface java.sql.ResultSetnext in class VTITemplatejava.sql.SQLExceptionpublic boolean isClosed()
isClosed in interface java.sql.ResultSetpublic boolean wasNull()
throws java.sql.SQLException
wasNull in interface java.sql.ResultSetwasNull in class VTITemplateBasejava.sql.SQLExceptionpublic java.sql.ResultSetMetaData getMetaData()
throws java.sql.SQLException
getMetaData in interface java.sql.ResultSetgetMetaData in class VTITemplateBasejava.sql.SQLExceptionpublic java.io.InputStream getAsciiStream(int i)
throws java.sql.SQLException
getAsciiStream in interface java.sql.ResultSetgetAsciiStream in class VTITemplateBasejava.sql.SQLExceptionpublic java.math.BigDecimal getBigDecimal(int i)
throws java.sql.SQLException
getBigDecimal in interface java.sql.ResultSetgetBigDecimal in class VTITemplateBasejava.sql.SQLExceptionpublic java.math.BigDecimal getBigDecimal(int i,
int scale)
throws java.sql.SQLException
getBigDecimal in interface java.sql.ResultSetgetBigDecimal in class VTITemplateBasejava.sql.SQLExceptionpublic java.io.InputStream getBinaryStream(int i)
throws java.sql.SQLException
getBinaryStream in interface java.sql.ResultSetgetBinaryStream in class VTITemplateBasejava.sql.SQLExceptionpublic java.sql.Blob getBlob(int i)
throws java.sql.SQLException
getBlob in interface java.sql.ResultSetgetBlob in class VTITemplateBasejava.sql.SQLExceptionpublic boolean getBoolean(int i)
throws java.sql.SQLException
getBoolean in interface java.sql.ResultSetgetBoolean in class VTITemplateBasejava.sql.SQLExceptionpublic byte getByte(int i)
throws java.sql.SQLException
getByte in interface java.sql.ResultSetgetByte in class VTITemplateBasejava.sql.SQLExceptionpublic byte[] getBytes(int i)
throws java.sql.SQLException
getBytes in interface java.sql.ResultSetgetBytes in class VTITemplateBasejava.sql.SQLExceptionpublic java.io.Reader getCharacterStream(int i)
throws java.sql.SQLException
getCharacterStream in interface java.sql.ResultSetgetCharacterStream in class VTITemplateBasejava.sql.SQLExceptionpublic java.sql.Clob getClob(int i)
throws java.sql.SQLException
getClob in interface java.sql.ResultSetgetClob in class VTITemplateBasejava.sql.SQLExceptionpublic java.sql.Date getDate(int i)
throws java.sql.SQLException
getDate in interface java.sql.ResultSetgetDate in class VTITemplateBasejava.sql.SQLExceptionpublic java.sql.Date getDate(int i,
java.util.Calendar cal)
throws java.sql.SQLException
getDate in interface java.sql.ResultSetgetDate in class VTITemplateBasejava.sql.SQLExceptionpublic double getDouble(int i)
throws java.sql.SQLException
getDouble in interface java.sql.ResultSetgetDouble in class VTITemplateBasejava.sql.SQLExceptionpublic float getFloat(int i)
throws java.sql.SQLException
getFloat in interface java.sql.ResultSetgetFloat in class VTITemplateBasejava.sql.SQLExceptionpublic int getInt(int i)
throws java.sql.SQLException
getInt in interface java.sql.ResultSetgetInt in class VTITemplateBasejava.sql.SQLExceptionpublic long getLong(int i)
throws java.sql.SQLException
getLong in interface java.sql.ResultSetgetLong in class VTITemplateBasejava.sql.SQLExceptionpublic java.lang.Object getObject(int i)
throws java.sql.SQLException
getObject in interface java.sql.ResultSetgetObject in class VTITemplateBasejava.sql.SQLExceptionpublic short getShort(int i)
throws java.sql.SQLException
getShort in interface java.sql.ResultSetgetShort in class VTITemplateBasejava.sql.SQLExceptionpublic java.lang.String getString(int i)
throws java.sql.SQLException
getString in interface java.sql.ResultSetgetString in class VTITemplateBasejava.sql.SQLExceptionpublic java.sql.Time getTime(int i)
throws java.sql.SQLException
getTime in interface java.sql.ResultSetgetTime in class VTITemplateBasejava.sql.SQLExceptionpublic java.sql.Time getTime(int i,
java.util.Calendar cal)
throws java.sql.SQLException
getTime in interface java.sql.ResultSetgetTime in class VTITemplateBasejava.sql.SQLExceptionpublic java.sql.Timestamp getTimestamp(int i)
throws java.sql.SQLException
getTimestamp in interface java.sql.ResultSetgetTimestamp in class VTITemplateBasejava.sql.SQLExceptionpublic java.sql.Timestamp getTimestamp(int i,
java.util.Calendar cal)
throws java.sql.SQLException
getTimestamp in interface java.sql.ResultSetgetTimestamp in class VTITemplateBasejava.sql.SQLExceptionpublic void initScan(java.lang.String[] columnNames,
Restriction restriction)
throws java.sql.SQLException
RestrictedVTIInitialize a scan of a ResultSet. This method is called once before the scan begins. It is called before any ResultSet method is called. This method performs two tasks:
The columnNames argument is an array of columns which need to be fetched. This is an array of the column names declared in the Table Function's CREATE FUNCTION statement. Column names which were double-quoted in the CREATE FUNCTION statement appear case-sensitive in this array. Column names which were not double-quoted appear upper-cased. Derby asks the Table Function to fetch all columns mentioned in the query. This includes columns mentioned in the SELECT list as well as columns mentioned in the WHERE clause. Note that a column could be mentioned in the WHERE clause in a complex expression which could not be passed to the Table Function via the restriction argument.
The array has one slot for each column declared in the CREATE FUNCTION statement. Slot 0 corresponds to the first column declared in the CREATE FUNCTION statement and so on. If a column does not need to be fetched, then the corresponding slot is null. If a column needs to be fetched, then the corresponding slot holds the column's name.
Note that even though the array may have gaps, it is expected that columns in the ResultSet will occur at the positions declared in the CREATE FUNCTION statement. Consider the following declaration:
create function foreignEmployeeTable()
returns table
(
id int,
birthDay date,
firstName varchar( 100 ),
lastName varchar( 100 )
)
...
and the following query:
select lastName from table( foreignEmployeeTable() ) s
In this example, the array passed to this method will have 4 slots. Slots 0, 1, and 2 will be null and slot 3 will hold the String "LASTNAME". Last names will be retrieved from the ResultSet by calls to getString( 4 )--remember that JDBC column ids are 1-based.
The restriction argument is a simple expression which should be evaluated inside the Table Function in order to eliminate rows. The expression is a binary tree built out of ANDs, ORs, and column qualifiers. The column qualifiers are simple comparisons between constant values and columns in the Table Function. The Table Function only returns rows which satisfy the expression. The restriction is redundantly enforced by Derby on the rows returned by the ResultSet--this means that restriction gives the Table Function a hint about how to optimize its performance but the Table Function is not required to enforce the entire restriction.
initScan in interface RestrictedVTIjava.sql.SQLExceptionprivate static java.sql.Connection getForeignConnection(java.lang.String connectionURL)
throws java.sql.SQLException
java.sql.SQLExceptionprivate java.lang.String makeQuery()
Build the query which will be sent to the foreign database.
private static java.lang.String delimitedID(java.lang.String text)
private static java.sql.PreparedStatement prepareStatement(java.sql.Connection conn,
java.lang.String text)
throws java.sql.SQLException
java.sql.SQLExceptionprivate int mapColumnNumber(int derbyNumber)
Map a 1-based Derby column number to a 1-based column number in the foreign query.
Apache Derby V10.10 Internals - Copyright © 2004,2014 The Apache Software Foundation. All Rights Reserved.