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, getTimestamp
absolute, 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, updateTimestamp
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
getHoldability, 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, updateRowId, updateRowId, updateSQLXML, updateSQLXML
private 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.AutoCloseable
close
in interface java.sql.ResultSet
close
in class VTITemplate
java.sql.SQLException
public boolean next() throws java.sql.SQLException
next
in interface java.sql.ResultSet
next
in class VTITemplate
java.sql.SQLException
public boolean isClosed()
isClosed
in interface java.sql.ResultSet
public boolean wasNull() throws java.sql.SQLException
wasNull
in interface java.sql.ResultSet
wasNull
in class VTITemplateBase
java.sql.SQLException
public java.sql.ResultSetMetaData getMetaData() throws java.sql.SQLException
getMetaData
in interface java.sql.ResultSet
getMetaData
in class VTITemplateBase
java.sql.SQLException
public java.io.InputStream getAsciiStream(int i) throws java.sql.SQLException
getAsciiStream
in interface java.sql.ResultSet
getAsciiStream
in class VTITemplateBase
java.sql.SQLException
public java.math.BigDecimal getBigDecimal(int i) throws java.sql.SQLException
getBigDecimal
in interface java.sql.ResultSet
getBigDecimal
in class VTITemplateBase
java.sql.SQLException
public java.math.BigDecimal getBigDecimal(int i, int scale) throws java.sql.SQLException
getBigDecimal
in interface java.sql.ResultSet
getBigDecimal
in class VTITemplateBase
java.sql.SQLException
public java.io.InputStream getBinaryStream(int i) throws java.sql.SQLException
getBinaryStream
in interface java.sql.ResultSet
getBinaryStream
in class VTITemplateBase
java.sql.SQLException
public java.sql.Blob getBlob(int i) throws java.sql.SQLException
getBlob
in interface java.sql.ResultSet
getBlob
in class VTITemplateBase
java.sql.SQLException
public boolean getBoolean(int i) throws java.sql.SQLException
getBoolean
in interface java.sql.ResultSet
getBoolean
in class VTITemplateBase
java.sql.SQLException
public byte getByte(int i) throws java.sql.SQLException
getByte
in interface java.sql.ResultSet
getByte
in class VTITemplateBase
java.sql.SQLException
public byte[] getBytes(int i) throws java.sql.SQLException
getBytes
in interface java.sql.ResultSet
getBytes
in class VTITemplateBase
java.sql.SQLException
public java.io.Reader getCharacterStream(int i) throws java.sql.SQLException
getCharacterStream
in interface java.sql.ResultSet
getCharacterStream
in class VTITemplateBase
java.sql.SQLException
public java.sql.Clob getClob(int i) throws java.sql.SQLException
getClob
in interface java.sql.ResultSet
getClob
in class VTITemplateBase
java.sql.SQLException
public java.sql.Date getDate(int i) throws java.sql.SQLException
getDate
in interface java.sql.ResultSet
getDate
in class VTITemplateBase
java.sql.SQLException
public java.sql.Date getDate(int i, java.util.Calendar cal) throws java.sql.SQLException
getDate
in interface java.sql.ResultSet
getDate
in class VTITemplateBase
java.sql.SQLException
public double getDouble(int i) throws java.sql.SQLException
getDouble
in interface java.sql.ResultSet
getDouble
in class VTITemplateBase
java.sql.SQLException
public float getFloat(int i) throws java.sql.SQLException
getFloat
in interface java.sql.ResultSet
getFloat
in class VTITemplateBase
java.sql.SQLException
public int getInt(int i) throws java.sql.SQLException
getInt
in interface java.sql.ResultSet
getInt
in class VTITemplateBase
java.sql.SQLException
public long getLong(int i) throws java.sql.SQLException
getLong
in interface java.sql.ResultSet
getLong
in class VTITemplateBase
java.sql.SQLException
public java.lang.Object getObject(int i) throws java.sql.SQLException
getObject
in interface java.sql.ResultSet
getObject
in class VTITemplateBase
java.sql.SQLException
public short getShort(int i) throws java.sql.SQLException
getShort
in interface java.sql.ResultSet
getShort
in class VTITemplateBase
java.sql.SQLException
public java.lang.String getString(int i) throws java.sql.SQLException
getString
in interface java.sql.ResultSet
getString
in class VTITemplateBase
java.sql.SQLException
public java.sql.Time getTime(int i) throws java.sql.SQLException
getTime
in interface java.sql.ResultSet
getTime
in class VTITemplateBase
java.sql.SQLException
public java.sql.Time getTime(int i, java.util.Calendar cal) throws java.sql.SQLException
getTime
in interface java.sql.ResultSet
getTime
in class VTITemplateBase
java.sql.SQLException
public java.sql.Timestamp getTimestamp(int i) throws java.sql.SQLException
getTimestamp
in interface java.sql.ResultSet
getTimestamp
in class VTITemplateBase
java.sql.SQLException
public java.sql.Timestamp getTimestamp(int i, java.util.Calendar cal) throws java.sql.SQLException
getTimestamp
in interface java.sql.ResultSet
getTimestamp
in class VTITemplateBase
java.sql.SQLException
public void initScan(java.lang.String[] columnNames, Restriction restriction) throws java.sql.SQLException
RestrictedVTI
Initialize 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 RestrictedVTI
java.sql.SQLException
private static java.sql.Connection getForeignConnection(java.lang.String connectionURL) throws java.sql.SQLException
java.sql.SQLException
private 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.SQLException
private 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,2013 The Apache Software Foundation. All Rights Reserved.