|
Changed priority to trivial, need to consider whether to change current behavior for sqlname == null
ok.
My working path for CachedRowSetImpl is: @Override public void populate(ResultSet rs) throws SQLException { super.populate(rs); this.pathMetaData(rs.getMetaData()); } private void pathMetaData(ResultSetMetaData rsmd) throws SQLException { int numCols = rsmd.getColumnCount(); for (int col = 1; col <= numCols; col++) { String colName = rsmd.getColumnName(col); String colLabel = rsmd.getColumnLabel(col); if (colLabel != null && !colLabel.trim().equals("") && !colLabel.equals(colName) ) ((RowSetMetaDataImpl)this.getMetaData()).setColumnName(col, colLabel); } } P.S.
Could you provide a simple method for use in Fbdriver user-defined classes such as myFBMetaData myFBResultset myFBConnectionRequestInfo and others for example when we are used non-ANSI password fo FB my path is monstr: public class JNMXFBDriver extends org.firebirdsql.jdbc.FBDriver { private final Map mcfToDataSourceMap = new HashMap(); @Override public Connection connect(String url, Properties originalInfo) throws SQLException //, GDSException, FBResourceException { final GDSType type = GDSFactory.getTypeForProtocol(url); if (type == null) return null; try { if (originalInfo == null) originalInfo = new Properties(); Map normalizedInfo = FBDriverPropertyManager.normalize(url, originalInfo); int qMarkIndex = url.indexOf('?'); if (qMarkIndex != -1) url = url.substring(0, qMarkIndex); JNMXFBManagedConnectionFactory mcf = new JNMXFBManagedConnectionFactory(type); String databaseURL = GDSFactory.getDatabasePath(type, url); mcf.setDatabase(databaseURL); for (Iterator iter = normalizedInfo.entrySet().iterator(); iter.hasNext();) { Map.Entry entry = (Map.Entry) iter.next(); mcf.setNonStandardProperty((String)entry.getKey(), (String)entry.getValue()); } FBConnectionHelper.processTpbMapping(mcf.getGDS(), mcf, originalInfo); mcf = (JNMXFBManagedConnectionFactory)mcf.canonicalize(); FBDataSource dataSource = createDataSource(mcf); return dataSource.getConnection(mcf.getUserName(), mcf.getPassword()); } catch(ResourceException resex) { throw new FBSQLException(resex); } catch(GDSException ex) { throw new FBSQLException(ex); } } private FBDataSource createDataSource(FBManagedConnectionFactory mcf) throws ResourceException { FBDataSource dataSource = null; synchronized (mcfToDataSourceMap) { dataSource = (FBDataSource)mcfToDataSourceMap.get(mcf); if (dataSource == null) { dataSource = (FBDataSource)mcf.createConnectionFactory(); mcfToDataSourceMap.put(mcf, dataSource); } } return dataSource; } } class JNMXFBConnectionRequestInfo extends FBConnectionRequestInfo { public JNMXFBConnectionRequestInfo(DatabaseParameterBuffer dpb) { super(dpb); } @Override public void setPassword(String password) { removeArgument(DatabaseParameterBufferExtension.PASSWORD); if (password != null) { try { addArgument(DatabaseParameterBufferExtension.PASSWORD, password.getBytes("Cp1251")); } catch (UnsupportedEncodingException ex) { Logger.getLogger(FBConnectionRequestInfo.class.getName()).log(Level.SEVERE, null, ex); } } } } class JNMXFBManagedConnectionFactory extends FBManagedConnectionFactory { // private ConnectionManager defaultCm = new FBStandAloneConnectionManager(); JNMXFBManagedConnectionFactory(GDSType type) { super(type); // this.setDefaultConnectionManager(defaultCm); } @Override public FBConnectionRequestInfo getDefaultConnectionRequestInfo() throws ResourceException { try { return new JNMXFBConnectionRequestInfo(getDatabaseParameterBuffer().deepCopy()); } catch(SQLException ex) { throw new FBResourceException(ex); } } } but i`m not find easy way to use myFBResultSet :) The CachedRowSetImpl thing is a known bug in the Sun/Oracle implementation of the CachedRowSet interface, see the releasenotes section 'Compatibility with com.sun.rowset.*' and http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7046875 The person that wrote CachedRowSetImpl was - apparently - also confused by the distinction between columnName and columnLabel.
Furthermore do not dump unrelated things into this ticket, please mail to the Firebird-Java mailinglist to discuss things or create a separate ticket for a feature request. Given the confusion this change is causing, I am considering to introduce a property which will report the columLabel for the name as well (as for example Sybase does, see http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc39001.0605/html/prjdbc/prjdbc14.htm property GET_COLUMN_ LABEL_FOR_NAME )
Scheduled for 2.3 and 2.2.1, no final decision made yet
Added connection property columnLabelForName which will make the ResultSetMetaData.getColumnName return the same value as getColumnLabel (note: this is not JDBC-compliant!)
This property can be added to the connection properties: * Through a properties object (with value true) * In the connection URL (columnLabelForName=true) * On a DataSource by setting setNonStandardProperty("columnLabelForName", "true") or setNonStandardProperty("columnLabelForName=true"); |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
JDBC-162for compliance with the JDBC specification. It is also described in the releasenotes under "Other fixes and changes". For your intended purpose you need to use getColumnLabel as getColumnName is meant to return the original column name (if any or an empty string if the result column did not come from a table column is available).The JDBC specification makes a distinction between label and name. The label is the name specified by the AS clause, and if no AS clause is specified then it use the name of the column. The name of the column is either the original name of the column in its source table (eg which you can retrieve using getTableName), or an empty string if the resultset column does not come from a table. I do admit that this last part requires a bit of reading between the lines as the JDBC spec does not say this explicitly, but returning the value of the AS clause for columnName is not correct.
The way Jaybird handles it now for sqlname == null is also wrong as well; it should just return an empty string there.