home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Symantec Visual Cafe for Java 2.5
/
symantec-visual-cafe-2.5-database-dev-edition.iso
/
VCafe
/
prosrc.bin
/
JDBCDataSourceDataStore.java
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
Macintosh to JP
NeXTSTEP
RISC OS/Acorn
Shift JIS
UTF-8
Wrap
Java Source
|
1998-03-18
|
31.6 KB
|
1,003 lines
/*
* @(#JDBCDataSourceDataStore.java
*
* Copyright (c) 1997 Symantec Corporation. All Rights Reserved.
*
*/
package symantec.itools.db.awt;
import symantec.itools.db.beans.binding.*;
import symantec.itools.db.pro.*;
import java.sql.SQLException;
import java.util.BitSet;
import java.util.StringTokenizer;
import java.sql.Types;
/**
* This implements data store for the TableView component that uses a JDBCDataSource
* for its data.
* <p>
* All rows coming from DbaDataSource are zero-relative.<br>
* All columns coming from DbaDataSource are one-relative.
*
* @see symantec.itools.db.awt.DbDataSource
* @see symantec.itools.db.awt.DbDataUpdater
* @see symantec.itools.db.awt.MetaTable
*/
public class JDBCDataSourceDataStore implements DbDataStore, MetaTable, DbDataUpdater,
TriggerUIListener/*, RowChangedListener*/{
symantec.itools.db.beans.binding.QueryNavigator jdbcDataSource = null;
DataStoreMetaTable meta = null;
int coltoshow=0;
boolean fetchModeFlag = false;
DbDataSource source = null;
boolean wantPrintOuts=false;
boolean ignoreEvent = false;
/**
* Obsolete.
*/
public static final int MAX_DISPLAY_SIZE = 60;
/**
* Constructs a DbaDataStore that uses the given JDBCDataSource for data.
*
* @param rv the RelatioView to used for data access
* @param masterView obsolete
* @exception SQLException
* if a SQL database access error occurred
*/
public JDBCDataSourceDataStore(symantec.itools.db.beans.binding.QueryNavigator jdbcDataSource){
if (jdbcDataSource != null)
{
try{
this.jdbcDataSource = jdbcDataSource;
Class m_POFactory=null;
java.util.StringTokenizer st = new java.util.StringTokenizer(jdbcDataSource.getClassName());
String className = null;
//the returned class name can be something like 'class JDBCRow'
//only want 'JDBCRow'
while(st.hasMoreTokens()){
className = st.nextToken();
}
m_POFactory = Class.forName(className);
PersistentObject newPO = (PersistentObject)m_POFactory.newInstance();
meta = new DataStoreMetaTable(newPO/*jdbcDataSource.getTable()*/);
jdbcDataSource.addTriggerUIListener(this);
}catch(Exception e){}
}
}
/**
* Clears all row data from this jdbcDataSource.
* <p>
* Note that setDbDataSource() must be called before using this method.
*
* @exception SQLException
* if a SQL database access error occurred
*
* @see #setDbDataSource
*/
void resetRows() throws SQLException
{
if(wantPrintOuts)System.out.println("in resetrows");
ignoreEvent = true;
initRowMapping();
source.view.clear();
// source.view.redrawAsync(); // clear calls redrawAsync
}
/**
* Sets the fetch mode for getting data. When fetch mode is enabled,
* a grid expects to rapidly read lots of data for read only purposes.
* Knowing this can allow some data stores to more efficiently get the
* data. The TableView provides a guarantee that the current data row will
* not be changed
* @param manual true if fetch mode is to be entered
*/
public void fetchMode(boolean manual)
{
// if(wantPrintOuts)System.out.println("in fetchmode");
setManRowChangeFlag(manual);
}
/**
* Returns the current send notification flag.
* This is used to determine if the RelationView sends notifications
* when it's modified.
* When fetch mode is enabled this returns a value of true. == no notification
*
* @return the current send notification flag
* @see #fetchMode
*/
public boolean manualRowChangeFlag()
{
if(wantPrintOuts)System.out.println("in manualRowChangeFlag");
return fetchModeFlag;
}
private void setManRowChangeFlag(boolean val)
{
// if(wantPrintOuts)System.out.println("in setManrowChangeFlag");
fetchModeFlag = val;
}
/**
* Sets the current row in the data store.
* <p>
* This is a standard DbDataStore interface method.
*
* @param row the zero-relative row index
* @exception TypeNotSupported
* if the data store does not support the type of action requested
* or is not successful
*/
public void setCurrentRow(int row) throws TypeNotSupported {
if(wantPrintOuts)System.out.println("in set current row" + row);
row++;//goto is 1 based
ignoreEvent = true;
try
{
{
jdbcDataSource.go_to(row);
}
} catch(Exception ex)
{
throw new TypeNotSupported(ex.getMessage());
}
}
/**
* Determines if the given row is the current row in the data store.
*
* @param row the zero-relative index of the row to check
* @return true if it is the current row, false otherwise
* @see #setCurrentRow
*/
public boolean isCurrentRow(int row) {
if(wantPrintOuts)System.out.println("in isCurrentRow");
try
{
{
return row == jdbcDataSource.getCurrentRowNumber();
}
}
catch(Exception ex)
{
return false;
}
}
/**
* Sets the database data source that requests data and possibly
* caches the SQL data.
* <p>
* This is a standard DbDataStore interface method.
*
* @param ds the data source
*/
public void setDbDataSource(DbDataSource ds) {
if(wantPrintOuts)System.out.println("in setDbDataSource");
if (source != null)
{
return;
}
source = ds;
initRowMapping();
}
/**
* Called by a DbDataSource to determine if the store provides its own
* caching services.
* <p>
* This is a standard DbDataStore interface method.
*
* @return true if the store provides scrollable caching
*/
public boolean supportsCaching() {
if(wantPrintOuts)System.out.println("in supportCaching");
return true;
}
/**
* Gets the last row that exists within the specified range.
* <p>
* This is a standard DbDataStore interface method.
*
* @param top the zero-relative index of the first row in the range
* @param bottom the zero-relative index of the last row in the range
* @return the last row that exists in the given range
* @exception DataNotAvailable
* if the requested data cannot be accessed in the data store
*/
public int validDataRowRange(int top, int bottom) throws DataNotAvailable {
//iterate from top to bottom and find the last valid number in range
if(wantPrintOuts)System.out.println("in ValidDataRowRange");
bottom += 3; //a few extra for scrollbars
int lastInRange = Math.max(0, top); //always want to ensure at least try
//first row
try {
setManRowChangeFlag(true);
while(lastInRange<=bottom) {
jdbcDataSource.getElementAt(lastInRange);
lastInRange++;
}
} catch(PositionOutOfRangeException e) {
} finally{
setManRowChangeFlag(false);
}
if (lastInRange == top) {
throw new DataNotAvailable("top is greater than last row in database");
}
lastIndex_ = (lastIndex_ < lastInRange) ? lastInRange : lastIndex_;
return lastInRange;
//return bottom;
}
/**
* Gets the data element for the specified position.
* <p>
* This is a standard DbDataStore interface method.
*
* @param row the zero-relative index of the element's row
* @param col the one-relative index of the element's column
* @return the element's data
* @exception DataNotAvailable
* if the requested data cannot be accessed in the data store
*/
public Data getData(int row, int col) throws DataNotAvailable {
//if(wantPrintOuts)System.out.println("in getdata");
Data d = null;
try {
setManRowChangeFlag(true);
String str = null;
Object ob = null;
ob = jdbcDataSource.getValueFromFirst(row, col-1);
if(ob != null){
str = ob.toString();
}else{
str = "";
}
d = new ImageStringData(source, str);
} catch(Exception ex) {
throw new DataNotAvailable(ex.getMessage());
} finally {
setManRowChangeFlag(false);
}
lastIndex_ = (lastIndex_ < row) ? row : lastIndex_;
return d;
}
/**
* Sets a new value in the specified position. The method is only
* called when the store supports caching.
* <p>
* This is a standard DbDataStore interface method.
*
* @param row the zero-relative index of the row to update
* @param col the one-relative index of the column to update
* @param data the data element that holds the new value
* @exception TypeNotSupported
* if the data store does not support the type of action requested
* or is not successful
*/
public void update(int row, int col, Data data) throws TypeNotSupported {
if(wantPrintOuts)System.out.println("in update");
try {
setManRowChangeFlag(true);
//ignoreEvent = true;
jdbcDataSource.setValueFromFirst(data.toString(),row,col-1);
} catch(Exception ex) {
throw new TypeNotSupported(ex.getMessage());
} finally {
setManRowChangeFlag(false);
}
}
//BS: added NONEXISTS_ROW support
/**
* Gets the current state of the specified row.
*
* @param row the zero-relative row index
* @return the state of the row's data. One of NEW_ROW, CLEAN_ROW, DELETED_ROW,
* or MODIFIED_ROW or NONEXISTS_ROW
* @see symantec.itools.db.awt.DataSource#NEW_ROW
* @see symantec.itools.db.awt.DataSource#CLEAN_ROW
* @see symantec.itools.db.awt.DataSource#DELETED_ROW
* @see symantec.itools.db.awt.DataSource#MODIFIED_ROW
* @see symantec.itools.db.awt.DataSource#NONEXISTS_ROW
*/
public int rowState(int row)
{
if(wantPrintOuts)System.out.println("into Rowstate");
int rowState = DataSource.NEW_ROW;
try
{
setManRowChangeFlag(true);
boolean success = true;
//we want the state of the row Row but without setting it as current
PersistentObject po = null;
try{
po = (PersistentObject)jdbcDataSource.getElementAt(row);
}catch (PositionOutOfRangeException e) {
success = false;
}
if (!success)
rowState = DataSource.NONEXISTS_ROW;
if(rowState != DataSource.NONEXISTS_ROW){
if(po != null){
if(po.getMarkedAsDeleted()){
rowState = DataSource.DELETED_ROW;
}else
if(po.getMarkedAsNew()){
rowState = DataSource.NEW_ROW;
}else
if(po.getMarkedAsModified()){
rowState = DataSource.MODIFIED_ROW;
}else
rowState = DataSource.CLEAN_ROW;
} //now what?!?
}
}
catch(Exception ex)
{
//if fails assume new
ex.printStackTrace();
} finally {
setManRowChangeFlag(false);
}
return rowState;
}
/**
* Requests the data store clear all cached data.
* <p>
* This is a standard DbDataStore interface method.
*
*/
public void clear() {
if(wantPrintOuts)System.out.println("in clear");
initRowMapping();
//time to start all over
}
/**
* Requests the data store get the values from the database again.
* <p>
* This is a standard DbDataStore interface method.
*
*/
public void refresh() {
if(wantPrintOuts)System.out.println("in refresh");
// try {
ignoreEvent = true;
//vj: Invoke the datasource restart method
// We need to do this because of master/detail
// changes.
//jdbcDataSource.startQueryByExample();
//ignoreEvent = true;
//jdbcDataSource.executeQueryByExample();
jdbcDataSource.restart();
lastIndex_ = 0;
// } catch(SQLException ex) {
// }
}
/**
* Requests that any actions performed on a row be undone. The meaning
* is left open and is interpreted as appropriate for the type of
* data store.
* <p>
* This is a standard DbDataStore interface method.
*
* @param row the zero-relative row index
* @exception TypeNotSupported
* if the data store does not support the type of action requested
* or is not successful
*/
public void undoRow(int row) throws TypeNotSupported {
if(wantPrintOuts)System.out.println("in undorow");
row++;
//vj: Set the row as the current row. Only this would enable multiple-undo's
ignoreEvent = true;
jdbcDataSource.go_to(row);
ignoreEvent = true;
// try {
jdbcDataSource.undoChanges();
// } catch(SQLException ex) {
// throw new TypeNotSupported(ex.getMessage());
// }
}
/**
* Returns the number of rows actually retrieved from the database.
* <p>
* This is a standard DbDataStore interface method.
*
*/
public int rowsRetrieved() {
//if(wantPrintOuts)System.out.println("in rowsretrieved");
return lastIndex_;
}
/**
* Requests the store to get all of the elements in the result set.
* <p>
* This is a standard DbDataStore interface method.
*
* @return the number of rows gotten
*/
public int fetchAllRows() {
if(wantPrintOuts)System.out.println("in fetchallrows");
int count=1;
try {
setManRowChangeFlag(true);
while(true) {
jdbcDataSource.getElementAt(count);
ignoreEvent = true;
jdbcDataSource.go_to(count);
count++;
}
}catch(PositionOutOfRangeException ex){
}finally {
setManRowChangeFlag(false);
}
lastIndex_ = count-1;
return count-1;
}
//-------------------------------------------------------------------------
// DbDataUpdater Methods
//-------------------------------------------------------------------------
/**
* Undeletes a row.
* <p>
* This is a standard DbDataUpdater interface method.
*
* @param row the zero-relative row index
* @exception TypeNotSupported
* if the data source does not support the type of action requested
* or is not successful
*/
public void undeleteRow(int row) throws TypeNotSupported {
if(wantPrintOuts)System.out.println("in undeleteRow");
undoRow(row);
// throw new TypeNotSupported("undelete row not supported"/*ex.getMessage()*/);
}
/**
* Deletes a row or marks a row for deletion.
* <p>
* This is a standard DbDataUpdater interface method.
*
* @param row the zero-relative row index
* @exception TypeNotSupported
* if the data source does not support the type of action requested
* or is not successful
*/
public void deleteRow(int row) throws TypeNotSupported {
if(wantPrintOuts)System.out.println("in deleteRow");
row++;
//BS: current record in relation view should be set to 'row'
//otherwise the current record is always the first and gets
//deleted
ignoreEvent = true;
jdbcDataSource.go_to(row);
ignoreEvent = true;
jdbcDataSource.delete();
}
/**
* Saves the current state as appopriate.
* If this object caches, it iterates through the cache and updates
* all non-clean rows.
* <p>
* This is a standard DbDataUpdater interface method.
*
* @exception TypeNotSupported
* if the data source does not support the type of action requested
* or is not successful
*/
public void save() throws TypeNotSupported {
if(wantPrintOuts)System.out.println("in save");
ignoreEvent = true;
// try {
jdbcDataSource.saveAll();
if(wantPrintOuts)System.out.println("JDBCDataSourceDataStore: in save");
// } catch(SQLException ex) {
// throw new TypeNotSupported(ex.getMessage());
// }
}
/**
* Gets the next new Record within the RelationView's Record buffers.
* After calling this method, the current Record of the RelationView will
* be positioned at the new Record.
*
* @exception TypeNotSupported
* if the data source does not support the type of action requested
* or is not successful
*/
public void getNewRecord() throws TypeNotSupported
{
if(wantPrintOuts)System.out.println("in getNewRecord");
ignoreEvent = true;
showRecords(0,10);
// try {
jdbcDataSource.insert();
showRecords(0,10);
//source.view.setFocusToRow(/*jdbcDataSource.getCurrentRowNumber() -*/1);
if(wantPrintOuts)System.out.println(jdbcDataSource.getCurrentRowNumber());
// } catch(SQLException ex) {
// throw new TypeNotSupported(ex.getMessage());
// }
}
/**
* Appends a new row.
* @param row ignored
* @exception TypeNotSupported
* if the data source does not support the type of action requested
* or is not successful
*/
public void insertRow(int row) throws TypeNotSupported {
if(wantPrintOuts)System.out.println("in insertRow");
appendRow();
}
/**
* Appends a new row.
* <p>
* This is a standard DbDataUpdater interface method.
*
* @return the zero-relative index of the new row
* @exception TypeNotSupported
* if the data source does not support the type of action requested
* or is not successful
*/
public int appendRow() throws TypeNotSupported {
if(wantPrintOuts)System.out.println("in appendRow");
getNewRecord();
return 0;
}
String m_InputColumnNames = null;
public void setColumnsNamesToShow(String name){
m_InputColumnNames = name;
}
//hides or shows columns depending of the DataBinding that was given to the Grid
public void setColumnsToShow() throws java.sql.SQLException {
//suppress the part after '%'
StringTokenizer stf = new StringTokenizer(m_InputColumnNames,"%");
StringTokenizer st = null;
if(stf.hasMoreTokens())
st = new StringTokenizer(stf.nextToken(),"@,");
String n = null;
if(st.hasMoreTokens())
n = st.nextToken();
if(st.hasMoreTokens()){
//check if the 1st parameter is 'All', in that case, don't do anything
n = st.nextToken();
if(!n.equalsIgnoreCase("All")){
int count = meta.getColumnCount();
try{
//first hide all columns (easier)
for(int i = 0; i < count; i++)
source.view.showColumn(i+1, false);
boolean goon = true;
do{
//is this a valid column name ?
try{
source.view.showColumn(meta.columnNumberfromName(n)+1, true);//meta index is 0 based
}catch(SQLException e){
//this maybe a column index
source.view.showColumn(Integer.parseInt(n), true);
}
if(st.hasMoreTokens())
n = st.nextToken();
else
goon = false;
}while(goon);
}catch(NumberFormatException ex){
//we got an error there, a parameter is neither a valid
//column index, nor a valid column name. Show all columns
for(int i = 0; i < count; i++)
source.view.showColumn(i+1, true);
}
}
}
}
//-------------------------------------------------------------------------
// MetaTable Methods
//-------------------------------------------------------------------------
public void setColtoShow(int val){
if(wantPrintOuts)System.out.println("in setColtoShow");
coltoshow=val;
}
/**
* Configures the given TableView the desired way.
* TableView setup often depends on the number and type of data fields
* that will be displayed.
* <p>
* This is a standard MetaTable interface method.
*
* @param view the grid to configure
*/
//BS: setupTableView changed to setupTableView(TableView v);
//changed name of meth. and param.
//TableView.AUTONUMBER changed to TableView.AUTONUMBER
public void setupTableView(TableView v) {
if(wantPrintOuts)System.out.println("in setupTableView");
try {
//create the proper number of columns
//make sure the BasicCell is set as default
v.setAutoRedraw(false);
int cols = meta.getColumnCount();
//int cols = coltoshow;
if(coltoshow==0||meta.getColumnCount()<=coltoshow)
cols=meta.getColumnCount();
v.createColumns(cols);
//setup row headings
v.setRowLabelHeadingStyle(TableView.AUTONUMBER);
//set the column headings and widths
for (int col=1; col<=cols; col++) {
int size = meta.getColumnDisplaySize(col-1);//JDBCRow has 0-based col indexes
size = Math.min(0, size);
size = Math.max(0, MAX_DISPLAY_SIZE);
v.setHeading(meta.getColumnLabel(col-1),
col,
java.lang.Math.min(size, 10));
setupColumn(v, col);
}
setColumnsToShow();
} catch(Exception ex) {
//Not much to do here but set one heading called error
//and set the message in the first cell
}finally{
v.setAutoRedraw(true);
}
}
/**
* Obsolete.
*/
public void setDataSource(DataSource ds) {
if(wantPrintOuts)System.out.println("in setDatasource");
}
/**
* Determines if the data of the cell at the given location is
* user-editable.
* <p>
* This is a standard MetaTable interface method.
*
* @param row the zero-relative row index
* @param col the one-relative column index
* @return true if it is user-editable, false otherwise
* @exception DataNotAvailable
* if the requested data cannot be accessed in the data store
*/
public boolean isDataEditable(int row, int col) throws DataNotAvailable {
if(wantPrintOuts)System.out.println("in isDataEditable");
//only tests on the column
//return true;
return meta.isWritable(col-1);
}
//BS: added arrangeForViewing, this function newly defined in DataStore interface
/**
* Adjusts the given data as needed before it is viewed in the TableView.
* <p>
* This is a standard MetaTable interface method.
*
* @param the data
* @return the arranged data
*/
public Data[] arrangeForViewing(Data data[]) {
if(wantPrintOuts)System.out.println("in arrangeForViewing");
return data;
}
/**
* Sets up the specified column in the given view as needed.
* Column setup often varies depending on the type of data that will
* be shown in the column.
* <p>
* This is a standard MetaTable interface method.
*
* @param view the TableView that is being set up
* @param col the one-relative position of the column to set up
*/
public void setupColumn(TableView view, int col) throws java.sql.SQLException, DataNotAvailable {
if(wantPrintOuts)System.out.println("in setupColumn");
//assume all cols aligned left
// try {
int type = meta.getColumnType(col-1);
switch(type) {
case Types.BIGINT:
case Types.INTEGER:
case Types.DOUBLE:
case Types.FLOAT:
case Types.NUMERIC:
case Types.SMALLINT:
case Types.TINYINT:
case Types.REAL:
view.setColumnAlignment(col,TableView.RIGHT);
break;
case Types.CHAR:
case Types.DATE:
case Types.VARCHAR:
case Types.LONGVARCHAR:
case Types.NULL:
case Types.OTHER:
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
case Types.TIME:
case Types.TIMESTAMP:
case Types.BIT:
default:
view.setColumnAlignment(col,TableView.LEFT);
}
if (meta.isCurrency(col-1)) {
view.setColumnAlignment(col,TableView.RIGHT);
}
if (!meta.isWritable(col-1)) {
view.setColEditable(col, false);
}
// } catch(SQLException ex) {
//why not try a default
// view.setColumnAlignment(col,TableView.LEFT);
// }
}
int lastIndex_ = 0; //pointer to last element in map,
private void initRowMapping() {
if(wantPrintOuts)System.out.println("in initRowMapping");
lastIndex_ = 0;
}
/**
* Processes a TriggerUIEvent
* <p>
* This is a standard TriggerUIListener interface method.
*
* @param e the TriggerUIEvent to process
*/
public void commitUI(TriggerUIEvent e){
if(wantPrintOuts)System.out.println("JDBCDataSourceDatastore: in commitUI; ignoreEvent:" +
ignoreEvent);
if(!ignoreEvent){
if(wantPrintOuts)System.out.println("type: " + e.m_Type);
switch(e.m_Type){
case TriggerUIEvent.RECORDSETCHANGED:
source.view.refreshView();
break;
case TriggerUIEvent.RECORDNAVIGATION:
//vj: row is already zero-based
//source.view.setFocusToRow(e.m_Row-1);
source.view.setFocusToRow(e.m_Row + 1);
break;
case TriggerUIEvent.RECORDDELETED:
source.view.redrawRow(e.m_Row -1);
break;
case TriggerUIEvent.RECORDINSERTED:
source.view.refreshView();
//vj: row is already zero-based
//source.view.setFocusToRow(e.m_Row-1);
source.view.setFocusToRow(e.m_Row + 1);
break;
case TriggerUIEvent.RECORDSAVEDALL:
source.view.refreshView();
break;
case TriggerUIEvent.RECORDCHANGED:
source.view.redrawRow(e.m_Row -1);
if(wantPrintOuts)System.out.println("refreshing row: " + (e.m_Row -1));
break;
default:
source.view.refreshView();
ignoreEvent=true;
break;
}
}else{
ignoreEvent = false;
}
}
//debug function
void showRecords(int start, int stop){
if(wantPrintOuts)System.out.println("Current row: " + jdbcDataSource.getCurrentRowNumber());
for(int i = start; i < stop; i++){
try{
if(wantPrintOuts)System.out.println("rowState: " + rowState(i));
if(getData(i,1)==null)
if(wantPrintOuts)System.out.println("getData(" + i + ",1) est null");
if(wantPrintOuts)System.out.println("getData: " + i + " " + getData(i,1) + " " +
getData(i,2));
}catch(DataNotAvailable e){
if(wantPrintOuts)System.out.println("showRecords caught an exception: " + e.getMessage());
if(wantPrintOuts)System.out.println(e.getMessage());
}
}
}
//we don't need to support the dataBinding method, the Grid supports it
public void setDataBinding(String dataNamme){}
public class DataStoreMetaTable {
//The metaData has column indexes starting at 0, we use indexes starting
// at 1 !!!!
symantec.itools.db.beans.binding.PersistentObject t = null;
public DataStoreMetaTable(symantec.itools.db.beans.binding.PersistentObject table){
t = table;
}
public int getColumnCount() throws java.sql.SQLException
{
return t.getDataModel().getMemberCount();
}
public String getColumnLabel(int col) throws java.sql.SQLException
{
return t.getDataModel().getMemberModel(col).getName();
}
/* returns a int corresponding to a type as defined in java.sql.Types
*/
public int getColumnType(int col) throws java.sql.SQLException
{
return t.getDataModel().getMemberModel(col).getType();
}
public boolean isWritable(int col) throws DataNotAvailable
{
return t.getDataModel().getMemberModel(col).isWritable();
}
/* not supported by columnMetaData
*/
public int getColumnDisplaySize(int col) throws java.sql.SQLException
{
return (getColumnLabel(col)).length();
}
/* not supported by columnMetaData
*/
public boolean isCurrency(int col)
{
return false;
}
public int columnNumberfromName(String n) throws SQLException{
int col = 0;
int count = getColumnCount();
while(col < count){
if(n.equals(getColumnLabel(col))){
return col;
}
col++;
}
throw new SQLException("column name: " + n + "not found!");
}
}
}