Source Code Cross Referenced for VirtualDatabaseDynamicMetaData.java in  » Database-JDBC-Connection-Pool » sequoia-2.10.9 » org » continuent » sequoia » controller » virtualdatabase » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database JDBC Connection Pool » sequoia 2.10.9 » org.continuent.sequoia.controller.virtualdatabase 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * Sequoia: Database clustering technology.
0003:         * Copyright (C) 2002-2004 French National Institute For Research In Computer
0004:         * Science And Control (INRIA).
0005:         * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
0006:         * Contact: sequoia@continuent.org
0007:         * 
0008:         * Licensed under the Apache License, Version 2.0 (the "License");
0009:         * you may not use this file except in compliance with the License.
0010:         * You may obtain a copy of the License at
0011:         * 
0012:         * http://www.apache.org/licenses/LICENSE-2.0
0013:         * 
0014:         * Unless required by applicable law or agreed to in writing, software
0015:         * distributed under the License is distributed on an "AS IS" BASIS,
0016:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:         * See the License for the specific language governing permissions and
0018:         * limitations under the License. 
0019:         *
0020:         * Initial developer(s): Julie Marguerite.
0021:         * Contributor(s): Emmanuel Cecchet, Nicolas Modrzyk, Damian Arregui.
0022:         */package org.continuent.sequoia.controller.virtualdatabase;
0023:
0024:        import java.sql.DatabaseMetaData;
0025:        import java.sql.ResultSet;
0026:        import java.sql.ResultSetMetaData;
0027:        import java.sql.SQLException;
0028:        import java.sql.Types;
0029:        import java.util.ArrayList;
0030:        import java.util.Collection;
0031:        import java.util.Iterator;
0032:        import java.util.Map;
0033:
0034:        import org.continuent.hedera.adapters.MulticastRequestAdapter;
0035:        import org.continuent.hedera.adapters.MulticastResponse;
0036:        import org.continuent.hedera.channel.NotConnectedException;
0037:        import org.continuent.sequoia.common.authentication.AuthenticationManager;
0038:        import org.continuent.sequoia.common.exceptions.ControllerException;
0039:        import org.continuent.sequoia.common.exceptions.NoMoreBackendException;
0040:        import org.continuent.sequoia.common.exceptions.UnreachableBackendException;
0041:        import org.continuent.sequoia.common.log.Trace;
0042:        import org.continuent.sequoia.common.protocol.Field;
0043:        import org.continuent.sequoia.common.sql.schema.DatabaseColumn;
0044:        import org.continuent.sequoia.common.sql.schema.DatabaseProcedure;
0045:        import org.continuent.sequoia.common.sql.schema.DatabaseProcedureParameter;
0046:        import org.continuent.sequoia.common.sql.schema.DatabaseSchema;
0047:        import org.continuent.sequoia.common.sql.schema.DatabaseTable;
0048:        import org.continuent.sequoia.common.users.VirtualDatabaseUser;
0049:        import org.continuent.sequoia.controller.backend.DatabaseBackend;
0050:        import org.continuent.sequoia.controller.backend.result.ControllerResultSet;
0051:        import org.continuent.sequoia.controller.connection.AbstractConnectionManager;
0052:        import org.continuent.sequoia.controller.connection.PooledConnection;
0053:        import org.continuent.sequoia.controller.core.ControllerConstants;
0054:        import org.continuent.sequoia.controller.requestmanager.RAIDbLevels;
0055:        import org.continuent.sequoia.controller.requestmanager.RequestManager;
0056:        import org.continuent.sequoia.controller.requests.AbstractRequest;
0057:        import org.continuent.sequoia.controller.requests.UnknownReadRequest;
0058:        import org.continuent.sequoia.controller.virtualdatabase.protocol.GetMetadata;
0059:
0060:        /**
0061:         * Class that gathers the dynamic metadata for a virtual database, that means
0062:         * all the metadata subject to changes during the lifetime of the application.
0063:         * 
0064:         * @author <a href="mailto:Julie.Marguerite@inria.fr">Julie.Marguerite </a>
0065:         * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
0066:         * @author <a href="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a> *
0067:         * @author <a href="mailto:damian.arregui@continuent.com">Damian Arregui</a>
0068:         */
0069:        public class VirtualDatabaseDynamicMetaData {
0070:
0071:            /** Detect a null valu for int */
0072:            public static final int NULL_VALUE = -999;
0073:
0074:            private VirtualDatabase vdb;
0075:            private String vdbName;
0076:            private RequestManager requestManager;
0077:
0078:            /** Logger instance. */
0079:            private Trace logger = null;
0080:
0081:            /**
0082:             * Reference the database for this metadata. Do not fetch any data at this
0083:             * time
0084:             * 
0085:             * @param database to link this metadata to
0086:             */
0087:            public VirtualDatabaseDynamicMetaData(VirtualDatabase database) {
0088:                this .vdb = database;
0089:                this .vdbName = database.getDatabaseName();
0090:                requestManager = database.getRequestManager();
0091:                if (requestManager == null)
0092:                    throw new RuntimeException(
0093:                            "Null request manager in VirtualDatabaseMetaData");
0094:
0095:                this .logger = Trace
0096:                        .getLogger("org.continuent.sequoia.controller.virtualdatabase.VirtualDatabaseWorkerThread."
0097:                                + vdbName + ".metadata");
0098:            }
0099:
0100:            /**
0101:             * @see java.sql.DatabaseMetaData#getAttributes(java.lang.String,
0102:             *      java.lang.String, java.lang.String, java.lang.String)
0103:             */
0104:            public ControllerResultSet getAttributes(
0105:                    ConnectionContext connContext, String catalog,
0106:                    String schemaPattern, String typeNamePattern,
0107:                    String attributeNamePattern) throws SQLException {
0108:                // This is a JDBC 3.0 feature
0109:                try {
0110:                    int raidbLevel = requestManager.getLoadBalancer()
0111:                            .getRAIDbLevel();
0112:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
0113:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
0114:                        return doGetAttributes(connContext, catalog,
0115:                                schemaPattern, typeNamePattern,
0116:                                attributeNamePattern);
0117:                    }
0118:                } catch (NoMoreBackendException ignore) {
0119:                    // No backend is available, try getting metadata from a remote controller
0120:                    Class[] argTypes = { ConnectionContext.class, String.class,
0121:                            String.class, String.class, String.class };
0122:                    Object[] args = { connContext, catalog, schemaPattern,
0123:                            typeNamePattern, attributeNamePattern };
0124:                    ControllerResultSet crs = getMetaDataFromRemoteController(
0125:                            "doGetAttributes", argTypes, args);
0126:                    if (crs != null)
0127:                        return crs;
0128:                }
0129:
0130:                // Feature not supported in RAIDb-0 and RAIDb-2, return an empty ResultSet
0131:
0132:                ArrayList data = new ArrayList();
0133:                ControllerResultSet rs = new ControllerResultSet(
0134:                        getAttributesFields, data);
0135:                return rs;
0136:            }
0137:
0138:            /**
0139:             * @see #getAttributes(String, String, String, String, String)
0140:             */
0141:            private ControllerResultSet doGetAttributes(
0142:                    ConnectionContext connContext, String catalog,
0143:                    String schemaPattern, String typeNamePattern,
0144:                    String attributeNamePattern) throws SQLException {
0145:                ConnectionAndDatabaseMetaData info = null;
0146:                try {
0147:                    info = getMetaDataFromFirstAvailableBackend(connContext);
0148:                    DatabaseMetaData m = info.getDatabaseMetaData();
0149:                    ResultSet cols = m.getAttributes(catalog, schemaPattern,
0150:                            typeNamePattern, attributeNamePattern);
0151:                    ArrayList data = new ArrayList();
0152:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
0153:                        Object[] row = new Object[21];
0154:                        row[0] = cols.getObject(1); // TYPE_CAT
0155:                        row[1] = cols.getObject(2); // TYPE_SCHEM
0156:                        row[2] = cols.getObject(3); // TYPE_NAME
0157:                        row[3] = cols.getObject(4); // DATA_TYPE
0158:                        row[4] = cols.getObject(5); // ATTR_NAME
0159:                        row[5] = cols.getObject(6); // ATTR_TYPE_NAME
0160:                        row[6] = cols.getObject(7); // ATTR_SIZE
0161:                        row[7] = cols.getObject(8); // DECIMAL_DIGITS
0162:                        row[8] = cols.getObject(9); // NUM_PREC_RADIX
0163:                        row[9] = cols.getObject(10); // NULLABLE
0164:                        row[10] = cols.getObject(11); // REMARKS
0165:                        row[11] = cols.getObject(12); // ATTR_DEF
0166:                        row[12] = cols.getObject(13); // SQL_DATA_TYPE
0167:                        row[13] = cols.getObject(14); // SQL_DATETIME_SUB
0168:                        row[14] = cols.getObject(15); // CHAR_OCTET_LENGTH
0169:                        row[15] = cols.getObject(16); // ORDINAL_POSITION
0170:                        row[16] = cols.getObject(17); // IS_NULLABLE
0171:                        row[17] = cols.getObject(18); // SCOPE_CATALOG
0172:                        row[18] = cols.getObject(19); // SCOPE_SCHEMA
0173:                        row[19] = cols.getObject(20); // SCOPE_TABLE
0174:                        row[20] = cols.getObject(21); // SOURCE_DATA_TYPE
0175:                        data.add(row);
0176:                    }
0177:                    Field[] fields;
0178:                    if (vdb.useStaticResultSetMetaData())
0179:                        fields = getAttributesFields;
0180:                    else { // Fetch metdata as well
0181:                        ResultSetMetaData metaData = cols.getMetaData();
0182:                        if (metaData == null)
0183:                            fields = getAttributesFields;
0184:                        else
0185:                            fields = ControllerConstants.CONTROLLER_FACTORY
0186:                                    .getResultSetMetaDataFactory()
0187:                                    .copyResultSetMetaData(metaData, null);
0188:                    }
0189:                    return new ControllerResultSet(fields, data);
0190:                } catch (SQLException e) {
0191:                    throw e;
0192:                } finally {
0193:                    releaseConnection(info);
0194:                }
0195:            }
0196:
0197:            /**
0198:             * @see java.sql.DatabaseMetaData#getBestRowIdentifier(java.lang.String,
0199:             *      java.lang.String, java.lang.String, int, boolean)
0200:             */
0201:            public ControllerResultSet getBestRowIdentifier(
0202:                    ConnectionContext connContext, String catalog,
0203:                    String schema, String table, int scope, boolean nullable)
0204:                    throws SQLException {
0205:                try {
0206:                    int raidbLevel = requestManager.getLoadBalancer()
0207:                            .getRAIDbLevel();
0208:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
0209:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
0210:                        return doGetBestRowIdentifier(connContext, catalog,
0211:                                schema, table, scope, nullable);
0212:                    }
0213:                } catch (NoMoreBackendException ignore) {
0214:                    // No backend is available, try getting metadata from a remote controller
0215:                    Class[] argTypes = { ConnectionContext.class, String.class,
0216:                            String.class, String.class, int.class,
0217:                            boolean.class };
0218:                    Object[] args = { connContext, catalog, schema, table,
0219:                            new Integer(scope), Boolean.valueOf(nullable) };
0220:                    ControllerResultSet crs = getMetaDataFromRemoteController(
0221:                            "doGetBestRowIdentifier", argTypes, args);
0222:                    if (crs != null)
0223:                        return crs;
0224:                }
0225:
0226:                // Feature not supported in RAIDb-0 and RAIDb-2, return an empty ResultSet
0227:
0228:                ArrayList data = new ArrayList();
0229:                ControllerResultSet rs = new ControllerResultSet(
0230:                        getBestRowIdentifierAndVersionColumnsFields, data);
0231:                return rs;
0232:            }
0233:
0234:            /**
0235:             * @see #getBestRowIdentifier(ConnectionContext, String, String, String, int,
0236:             *      boolean)
0237:             */
0238:            public ControllerResultSet doGetBestRowIdentifier(
0239:                    ConnectionContext connContext, String catalog,
0240:                    String schema, String table, int scope, boolean nullable)
0241:                    throws SQLException {
0242:                ConnectionAndDatabaseMetaData info = null;
0243:                try {
0244:                    info = getMetaDataFromFirstAvailableBackend(connContext);
0245:                    DatabaseMetaData m = info.getDatabaseMetaData();
0246:                    ResultSet cols = m.getBestRowIdentifier(catalog, schema,
0247:                            table, scope, nullable);
0248:                    ArrayList data = new ArrayList();
0249:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
0250:                        Object[] row = new Object[8];
0251:                        row[0] = cols.getObject(1); // SCOPE
0252:                        row[1] = cols.getObject(2); // COLUMN_NAME
0253:                        row[2] = cols.getObject(3); // DATA_TYPE
0254:                        row[3] = cols.getObject(4); // TYPE_NAME
0255:                        row[4] = cols.getObject(5); // COLUMN_SIZE
0256:                        row[5] = cols.getObject(6); // BUFFER_LENGTH
0257:                        row[6] = cols.getObject(7); // DECIMAL_DIGITS
0258:                        row[7] = cols.getObject(8); // PSEUDO_COLUMN
0259:                        data.add(row);
0260:                    }
0261:                    Field[] fields;
0262:                    if (vdb.useStaticResultSetMetaData())
0263:                        fields = getBestRowIdentifierAndVersionColumnsFields;
0264:                    else { // Fetch metdata as well
0265:                        ResultSetMetaData metaData = cols.getMetaData();
0266:                        if (metaData == null)
0267:                            fields = getBestRowIdentifierAndVersionColumnsFields;
0268:                        else
0269:                            fields = ControllerConstants.CONTROLLER_FACTORY
0270:                                    .getResultSetMetaDataFactory()
0271:                                    .copyResultSetMetaData(metaData, null);
0272:                    }
0273:                    return new ControllerResultSet(fields, data);
0274:                } catch (SQLException e) {
0275:                    throw e;
0276:                } finally {
0277:                    releaseConnection(info);
0278:                }
0279:            }
0280:
0281:            /**
0282:             * Build a list of Catalogs from a givem list of virtual database names
0283:             * 
0284:             * @param list of virtual database from the controller
0285:             * @return <code>ResultSet</code> with list of catalogs
0286:             */
0287:            public ControllerResultSet getCatalogs(ArrayList list) {
0288:                int size = list.size();
0289:                ArrayList data = new ArrayList(size);
0290:                for (int i = 0; i < size; i++) {
0291:                    Object[] row = new Object[1];
0292:                    row[0] = list.get(i);
0293:                    data.add(row);
0294:                }
0295:                ControllerResultSet rs = new ControllerResultSet(
0296:                        getCatalogsFields, data);
0297:                return rs;
0298:            }
0299:
0300:            /**
0301:             * @see java.sql.DatabaseMetaData#getColumnPrivileges(java.lang.String,
0302:             *      java.lang.String, java.lang.String, java.lang.String)
0303:             */
0304:            public ControllerResultSet getColumnPrivileges(
0305:                    ConnectionContext connContext, String catalog,
0306:                    String schema, String table, String columnNamePattern)
0307:                    throws SQLException {
0308:                try {
0309:                    int raidbLevel = requestManager.getLoadBalancer()
0310:                            .getRAIDbLevel();
0311:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
0312:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
0313:                        return doGetColumnPrivileges(connContext, catalog,
0314:                                schema, table, columnNamePattern);
0315:                    }
0316:                } catch (NoMoreBackendException ignore) {
0317:                    // No backend is available, try getting metadata from a remote controller
0318:                    Class[] argTypes = { ConnectionContext.class, String.class,
0319:                            String.class, String.class, String.class };
0320:                    Object[] args = { connContext, catalog, schema, table,
0321:                            columnNamePattern };
0322:                    ControllerResultSet crs = getMetaDataFromRemoteController(
0323:                            "doGetColumnPrivileges", argTypes, args);
0324:                    if (crs != null)
0325:                        return crs;
0326:                }
0327:
0328:                AuthenticationManager manager = requestManager
0329:                        .getVirtualDatabase().getAuthenticationManager();
0330:
0331:                DatabaseSchema dbs = requestManager.getDatabaseSchema();
0332:                if (dbs == null)
0333:                    throw new SQLException(
0334:                            "Unable to fetch the virtual database schema");
0335:
0336:                if (columnNamePattern == null)
0337:                    // if null is passed then select all tables
0338:                    columnNamePattern = "%";
0339:
0340:                DatabaseTable dbTable = dbs.getTable(table);
0341:                if (dbTable == null)
0342:                    throw new SQLException("Unable to find table " + table);
0343:
0344:                ArrayList columns = dbTable.getColumns();
0345:                int size = columns.size();
0346:                ArrayList data = new ArrayList();
0347:
0348:                ArrayList virtualLogins = manager.getVirtualLogins();
0349:                int vsize = virtualLogins.size();
0350:                VirtualDatabaseUser vu;
0351:
0352:                for (int i = 0; i < size; i++) {
0353:                    DatabaseColumn c = (DatabaseColumn) columns.get(i);
0354:                    if (columnNamePattern.equals("%")
0355:                            || columnNamePattern.equals(c.getName())) {
0356:                        for (int j = 0; j < vsize; j++) {
0357:                            vu = (VirtualDatabaseUser) virtualLogins.get(0);
0358:
0359:                            if (logger.isDebugEnabled())
0360:                                logger.debug("Found privilege for user:"
0361:                                        + vu.getLogin() + " on column:"
0362:                                        + c.getName());
0363:                            Object[] row = new Object[8];
0364:                            row[0] = vdbName; // table cat
0365:                            row[1] = null; // table schema
0366:                            row[2] = table; // table name
0367:                            row[3] = c.getName(); // column name
0368:                            row[4] = null; // grantor
0369:                            row[5] = vu.getLogin(); // grantee
0370:                            row[6] = "UPDATE"; // privilege
0371:                            row[7] = "NO"; // IS_GRANTABLE
0372:                            data.add(row);
0373:                        }
0374:                    }
0375:                }
0376:
0377:                ControllerResultSet rs = new ControllerResultSet(
0378:                        getColumnPrivilegesFields, data);
0379:                return rs;
0380:            }
0381:
0382:            /**
0383:             * @see #getColumnPrivileges(ConnectionContext, String, String, String,
0384:             *      String)
0385:             */
0386:            public ControllerResultSet doGetColumnPrivileges(
0387:                    ConnectionContext connContext, String catalog,
0388:                    String schema, String table, String columnNamePattern)
0389:                    throws SQLException {
0390:                ConnectionAndDatabaseMetaData info = null;
0391:                try {
0392:                    info = getMetaDataFromFirstAvailableBackend(connContext);
0393:                    DatabaseMetaData m = info.getDatabaseMetaData();
0394:                    ResultSet cols = m.getColumnPrivileges(catalog, schema,
0395:                            table, columnNamePattern);
0396:                    ArrayList data = new ArrayList();
0397:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
0398:                        Object[] row = new Object[8];
0399:                        row[0] = cols.getObject(1); // TABLE_CAT
0400:                        row[1] = cols.getObject(2); // TABLE_SCHEM
0401:                        row[2] = cols.getObject(3); // TABLE_NAME
0402:                        row[3] = cols.getObject(4); // COLUMN_NAME
0403:                        row[4] = cols.getObject(5); // GRANTOR
0404:                        row[5] = cols.getObject(6); // GRANTEE
0405:                        row[6] = cols.getObject(7); // PRIVILEGE
0406:                        row[7] = cols.getObject(8); // IS_GRANTABLE
0407:                        data.add(row);
0408:                    }
0409:                    return new ControllerResultSet(getColumnPrivilegesFields,
0410:                            data);
0411:                } catch (SQLException e) {
0412:                    throw e;
0413:                } finally {
0414:                    releaseConnection(info);
0415:                }
0416:            }
0417:
0418:            /**
0419:             * @see java.sql.DatabaseMetaData#getColumns(java.lang.String,
0420:             *      java.lang.String, java.lang.String, java.lang.String)
0421:             */
0422:            public ControllerResultSet getColumns(
0423:                    ConnectionContext connContext, String catalog,
0424:                    String schemaPattern, String tableNamePattern,
0425:                    String columnNamePattern) throws SQLException {
0426:                if (logger.isDebugEnabled())
0427:                    logger.debug("Getting columns for " + vdbName);
0428:
0429:                try {
0430:                    int raidbLevel = requestManager.getLoadBalancer()
0431:                            .getRAIDbLevel();
0432:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
0433:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
0434:                        return doGetColumns(connContext, catalog,
0435:                                schemaPattern, tableNamePattern,
0436:                                columnNamePattern);
0437:                    }
0438:                } catch (NoMoreBackendException ignore) {
0439:                    // No backend is available, try getting metadata from a remote controller
0440:                    Class[] argTypes = { ConnectionContext.class, String.class,
0441:                            String.class, String.class, String.class };
0442:                    Object[] args = { connContext, catalog, schemaPattern,
0443:                            tableNamePattern, columnNamePattern };
0444:                    ControllerResultSet crs = getMetaDataFromRemoteController(
0445:                            "doGetColumns", argTypes, args);
0446:                    if (crs != null)
0447:                        return crs;
0448:                }
0449:
0450:                // Ok from this point on, this is RAIDb-0 or RAIDb-2 and we have to build
0451:                // the results ourselves.
0452:                DatabaseSchema dbs = requestManager.getDatabaseSchema();
0453:                if (dbs == null)
0454:                    throw new SQLException(
0455:                            "Unable to fetch the virtual database schema");
0456:
0457:                if (tableNamePattern == null)
0458:                    tableNamePattern = "%"; // if null is passed then select
0459:                // all tables
0460:
0461:                if (columnNamePattern == null)
0462:                    columnNamePattern = "%"; // if null is passed then
0463:
0464:                // Build the ResultSet
0465:                Collection tables = dbs.getTables().values();
0466:                ArrayList data = new ArrayList(tables.size());
0467:
0468:                for (Iterator iter = tables.iterator(); iter.hasNext();) {
0469:                    DatabaseTable t = (DatabaseTable) iter.next();
0470:
0471:                    if (tableNamePattern.equals("%")
0472:                            || tableNamePattern.equals(t.getName())) {
0473:                        if (logger.isDebugEnabled())
0474:                            logger.debug("Found table " + t.getName());
0475:                        ArrayList columns = t.getColumns();
0476:                        for (int j = 0; j < columns.size(); j++) {
0477:                            DatabaseColumn c = (DatabaseColumn) columns.get(j);
0478:                            if (columnNamePattern.equals("%")
0479:                                    || columnNamePattern.equals(c.getName())) {
0480:                                if (logger.isDebugEnabled())
0481:                                    logger.debug("Found column " + c.getName());
0482:                                Object[] row = new Object[22];
0483:                                row[0] = vdbName; // TABLE_CAT
0484:                                row[1] = null; // TABLE_SCHEM
0485:                                row[2] = t.getName(); // TABLE_NAME
0486:                                row[3] = c.getName(); // COLUMN_NAME
0487:                                row[4] = new Integer(c.getType()); // DATA_TYPE
0488:                                row[5] = null; // TYPE_NAME
0489:                                row[6] = null; // COLUMN_SIZE
0490:                                row[7] = null; // BUFFER_LENGTH
0491:                                row[8] = null; // DECIMAL_DIGITS
0492:                                row[9] = null; // NUM_PREC_RADIX
0493:                                row[10] = null; // NULLABLE
0494:                                row[11] = null; // REMARKS
0495:                                row[12] = null; // COLUMN_DEF
0496:                                row[13] = null; // SQL_DATA_TYPE
0497:                                row[14] = null; // SQL_DATETIME_SUB
0498:                                row[15] = null; // CHAR_OCTET_LENGTH
0499:                                row[16] = null; // ORDINAL_POSITION
0500:                                row[17] = ""; // IS_NULLABLE
0501:                                row[18] = null; // SCOPE_CATALOG
0502:                                row[19] = null;// SCOPE_SCHEMA
0503:                                row[20] = null;// SCOPE_TABLE
0504:                                row[21] = null; // SOURCE_DATA_TYPE
0505:                                data.add(row);
0506:                            }
0507:                        }
0508:                    }
0509:                }
0510:                ControllerResultSet rs = new ControllerResultSet(
0511:                        getColumnsFields, data);
0512:                return rs;
0513:            }
0514:
0515:            /**
0516:             * @see #getColumns(ConnectionContext, String, String, String, String)
0517:             */
0518:            public ControllerResultSet doGetColumns(
0519:                    ConnectionContext connContext, String catalog,
0520:                    String schemaPattern, String tableNamePattern,
0521:                    String columnNamePattern) throws SQLException {
0522:                ConnectionAndDatabaseMetaData info = null;
0523:                try {
0524:                    info = getMetaDataFromFirstAvailableBackend(connContext);
0525:                    DatabaseMetaData m = info.getDatabaseMetaData();
0526:                    ResultSet cols = m.getColumns(catalog, schemaPattern,
0527:                            tableNamePattern, columnNamePattern);
0528:                    ArrayList data = new ArrayList();
0529:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
0530:                        Object[] row = new Object[22];
0531:                        row[0] = cols.getObject(1); // TABLE_CAT
0532:                        row[1] = cols.getObject(2); // TABLE_SCHEM
0533:                        row[2] = cols.getObject(3); // TABLE_NAME
0534:                        row[3] = cols.getObject(4); // COLUMN_NAME
0535:                        row[4] = cols.getObject(5); // DATA_TYPE
0536:                        row[5] = cols.getObject(6); // TYPE_NAME
0537:                        row[6] = cols.getObject(7); // COLUMN_SIZE
0538:                        row[7] = cols.getObject(8); // BUFFER_LENGTH
0539:                        row[8] = cols.getObject(9); // DECIMAL_DIGITS
0540:                        row[9] = cols.getObject(10); // NUM_PREC_RADIX
0541:                        row[10] = cols.getObject(11); // NULLABLE
0542:                        row[11] = cols.getObject(12); // REMARKS
0543:                        row[12] = cols.getObject(13); // COLUMN_DEF
0544:                        row[13] = cols.getObject(14); // SQL_DATA_TYPE
0545:                        row[14] = cols.getObject(15); // SQL_DATETIME_SUB
0546:                        row[15] = cols.getObject(16); // CHAR_OCTET_LENGTH
0547:                        row[16] = cols.getObject(17); // ORDINAL_POSITION
0548:                        row[17] = cols.getObject(18); // IS_NULLABLE
0549:                        // JDBC 3.0 starts here
0550:                        try {
0551:                            row[18] = cols.getObject(19); // SCOPE_CATALOG
0552:                            row[19] = cols.getObject(20); // SCOPE_SCHEMA
0553:                            row[20] = cols.getObject(21); // SCOPE_TABLE
0554:                            row[21] = cols.getObject(22); // SOURCE_DATA_TYPE
0555:                        } catch (Exception e) { // Driver does not support JDBC 3.0 cut here
0556:                            row[18] = null; // SCOPE_CATALOG
0557:                            row[19] = null;// SCOPE_SCHEMA
0558:                            row[20] = null;// SCOPE_TABLE
0559:                            row[21] = null; // SOURCE_DATA_TYPE
0560:                        }
0561:                        data.add(row);
0562:                    }
0563:                    Field[] fields;
0564:                    if (vdb.useStaticResultSetMetaData())
0565:                        fields = getColumnsFields;
0566:                    else { // Fetch metdata as well
0567:                        ResultSetMetaData metaData = cols.getMetaData();
0568:                        if (metaData == null)
0569:                            fields = getColumnsFields;
0570:                        else
0571:                            fields = ControllerConstants.CONTROLLER_FACTORY
0572:                                    .getResultSetMetaDataFactory()
0573:                                    .copyResultSetMetaData(metaData, null);
0574:                    }
0575:                    return new ControllerResultSet(fields, data);
0576:                } catch (SQLException e) {
0577:                    throw e;
0578:                } finally {
0579:                    releaseConnection(info);
0580:                }
0581:            }
0582:
0583:            /**
0584:             * @see java.sql.DatabaseMetaData#getCrossReference(java.lang.String,
0585:             *      java.lang.String, java.lang.String, java.lang.String,
0586:             *      java.lang.String, java.lang.String)
0587:             */
0588:            public ControllerResultSet getCrossReference(
0589:                    ConnectionContext connContext, String primaryCatalog,
0590:                    String primarySchema, String primaryTable,
0591:                    String foreignCatalog, String foreignSchema,
0592:                    String foreignTable) throws SQLException {
0593:                try {
0594:                    int raidbLevel = requestManager.getLoadBalancer()
0595:                            .getRAIDbLevel();
0596:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
0597:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
0598:                        return doGetCrossReference(connContext, primaryCatalog,
0599:                                primarySchema, primaryTable, foreignCatalog,
0600:                                foreignSchema, foreignTable);
0601:                    }
0602:                } catch (NoMoreBackendException ignore) {
0603:                    // No backend is available, try getting metadata from a remote controller
0604:                    Class[] argTypes = { ConnectionContext.class, String.class,
0605:                            String.class, String.class, String.class,
0606:                            String.class, String.class };
0607:                    Object[] args = { connContext, primaryCatalog,
0608:                            primarySchema, primaryTable, foreignCatalog,
0609:                            foreignSchema, foreignTable };
0610:                    ControllerResultSet crs = getMetaDataFromRemoteController(
0611:                            "doGetCrossReference", argTypes, args);
0612:                    if (crs != null)
0613:                        return crs;
0614:                }
0615:
0616:                // Feature not supported in RAIDb-0 and RAIDb-2, return an empty ResultSet
0617:
0618:                ArrayList data = new ArrayList();
0619:                ControllerResultSet rs = new ControllerResultSet(
0620:                        getCrossReferenceOrImportExportedKeysFields, data);
0621:                return rs;
0622:            }
0623:
0624:            /**
0625:             * @see #getCrossReference(ConnectionContext, String, String, String, String,
0626:             *      String, String)
0627:             */
0628:            public ControllerResultSet doGetCrossReference(
0629:                    ConnectionContext connContext, String primaryCatalog,
0630:                    String primarySchema, String primaryTable,
0631:                    String foreignCatalog, String foreignSchema,
0632:                    String foreignTable) throws SQLException {
0633:                ConnectionAndDatabaseMetaData info = null;
0634:                try {
0635:                    info = getMetaDataFromFirstAvailableBackend(connContext);
0636:                    DatabaseMetaData m = info.getDatabaseMetaData();
0637:                    ResultSet cols = m.getCrossReference(primaryCatalog,
0638:                            primarySchema, primaryTable, foreignCatalog,
0639:                            foreignSchema, foreignTable);
0640:                    ArrayList data = new ArrayList();
0641:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
0642:                        Object[] row = new Object[14];
0643:                        row[0] = cols.getObject(1); // PKTABLE_CAT
0644:                        row[1] = cols.getObject(2); // PKTABLE_SCHEM
0645:                        row[2] = cols.getObject(3); // PKTABLE_NAME
0646:                        row[3] = cols.getObject(4); // PKCOLUMN_NAME
0647:                        row[4] = cols.getObject(5); // FKTABLE_CAT
0648:                        row[5] = cols.getObject(6); // FKTABLE_SCHEM
0649:                        row[6] = cols.getObject(7); // FKTABLE_NAME
0650:                        row[7] = cols.getObject(8); // FKCOLUMN_NAME
0651:                        row[8] = cols.getObject(9); // KEY_SEQ
0652:                        row[9] = cols.getObject(10); // UPDATE_RULE
0653:                        row[10] = cols.getObject(11); // DELETE_RULE
0654:                        row[11] = cols.getObject(12); // FK_NAME
0655:                        row[12] = cols.getObject(13); // PK_NAME
0656:                        row[13] = cols.getObject(14); // DEFERRABILITY
0657:                        data.add(row);
0658:                    }
0659:                    Field[] fields;
0660:                    if (vdb.useStaticResultSetMetaData())
0661:                        fields = getCrossReferenceOrImportExportedKeysFields;
0662:                    else { // Fetch metdata as well
0663:                        ResultSetMetaData metaData = cols.getMetaData();
0664:                        if (metaData == null)
0665:                            fields = getCrossReferenceOrImportExportedKeysFields;
0666:                        else
0667:                            fields = ControllerConstants.CONTROLLER_FACTORY
0668:                                    .getResultSetMetaDataFactory()
0669:                                    .copyResultSetMetaData(metaData, null);
0670:                    }
0671:                    return new ControllerResultSet(fields, data);
0672:                } catch (SQLException e) {
0673:                    throw e;
0674:                } finally {
0675:                    releaseConnection(info);
0676:                }
0677:            }
0678:
0679:            /**
0680:             * @see java.sql.DatabaseMetaData#getExportedKeys(java.lang.String,
0681:             *      java.lang.String, java.lang.String)
0682:             */
0683:            public ControllerResultSet getExportedKeys(
0684:                    ConnectionContext connContext, String catalog,
0685:                    String schema, String table) throws SQLException {
0686:                try {
0687:                    int raidbLevel = requestManager.getLoadBalancer()
0688:                            .getRAIDbLevel();
0689:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
0690:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
0691:                        return doGetExportedKeys(connContext, catalog, schema,
0692:                                table);
0693:                    }
0694:                } catch (NoMoreBackendException ignore) {
0695:                    // No backend is available, try getting metadata from a remote controller
0696:                    Class[] argTypes = { ConnectionContext.class, String.class,
0697:                            String.class, String.class };
0698:                    Object[] args = { connContext, catalog, schema, table };
0699:                    ControllerResultSet crs = getMetaDataFromRemoteController(
0700:                            "doGetExportedKeys", argTypes, args);
0701:                    if (crs != null)
0702:                        return crs;
0703:                }
0704:
0705:                // Feature not supported in RAIDb-0 and RAIDb-2, return an empty ResultSet
0706:
0707:                ArrayList data = new ArrayList();
0708:                ControllerResultSet rs = new ControllerResultSet(
0709:                        getCrossReferenceOrImportExportedKeysFields, data);
0710:                return rs;
0711:            }
0712:
0713:            /**
0714:             * @see #getExportedKeys(ConnectionContext, String, String, String)
0715:             */
0716:            public ControllerResultSet doGetExportedKeys(
0717:                    ConnectionContext connContext, String catalog,
0718:                    String schema, String table) throws SQLException {
0719:                ConnectionAndDatabaseMetaData info = null;
0720:                try {
0721:                    info = getMetaDataFromFirstAvailableBackend(connContext);
0722:                    DatabaseMetaData m = info.getDatabaseMetaData();
0723:                    ResultSet cols = m.getExportedKeys(catalog, schema, table);
0724:                    ArrayList data = new ArrayList();
0725:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
0726:                        Object[] row = new Object[14];
0727:                        row[0] = cols.getObject(1); // PKTABLE_CAT
0728:                        row[1] = cols.getObject(2); // PKTABLE_SCHEM
0729:                        row[2] = cols.getObject(3); // PKTABLE_NAME
0730:                        row[3] = cols.getObject(4); // PKCOLUMN_NAME
0731:                        row[4] = cols.getObject(5); // FKTABLE_CAT
0732:                        row[5] = cols.getObject(6); // FKTABLE_SCHEM
0733:                        row[6] = cols.getObject(7); // FKTABLE_NAME
0734:                        row[7] = cols.getObject(8); // FKCOLUMN_NAME
0735:                        row[8] = cols.getObject(9); // KEY_SEQ
0736:                        row[9] = cols.getObject(10); // UPDATE_RULE
0737:                        row[10] = cols.getObject(11); // DELETE_RULE
0738:                        row[11] = cols.getObject(12); // FK_NAME
0739:                        row[12] = cols.getObject(13); // PK_NAME
0740:                        row[13] = cols.getObject(14); // DEFERRABILITY
0741:                        data.add(row);
0742:                    }
0743:                    Field[] fields;
0744:                    if (vdb.useStaticResultSetMetaData())
0745:                        fields = getCrossReferenceOrImportExportedKeysFields;
0746:                    else { // Fetch metdata as well
0747:                        ResultSetMetaData metaData = cols.getMetaData();
0748:                        if (metaData == null)
0749:                            fields = getCrossReferenceOrImportExportedKeysFields;
0750:                        else
0751:                            fields = ControllerConstants.CONTROLLER_FACTORY
0752:                                    .getResultSetMetaDataFactory()
0753:                                    .copyResultSetMetaData(metaData, null);
0754:                    }
0755:                    return new ControllerResultSet(fields, data);
0756:                } catch (SQLException e) {
0757:                    throw e;
0758:                } finally {
0759:                    releaseConnection(info);
0760:                }
0761:            }
0762:
0763:            /**
0764:             * @see java.sql.DatabaseMetaData#getImportedKeys(java.lang.String,
0765:             *      java.lang.String, java.lang.String)
0766:             */
0767:            public ControllerResultSet getImportedKeys(
0768:                    ConnectionContext connContext, String catalog,
0769:                    String schema, String table) throws SQLException {
0770:                try {
0771:                    int raidbLevel = requestManager.getLoadBalancer()
0772:                            .getRAIDbLevel();
0773:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
0774:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
0775:                        return doGetImportedKeys(connContext, catalog, schema,
0776:                                table);
0777:                    }
0778:                } catch (NoMoreBackendException ignore) {
0779:                    // No backend is available, try getting metadata from a remote controller
0780:                    Class[] argTypes = { ConnectionContext.class, String.class,
0781:                            String.class, String.class };
0782:                    Object[] args = { connContext, catalog, schema, table };
0783:                    ControllerResultSet crs = getMetaDataFromRemoteController(
0784:                            "doGetImportedKeys", argTypes, args);
0785:                    if (crs != null)
0786:                        return crs;
0787:                }
0788:
0789:                // Feature not supported in RAIDb-0 and RAIDb-2, return an empty ResultSet
0790:
0791:                ArrayList data = new ArrayList();
0792:                ControllerResultSet rs = new ControllerResultSet(
0793:                        getCrossReferenceOrImportExportedKeysFields, data);
0794:                return rs;
0795:            }
0796:
0797:            /**
0798:             * @see #doGetImportedKeys(ConnectionContext, String, String, String)
0799:             */
0800:            public ControllerResultSet doGetImportedKeys(
0801:                    ConnectionContext connContext, String catalog,
0802:                    String schema, String table) throws SQLException {
0803:                ConnectionAndDatabaseMetaData info = null;
0804:                try {
0805:                    info = getMetaDataFromFirstAvailableBackend(connContext);
0806:                    DatabaseMetaData m = info.getDatabaseMetaData();
0807:                    ResultSet cols = m.getImportedKeys(catalog, schema, table);
0808:                    ArrayList data = new ArrayList();
0809:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
0810:                        Object[] row = new Object[14];
0811:                        row[0] = cols.getObject(1); // PKTABLE_CAT
0812:                        row[1] = cols.getObject(2); // PKTABLE_SCHEM
0813:                        row[2] = cols.getObject(3); // PKTABLE_NAME
0814:                        row[3] = cols.getObject(4); // PKCOLUMN_NAME
0815:                        row[4] = cols.getObject(5); // FKTABLE_CAT
0816:                        row[5] = cols.getObject(6); // FKTABLE_SCHEM
0817:                        row[6] = cols.getObject(7); // FKTABLE_NAME
0818:                        row[7] = cols.getObject(8); // FKCOLUMN_NAME
0819:                        row[8] = cols.getObject(9); // KEY_SEQ
0820:                        row[9] = cols.getObject(10); // UPDATE_RULE
0821:                        row[10] = cols.getObject(11); // DELETE_RULE
0822:                        row[11] = cols.getObject(12); // FK_NAME
0823:                        row[12] = cols.getObject(13); // PK_NAME
0824:                        row[13] = cols.getObject(14); // DEFERRABILITY
0825:                        data.add(row);
0826:                    }
0827:                    Field[] fields;
0828:                    if (vdb.useStaticResultSetMetaData())
0829:                        fields = getCrossReferenceOrImportExportedKeysFields;
0830:                    else { // Fetch metdata as well
0831:                        ResultSetMetaData metaData = cols.getMetaData();
0832:                        if (metaData == null)
0833:                            fields = getCrossReferenceOrImportExportedKeysFields;
0834:                        else
0835:                            fields = ControllerConstants.CONTROLLER_FACTORY
0836:                                    .getResultSetMetaDataFactory()
0837:                                    .copyResultSetMetaData(metaData, null);
0838:                    }
0839:                    return new ControllerResultSet(fields, data);
0840:                } catch (SQLException e) {
0841:                    throw e;
0842:                } finally {
0843:                    releaseConnection(info);
0844:                }
0845:            }
0846:
0847:            /**
0848:             * @see java.sql.DatabaseMetaData#getIndexInfo(java.lang.String,
0849:             *      java.lang.String, java.lang.String, boolean, boolean)
0850:             */
0851:            public ControllerResultSet getIndexInfo(
0852:                    ConnectionContext connContext, String catalog,
0853:                    String schema, String table, boolean unique,
0854:                    boolean approximate) throws SQLException {
0855:                try {
0856:                    int raidbLevel = requestManager.getLoadBalancer()
0857:                            .getRAIDbLevel();
0858:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
0859:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
0860:                        return doGetIndexInfo(connContext, catalog, schema,
0861:                                table, unique, approximate);
0862:                    }
0863:                } catch (NoMoreBackendException ignore) {
0864:                    // No backend is available, try getting metadata from a remote controller
0865:                    Class[] argTypes = { ConnectionContext.class, String.class,
0866:                            String.class, String.class, boolean.class,
0867:                            boolean.class };
0868:                    Object[] args = { connContext, catalog, schema, table,
0869:                            Boolean.valueOf(unique),
0870:                            Boolean.valueOf(approximate) };
0871:                    ControllerResultSet crs = getMetaDataFromRemoteController(
0872:                            "doGetIndexInfo", argTypes, args);
0873:                    if (crs != null)
0874:                        return crs;
0875:                }
0876:
0877:                // Feature not supported in RAIDb-0 and RAIDb-2, return an empty ResultSet
0878:                ArrayList data = new ArrayList();
0879:                ControllerResultSet rs = new ControllerResultSet(
0880:                        getIndexInfoFields, data);
0881:                return rs;
0882:            }
0883:
0884:            /**
0885:             * @see #getIndexInfo(ConnectionContext, String, String, String, boolean,
0886:             *      boolean)
0887:             */
0888:            public ControllerResultSet doGetIndexInfo(
0889:                    ConnectionContext connContext, String catalog,
0890:                    String schema, String table, boolean unique,
0891:                    boolean approximate) throws SQLException {
0892:                ConnectionAndDatabaseMetaData info = null;
0893:                try {
0894:                    info = getMetaDataFromFirstAvailableBackend(connContext);
0895:                    DatabaseMetaData m = info.getDatabaseMetaData();
0896:                    ResultSet cols = m.getIndexInfo(catalog, schema, table,
0897:                            unique, approximate);
0898:                    ArrayList data = new ArrayList();
0899:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
0900:                        Object[] row = new Object[13];
0901:                        row[0] = cols.getObject(1); // TABLE_CAT
0902:                        row[1] = cols.getObject(2); // TABLE_SCHEM
0903:                        row[2] = cols.getObject(3); // TABLE_NAME
0904:                        row[3] = cols.getObject(4); // NON_UNIQUE
0905:                        row[4] = cols.getObject(5); // INDEX_QUALIFIER
0906:                        row[5] = cols.getObject(6); // INDEX_NAME
0907:                        row[6] = cols.getObject(7); // TYPE
0908:                        row[7] = cols.getObject(8); // ORDINAL_POSITION
0909:                        row[8] = cols.getObject(9); // COLUMN_NAME
0910:                        row[9] = cols.getObject(10); // ASC_OR_DESC
0911:                        row[10] = cols.getObject(11); // CARDINALITY
0912:                        row[11] = cols.getObject(12); // PAGES
0913:                        row[12] = cols.getObject(13); // FILTER_CONDITION
0914:                        data.add(row);
0915:                    }
0916:                    Field[] fields;
0917:                    if (vdb.useStaticResultSetMetaData())
0918:                        fields = getIndexInfoFields;
0919:                    else { // Fetch metdata as well
0920:                        ResultSetMetaData metaData = cols.getMetaData();
0921:                        if (metaData == null)
0922:                            fields = getIndexInfoFields;
0923:                        else
0924:                            fields = ControllerConstants.CONTROLLER_FACTORY
0925:                                    .getResultSetMetaDataFactory()
0926:                                    .copyResultSetMetaData(metaData, null);
0927:                    }
0928:                    return new ControllerResultSet(fields, data);
0929:                } catch (SQLException e) {
0930:                    throw e;
0931:                } finally {
0932:                    releaseConnection(info);
0933:                }
0934:            }
0935:
0936:            /**
0937:             * Gets a description of a table's primary key columns for the given login.
0938:             * Primary keys are ordered by COLUMN_NAME.
0939:             * 
0940:             * @see java.sql.DatabaseMetaData#getPrimaryKeys(java.lang.String,
0941:             *      java.lang.String, java.lang.String)
0942:             */
0943:            public ControllerResultSet getPrimaryKeys(
0944:                    ConnectionContext connContext, String catalog,
0945:                    String schema, String table) throws SQLException {
0946:                if (logger.isDebugEnabled())
0947:                    logger.debug("Getting getPrimaryKeys for " + vdbName);
0948:
0949:                try {
0950:                    int raidbLevel = requestManager.getLoadBalancer()
0951:                            .getRAIDbLevel();
0952:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
0953:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
0954:                        return doGetPrimaryKeys(connContext, catalog, schema,
0955:                                table);
0956:                    }
0957:                } catch (NoMoreBackendException ignore) {
0958:                    // No backend is available, try getting metadata from a remote controller
0959:                    Class[] argTypes = { ConnectionContext.class, String.class,
0960:                            String.class, String.class };
0961:                    Object[] args = { connContext, catalog, schema, table };
0962:                    ControllerResultSet crs = getMetaDataFromRemoteController(
0963:                            "doGetPrimaryKeys", argTypes, args);
0964:                    if (crs != null)
0965:                        return crs;
0966:                }
0967:
0968:                // Ok from this point on, this is RAIDb-0 or RAIDb-2 and we have to build
0969:                // the results ourselves.
0970:                DatabaseSchema dbs = requestManager.getDatabaseSchema();
0971:                if (dbs == null)
0972:                    throw new SQLException(
0973:                            "Unable to fetch the virtual database schema");
0974:
0975:                if (table == null)
0976:                    table = "%"; // if null is passed then
0977:                // select all tables
0978:
0979:                // Build the ResultSet
0980:                Collection tables = dbs.getTables().values();
0981:                ArrayList data = new ArrayList(tables.size());
0982:
0983:                for (Iterator iter = tables.iterator(); iter.hasNext();) {
0984:                    DatabaseTable t = (DatabaseTable) iter.next();
0985:                    if (table.equals("%") || table.equals(t.getName())) {
0986:                        ArrayList columns = t.getColumns();
0987:                        for (int j = 0; j < columns.size(); j++) {
0988:                            DatabaseColumn c = (DatabaseColumn) columns.get(j);
0989:                            if (c.isUnique()) {
0990:                                if (logger.isDebugEnabled())
0991:                                    logger.debug("Found primary key"
0992:                                            + c.getName());
0993:                                Object[] row = new Object[6];
0994:                                row[0] = vdbName; // TABLE_CAT
0995:                                row[1] = null; // TABLE_SCHEM
0996:                                row[2] = t.getName(); // TABLE_NAME
0997:                                row[3] = c.getName(); // COLUMN_NAME
0998:                                row[4] = new Integer(c.getType()); // KEY_SEQ
0999:                                row[5] = c.getName(); // PK_NAME
1000:                                data.add(row);
1001:                            } else {
1002:                                if (logger.isDebugEnabled())
1003:                                    logger.debug("Key " + c.getName()
1004:                                            + " is not unique");
1005:                            }
1006:                        }
1007:                    }
1008:                }
1009:                ControllerResultSet rs = new ControllerResultSet(
1010:                        getPrimaryKeysFields, data);
1011:                return rs;
1012:            }
1013:
1014:            /**
1015:             * @see #getPrimaryKeys(ConnectionContext, String, String, String)
1016:             */
1017:            public ControllerResultSet doGetPrimaryKeys(
1018:                    ConnectionContext connContext, String catalog,
1019:                    String schema, String table) throws SQLException {
1020:                ConnectionAndDatabaseMetaData info = null;
1021:                try {
1022:                    info = getMetaDataFromFirstAvailableBackend(connContext);
1023:                    DatabaseMetaData m = info.getDatabaseMetaData();
1024:                    ResultSet pks = m.getPrimaryKeys(catalog, schema, table);
1025:                    ArrayList data = new ArrayList();
1026:                    while (pks.next()) { // Unroll the loop for comments (and speed?)
1027:                        Object[] row = new Object[6];
1028:                        row[0] = pks.getObject(1); // TABLE_CAT
1029:                        row[1] = pks.getObject(2); // TABLE_SCHEM
1030:                        row[2] = pks.getObject(3); // TABLE_NAME
1031:                        row[3] = pks.getObject(4); // COLUMN_NAME
1032:                        row[4] = pks.getObject(5); // KEY_SEQ
1033:                        row[5] = pks.getObject(6); // PK_NAME
1034:                        data.add(row);
1035:                    }
1036:                    return new ControllerResultSet(getPrimaryKeysFields, data);
1037:                } catch (SQLException e) {
1038:                    throw e;
1039:                } finally {
1040:                    releaseConnection(info);
1041:                }
1042:            }
1043:
1044:            /**
1045:             * @see org.continuent.sequoia.driver.DatabaseMetaData#getProcedureColumns
1046:             */
1047:            public ControllerResultSet getProcedureColumns(
1048:                    ConnectionContext connContext, String catalog,
1049:                    String schemaPattern, String procedureNamePattern,
1050:                    String columnNamePattern) throws SQLException {
1051:                try {
1052:                    int raidbLevel = requestManager.getLoadBalancer()
1053:                            .getRAIDbLevel();
1054:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
1055:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
1056:                        return doGetProcedureColumns(connContext, catalog,
1057:                                schemaPattern, procedureNamePattern,
1058:                                columnNamePattern);
1059:                    }
1060:                } catch (NoMoreBackendException ignore) {
1061:                    // No backend is available, try getting metadata from a remote controller
1062:                    Class[] argTypes = { ConnectionContext.class, String.class,
1063:                            String.class, String.class, String.class };
1064:                    Object[] args = { connContext, catalog, schemaPattern,
1065:                            procedureNamePattern, columnNamePattern };
1066:                    ControllerResultSet crs = getMetaDataFromRemoteController(
1067:                            "doGetProcedureColumns", argTypes, args);
1068:                    if (crs != null)
1069:                        return crs;
1070:                }
1071:
1072:                DatabaseSchema dbs = requestManager.getDatabaseSchema();
1073:                if (dbs == null)
1074:                    throw new SQLException(
1075:                            "Unable to fetch the virtual database schema");
1076:
1077:                if (procedureNamePattern == null)
1078:                    procedureNamePattern = "%";
1079:
1080:                if (columnNamePattern == null)
1081:                    columnNamePattern = "%";
1082:
1083:                // Build the ResultSet
1084:                Collection procedures = dbs.getProcedures().values();
1085:                ArrayList data = new ArrayList(procedures.size());
1086:
1087:                for (Iterator iter = procedures.iterator(); iter.hasNext();) {
1088:                    DatabaseProcedure sp = (DatabaseProcedure) iter.next();
1089:                    if (procedureNamePattern.equals("%")
1090:                            || procedureNamePattern.equals(sp.getName())) {
1091:                        if (logger.isDebugEnabled())
1092:                            logger.debug("Found matching procedure "
1093:                                    + sp.getName());
1094:
1095:                        ArrayList params = sp.getParameters();
1096:                        int sizep = params.size();
1097:                        DatabaseProcedureParameter param;
1098:                        for (int k = 0; k < sizep; k++) {
1099:                            param = (DatabaseProcedureParameter) params.get(k);
1100:                            if (columnNamePattern.equals("%")
1101:                                    || columnNamePattern.equals(sp.getName())) {
1102:                                if (logger.isDebugEnabled())
1103:                                    logger
1104:                                            .debug("Found matching procedure parameter"
1105:                                                    + param.getName());
1106:
1107:                                Object[] row = new Object[13];
1108:                                row[0] = vdbName; // PROCEDURE_CAT
1109:                                row[1] = null; // PROCEDURE_SCHEM
1110:                                row[2] = sp.getName(); // PROCEDURE_NAME
1111:                                row[3] = param.getName(); // COLUMN_NAME
1112:                                row[4] = new Integer(param.getColumnType()); // COLUMN_TYPE
1113:                                row[5] = new Integer(param.getDataType()); // DATA_TYPE
1114:                                row[6] = param.getTypeName(); // TYPE_NAME
1115:                                row[7] = new Float(param.getPrecision()); // PRECISION
1116:                                row[8] = new Integer(param.getLength()); // LENGTH
1117:                                row[9] = new Integer(param.getScale()); // SCALE
1118:                                row[10] = new Integer(param.getRadix()); // RADIX
1119:                                row[11] = new Integer(param.getNullable()); // NULLABLE
1120:                                row[12] = param.getRemarks();
1121:
1122:                                data.add(row);
1123:                            }
1124:                        }
1125:                    }
1126:                }
1127:                ControllerResultSet rs = new ControllerResultSet(
1128:                        getProcedureColumnsFields, data);
1129:                return rs;
1130:            }
1131:
1132:            /**
1133:             * @see #getProcedureColumns(ConnectionContext, String, String, String,
1134:             *      String)
1135:             */
1136:            public ControllerResultSet doGetProcedureColumns(
1137:                    ConnectionContext connContext, String catalog,
1138:                    String schemaPattern, String procedureNamePattern,
1139:                    String columnNamePattern) throws SQLException {
1140:                ConnectionAndDatabaseMetaData info = null;
1141:                try {
1142:                    info = getMetaDataFromFirstAvailableBackend(connContext);
1143:                    DatabaseMetaData m = info.getDatabaseMetaData();
1144:                    ResultSet cols = m.getColumns(catalog, schemaPattern,
1145:                            procedureNamePattern, columnNamePattern);
1146:                    ArrayList data = new ArrayList();
1147:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
1148:                        Object[] row = new Object[13];
1149:                        row[0] = cols.getObject(1); // PROCEDURE_CAT
1150:                        row[1] = cols.getObject(2); // PROCEDURE_SCHEM
1151:                        row[2] = cols.getObject(3); // PROCEDURE_NAME
1152:                        row[3] = cols.getObject(4); // COLUMN_NAME
1153:                        row[4] = cols.getObject(5); // COLUMN_TYPE
1154:                        row[5] = cols.getObject(6); // DATA_TYPE
1155:                        row[6] = cols.getObject(7); // TYPE_NAME
1156:                        row[7] = cols.getObject(8); // PRECISION
1157:                        row[8] = cols.getObject(9); // LENGTH
1158:                        row[9] = cols.getObject(10); // SCALE
1159:                        row[10] = cols.getObject(11); // RADIX
1160:                        row[11] = cols.getObject(12); // NULLABLE
1161:                        row[12] = cols.getObject(13); // REMARKS
1162:                        data.add(row);
1163:                    }
1164:                    Field[] fields;
1165:                    if (vdb.useStaticResultSetMetaData())
1166:                        fields = getProcedureColumnsFields;
1167:                    else { // Fetch metdata as well
1168:                        ResultSetMetaData metaData = cols.getMetaData();
1169:                        if (metaData == null)
1170:                            fields = getProcedureColumnsFields;
1171:                        else
1172:                            fields = ControllerConstants.CONTROLLER_FACTORY
1173:                                    .getResultSetMetaDataFactory()
1174:                                    .copyResultSetMetaData(metaData, null);
1175:                    }
1176:                    return new ControllerResultSet(fields, data);
1177:                } catch (SQLException e) {
1178:                    throw e;
1179:                } finally {
1180:                    releaseConnection(info);
1181:                }
1182:            }
1183:
1184:            /**
1185:             * @see org.continuent.sequoia.driver.DatabaseMetaData#getProcedures(String,
1186:             *      String, String)
1187:             */
1188:            public ControllerResultSet getProcedures(
1189:                    ConnectionContext connContext, String catalog,
1190:                    String schemaPattern, String procedureNamePattern)
1191:                    throws SQLException {
1192:                try {
1193:                    int raidbLevel = requestManager.getLoadBalancer()
1194:                            .getRAIDbLevel();
1195:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
1196:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
1197:                        return doGetProcedures(connContext, catalog,
1198:                                schemaPattern, procedureNamePattern);
1199:                    }
1200:                } catch (NoMoreBackendException ignore) {
1201:                    // No backend is available, try getting metadata from a remote controller
1202:                    Class[] argTypes = { ConnectionContext.class, String.class,
1203:                            String.class, String.class };
1204:                    Object[] args = { connContext, catalog, schemaPattern,
1205:                            procedureNamePattern };
1206:                    ControllerResultSet crs = getMetaDataFromRemoteController(
1207:                            "doGetProcedures", argTypes, args);
1208:                    if (crs != null)
1209:                        return crs;
1210:                }
1211:
1212:                DatabaseSchema dbs = requestManager.getDatabaseSchema();
1213:                if (dbs == null)
1214:                    throw new SQLException(
1215:                            "Unable to fetch the virtual database schema");
1216:
1217:                if (procedureNamePattern == null)
1218:                    procedureNamePattern = "%"; // if null is passed then
1219:                // select all procedures
1220:
1221:                // Build the ResultSet
1222:                Collection procedures = dbs.getProcedures().values();
1223:                ArrayList data = new ArrayList(procedures.size());
1224:
1225:                for (Iterator iter = procedures.iterator(); iter.hasNext();) {
1226:                    DatabaseProcedure sp = (DatabaseProcedure) iter.next();
1227:                    if (procedureNamePattern.equals("%")
1228:                            || procedureNamePattern.equals(sp.getName())) {
1229:                        if (logger.isDebugEnabled())
1230:                            logger.debug("Found procedure " + sp.getName());
1231:                        Object[] row = new Object[8];
1232:                        row[0] = vdbName; // PROCEDURE_CAT
1233:                        row[1] = null; // PROCEDURE_SCHEM
1234:                        row[2] = sp.getName(); // PROCEDURE_NAME
1235:                        row[3] = null; // reserved for future use
1236:                        row[4] = null; // reserved for future use
1237:                        row[5] = null; // reserved for future use
1238:                        row[6] = sp.getRemarks(); // REMARKS
1239:                        row[7] = new Integer(sp.getProcedureType()); // PROCEDURE_TYPE
1240:                        data.add(row);
1241:                    }
1242:                }
1243:                ControllerResultSet rs = new ControllerResultSet(
1244:                        getProceduresFields, data);
1245:                return rs;
1246:            }
1247:
1248:            /**
1249:             * @see #getProcedures(ConnectionContext, String, String, String)
1250:             */
1251:            public ControllerResultSet doGetProcedures(
1252:                    ConnectionContext connContext, String catalog,
1253:                    String schemaPattern, String procedureNamePattern)
1254:                    throws SQLException {
1255:                ConnectionAndDatabaseMetaData info = null;
1256:                try {
1257:                    info = getMetaDataFromFirstAvailableBackend(connContext);
1258:                    DatabaseMetaData m = info.getDatabaseMetaData();
1259:                    ResultSet cols = m.getProcedures(catalog, schemaPattern,
1260:                            procedureNamePattern);
1261:                    ArrayList data = new ArrayList();
1262:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
1263:                        Object[] row = new Object[8];
1264:                        row[0] = cols.getObject(1); // PROCEDURE_CAT
1265:                        row[1] = cols.getObject(2); // PROCEDURE_SCHEM
1266:                        row[2] = cols.getObject(3); // PROCEDURE_NAME
1267:                        row[3] = cols.getObject(4); // reserved for future use
1268:                        row[4] = cols.getObject(5); // reserved for future use
1269:                        row[5] = cols.getObject(6); // reserved for future use
1270:                        row[6] = cols.getObject(7); // REMARKS
1271:                        row[7] = cols.getObject(8); // PROCEDURE_TYPE
1272:                        data.add(row);
1273:                    }
1274:                    Field[] fields;
1275:                    if (vdb.useStaticResultSetMetaData())
1276:                        fields = getProceduresFields;
1277:                    else { // Fetch metdata as well
1278:                        ResultSetMetaData metaData = cols.getMetaData();
1279:                        if (metaData == null)
1280:                            fields = getProceduresFields;
1281:                        else
1282:                            fields = ControllerConstants.CONTROLLER_FACTORY
1283:                                    .getResultSetMetaDataFactory()
1284:                                    .copyResultSetMetaData(metaData, null);
1285:                    }
1286:                    return new ControllerResultSet(fields, data);
1287:                } catch (SQLException e) {
1288:                    throw e;
1289:                } finally {
1290:                    releaseConnection(info);
1291:                }
1292:            }
1293:
1294:            /**
1295:             * Will return the schema from the call to getSchemas() on the first available
1296:             * node.
1297:             * 
1298:             * @see java.sql.DatabaseMetaData#getSchemas()
1299:             */
1300:            public ControllerResultSet getSchemas(ConnectionContext connContext)
1301:                    throws SQLException {
1302:                try { // Forward directly to the underlying backend
1303:                    return doGetSchemas(connContext);
1304:                } catch (NoMoreBackendException ignore) {
1305:                    // No backend is available, try getting metadata from a remote controller
1306:                    Class[] argTypes = { ConnectionContext.class };
1307:                    Object[] args = { connContext };
1308:                    ControllerResultSet crs = getMetaDataFromRemoteController(
1309:                            "doGetSchemas", argTypes, args);
1310:                    if (crs != null)
1311:                        return crs;
1312:                }
1313:
1314:                Object[] row = new Object[2];
1315:                row[0] = vdbName; // TABLE_SCHEM
1316:                row[1] = null; // TABLE_CATALOG
1317:                ArrayList data = new ArrayList();
1318:                data.add(row);
1319:                return new ControllerResultSet(getSchemasFields, data);
1320:            }
1321:
1322:            /**
1323:             * @see #getSchemas(String)
1324:             */
1325:            public ControllerResultSet doGetSchemas(
1326:                    ConnectionContext connContext) throws SQLException {
1327:                ConnectionAndDatabaseMetaData info = null;
1328:                try {
1329:                    info = getMetaDataFromFirstAvailableBackend(connContext);
1330:                    DatabaseMetaData m = info.getDatabaseMetaData();
1331:                    ResultSet cols = m.getSchemas();
1332:                    ArrayList data = new ArrayList();
1333:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
1334:                        Object[] row = new Object[2];
1335:                        row[0] = cols.getObject(1); // TABLE_SCHEM
1336:                        // JDBC 3.0 starts here
1337:                        try {
1338:                            row[1] = cols.getObject(2); // TABLE_CATALOG
1339:                        } catch (Exception e) { // Driver does not support JDBC 3.0 cut here
1340:                            row[1] = null; // TABLE_SCHEM
1341:                        }
1342:                        data.add(row);
1343:                    }
1344:                    Field[] fields;
1345:                    if (vdb.useStaticResultSetMetaData())
1346:                        fields = getSchemasFields;
1347:                    else { // Fetch metdata as well
1348:                        ResultSetMetaData metaData = cols.getMetaData();
1349:                        if (metaData == null)
1350:                            fields = getSchemasFields;
1351:                        else
1352:                            fields = ControllerConstants.CONTROLLER_FACTORY
1353:                                    .getResultSetMetaDataFactory()
1354:                                    .copyResultSetMetaData(metaData, null);
1355:                    }
1356:                    return new ControllerResultSet(fields, data);
1357:                } catch (SQLException e) {
1358:                    throw e;
1359:                } finally {
1360:                    releaseConnection(info);
1361:                }
1362:            }
1363:
1364:            /**
1365:             * @see java.sql.DatabaseMetaData#getSuperTables(java.lang.String,
1366:             *      java.lang.String, java.lang.String)
1367:             */
1368:            public ControllerResultSet getSuperTables(
1369:                    ConnectionContext connContext, String catalog,
1370:                    String schemaPattern, String tableNamePattern)
1371:                    throws SQLException {
1372:                try {
1373:                    int raidbLevel = requestManager.getLoadBalancer()
1374:                            .getRAIDbLevel();
1375:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
1376:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
1377:                        return doGetSuperTables(connContext, catalog,
1378:                                schemaPattern, tableNamePattern);
1379:                    }
1380:                } catch (NoMoreBackendException ignore) {
1381:                    // No backend is available, try getting metadata from a remote controller
1382:                    Class[] argTypes = { ConnectionContext.class, String.class,
1383:                            String.class, String.class };
1384:                    Object[] args = { connContext, catalog, schemaPattern,
1385:                            tableNamePattern };
1386:                    ControllerResultSet crs = getMetaDataFromRemoteController(
1387:                            "doGetSuperTables", argTypes, args);
1388:                    if (crs != null)
1389:                        return crs;
1390:                }
1391:
1392:                // Feature not supported in RAIDb-0 and RAIDb-2, return an empty ResultSet
1393:
1394:                ArrayList data = new ArrayList();
1395:                ControllerResultSet rs = new ControllerResultSet(
1396:                        getSuperTablesFields, data);
1397:                return rs;
1398:            }
1399:
1400:            /**
1401:             * @see #getSuperTables(ConnectionContext, String, String, String)
1402:             */
1403:            public ControllerResultSet doGetSuperTables(
1404:                    ConnectionContext connContext, String catalog,
1405:                    String schemaPattern, String tableNamePattern)
1406:                    throws SQLException {
1407:                ConnectionAndDatabaseMetaData info = null;
1408:                try {
1409:                    info = getMetaDataFromFirstAvailableBackend(connContext);
1410:                    DatabaseMetaData m = info.getDatabaseMetaData();
1411:                    ResultSet cols = m.getSuperTables(catalog, schemaPattern,
1412:                            tableNamePattern);
1413:                    ArrayList data = new ArrayList();
1414:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
1415:                        Object[] row = new Object[4];
1416:                        row[0] = cols.getObject(1); // TABLE_CAT
1417:                        row[1] = cols.getObject(2); // TABLE_SCHEM
1418:                        row[2] = cols.getObject(3); // TABLE_NAME
1419:                        row[3] = cols.getObject(4); // SUPERTABLE_NAME
1420:                        data.add(row);
1421:                    }
1422:                    Field[] fields;
1423:                    if (vdb.useStaticResultSetMetaData())
1424:                        fields = getSuperTablesFields;
1425:                    else { // Fetch metdata as well
1426:                        ResultSetMetaData metaData = cols.getMetaData();
1427:                        if (metaData == null)
1428:                            fields = getSuperTablesFields;
1429:                        else
1430:                            fields = ControllerConstants.CONTROLLER_FACTORY
1431:                                    .getResultSetMetaDataFactory()
1432:                                    .copyResultSetMetaData(metaData, null);
1433:                    }
1434:                    return new ControllerResultSet(fields, data);
1435:                } catch (SQLException e) {
1436:                    throw e;
1437:                } finally {
1438:                    releaseConnection(info);
1439:                }
1440:            }
1441:
1442:            /**
1443:             * @see java.sql.DatabaseMetaData#getSuperTypes(java.lang.String,
1444:             *      java.lang.String, java.lang.String)
1445:             */
1446:            public ControllerResultSet getSuperTypes(
1447:                    ConnectionContext connContext, String catalog,
1448:                    String schemaPattern, String tableNamePattern)
1449:                    throws SQLException {
1450:                try {
1451:                    int raidbLevel = requestManager.getLoadBalancer()
1452:                            .getRAIDbLevel();
1453:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
1454:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
1455:                        return doGetSuperTypes(connContext, catalog,
1456:                                schemaPattern, tableNamePattern);
1457:                    }
1458:                } catch (NoMoreBackendException ignore) {
1459:                    // No backend is available, try getting metadata from a remote controller
1460:                    Class[] argTypes = { ConnectionContext.class, String.class,
1461:                            String.class, String.class };
1462:                    Object[] args = { connContext, catalog, schemaPattern,
1463:                            tableNamePattern };
1464:                    ControllerResultSet crs = getMetaDataFromRemoteController(
1465:                            "doGetSuperTypes", argTypes, args);
1466:                    if (crs != null)
1467:                        return crs;
1468:                }
1469:
1470:                // Feature not supported in RAIDb-0 and RAIDb-2, return an empty ResultSet
1471:
1472:                ArrayList data = new ArrayList();
1473:                ControllerResultSet rs = new ControllerResultSet(
1474:                        getSuperTypesFields, data);
1475:                return rs;
1476:            }
1477:
1478:            /**
1479:             * @see #getSuperTypes(ConnectionContext, String, String, String)
1480:             */
1481:            public ControllerResultSet doGetSuperTypes(
1482:                    ConnectionContext connContext, String catalog,
1483:                    String schemaPattern, String tableNamePattern)
1484:                    throws SQLException {
1485:                ConnectionAndDatabaseMetaData info = null;
1486:                try {
1487:                    info = getMetaDataFromFirstAvailableBackend(connContext);
1488:                    DatabaseMetaData m = info.getDatabaseMetaData();
1489:                    ResultSet cols = m.getSuperTypes(catalog, schemaPattern,
1490:                            tableNamePattern);
1491:                    ArrayList data = new ArrayList();
1492:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
1493:                        Object[] row = new Object[5];
1494:                        row[0] = cols.getObject(1); // TYPE_CAT
1495:                        row[1] = cols.getObject(2); // TYPE_SCHEM
1496:                        row[2] = cols.getObject(3); // TYPE_NAME
1497:                        row[3] = cols.getObject(4); // SUPERTYPE_CAT
1498:                        row[4] = cols.getObject(5); // SUPERTYPE_SCHEM
1499:                        data.add(row);
1500:                    }
1501:                    Field[] fields;
1502:                    if (vdb.useStaticResultSetMetaData())
1503:                        fields = getSuperTypesFields;
1504:                    else { // Fetch metdata as well
1505:                        ResultSetMetaData metaData = cols.getMetaData();
1506:                        if (metaData == null)
1507:                            fields = getSuperTypesFields;
1508:                        else
1509:                            fields = ControllerConstants.CONTROLLER_FACTORY
1510:                                    .getResultSetMetaDataFactory()
1511:                                    .copyResultSetMetaData(metaData, null);
1512:                    }
1513:                    return new ControllerResultSet(fields, data);
1514:                } catch (SQLException e) {
1515:                    throw e;
1516:                } finally {
1517:                    releaseConnection(info);
1518:                }
1519:            }
1520:
1521:            /**
1522:             * @see org.continuent.sequoia.driver.DatabaseMetaData#getTablePrivileges(String,
1523:             *      String, String)
1524:             */
1525:            public ControllerResultSet getTablePrivileges(
1526:                    ConnectionContext connContext, String catalog,
1527:                    String schemaPattern, String tableNamePattern)
1528:                    throws SQLException {
1529:                try {
1530:                    int raidbLevel = requestManager.getLoadBalancer()
1531:                            .getRAIDbLevel();
1532:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
1533:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
1534:                        return doGetTablePrivileges(connContext, catalog,
1535:                                schemaPattern, tableNamePattern);
1536:                    }
1537:                } catch (NoMoreBackendException ignore) {
1538:                    // No backend is available, try getting metadata from a remote controller
1539:                    Class[] argTypes = { ConnectionContext.class, String.class,
1540:                            String.class, String.class };
1541:                    Object[] args = { connContext, catalog, schemaPattern,
1542:                            tableNamePattern };
1543:                    ControllerResultSet crs = getMetaDataFromRemoteController(
1544:                            "doGetTablePrivileges", argTypes, args);
1545:                    if (crs != null)
1546:                        return crs;
1547:                }
1548:
1549:                AuthenticationManager manager = requestManager
1550:                        .getVirtualDatabase().getAuthenticationManager();
1551:
1552:                DatabaseSchema dbs = requestManager.getDatabaseSchema();
1553:                if (dbs == null)
1554:                    throw new SQLException(
1555:                            "Unable to fetch the virtual database schema");
1556:
1557:                if (tableNamePattern == null)
1558:                    // if null is passed then select all tables
1559:                    tableNamePattern = "%";
1560:
1561:                ArrayList virtualLogins = manager.getVirtualLogins();
1562:                int vsize = virtualLogins.size();
1563:                VirtualDatabaseUser vu;
1564:
1565:                Collection tables = dbs.getTables().values();
1566:                ArrayList data = new ArrayList(tables.size());
1567:                for (Iterator iter = tables.iterator(); iter.hasNext();) {
1568:                    DatabaseTable t = (DatabaseTable) iter.next();
1569:                    if (tableNamePattern.equals("%")
1570:                            || tableNamePattern.equals(t.getName())) {
1571:                        for (int j = 0; j < vsize; j++) {
1572:                            vu = (VirtualDatabaseUser) virtualLogins.get(0);
1573:
1574:                            if (logger.isDebugEnabled())
1575:                                logger.debug("Found privilege for user:"
1576:                                        + vu.getLogin() + " on table:"
1577:                                        + t.getName());
1578:                            Object[] row = new Object[7];
1579:                            row[0] = vdbName; // table cat
1580:                            row[1] = null; // table schema
1581:                            row[2] = t.getName(); // table name
1582:                            row[3] = null; // grantor
1583:                            row[4] = vu.getLogin(); // grantee
1584:                            row[5] = "UPDATE"; // privilege
1585:                            row[6] = "NO"; // IS_GRANTABLE
1586:                            data.add(row);
1587:                        }
1588:                    }
1589:                }
1590:
1591:                ControllerResultSet rs = new ControllerResultSet(
1592:                        getTablePrivilegesFields, data);
1593:                return rs;
1594:            }
1595:
1596:            /**
1597:             * @see #getTablePrivileges(ConnectionContext, String, String, String)
1598:             */
1599:            public ControllerResultSet doGetTablePrivileges(
1600:                    ConnectionContext connContext, String catalog,
1601:                    String schemaPattern, String tableNamePattern)
1602:                    throws SQLException {
1603:                ConnectionAndDatabaseMetaData info = null;
1604:                try {
1605:                    info = getMetaDataFromFirstAvailableBackend(connContext);
1606:                    DatabaseMetaData m = info.getDatabaseMetaData();
1607:                    ResultSet cols = m.getTablePrivileges(catalog,
1608:                            schemaPattern, tableNamePattern);
1609:                    ArrayList data = new ArrayList();
1610:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
1611:                        Object[] row = new Object[7];
1612:                        row[0] = cols.getObject(1); // TABLE_CAT
1613:                        row[1] = cols.getObject(2); // TABLE_SCHEM
1614:                        row[2] = cols.getObject(3); // TABLE_NAME
1615:                        row[3] = cols.getObject(4); // GRANTOR
1616:                        row[4] = cols.getObject(5); // GRANTEE
1617:                        row[5] = cols.getObject(6); // PRIVILEGE
1618:                        row[6] = cols.getObject(7); // IS_GRANTABLE
1619:                        data.add(row);
1620:                    }
1621:                    Field[] fields;
1622:                    if (vdb.useStaticResultSetMetaData())
1623:                        fields = getTablePrivilegesFields;
1624:                    else { // Fetch metdata as well
1625:                        ResultSetMetaData metaData = cols.getMetaData();
1626:                        if (metaData == null)
1627:                            fields = getTablePrivilegesFields;
1628:                        else
1629:                            fields = ControllerConstants.CONTROLLER_FACTORY
1630:                                    .getResultSetMetaDataFactory()
1631:                                    .copyResultSetMetaData(metaData, null);
1632:                    }
1633:                    return new ControllerResultSet(fields, data);
1634:                } catch (SQLException e) {
1635:                    throw e;
1636:                } finally {
1637:                    releaseConnection(info);
1638:                }
1639:            }
1640:
1641:            /**
1642:             * @see org.continuent.sequoia.driver.DatabaseMetaData#getTables(String,
1643:             *      String, String, String[])
1644:             */
1645:            public ControllerResultSet getTables(ConnectionContext connContext,
1646:                    String catalog, String schemaPattern,
1647:                    String tableNamePattern, String[] types)
1648:                    throws SQLException {
1649:                try {
1650:                    int raidbLevel = requestManager.getLoadBalancer()
1651:                            .getRAIDbLevel();
1652:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
1653:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
1654:                        return doGetTables(connContext, catalog, schemaPattern,
1655:                                tableNamePattern, types);
1656:                    }
1657:                } catch (NoMoreBackendException ignore) {
1658:                    // No backend is available, try getting metadata from a remote controller
1659:                    Class[] argTypes = { ConnectionContext.class, String.class,
1660:                            String.class, String.class, String[].class };
1661:                    Object[] args = { connContext, catalog, schemaPattern,
1662:                            tableNamePattern, types };
1663:                    ControllerResultSet crs = getMetaDataFromRemoteController(
1664:                            "doGetTables", argTypes, args);
1665:                    if (crs != null)
1666:                        return crs;
1667:                }
1668:
1669:                DatabaseSchema dbs = requestManager.getDatabaseSchema();
1670:                if (dbs == null)
1671:                    throw new SQLException(
1672:                            "No virtual database schema can be found possibly because no backend is enabled on that controller");
1673:
1674:                if (tableNamePattern == null)
1675:                    // if null is passed then select all tables
1676:                    tableNamePattern = "%";
1677:
1678:                // Build the ResultSet
1679:                Collection tables = dbs.getTables().values();
1680:                ArrayList data = new ArrayList(tables.size());
1681:
1682:                for (Iterator iter = tables.iterator(); iter.hasNext();) {
1683:                    DatabaseTable t = (DatabaseTable) iter.next();
1684:                    if (tableNamePattern.equals("%")
1685:                            || t.getName().indexOf(tableNamePattern) != -1) {
1686:                        if (logger.isDebugEnabled())
1687:                            logger.debug("Found table " + t.getName());
1688:                        Object[] row = new Object[10];
1689:                        row[0] = vdbName; // TABLE_CAT
1690:                        row[1] = null; // TABLE_SCHEM
1691:                        row[2] = t.getName(); // TABLE_NAME
1692:                        row[3] = "TABLE"; // TABLE_TYPE
1693:                        row[4] = null; // REMARKS
1694:                        row[5] = null; // TYPE_CAT
1695:                        row[6] = null; // TYPE_SCHEM
1696:                        row[7] = null; // TYPE_NAME
1697:                        row[8] = null; // SELF_REFERENCING_COL_NAME
1698:                        row[9] = "SYSTEM"; // REF_GENERATION
1699:                        data.add(row);
1700:                    }
1701:                }
1702:                ControllerResultSet rs = new ControllerResultSet(
1703:                        getTablesFields, data);
1704:                return rs;
1705:            }
1706:
1707:            /**
1708:             * @see #getTables(ConnectionContext, String, String, String, String[])
1709:             */
1710:            public ControllerResultSet doGetTables(
1711:                    ConnectionContext connContext, String catalog,
1712:                    String schemaPattern, String tableNamePattern,
1713:                    String[] types) throws SQLException {
1714:                ConnectionAndDatabaseMetaData info = null;
1715:                try {
1716:                    info = getMetaDataFromFirstAvailableBackend(connContext);
1717:                    DatabaseMetaData m = info.getDatabaseMetaData();
1718:                    ResultSet cols = m.getTables(catalog, schemaPattern,
1719:                            tableNamePattern, types);
1720:                    ArrayList data = new ArrayList();
1721:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
1722:                        Object[] row = new Object[10];
1723:                        row[0] = cols.getObject(1); // TABLE_CAT
1724:                        row[1] = cols.getObject(2); // TABLE_SCHEM
1725:                        row[2] = cols.getObject(3); // TABLE_NAME
1726:                        row[3] = cols.getObject(4); // TABLE_TYPE
1727:                        row[4] = cols.getObject(5); // REMARKS
1728:
1729:                        // JDBC 3.0 starts here
1730:                        try {
1731:                            row[5] = cols.getObject(6); // TYPE_CAT
1732:                            row[6] = cols.getObject(7); // TYPE_SCHEM
1733:                            row[7] = cols.getObject(8); // TYPE_NAME
1734:                            row[8] = cols.getObject(9); // SELF_REFERENCING_COL_NAME
1735:                            row[9] = cols.getObject(10); // REF_GENERATION
1736:                        } catch (Exception e) { // Driver does not support JDBC 3.0 cut here
1737:                            row[5] = null;
1738:                            row[6] = null;
1739:                            row[7] = null;
1740:                            row[8] = null;
1741:                            row[9] = null;
1742:                        }
1743:                        data.add(row);
1744:                    }
1745:                    Field[] fields;
1746:                    if (vdb.useStaticResultSetMetaData())
1747:                        fields = getTablesFields;
1748:                    else { // Fetch metdata as well
1749:                        ResultSetMetaData metaData = cols.getMetaData();
1750:                        if (metaData == null)
1751:                            fields = getTablesFields;
1752:                        else
1753:                            fields = ControllerConstants.CONTROLLER_FACTORY
1754:                                    .getResultSetMetaDataFactory()
1755:                                    .copyResultSetMetaData(metaData, null);
1756:                    }
1757:                    return new ControllerResultSet(fields, data);
1758:                } catch (SQLException e) {
1759:                    throw e;
1760:                } finally {
1761:                    releaseConnection(info);
1762:                }
1763:            }
1764:
1765:            /**
1766:             * @see org.continuent.sequoia.driver.DatabaseMetaData#getTableTypes()
1767:             */
1768:            public ControllerResultSet getTableTypes(
1769:                    ConnectionContext connContext) throws SQLException {
1770:                try {
1771:                    int raidbLevel = requestManager.getLoadBalancer()
1772:                            .getRAIDbLevel();
1773:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
1774:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
1775:                        return doGetTableTypes(connContext);
1776:                    }
1777:                } catch (NoMoreBackendException ignore) {
1778:                    // No backend is available, try getting metadata from a remote controller
1779:                    Class[] argTypes = { ConnectionContext.class };
1780:                    Object[] args = { connContext };
1781:                    ControllerResultSet crs = getMetaDataFromRemoteController(
1782:                            "doGetTableTypes", argTypes, args);
1783:                    if (crs != null)
1784:                        return crs;
1785:                }
1786:
1787:                ArrayList list = new ArrayList(1);
1788:                Object[] row = new Object[1];
1789:                row[0] = "TABLE"; // TABLE_TYPE
1790:                list.add(row);
1791:                ControllerResultSet rs = new ControllerResultSet(
1792:                        getTableTypesFields, list);
1793:                return rs;
1794:            }
1795:
1796:            /**
1797:             * @see #getTableTypes(ConnectionContext)
1798:             */
1799:            public ControllerResultSet doGetTableTypes(
1800:                    ConnectionContext connContext) throws SQLException {
1801:                ConnectionAndDatabaseMetaData info = null;
1802:                try {
1803:                    info = getMetaDataFromFirstAvailableBackend(connContext);
1804:                    DatabaseMetaData m = info.getDatabaseMetaData();
1805:                    ResultSet cols = m.getTableTypes();
1806:                    ArrayList data = new ArrayList();
1807:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
1808:                        Object[] row = new Object[1];
1809:                        row[0] = cols.getObject(1); // TABLE_TYPE
1810:                        data.add(row);
1811:                    }
1812:                    Field[] fields;
1813:                    if (vdb.useStaticResultSetMetaData())
1814:                        fields = getTableTypesFields;
1815:                    else { // Fetch metdata as well
1816:                        ResultSetMetaData metaData = cols.getMetaData();
1817:                        if (metaData == null)
1818:                            fields = getTableTypesFields;
1819:                        else
1820:                            fields = ControllerConstants.CONTROLLER_FACTORY
1821:                                    .getResultSetMetaDataFactory()
1822:                                    .copyResultSetMetaData(metaData, null);
1823:                    }
1824:                    return new ControllerResultSet(fields, data);
1825:                } catch (SQLException e) {
1826:                    throw e;
1827:                } finally {
1828:                    releaseConnection(info);
1829:                }
1830:            }
1831:
1832:            /**
1833:             * @see org.continuent.sequoia.driver.DatabaseMetaData#getTypeInfo()
1834:             */
1835:            public ControllerResultSet getTypeInfo(ConnectionContext connContext)
1836:                    throws SQLException {
1837:                try {
1838:                    int raidbLevel = requestManager.getLoadBalancer()
1839:                            .getRAIDbLevel();
1840:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
1841:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
1842:                        return doGetTypeInfo(connContext);
1843:                    }
1844:                } catch (NoMoreBackendException ignore) {
1845:                    // No backend is available, try getting metadata from a remote controller
1846:                    Class[] argTypes = { ConnectionContext.class };
1847:                    Object[] args = { connContext };
1848:                    ControllerResultSet crs = getMetaDataFromRemoteController(
1849:                            "doGetTypeInfo", argTypes, args);
1850:                    if (crs != null)
1851:                        return crs;
1852:                }
1853:
1854:                // Feature not supported in RAIDb-0 and RAIDb-2, return an empty ResultSet
1855:
1856:                ArrayList data = new ArrayList();
1857:                ControllerResultSet rs = new ControllerResultSet(
1858:                        getTypeInfoFields, data);
1859:                return rs;
1860:            }
1861:
1862:            /**
1863:             * @see #getTypeInfo(ConnectionContext)
1864:             */
1865:            public ControllerResultSet doGetTypeInfo(
1866:                    ConnectionContext connContext) throws SQLException {
1867:                ConnectionAndDatabaseMetaData info = null;
1868:                try {
1869:                    info = getMetaDataFromFirstAvailableBackend(connContext);
1870:                    DatabaseMetaData m = info.getDatabaseMetaData();
1871:                    ResultSet cols = m.getTypeInfo();
1872:                    ArrayList data = new ArrayList();
1873:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
1874:                        Object[] row = new Object[18];
1875:                        row[0] = cols.getObject(1); // TYPE_NAME
1876:                        row[1] = cols.getObject(2); // DATA_TYPE
1877:                        row[2] = cols.getObject(3); // PRECISION
1878:                        row[3] = cols.getObject(4); // LITERAL_PREFIX
1879:                        row[4] = cols.getObject(5); // LITERAL_SUFFIX
1880:                        row[5] = cols.getObject(6); // CREATE_PARAMS
1881:                        row[6] = cols.getObject(7); // NULLABLE
1882:                        row[7] = cols.getObject(8); // CASE_SENSITIVE
1883:                        row[8] = cols.getObject(9); // SEARCHABLE
1884:                        row[9] = cols.getObject(10); // UNSIGNED_ATTRIBUTE
1885:                        row[10] = cols.getObject(11); // FIXED_PREC_SCALE
1886:                        row[11] = cols.getObject(12); // AUTO_INCREMENT
1887:                        row[12] = cols.getObject(13); // LOCAL_TYPE_NAME
1888:                        row[13] = cols.getObject(14); // MINIMUM_SCALE
1889:                        row[14] = cols.getObject(15); // MAXIMUM_SCALE
1890:                        row[15] = cols.getObject(16); // SQL_DATA_TYPE
1891:                        row[16] = cols.getObject(17); // SQL_DATETIME_SUB
1892:                        row[17] = cols.getObject(18); // NUM_PREC_RADIX
1893:                        data.add(row);
1894:                    }
1895:                    Field[] fields;
1896:                    if (vdb.useStaticResultSetMetaData())
1897:                        fields = getTypeInfoFields;
1898:                    else { // Fetch metdata as well
1899:                        ResultSetMetaData metaData = cols.getMetaData();
1900:                        if (metaData == null)
1901:                            fields = getTypeInfoFields;
1902:                        else
1903:                            fields = ControllerConstants.CONTROLLER_FACTORY
1904:                                    .getResultSetMetaDataFactory()
1905:                                    .copyResultSetMetaData(metaData, null);
1906:                    }
1907:                    return new ControllerResultSet(fields, data);
1908:                } catch (SQLException e) {
1909:                    throw e;
1910:                } finally {
1911:                    releaseConnection(info);
1912:                }
1913:            }
1914:
1915:            /**
1916:             * @see org.continuent.sequoia.driver.DatabaseMetaData#getUDTs(String, String,
1917:             *      String, int[])
1918:             */
1919:            public ControllerResultSet getUDTs(ConnectionContext connContext,
1920:                    String catalog, String schemaPattern,
1921:                    String tableNamePattern, int[] types) throws SQLException {
1922:                try {
1923:                    int raidbLevel = requestManager.getLoadBalancer()
1924:                            .getRAIDbLevel();
1925:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
1926:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
1927:                        return doGetUDTs(connContext, catalog, schemaPattern,
1928:                                tableNamePattern, types);
1929:                    }
1930:                } catch (NoMoreBackendException ignore) {
1931:                    // No backend is available, try getting metadata from a remote controller
1932:                    Class[] argTypes = { ConnectionContext.class, String.class,
1933:                            String.class, String.class, int[].class };
1934:                    Object[] args = { connContext, catalog, schemaPattern,
1935:                            tableNamePattern, types };
1936:                    ControllerResultSet crs = getMetaDataFromRemoteController(
1937:                            "doGetUDTs", argTypes, args);
1938:                    if (crs != null)
1939:                        return crs;
1940:                }
1941:
1942:                // Feature not supported in RAIDb-0 and RAIDb-2, return an empty ResultSet
1943:
1944:                ArrayList data = new ArrayList();
1945:                ControllerResultSet rs = new ControllerResultSet(getUDTsFields,
1946:                        data);
1947:                return rs;
1948:            }
1949:
1950:            /**
1951:             * @see #getUDTs(ConnectionContext, String, String, String, int[])
1952:             */
1953:            public ControllerResultSet doGetUDTs(ConnectionContext connContext,
1954:                    String catalog, String schemaPattern,
1955:                    String tableNamePattern, int[] types) throws SQLException {
1956:                ConnectionAndDatabaseMetaData info = null;
1957:                try {
1958:                    info = getMetaDataFromFirstAvailableBackend(connContext);
1959:                    DatabaseMetaData m = info.getDatabaseMetaData();
1960:                    ResultSet cols = m.getUDTs(catalog, schemaPattern,
1961:                            tableNamePattern, types);
1962:                    ArrayList data = new ArrayList();
1963:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
1964:                        Object[] row = new Object[7];
1965:                        row[0] = cols.getObject(1); // TYPE_CAT
1966:                        row[1] = cols.getObject(2); // TYPE_SCHEM
1967:                        row[2] = cols.getObject(3); // TYPE_NAME
1968:                        row[3] = cols.getObject(4); // CLASS_NAME
1969:                        row[4] = cols.getObject(5); // DATA_TYPE
1970:                        row[5] = cols.getObject(6); // REMARKS
1971:
1972:                        // JDBC 3.0 starts here
1973:                        try {
1974:                            row[6] = cols.getObject(7); // BASE_TYPE
1975:                        } catch (Exception e) { // Driver does not support JDBC 3.0 cut here
1976:                            row[6] = null; // BASE_TYPE
1977:                        }
1978:
1979:                        data.add(row);
1980:                    }
1981:                    Field[] fields;
1982:                    if (vdb.useStaticResultSetMetaData())
1983:                        fields = getUDTsFields;
1984:                    else { // Fetch metdata as well
1985:                        ResultSetMetaData metaData = cols.getMetaData();
1986:                        if (metaData == null)
1987:                            fields = getUDTsFields;
1988:                        else
1989:                            fields = ControllerConstants.CONTROLLER_FACTORY
1990:                                    .getResultSetMetaDataFactory()
1991:                                    .copyResultSetMetaData(metaData, null);
1992:                    }
1993:                    return new ControllerResultSet(fields, data);
1994:                } catch (SQLException e) {
1995:                    throw e;
1996:                } finally {
1997:                    releaseConnection(info);
1998:                }
1999:            }
2000:
2001:            /**
2002:             * @see org.continuent.sequoia.driver.DatabaseMetaData#getVersionColumns(String,
2003:             *      String, String)
2004:             */
2005:            public ControllerResultSet getVersionColumns(
2006:                    ConnectionContext connContext, String catalog,
2007:                    String schema, String table) throws SQLException {
2008:                try {
2009:                    int raidbLevel = requestManager.getLoadBalancer()
2010:                            .getRAIDbLevel();
2011:                    if ((raidbLevel == RAIDbLevels.RAIDb1)
2012:                            || (raidbLevel == RAIDbLevels.SingleDB)) { // Forward directly to the underlying backend
2013:                        return doGetVersionColumns(connContext, catalog,
2014:                                schema, table);
2015:                    }
2016:                } catch (NoMoreBackendException ignore) {
2017:                    // No backend is available, try getting metadata from a remote controller
2018:                    Class[] argTypes = { ConnectionContext.class, String.class,
2019:                            String.class, String.class };
2020:                    Object[] args = { connContext, catalog, schema, table };
2021:                    ControllerResultSet crs = getMetaDataFromRemoteController(
2022:                            "doGetVersionColumns", argTypes, args);
2023:                    if (crs != null)
2024:                        return crs;
2025:                }
2026:
2027:                // Feature not supported in RAIDb-0 and RAIDb-2, return an empty ResultSet
2028:
2029:                ArrayList data = new ArrayList();
2030:                ControllerResultSet rs = new ControllerResultSet(
2031:                        getBestRowIdentifierAndVersionColumnsFields, data);
2032:                return rs;
2033:            }
2034:
2035:            /**
2036:             * @see #getVersionColumns(ConnectionContext, String, String, String)
2037:             */
2038:            public ControllerResultSet doGetVersionColumns(
2039:                    ConnectionContext connContext, String catalog,
2040:                    String schema, String table) throws SQLException {
2041:                ConnectionAndDatabaseMetaData info = null;
2042:                try {
2043:                    info = getMetaDataFromFirstAvailableBackend(connContext);
2044:                    DatabaseMetaData m = info.getDatabaseMetaData();
2045:                    ResultSet cols = m
2046:                            .getVersionColumns(catalog, schema, table);
2047:                    ArrayList data = new ArrayList();
2048:                    while (cols.next()) { // Unroll the loop for comments (and speed?)
2049:                        Object[] row = new Object[8];
2050:                        row[0] = cols.getObject(1); // SCOPE
2051:                        row[1] = cols.getObject(2); // COLUMN_NAME
2052:                        row[2] = cols.getObject(3); // DATA_TYPE
2053:                        row[3] = cols.getObject(4); // TYPE_NAME
2054:                        row[4] = cols.getObject(5); // COLUMN_SIZE
2055:                        row[5] = cols.getObject(6); // BUFFER_LENGTH
2056:                        row[6] = cols.getObject(7); // DECIMAL_DIGITS
2057:                        row[7] = cols.getObject(8); // PSEUDO_COLUMN
2058:                        data.add(row);
2059:                    }
2060:                    Field[] fields;
2061:                    if (vdb.useStaticResultSetMetaData())
2062:                        fields = getBestRowIdentifierAndVersionColumnsFields;
2063:                    else { // Fetch metdata as well
2064:                        ResultSetMetaData metaData = cols.getMetaData();
2065:                        if (metaData == null)
2066:                            fields = getBestRowIdentifierAndVersionColumnsFields;
2067:                        else
2068:                            fields = ControllerConstants.CONTROLLER_FACTORY
2069:                                    .getResultSetMetaDataFactory()
2070:                                    .copyResultSetMetaData(metaData, null);
2071:                    }
2072:                    return new ControllerResultSet(fields, data);
2073:                } catch (SQLException e) {
2074:                    throw e;
2075:                } finally {
2076:                    releaseConnection(info);
2077:                }
2078:            }
2079:
2080:            /**
2081:             * Get DatabaseMetaData from the first available backend.
2082:             * 
2083:             * @param login the login to use to fetch metadata
2084:             * @return the DatabaseMetaData obtained from the first available backend
2085:             *         among with the connection information
2086:             * @throws NoMoreBackendException if no backend is enabled on this controller
2087:             * @throws SQLException if an error occured while getting MetaData
2088:             */
2089:            private ConnectionAndDatabaseMetaData getMetaDataFromFirstAvailableBackend(
2090:                    ConnectionContext connContext)
2091:                    throws NoMoreBackendException, SQLException {
2092:                DatabaseBackend b = requestManager.getVirtualDatabase()
2093:                        .getFirstAvailableBackend();
2094:                if (b == null)
2095:                    throw new NoMoreBackendException(
2096:                            "No backend is enabled for virtual database "
2097:                                    + vdbName);
2098:                AbstractConnectionManager cm = b
2099:                        .getConnectionManager(connContext.getLogin());
2100:                if (cm == null)
2101:                    throw new SQLException("Invalid login "
2102:                            + connContext.getLogin() + " on backend "
2103:                            + b.getName());
2104:
2105:                PooledConnection c = null;
2106:                try {
2107:                    if (connContext.isStartedTransaction()) { // Retrieve connection in the proper transaction context
2108:                        c = cm.retrieveConnectionForTransaction(connContext
2109:                                .getTransactionId());
2110:                        // If the transaction was not started yet, we fallback as if we were in
2111:                        // autocommit to prevent issues related to lazy transaction start
2112:                    }
2113:                    if (c == null) { // Retrieve the appropriate connection if the connection is persistent
2114:                        // or allocate a new one.
2115:                        AbstractRequest fakeRequest = new UnknownReadRequest(
2116:                                "metadata", false, 0, "\n");
2117:                        fakeRequest.setIsAutoCommit(true);
2118:                        fakeRequest.setPersistentConnection(connContext
2119:                                .isPersistentConnection());
2120:                        fakeRequest.setPersistentConnectionId(connContext
2121:                                .getPersistentConnectionId());
2122:                        // Cleanup transactional context in case we fallback from a failure to
2123:                        // retrieve connection from transaction because the transaction was not
2124:                        // started yet (see previous if statement above)
2125:                        connContext.setStartedTransaction(false);
2126:                        c = cm.retrieveConnectionInAutoCommit(fakeRequest);
2127:                    }
2128:                } catch (UnreachableBackendException e) {
2129:                    throw new SQLException(
2130:                            "Unable to get a connection for login "
2131:                                    + connContext);
2132:                }
2133:                return new ConnectionAndDatabaseMetaData(c, cm, c
2134:                        .getConnection().getMetaData(), connContext);
2135:            }
2136:
2137:            /**
2138:             * Release the connection used to fetch the metadata
2139:             * 
2140:             * @param info the connection information returned by
2141:             *          getMetaDataFromFirstAvailableBackend
2142:             * @see #getMetaDataFromFirstAvailableBackend(String)
2143:             */
2144:            private void releaseConnection(ConnectionAndDatabaseMetaData info) {
2145:                if (info == null)
2146:                    return;
2147:
2148:                /*
2149:                 * Don't release the connection if it is persistent or in a transaction (it
2150:                 * should only be done at closing time for persistent connections and at
2151:                 * commit/rollback time for transactions
2152:                 */
2153:                if (info.getConnectionContext().isPersistentConnection()
2154:                        || info.getConnectionContext().isStartedTransaction())
2155:                    return;
2156:                info.getConnectionManager().releaseConnectionInAutoCommit(null,
2157:                        info.getConnection());
2158:            }
2159:
2160:            private ControllerResultSet getMetaDataFromRemoteController(
2161:                    String methodName, Class[] argTypes, Object[] args)
2162:                    throws SQLException {
2163:                // If vdb is NOT distributed return null, else try remote controllers
2164:                if (!vdb.isDistributed())
2165:                    return null;
2166:
2167:                DistributedVirtualDatabase dvdb = (DistributedVirtualDatabase) vdb;
2168:                try {
2169:                    MulticastResponse rspList = dvdb
2170:                            .getMulticastRequestAdapter()
2171:                            .multicastMessage(
2172:                                    dvdb.getAllMemberButUs(),
2173:                                    new GetMetadata(methodName, argTypes, args),
2174:                                    MulticastRequestAdapter.WAIT_ALL,
2175:                                    dvdb
2176:                                            .getMessageTimeouts()
2177:                                            .getVirtualDatabaseConfigurationTimeout());
2178:
2179:                    Map results = rspList.getResults();
2180:                    if (results.size() == 0)
2181:                        if (logger.isWarnEnabled())
2182:                            logger
2183:                                    .warn("No response while getting metadata from remote controller");
2184:                    for (Iterator iter = results.values().iterator(); iter
2185:                            .hasNext();) {
2186:                        Object response = iter.next();
2187:                        if (response instanceof  ControllerException) {
2188:                            if (logger.isErrorEnabled()) {
2189:                                logger
2190:                                        .error("Error while getting metadata from remote controller");
2191:                            }
2192:                        } else {
2193:                            // Here we succeded in getting metadata from a remote controller
2194:                            return (ControllerResultSet) response;
2195:                        }
2196:                    }
2197:                } catch (NotConnectedException e) {
2198:                    if (logger.isErrorEnabled())
2199:                        logger
2200:                                .error(
2201:                                        "Channel unavailable while getting metadata from remote controller",
2202:                                        e);
2203:                }
2204:
2205:                // Here we didn't succeded in getting metadata from another controller
2206:                // Throw exception (fixes SEQUOIA-500)
2207:                throw new SQLException(
2208:                        "Unable to fetch metadata from any backend in the cluster (probably no backend is enabled)");
2209:            }
2210:
2211:            /**
2212:             * This class defines a ConnectionAndDatabaseMetaData used to carry metadata
2213:             * and connection related information to properly release the connection later
2214:             * on.
2215:             * 
2216:             * @author <a href="mailto:emmanuel.cecchet@emicnetworks.com">Emmanuel Cecchet</a>
2217:             * @version 1.0
2218:             */
2219:            private class ConnectionAndDatabaseMetaData {
2220:                DatabaseMetaData databaseMetaData;
2221:                AbstractConnectionManager connectionManager;
2222:                PooledConnection connection;
2223:                ConnectionContext connContext;
2224:
2225:                /**
2226:                 * Creates a new <code>ConnectionAndDatabaseMetaData</code> object
2227:                 * 
2228:                 * @param c the connection used to get the metadata
2229:                 * @param cm the connection manager used to get the connection
2230:                 * @param metadata the metadata fetched from the connection
2231:                 * @param connContext connection context
2232:                 */
2233:                public ConnectionAndDatabaseMetaData(PooledConnection c,
2234:                        AbstractConnectionManager cm,
2235:                        DatabaseMetaData metadata, ConnectionContext connContext) {
2236:                    this .connection = c;
2237:                    this .connectionManager = cm;
2238:                    this .databaseMetaData = metadata;
2239:                    this .connContext = connContext;
2240:                }
2241:
2242:                /**
2243:                 * Returns the connection value.
2244:                 * 
2245:                 * @return Returns the connection.
2246:                 */
2247:                public PooledConnection getConnection() {
2248:                    return connection;
2249:                }
2250:
2251:                /**
2252:                 * Returns the connection context value.
2253:                 * 
2254:                 * @return Returns the connContext.
2255:                 */
2256:                public final ConnectionContext getConnectionContext() {
2257:                    return connContext;
2258:                }
2259:
2260:                /**
2261:                 * Returns the connectionManager value.
2262:                 * 
2263:                 * @return Returns the connectionManager.
2264:                 */
2265:                public AbstractConnectionManager getConnectionManager() {
2266:                    return connectionManager;
2267:                }
2268:
2269:                /**
2270:                 * Returns the databaseMetaData value.
2271:                 * 
2272:                 * @return Returns the databaseMetaData.
2273:                 */
2274:                public DatabaseMetaData getDatabaseMetaData() {
2275:                    return databaseMetaData;
2276:                }
2277:
2278:            }
2279:
2280:            /**
2281:             * @see java.sql.DatabaseMetaData#getAttributes(java.lang.String,
2282:             *      java.lang.String, java.lang.String, java.lang.String)
2283:             */
2284:            private static Field[] getAttributesFields = new Field[] {
2285:                    new Field("TYPE_CAT", "TYPE_CAT", 9, Types.VARCHAR,
2286:                            "VARCHAR", "String"),
2287:                    new Field("TYPE_SCHEM", "TYPE_SCHEM", 10, Types.VARCHAR,
2288:                            "VARCHAR", "String"),
2289:                    new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR,
2290:                            "VARCHAR", "String"),
2291:                    new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT,
2292:                            "SMALLINT", "Short"),
2293:                    new Field("ATTR_NAME", "ATTR_NAME", 10, Types.VARCHAR,
2294:                            "VARCHAR", "String"),
2295:                    new Field("ATTR_TYPE_NAME", "ATTR_TYPE_NAME", 10,
2296:                            Types.VARCHAR, "VARCHAR", "String"),
2297:                    new Field("ATTR_SIZE", "ATTR_SIZE", 10, Types.INTEGER,
2298:                            "INTEGER", "Integer"),
2299:                    new Field("DECIMAL_DIGITS", "DECIMAL_DIGITS", 10,
2300:                            Types.INTEGER, "INTEGER", "Integer"),
2301:                    new Field("NUM_PREC_RADIX", "NUM_PREC_RADIX", 10,
2302:                            Types.INTEGER, "INTEGER", "Integer"),
2303:                    new Field("NULLABLE", "NULLABLE", 10, Types.INTEGER,
2304:                            "INTEGER", "Integer"),
2305:                    new Field("REMARKS", "REMARKS", 10, Types.VARCHAR,
2306:                            "VARCHAR", "String"),
2307:                    new Field("ATTR_DEF", "ATTR_DEF", 10, Types.VARCHAR,
2308:                            "VARCHAR", "String"),
2309:                    new Field("SQL_DATA_TYPE", "SQL_DATA_TYPE", 10,
2310:                            Types.INTEGER, "INTEGER", "Integer"),
2311:                    new Field("SQL_DATETIME_SUB", "SQL_DATETIME_SUB", 10,
2312:                            Types.INTEGER, "INTEGER", "Integer"),
2313:                    new Field("CHAR_OCTET_LENGTH", "CHAR_OCTET_LENGTH", 10,
2314:                            Types.INTEGER, "INTEGER", "Integer"),
2315:                    new Field("ORDINAL_POSITION", "ORDINAL_POSITION", 10,
2316:                            Types.INTEGER, "INTEGER", "Integer"),
2317:                    new Field("IS_NULLABLE", "IS_NULLABLE", 10, Types.VARCHAR,
2318:                            "VARCHAR", "String"),
2319:                    new Field("SCOPE_CATALOG", "SCOPE_CATALOG", 10,
2320:                            Types.VARCHAR, "VARCHAR", "String"),
2321:                    new Field("SCOPE_SCHEMA", "SCOPE_SCHEMA", 10,
2322:                            Types.VARCHAR, "VARCHAR", "String"),
2323:                    new Field("SCOPE_TABLE", "SCOPE_TABLE", 10, Types.VARCHAR,
2324:                            "VARCHAR", "String") };
2325:
2326:            /**
2327:             * @see java.sql.DatabaseMetaData#getBestRowIdentifier(java.lang.String,
2328:             *      java.lang.String, java.lang.String, int, boolean)
2329:             */
2330:            private static Field[] getBestRowIdentifierAndVersionColumnsFields = new Field[] {
2331:                    new Field("SCOPE", "SCOPE", 10, Types.SMALLINT, "SMALLINT",
2332:                            "Short"),
2333:                    new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR,
2334:                            "VARCHAR", "String"),
2335:                    new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT,
2336:                            "SMALLINT", "Short"),
2337:                    new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR,
2338:                            "VARCHAR", "String"),
2339:                    new Field("COLUMN_SIZE", "COLUMN_SIZE", 10, Types.INTEGER,
2340:                            "INTEGER", "Integer"),
2341:                    new Field("BUFFER_LENGTH", "BUFFER_LENGTH", 10,
2342:                            Types.INTEGER, "INTEGER", "Integer"),
2343:                    new Field("DECIMAL_DIGITS", "DECIMAL_DIGITS", 10,
2344:                            Types.SMALLINT, "SMALLINT", "Short"),
2345:                    new Field("PSEUDO_COLUMN", "PSEUDO_COLUMN", 10,
2346:                            Types.SMALLINT, "SMALLINT", "Short") };
2347:
2348:            /**
2349:             * @see java.sql.DatabaseMetaData#getCatalogs()
2350:             */
2351:            private static Field[] getCatalogsFields = new Field[] { new Field(
2352:                    "TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR, "VARCHAR",
2353:                    "String") };
2354:
2355:            /**
2356:             * @see java.sql.DatabaseMetaData#getColumnPrivileges(java.lang.String,
2357:             *      java.lang.String, java.lang.String, java.lang.String)
2358:             */
2359:            private static Field[] getColumnPrivilegesFields = new Field[] {
2360:                    new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR,
2361:                            "VARCHAR", "String"),
2362:                    new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR,
2363:                            "VARCHAR", "String"),
2364:                    new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR,
2365:                            "VARCHAR", "String"),
2366:                    new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR,
2367:                            "VARCHAR", "String"),
2368:                    new Field("GRANTOR", "GRANTOR", 10, Types.VARCHAR,
2369:                            "VARCHAR", "String"),
2370:                    new Field("GRANTEE", "GRANTEE", 10, Types.VARCHAR,
2371:                            "VARCHAR", "String"),
2372:                    new Field("PRIVILEGE", "PRIVILEGE", 10, Types.VARCHAR,
2373:                            "VARCHAR", "String"),
2374:                    new Field("IS_GRANTABLE", "IS_GRANTABLE", 10,
2375:                            Types.VARCHAR, "VARCHAR", "String"), };
2376:
2377:            /**
2378:             * @see java.sql.DatabaseMetaData#getColumns(java.lang.String,
2379:             *      java.lang.String, java.lang.String, java.lang.String)
2380:             */
2381:            private static Field[] getColumnsFields = new Field[] {
2382:                    new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR,
2383:                            "VARCHAR", "String"),
2384:                    new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR,
2385:                            "VARCHAR", "String"),
2386:                    new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR,
2387:                            "VARCHAR", "String"),
2388:                    new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR,
2389:                            "VARCHAR", "String"),
2390:                    new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT,
2391:                            "SMALLINT", "Short"),
2392:                    new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR,
2393:                            "VARCHAR", "String"),
2394:                    new Field("COLUMN_SIZE", "COLUMN_SIZE", 10, Types.INTEGER,
2395:                            "INTEGER", "Integer"),
2396:                    new Field("BUFFER_LENGTH", "BUFFER_LENGTH", 10,
2397:                            Types.INTEGER, "INTEGER", "Integer"),
2398:                    new Field("DECIMAL_DIGITS", "DECIMAL_DIGITS", 10,
2399:                            Types.INTEGER, "INTEGER", "Integer"),
2400:                    new Field("NUM_PREC_RADIX", "NUM_PREC_RADIX", 10,
2401:                            Types.INTEGER, "INTEGER", "Integer"),
2402:                    new Field("NULLABLE", "NULLABLE", 10, Types.INTEGER,
2403:                            "INTEGER", "Integer"),
2404:                    new Field("REMARKS", "REMARKS", 10, Types.VARCHAR,
2405:                            "VARCHAR", "String"),
2406:                    new Field("COLUMN_DEF", "COLUMN_DEF", 10, Types.VARCHAR,
2407:                            "VARCHAR", "String"),
2408:                    new Field("SQL_DATA_TYPE", "SQL_DATA_TYPE", 10,
2409:                            Types.INTEGER, "INTEGER", "Integer"),
2410:                    new Field("SQL_DATETIME_SUB", "SQL_DATETIME_SUB", 10,
2411:                            Types.INTEGER, "INTEGER", "Integer"),
2412:                    new Field("CHAR_OCTET_LENGTH", "CHAR_OCTET_LENGTH", 10,
2413:                            Types.INTEGER, "INTEGER", "Integer"),
2414:                    new Field("ORDINAL_POSITION", "ORDINAL_POSITION", 10,
2415:                            Types.INTEGER, "INTEGER", "Integer"),
2416:                    new Field("IS_NULLABLE", "IS_NULLABLE", 10, Types.VARCHAR,
2417:                            "VARCHAR", "String"),
2418:                    new Field("SCOPE_CATALOG", "SCOPE_CATALOG", 10,
2419:                            Types.VARCHAR, "VARCHAR", "String"),
2420:                    new Field("SCOPE_SCHEMA", "SCOPE_SCHEMA", 10,
2421:                            Types.VARCHAR, "VARCHAR", "String"),
2422:                    new Field("SCOPE_TABLE", "SCOPE_TABLE", 10, Types.VARCHAR,
2423:                            "VARCHAR", "String"),
2424:                    new Field("SOURCE_DATA_TYPE", "SOURCE_DATA_TYPE", 10,
2425:                            Types.SMALLINT, "SMALLINT", "Short") };
2426:
2427:            /**
2428:             * @see java.sql.DatabaseMetaData#getCrossReference(java.lang.String,
2429:             *      java.lang.String, java.lang.String, java.lang.String,
2430:             *      java.lang.String, java.lang.String)
2431:             * @see java.sql.DatabaseMetaData#getImportedKeys(java.lang.String,
2432:             *      java.lang.String, java.lang.String)
2433:             */
2434:            private static Field[] getCrossReferenceOrImportExportedKeysFields = new Field[] {
2435:                    new Field("PKTABLE_CAT", "PKTABLE_CAT", 9, Types.VARCHAR,
2436:                            "VARCHAR", "String"),
2437:                    new Field("PKTABLE_SCHEM", "PKTABLE_SCHEM", 10,
2438:                            Types.VARCHAR, "VARCHAR", "String"),
2439:                    new Field("PKTABLE_NAME", "PKTABLE_NAME", 10,
2440:                            Types.VARCHAR, "VARCHAR", "String"),
2441:                    new Field("PKCOLUMN_NAME", "PKCOLUMN_NAME", 10,
2442:                            Types.VARCHAR, "VARCHAR", "String"),
2443:                    new Field("FKTABLE_CAT", "FKTABLE_CAT", 9, Types.VARCHAR,
2444:                            "VARCHAR", "String"),
2445:                    new Field("FKTABLE_SCHEM", "FKTABLE_SCHEM", 10,
2446:                            Types.VARCHAR, "VARCHAR", "String"),
2447:                    new Field("FKTABLE_NAME", "FKTABLE_NAME", 10,
2448:                            Types.VARCHAR, "VARCHAR", "String"),
2449:                    new Field("FKCOLUMN_NAME", "FKCOLUMN_NAME", 10,
2450:                            Types.VARCHAR, "VARCHAR", "String"),
2451:                    new Field("KEY_SEQ", "KEY_SEQ", 10, Types.SMALLINT,
2452:                            "SMALLINT", "Short"),
2453:                    new Field("UPDATE_RULE", "UPDATE_RULE", 10, Types.SMALLINT,
2454:                            "SMALLINT", "Short"),
2455:                    new Field("DELETE_RULE", "DELETE_RULE", 10, Types.SMALLINT,
2456:                            "SMALLINT", "Short"),
2457:                    new Field("FK_NAME", "FK_NAME", 10, Types.VARCHAR,
2458:                            "VARCHAR", "String"),
2459:                    new Field("PK_NAME", "PK_NAME", 10, Types.VARCHAR,
2460:                            "VARCHAR", "String"),
2461:                    new Field("DEFERRABILITY", "DEFERRABILITY", 10,
2462:                            Types.SMALLINT, "SMALLINT", "Short") };
2463:
2464:            /**
2465:             * @see java.sql.DatabaseMetaData#getIndexInfo(java.lang.String,
2466:             *      java.lang.String, java.lang.String, boolean, boolean)
2467:             */
2468:            private static Field[] getIndexInfoFields = new Field[] {
2469:                    new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR,
2470:                            "VARCHAR", "String"),
2471:                    new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR,
2472:                            "VARCHAR", "String"),
2473:                    new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR,
2474:                            "VARCHAR", "String"),
2475:                    new Field("NON_UNIQUE", "NON_UNIQUE", 10, Types.INTEGER,
2476:                            "INTEGER", "Integer"),
2477:                    new Field("INDEX_QUALIFIER", "INDEX_QUALIFIER", 10,
2478:                            Types.VARCHAR, "VARCHAR", "String"),
2479:                    new Field("INDEX_NAME", "INDEX_NAME", 10, Types.VARCHAR,
2480:                            "VARCHAR", "String"),
2481:                    new Field("TYPE", "TYPE", 10, Types.SMALLINT, "SMALLINT",
2482:                            "Short"),
2483:                    new Field("ORDINAL_POSITION", "ORDINAL_POSITION", 10,
2484:                            Types.SMALLINT, "SMALLINT", "Short"),
2485:                    new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR,
2486:                            "VARCHAR", "String"),
2487:                    new Field("ASC_OR_DESC", "ASC_OR_DESC", 10, Types.VARCHAR,
2488:                            "VARCHAR", "String"),
2489:                    new Field("CARDINALITY", "CARDINALITY", 10, Types.INTEGER,
2490:                            "INTEGER", "Integer"),
2491:                    new Field("PAGES", "PAGES", 10, Types.INTEGER, "INTEGER",
2492:                            "Integer"),
2493:                    new Field("FILTER_CONDITION", "FILTER_CONDITION", 10,
2494:                            Types.VARCHAR, "VARCHAR", "String") };
2495:
2496:            /**
2497:             * @see java.sql.DatabaseMetaData#getPrimaryKeys(java.lang.String,
2498:             *      java.lang.String, java.lang.String)
2499:             */
2500:            private static Field[] getPrimaryKeysFields = new Field[] {
2501:                    new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR,
2502:                            "VARCHAR", "String"),
2503:                    new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR,
2504:                            "VARCHAR", "String"),
2505:                    new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR,
2506:                            "VARCHAR", "String"),
2507:                    new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR,
2508:                            "VARCHAR", "String"),
2509:                    new Field("KEY_SEQ", "KEY_SEQ", 10, Types.SMALLINT,
2510:                            "SMALLINT", "Short"),
2511:                    new Field("PK_NAME", "PK_NAME", 10, Types.VARCHAR,
2512:                            "VARCHAR", "String") };
2513:            /**
2514:             * @see java.sql.DatabaseMetaData#getProcedureColumns(java.lang.String,
2515:             *      java.lang.String, java.lang.String, java.lang.String)
2516:             */
2517:            private static Field[] getProcedureColumnsFields = new Field[] {
2518:                    new Field("PROCEDURE_CAT", "PROCEDURE_CAT", 9,
2519:                            Types.VARCHAR, "VARCHAR", "String"),
2520:                    new Field("PROCEDURE_SCHEM", "PROCEDURE_SCHEM", 10,
2521:                            Types.VARCHAR, "VARCHAR", "String"),
2522:                    new Field("PROCEDURE_NAME", "PROCEDURE_NAME", 10,
2523:                            Types.VARCHAR, "VARCHAR", "String"),
2524:                    new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR,
2525:                            "VARCHAR", "String"),
2526:                    new Field("COLUMN_TYPE", "COLUMN_TYPE", 10, Types.SMALLINT,
2527:                            "SMALLINT", "Short"),
2528:                    new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT,
2529:                            "SMALLINT", "Short"),
2530:                    new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR,
2531:                            "VARCHAR", "String"),
2532:                    new Field("PRECISION", "PRECISION", 10, Types.FLOAT,
2533:                            "FLOAT", "Float"),
2534:                    new Field("LENGTH", "LENGTH", 10, Types.INTEGER, "INTEGER",
2535:                            "Integer"),
2536:                    new Field("SCALE", "SCALE", 10, Types.SMALLINT, "SMALLINT",
2537:                            "Short"),
2538:                    new Field("RADIX", "RADIX", 10, Types.SMALLINT, "SMALLINT",
2539:                            "Short"),
2540:                    new Field("NULLABLE", "NULLABLE", 10, Types.SMALLINT,
2541:                            "SMALLINT", "Short"),
2542:                    new Field("REMARKS", "REMARKS", 10, Types.VARCHAR,
2543:                            "VARCHAR", "String") };
2544:
2545:            /**
2546:             * @see java.sql.DatabaseMetaData#getProcedures(java.lang.String,
2547:             *      java.lang.String, java.lang.String)
2548:             */
2549:            private static Field[] getProceduresFields = new Field[] {
2550:                    new Field("PROCEDURE_CAT", "PROCEDURE_CAT", 9,
2551:                            Types.VARCHAR, "VARCHAR", "String"),
2552:                    new Field("PROCEDURE_SCHEM", "PROCEDURE_SCHEM", 10,
2553:                            Types.VARCHAR, "VARCHAR", "String"),
2554:                    new Field("PROCEDURE_NAME", "PROCEDURE_NAME", 10,
2555:                            Types.VARCHAR, "VARCHAR", "String"),
2556:                    new Field("", "", 0, Types.VARCHAR, "VARCHAR", "String"),
2557:                    new Field("", "", 0, Types.VARCHAR, "VARCHAR", "String"),
2558:                    new Field("", "", 0, Types.VARCHAR, "VARCHAR", "String"),
2559:                    new Field("REMARKS", "REMARKS", 10, Types.VARCHAR,
2560:                            "VARCHAR", "String"),
2561:                    new Field("PROCEDURE_TYPE", "PROCEDURE_TYPE", 10,
2562:                            Types.SMALLINT, "SMALLINT", "Short") };
2563:
2564:            /**
2565:             * @see java.sql.DatabaseMetaData#getSchemas()
2566:             */
2567:            private static Field[] getSchemasFields = new Field[] {
2568:                    new Field("TABLE_SCHEM", "TABLE_SCHEM", 9, Types.VARCHAR,
2569:                            "VARCHAR", "String"),
2570:                    new Field("TABLE_CATALOG", "TABLE_CATALOG", 9,
2571:                            Types.VARCHAR, "VARCHAR", "String") };
2572:
2573:            /**
2574:             * @see java.sql.DatabaseMetaData#getSuperTables(java.lang.String,
2575:             *      java.lang.String, java.lang.String)
2576:             */
2577:            private static Field[] getSuperTablesFields = new Field[] {
2578:                    new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR,
2579:                            "VARCHAR", "String"),
2580:                    new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR,
2581:                            "VARCHAR", "String"),
2582:                    new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR,
2583:                            "VARCHAR", "String"),
2584:                    new Field("SUPERTABLE_NAME", "SUPERTABLE_NAME", 10,
2585:                            Types.VARCHAR, "VARCHAR", "String") };
2586:
2587:            /**
2588:             * @see java.sql.DatabaseMetaData#getSuperTypes(java.lang.String,
2589:             *      java.lang.String, java.lang.String)
2590:             */
2591:            private static Field[] getSuperTypesFields = new Field[] {
2592:                    new Field("TYPE_CAT", "TYPE_CAT", 9, Types.VARCHAR,
2593:                            "VARCHAR", "String"),
2594:                    new Field("TYPE_SCHEM", "TYPE_SCHEM", 10, Types.VARCHAR,
2595:                            "VARCHAR", "String"),
2596:                    new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR,
2597:                            "VARCHAR", "String"),
2598:                    new Field("SUPERTYPE_CAT", "SUPERTYPE_CAT", 10,
2599:                            Types.VARCHAR, "VARCHAR", "String"),
2600:                    new Field("SUPERTYPE_SCHEM", "SUPERTYPE_SCHEM", 10,
2601:                            Types.VARCHAR, "VARCHAR", "String") };
2602:
2603:            /**
2604:             * @see java.sql.DatabaseMetaData#getTablePrivileges(java.lang.String,
2605:             *      java.lang.String, java.lang.String)
2606:             */
2607:            private static Field[] getTablePrivilegesFields = new Field[] {
2608:                    new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR,
2609:                            "VARCHAR", "String"),
2610:                    new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR,
2611:                            "VARCHAR", "String"),
2612:                    new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR,
2613:                            "VARCHAR", "String"),
2614:                    new Field("GRANTOR", "GRANTOR", 10, Types.VARCHAR,
2615:                            "VARCHAR", "String"),
2616:                    new Field("GRANTEE", "GRANTEE", 10, Types.VARCHAR,
2617:                            "VARCHAR", "String"),
2618:                    new Field("PRIVILEGE", "PRIVILEGE", 10, Types.VARCHAR,
2619:                            "VARCHAR", "String"),
2620:                    new Field("IS_GRANTABLE", "IS_GRANTABLE", 10,
2621:                            Types.VARCHAR, "VARCHAR", "String"), };
2622:
2623:            /**
2624:             * @see java.sql.DatabaseMetaData#getTables(String, String, String, String[])
2625:             */
2626:            private static Field[] getTablesFields = new Field[] {
2627:                    new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR,
2628:                            "VARCHAR", "String"),
2629:                    new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR,
2630:                            "VARCHAR", "String"),
2631:                    new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR,
2632:                            "VARCHAR", "String"),
2633:                    new Field("TABLE_TYPE", "TABLE_TYPE", 10, Types.VARCHAR,
2634:                            "VARCHAR", "String"),
2635:                    new Field("REMARKS", "REMARKS", 10, Types.VARCHAR,
2636:                            "VARCHAR", "String"),
2637:                    new Field("TYPE_CAT", "TYPE_CAT", 10, Types.VARCHAR,
2638:                            "VARCHAR", "String"),
2639:                    new Field("TYPE_SCHEM", "TYPE_SCHEM", 10, Types.VARCHAR,
2640:                            "VARCHAR", "String"),
2641:                    new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR,
2642:                            "VARCHAR", "String"),
2643:                    new Field("SELF_REFERENCING_COL_NAME",
2644:                            "SELF_REFERENCING_COL_NAME", 25, Types.VARCHAR,
2645:                            "VARCHAR", "String"),
2646:                    new Field("REF_GENERATION", "REF_GENERATION", 15,
2647:                            Types.VARCHAR, "VARCHAR", "String") };
2648:
2649:            /**
2650:             * @see java.sql.DatabaseMetaData#getTableTypes()
2651:             */
2652:            private static Field[] getTableTypesFields = new Field[] { new Field(
2653:                    "TABLE_TYPE", "TABLE_TYPE", 9, Types.VARCHAR, "VARCHAR",
2654:                    "String") };
2655:
2656:            /**
2657:             * @see java.sql.DatabaseMetaData#getTypeInfo()
2658:             */
2659:            private static Field[] getTypeInfoFields = new Field[] {
2660:                    new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR,
2661:                            "VARCHAR", "String"),
2662:                    new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT,
2663:                            "SMALLINT", "Short"),
2664:                    new Field("PRECISION", "PRECISION", 10, Types.INTEGER,
2665:                            "INTEGER", "Integer"),
2666:                    new Field("LITERAL_PREFIX", "LITERAL_PREFIX", 10,
2667:                            Types.VARCHAR, "VARCHAR", "String"),
2668:                    new Field("LITERAL_SUFFIX", "LITERAL_SUFFIX", 10,
2669:                            Types.VARCHAR, "VARCHAR", "String"),
2670:                    new Field("CREATE_PARAMS", "CREATE_PARAMS", 10,
2671:                            Types.VARCHAR, "VARCHAR", "String"),
2672:                    new Field("NULLABLE", "NULLABLE", 10, Types.INTEGER,
2673:                            "INTEGER", "Integer"),
2674:                    new Field("CASE_SENSITIVE", "CASE_SENSITIVE", 10,
2675:                            Types.INTEGER, "INTEGER", "Integer"),
2676:                    new Field("SEARCHABLE", "SEARCHABLE", 10, Types.SMALLINT,
2677:                            "SMALLINT", "Short"),
2678:                    new Field("UNSIGNED_ATTRIBUTE", "UNSIGNED_ATTRIBUTE", 10,
2679:                            Types.INTEGER, "INTEGER", "Integer"),
2680:                    new Field("FIXED_PREC_SCALE", "FIXED_PREC_SCALE", 10,
2681:                            Types.INTEGER, "INTEGER", "Integer"),
2682:                    new Field("AUTO_INCREMENT", "AUTO_INCREMENT", 10,
2683:                            Types.INTEGER, "INTEGER", "Integer"),
2684:                    new Field("LOCAL_TYPE_NAME", "LOCAL_TYPE_NAME", 10,
2685:                            Types.VARCHAR, "VARCHAR", "String"),
2686:                    new Field("MINIMUM_SCALE", "MINIMUM_SCALE", 10,
2687:                            Types.SMALLINT, "SMALLINT", "Short"),
2688:                    new Field("MAXIMUM_SCALE", "MAXIMUM_SCALE", 10,
2689:                            Types.SMALLINT, "SMALLINT", "Short"),
2690:                    new Field("SQL_DATA_TYPE", "SQL_DATA_TYPE", 10,
2691:                            Types.INTEGER, "INTEGER", "Integer"),
2692:                    new Field("SQL_DATETIME_SUB", "SQL_DATETIME_SUB", 10,
2693:                            Types.INTEGER, "INTEGER", "Integer"),
2694:                    new Field("NUM_PREC_RADIX", "NUM_PREC_RADIX", 10,
2695:                            Types.INTEGER, "INTEGER", "Integer") };
2696:
2697:            /**
2698:             * @see java.sql.DatabaseMetaData#getUDTs(java.lang.String, java.lang.String,
2699:             *      java.lang.String, int[])
2700:             */
2701:            private static Field[] getUDTsFields = new Field[] {
2702:                    new Field("TYPE_CAT", "TYPE_CAT", 9, Types.VARCHAR,
2703:                            "VARCHAR", "String"),
2704:                    new Field("TYPE_SCHEM", "TYPE_SCHEM", 10, Types.VARCHAR,
2705:                            "VARCHAR", "String"),
2706:                    new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR,
2707:                            "VARCHAR", "String"),
2708:                    new Field("CLASS_NAME", "CLASS_NAME", 10, Types.VARCHAR,
2709:                            "VARCHAR", "String"),
2710:                    new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT,
2711:                            "SMALLINT", "Short"),
2712:                    new Field("REMARKS", "REMARKS", 10, Types.VARCHAR,
2713:                            "VARCHAR", "String"),
2714:                    new Field("BASE_TYPE", "BASE_TYPE", 10, Types.SMALLINT,
2715:                            "SMALLINT", "Short") };
2716:
2717:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.