Source Code Cross Referenced for SqlDriver.java in  » Testing » PolePosition-0.20 » com » versant » core » jdbc » sql » 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 » Testing » PolePosition 0.20 » com.versant.core.jdbc.sql 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998 - 2005 Versant Corporation
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         * Versant Corporation - initial API and implementation
0010:         */
0011:        package com.versant.core.jdbc.sql;
0012:
0013:        import com.versant.core.jdbc.metadata.*;
0014:        import com.versant.core.jdbc.sql.exp.*;
0015:        import com.versant.core.jdbc.sql.conv.*;
0016:        import com.versant.core.jdbc.sql.diff.*;
0017:        import com.versant.core.jdbc.JdbcConverterFactory;
0018:        import com.versant.core.jdbc.JdbcMetaDataBuilder;
0019:        import com.versant.core.jdbc.JdbcUtils;
0020:        import com.versant.core.jdbc.conn.StatementWithLastSQL;
0021:        import com.versant.core.util.CharBuf;
0022:        import com.versant.core.util.classhelper.ClassHelper;
0023:        import com.versant.core.jdo.query.AggregateNode;
0024:        import com.versant.core.metadata.MDStatics;
0025:        import com.versant.core.metadata.MDStaticUtils;
0026:        import com.versant.core.metadata.ClassMetaData;
0027:
0028:        import java.util.*;
0029:        import java.util.Date;
0030:        import java.sql.*;
0031:        import java.math.BigDecimal;
0032:        import java.math.BigInteger;
0033:        import java.io.PrintWriter;
0034:        import java.io.File;
0035:        import java.net.URL;
0036:        import java.text.DecimalFormatSymbols;
0037:        import java.text.DecimalFormat;
0038:        import java.text.NumberFormat;
0039:
0040:        import com.versant.core.common.BindingSupportImpl;
0041:        import com.versant.core.common.Debug;
0042:
0043:        /**
0044:         * This is the base class for the classes responsible for generating SQL
0045:         * for different databases and interfacing to JDBC drivers. There is normally
0046:         * one shared instance per Store. This class is also responsible for creating
0047:         * columns for fields and so on during meta data generation.<p>
0048:         */
0049:        public abstract class SqlDriver {
0050:
0051:            public static final char[] DEFAULT_PARAM_CHARS = new char[] { '?' };
0052:
0053:            /**
0054:             * These are all the JDBC type codes that we care about. All SqlDriver
0055:             * subclasses must provide a mapping for each of these.
0056:             */
0057:            public static final int[] JDBC_TYPES = new int[] { Types.BIT,
0058:                    Types.TINYINT, Types.SMALLINT, Types.INTEGER, Types.BIGINT,
0059:                    Types.FLOAT, Types.REAL, Types.DOUBLE, Types.NUMERIC,
0060:                    Types.DECIMAL, Types.CHAR, Types.VARCHAR,
0061:                    Types.LONGVARCHAR, Types.DATE, Types.TIME, Types.TIMESTAMP,
0062:                    Types.BINARY, Types.VARBINARY, Types.LONGVARBINARY,
0063:                    Types.BLOB, Types.CLOB, };
0064:
0065:            protected BytesConverter.Factory bytesConverterFactory = new BytesConverter.Factory();
0066:            protected NullBytesAsBinaryConverter.Factory nullBytesAsBinaryConverterFactory = new NullBytesAsBinaryConverter.Factory();
0067:
0068:            protected static final int COMMENT_COL = 40;
0069:
0070:            private static char[] FOR_UPDATE = " FOR UPDATE".toCharArray();
0071:
0072:            private ArrayList allTableList = null;
0073:
0074:            protected static DecimalFormat doubleFormat;
0075:
0076:            public SqlDriver() {
0077:                doubleFormat = new DecimalFormat("#.#",
0078:                        new DecimalFormatSymbols(Locale.US));
0079:            }
0080:
0081:            /**
0082:             * Get the name of this driver.
0083:             */
0084:            public abstract String getName();
0085:
0086:            public int getMajorVersion() {
0087:                return -1;
0088:            }
0089:
0090:            public int getMinorVersion() {
0091:                return -1;
0092:            }
0093:
0094:            public String getMinorVersionPatchLevel() {
0095:                return "NOT_SET";
0096:            }
0097:
0098:            public String getVersion() {
0099:                return "NOT_SET";
0100:            }
0101:
0102:            /**
0103:             * Create a SqlDriver instance by name.
0104:             *
0105:             * @param jdbcDriver Optional JDBC driver for more accurate feature use
0106:             * @throws javax.jdo.JDOFatalUserException
0107:             *          if name is invalid
0108:             * @see #customizeForServer
0109:             */
0110:            public static SqlDriver createSqlDriver(String name,
0111:                    Driver jdbcDriver) {
0112:                SqlDriver ans = null;
0113:
0114:                if (name.equals("informix")) {
0115:                    ans = new InformixSqlDriver();
0116:                } else if (name.equals("informixse")) {
0117:                    ans = new InformixSESqlDriver();
0118:                } else if (name.equals("sybase")) {
0119:                    ans = new SybaseSqlDriver();
0120:                } else if (name.equals("db2")) {
0121:                    ans = new DB2SqlDriver();
0122:                } else if (name.equals("mssql")) {
0123:                    ans = new MsSqlDriver();
0124:
0125:                } else if (name.equals("postgres")) {
0126:                    ans = new PostgresSqlDriver();
0127:                } else if (name.equals("oracle")) {
0128:                    ans = new OracleSqlDriver();
0129:
0130:                } else if (name.equals("hypersonic")) {
0131:                    ans = new HypersonicSqlDriver();
0132:                } else if (name.equals("instantdb")) {
0133:                    ans = new InstantDbSqlDriver();
0134:                } else if (name.equals("mckoi")) {
0135:                    ans = new MckoiSqlDriver();
0136:                } else if (name.equals("sapdb")) {
0137:                    ans = new SapDbSqlDriver();
0138:                } else if (name.equals("interbase")) {
0139:                    ans = new InterbaseSqlDriver();
0140:                } else if (name.equals("pointbase")) {
0141:                    ans = new PointbaseSqlDriver();
0142:                } else if (name.equals("firebird")) {
0143:                    ans = new FirebirdSqlDriver();
0144:                } else if (name.equals("mysql")) {
0145:                    ans = new MySqlSqlDriver();
0146:                } else if (name.equals("daffodil")) {
0147:                    ans = new DaffodilSqlDriver();
0148:                } else if (name.equals("cache")) {
0149:                    ans = new CacheSqlDriver();
0150:
0151:                } else {
0152:                    throw BindingSupportImpl.getInstance().runtime(
0153:                            "Unknown db: " + name);
0154:                }
0155:                if (jdbcDriver != null)
0156:                    ans.init(jdbcDriver);
0157:                return ans;
0158:            }
0159:
0160:            /**
0161:             * Try and guess an appropriate SqlDriver name from a JDBC URL. Returns
0162:             * null if no match.
0163:             */
0164:            public static String getNameFromURL(String url) {
0165:                url = url.toLowerCase();
0166:                int i = url.indexOf(':');
0167:                if (i < 0)
0168:                    return null;
0169:                int j = ++i + 1;
0170:                int n = url.length();
0171:                for (; j < n; j++) {
0172:                    char c = url.charAt(j);
0173:                    if (c < 'a' || c > 'z')
0174:                        break;
0175:                }
0176:                String key = url.substring(i, j);
0177:                String[] a = new String[] { "cache", "cache", "db2", "db2",
0178:                        "firebirdsql", "firebird", "hsqldb", "hypersonic",
0179:                        "informix", "informix", "interbase", "interbase",
0180:                        "microsoft", "mssql", "mysql", "mysql", "oracle",
0181:                        "oracle", "pointbase", "pointbase", "postgresql",
0182:                        "postgres", "sapdb", "sapdb", "sybase", "sybase", };
0183:                for (i = 0; i < a.length; i += 2) {
0184:                    if (a[i].equals(key))
0185:                        return a[i + 1];
0186:                }
0187:                return null;
0188:            }
0189:
0190:            /**
0191:             * Try and guess an appropriate SqlDriver name from a JDBC URL. Returns
0192:             * null if no match.
0193:             */
0194:            public static String getDriverFromURL(String url) {
0195:                if (url == null)
0196:                    return null;
0197:                url = url.toLowerCase();
0198:                int i = url.indexOf(':');
0199:                if (i < 0)
0200:                    return null;
0201:                int j = ++i + 1;
0202:                int n = url.length();
0203:                for (; j < n; j++) {
0204:                    char c = url.charAt(j);
0205:                    if (c < 'a' || c > 'z')
0206:                        break;
0207:                }
0208:                String key = url.substring(i, j);
0209:                String[] a = new String[] { "cache",
0210:                        "com.intersys.jdbc.CacheDriver", "db2",
0211:                        "com.ibm.db2.jcc.DB2Driver", "firebirdsql",
0212:                        "org.firebirdsql.jdbc.FBDriver", "hsqldb",
0213:                        "org.hsqldb.jdbcDriver", "informix",
0214:                        "com.informix.jdbc.IfxDriver", "interbase",
0215:                        "interbase.interclient.Driver", "microsoft",
0216:                        "com.microsoft.jdbc.sqlserver.SQLServerDriver",
0217:                        "mysql", "com.mysql.jdbc.Driver", "oracle",
0218:                        "oracle.jdbc.driver.OracleDriver", "pointbase",
0219:                        "com.pointbase.jdbc.jdbcUniversalDriver", "postgresql",
0220:                        "org.postgresql.Driver", "sapdb",
0221:                        "com.sap.dbtech.jdbc.DriverSapDB", "sybase",
0222:                        "com.sybase.jdbc2.jdbc.SybDriver", };
0223:                for (i = 0; i < a.length; i += 2) {
0224:                    if (a[i].equals(key))
0225:                        return a[i + 1];
0226:                }
0227:                return null;
0228:            }
0229:
0230:            /**
0231:             * Load a JDBC driver class and create an instance of it. The driver
0232:             * class is unregistered if possible.
0233:             */
0234:            public static Driver createJdbcDriver(String name, ClassLoader cl) {
0235:                Class cls = null;
0236:                try {
0237:                    cls = ClassHelper.get().classForName(name, true, cl);
0238:                } catch (ClassNotFoundException e) {
0239:                    throw BindingSupportImpl.getInstance().invalidOperation(
0240:                            "JDBC Driver class '" + name
0241:                                    + "' is not available in the classpath");
0242:                }
0243:                Driver driver = null;
0244:                try {
0245:                    java.lang.Object drv = cls.newInstance();
0246:                    driver = (Driver) drv;
0247:                } catch (Exception e) {
0248:                    BindingSupportImpl.getInstance().runtime(
0249:                            "Unable to create "
0250:                                    + "instance of JDBC Driver class '" + name
0251:                                    + "': " + e, e);
0252:                }
0253:                try {
0254:                    DriverManager.deregisterDriver(driver);
0255:                } catch (Exception x) {
0256:                    // ignore
0257:                }
0258:                return driver;
0259:            }
0260:
0261:            /**
0262:             * Get the default type mappings for this driver. These map JDBC type
0263:             * codes from java.sql.Types to column properties.
0264:             *
0265:             * @see #getTypeMapping
0266:             */
0267:            public final JdbcTypeMapping[] getTypeMappings() {
0268:                int n = JDBC_TYPES.length;
0269:                JdbcTypeMapping[] a = new JdbcTypeMapping[n];
0270:                String database = getName();
0271:                for (int i = 0; i < n; i++) {
0272:                    int jdbcType = JDBC_TYPES[i];
0273:                    JdbcTypeMapping m = getTypeMapping(jdbcType);
0274:                    if (m != null) {
0275:                        m.setDatabase(database);
0276:                        m.setJdbcType(jdbcType);
0277:                    }
0278:                    a[i] = m;
0279:                }
0280:                return a;
0281:            }
0282:
0283:            /**
0284:             * Get the default type mapping for the supplied JDBC type code from
0285:             * java.sql.Types or null if the type is not supported. There is no
0286:             * need to set the database or jdbcType on the mapping as this is done
0287:             * after this call returns. Subclasses should override this and to
0288:             * customize type mappings.
0289:             */
0290:            protected JdbcTypeMapping getTypeMapping(int jdbcType) {
0291:                switch (jdbcType) {
0292:                case Types.BIT:
0293:                case Types.TINYINT:
0294:                case Types.SMALLINT:
0295:                case Types.INTEGER:
0296:                case Types.BIGINT:
0297:                    return new JdbcTypeMapping(JdbcTypes.toString(jdbcType), 0,
0298:                            0, JdbcTypeMapping.TRUE, JdbcTypeMapping.TRUE, null);
0299:                case Types.FLOAT:
0300:                case Types.REAL:
0301:                case Types.DOUBLE:
0302:                case Types.DATE:
0303:                case Types.TIME:
0304:                case Types.TIMESTAMP:
0305:                case Types.BLOB:
0306:                case Types.CLOB:
0307:                case Types.LONGVARCHAR:
0308:                case Types.LONGVARBINARY:
0309:                    return new JdbcTypeMapping(JdbcTypes.toString(jdbcType), 0,
0310:                            0, JdbcTypeMapping.TRUE, JdbcTypeMapping.FALSE,
0311:                            null);
0312:                case Types.DECIMAL:
0313:
0314:                case Types.NUMERIC:
0315:                    return new JdbcTypeMapping(JdbcTypes.toString(jdbcType),
0316:                            20, 10, JdbcTypeMapping.TRUE, JdbcTypeMapping.TRUE,
0317:                            null);
0318:                case Types.CHAR:
0319:                case Types.VARCHAR:
0320:                    return new JdbcTypeMapping(JdbcTypes.toString(jdbcType),
0321:                            255, 0, JdbcTypeMapping.TRUE, JdbcTypeMapping.TRUE,
0322:                            null);
0323:                case Types.BINARY:
0324:                case Types.VARBINARY:
0325:                    return new JdbcTypeMapping(JdbcTypes.toString(jdbcType),
0326:                            255, 0, JdbcTypeMapping.TRUE, JdbcTypeMapping.TRUE,
0327:                            bytesConverterFactory);
0328:                }
0329:                throw BindingSupportImpl.getInstance().internal(
0330:                        "Invalid type in getTypeMapping: " + jdbcType);
0331:            }
0332:
0333:            /**
0334:             * Get the default field mappings for this driver. These map java classes
0335:             * to column properties. Subclasses should override this, call super() and
0336:             * replace mappings as needed.
0337:             */
0338:            public HashMap getJavaTypeMappings() {
0339:                HashMap ans = new HashMap(61);
0340:
0341:                add(ans,
0342:                        new JdbcJavaTypeMapping(Boolean.TYPE, Types.BIT, false));
0343:                add(ans,
0344:                        new JdbcJavaTypeMapping(Boolean.class, Types.BIT, true));
0345:                add(ans, new JdbcJavaTypeMapping(Byte.TYPE, Types.TINYINT,
0346:                        false));
0347:                add(ans, new JdbcJavaTypeMapping(Byte.class, Types.TINYINT,
0348:                        true));
0349:                add(ans, new JdbcJavaTypeMapping(Short.TYPE, Types.SMALLINT,
0350:                        false));
0351:                add(ans, new JdbcJavaTypeMapping(Short.class, Types.SMALLINT,
0352:                        true));
0353:                add(ans, new JdbcJavaTypeMapping(Integer.TYPE, Types.INTEGER,
0354:                        false));
0355:                add(ans, new JdbcJavaTypeMapping(Integer.class, Types.INTEGER,
0356:                        true));
0357:                add(ans, new JdbcJavaTypeMapping(Character.TYPE, Types.CHAR,
0358:                        false));
0359:                add(ans, new JdbcJavaTypeMapping(Character.class, Types.CHAR,
0360:                        true));
0361:                add(ans,
0362:                        new JdbcJavaTypeMapping(Long.TYPE, Types.BIGINT, false));
0363:                add(ans,
0364:                        new JdbcJavaTypeMapping(Long.class, Types.BIGINT, true));
0365:                add(ans, new JdbcJavaTypeMapping(Float.TYPE, Types.REAL, false,
0366:                        false));
0367:                add(ans, new JdbcJavaTypeMapping(Float.class, Types.REAL, true,
0368:                        false));
0369:                add(ans, new JdbcJavaTypeMapping(Double.TYPE, Types.DOUBLE,
0370:                        false, false));
0371:                add(ans, new JdbcJavaTypeMapping(Double.class, Types.DOUBLE,
0372:                        true, false));
0373:
0374:                add(ans, new JdbcJavaTypeMapping(String.class, Types.VARCHAR,
0375:                        true));
0376:                add(ans, new JdbcJavaTypeMapping(Date.class, Types.TIMESTAMP,
0377:                        true, false));
0378:                add(ans, new JdbcJavaTypeMapping(BigDecimal.class,
0379:                        Types.NUMERIC, true));
0380:
0381:                add(ans, new JdbcJavaTypeMapping(BigInteger.class,
0382:                        Types.NUMERIC, 20, 0, JdbcJavaTypeMapping.TRUE, null));
0383:
0384:                JdbcConverterFactory f = new LocaleConverter.Factory();
0385:                add(ans, new JdbcJavaTypeMapping(Locale.class, Types.CHAR, 6,
0386:                        0, JdbcJavaTypeMapping.TRUE, f));
0387:
0388:                f = new CharConverter.Factory();
0389:                add(ans, new JdbcJavaTypeMapping(Character.class, Types.CHAR,
0390:                        1, 0, JdbcJavaTypeMapping.TRUE, f));
0391:                add(ans, new JdbcJavaTypeMapping(Character.TYPE, Types.CHAR, 1,
0392:                        0, JdbcJavaTypeMapping.FALSE, f));
0393:
0394:                // primitive array[] mappings
0395:                f = new ByteArrayConverter.Factory();
0396:                add(ans, new JdbcJavaTypeMapping(byte[].class, Types.BLOB, f));
0397:                f = new ShortArrayConverter.Factory();
0398:                add(ans, new JdbcJavaTypeMapping(short[].class, Types.BLOB, f));
0399:                f = new IntArrayConverter.Factory();
0400:                add(ans, new JdbcJavaTypeMapping(int[].class, Types.BLOB, f));
0401:                f = new LongArrayConverter.Factory();
0402:                add(ans, new JdbcJavaTypeMapping(long[].class, Types.BLOB, f));
0403:                f = new BooleanArrayConverter.Factory();
0404:                add(ans,
0405:                        new JdbcJavaTypeMapping(boolean[].class, Types.BLOB, f));
0406:                f = new CharArrayConverter.Factory();
0407:                add(ans, new JdbcJavaTypeMapping(char[].class, Types.BLOB, f));
0408:                f = new FloatArrayConverter.Factory();
0409:                add(ans, new JdbcJavaTypeMapping(float[].class, Types.BLOB, f));
0410:                f = new DoubleArrayConverter.Factory();
0411:                add(ans, new JdbcJavaTypeMapping(double[].class, Types.BLOB, f));
0412:
0413:                // extended types
0414:                add(ans, new JdbcJavaTypeMapping(File.class, Types.VARCHAR, -1,
0415:                        0, JdbcJavaTypeMapping.NOT_SET,
0416:                        new FileConverter.Factory(), false));
0417:                add(ans, new JdbcJavaTypeMapping(URL.class, Types.VARCHAR, -1,
0418:                        0, JdbcJavaTypeMapping.NOT_SET,
0419:                        new URLConverter.Factory(), false));
0420:                add(ans, new JdbcJavaTypeMapping(Timestamp.class,
0421:                        Types.TIMESTAMP, new TimestampConverter.Factory(),
0422:                        false));
0423:
0424:                return ans;
0425:            }
0426:
0427:            /**
0428:             * Add m to ans using its javaType as the key.
0429:             */
0430:            protected void add(HashMap ans, JdbcJavaTypeMapping m) {
0431:                m.setDatabase(getName());
0432:                ans.put(m.getJavaType(), m);
0433:            }
0434:
0435:            /**
0436:             * Perform any driver specific customization. This can be used to control
0437:             * functionality depending on the version of JDBC driver in use etc.
0438:             */
0439:            protected void init(Driver jdbcDriver) {
0440:            }
0441:
0442:            /**
0443:             * Does this store do anything in {@link #customizeForServer(java.sql.Connection)}.
0444:             * This avoids allocating a connection if it is not required which sorts
0445:             * out a problem we have with Torpedo.
0446:             */
0447:            public boolean isCustomizeForServerRequired() {
0448:                return false;
0449:            }
0450:
0451:            /**
0452:             * Perform any specific configuration appropriate for the database server
0453:             * in use. If any SQL is done on con call con.commit() before returning.
0454:             */
0455:            public void customizeForServer(Connection con) throws SQLException {
0456:            }
0457:
0458:            /**
0459:             * Create a default name generator instance for JdbcStore's using this
0460:             * driver.
0461:             */
0462:            public JdbcNameGenerator createJdbcNameGenerator() {
0463:                return createDefaultJdbcNameGenerator();
0464:            }
0465:
0466:            protected DefaultJdbcNameGenerator createDefaultJdbcNameGenerator() {
0467:                DefaultJdbcNameGenerator ans = new DefaultJdbcNameGenerator();
0468:                ans.setDatabaseType(getName());
0469:                return ans;
0470:            }
0471:
0472:            /**
0473:             * Some drivers require a call to clear the batches.
0474:             *
0475:             * @return
0476:             */
0477:            public boolean isClearBatchRequired() {
0478:                return false;
0479:            }
0480:
0481:            /**
0482:             * Does the JDBC driver support statement batching for inserts?
0483:             */
0484:            public boolean isInsertBatchingSupported() {
0485:                return false;
0486:            }
0487:
0488:            /**
0489:             * Does the JDBC driver support statement batching for updates?
0490:             */
0491:            public boolean isUpdateBatchingSupported() {
0492:                return false;
0493:            }
0494:
0495:            /**
0496:             * Can batching be used if the statement contains a column with the
0497:             * given JDBC type?
0498:             */
0499:            public boolean isBatchingSupportedForJdbcType(int jdbcType) {
0500:                return true;
0501:            }
0502:
0503:            /**
0504:             * Does the JDBC driver support scrollable result sets?
0505:             */
0506:            public boolean isScrollableResultSetSupported() {
0507:                return false;
0508:            }
0509:
0510:            /**
0511:             * Does the JDBC driver support Statement.setFetchSize()?
0512:             */
0513:            public boolean isFetchSizeSupported() {
0514:                return true;
0515:            }
0516:
0517:            /**
0518:             * Should PreparedStatement batching be used for this database and
0519:             * JDBC driver?
0520:             */
0521:            public boolean isPreparedStatementPoolingOK() {
0522:                return true;
0523:            }
0524:
0525:            /**
0526:             * How many PreparedStatement's should the pool be limited to by default
0527:             * (0 for unlimited) ?
0528:             */
0529:            public int getDefaultPsCacheMax() {
0530:                return 0;
0531:            }
0532:
0533:            /**
0534:             * Does this driver use the ANSI join syntax (i.e. the join clauses appear
0535:             * in the from list e.g. postgres)?
0536:             */
0537:            public boolean isAnsiJoinSyntax() {
0538:                return false;
0539:            }
0540:
0541:            /**
0542:             * May the ON clauses for joins in a subquery reference columns from the
0543:             * enclosing query? DB2 does not allow this.
0544:             */
0545:            public boolean isSubQueryJoinMayUseOuterQueryCols() {
0546:                return true;
0547:            }
0548:
0549:            /**
0550:             * Is null a valid value for a column with a foreign key constraint?
0551:             */
0552:            public boolean isNullForeignKeyOk() {
0553:                return false;
0554:            }
0555:
0556:            /**
0557:             * Must columns used in an order by statement appear in the select list?
0558:             */
0559:            public boolean isPutOrderColsInSelect() {
0560:                return false;
0561:            }
0562:
0563:            /**
0564:             * Should indexes be used for columns in the order by list that are
0565:             * also in the select list? This is used for databases that will not
0566:             * order by a column that is duplicated in the select list (e.g. Oracle).
0567:             */
0568:            public boolean isUseIndexesForOrderCols() {
0569:                return false;
0570:            }
0571:
0572:            public String getAliasPrepend() {
0573:                return " ";
0574:            }
0575:
0576:            /**
0577:             * Does the LIKE operator only support literal string and column
0578:             * arguments (e.g. Informix)?
0579:             */
0580:            public boolean isLikeStupid() {
0581:                return false;
0582:            }
0583:
0584:            /**
0585:             * What is the maximum number of parameters allowed for the IN (?, .. ?)
0586:             * operator?
0587:             */
0588:            public int getMaxInOperands() {
0589:                return 10;
0590:            }
0591:
0592:            /**
0593:             * Is it ok to convert simple 'exists (select ...)' clauses under an
0594:             * 'or' into outer joins?
0595:             */
0596:            public boolean isOptimizeExistsUnderOrToOuterJoin() {
0597:                return true;
0598:            }
0599:
0600:            /**
0601:             * Must 'exists (select ...)' clauses be converted into a join and
0602:             * distinct be added to the select (e.g. MySQL) ?
0603:             */
0604:            public boolean isConvertExistsToDistinctJoin() {
0605:                return false;
0606:            }
0607:
0608:            public boolean isConvertExistsToJoins(int type) {
0609:                switch (type) {
0610:                case SqlExp.NO:
0611:                    return false;
0612:                case SqlExp.YES:
0613:                    return true;
0614:                case SqlExp.YES_DISTINCT:
0615:                case SqlExp.YES_DISTINCT_NOT:
0616:                    return false;
0617:                default:
0618:                    throw BindingSupportImpl.getInstance().internal(
0619:                            "Unknown type '" + type + "'");
0620:                }
0621:            }
0622:
0623:            /**
0624:             * Must some expressions (+, -, string concat) be wrapped in brackets?
0625:             */
0626:            public boolean isExtraParens() {
0627:                return false;
0628:            }
0629:
0630:            /**
0631:             * Can the tx isolation level be set on this database?
0632:             */
0633:            public boolean isSetTransactionIsolationLevelSupported() {
0634:                return true;
0635:            }
0636:
0637:            /**
0638:             * Does this database support autoincrement or serial columns?
0639:             */
0640:            public boolean isAutoIncSupported() {
0641:                return false;
0642:            }
0643:
0644:            /**
0645:             * Does this database support comments embedded in SQL?
0646:             */
0647:            public boolean isCommentSupported() {
0648:                return true;
0649:            }
0650:
0651:            /**
0652:             * Generate SQL to create the database schema for the supplied tables.
0653:             * If con is not null then it must have autoCommit true.
0654:             */
0655:            public void generateDDL(ArrayList tables, Connection con,
0656:                    PrintWriter out, boolean comments) {
0657:                StatementWithLastSQL stat = null;
0658:                try {
0659:                    if (con != null) {
0660:                        stat = new StatementWithLastSQL(con.createStatement());
0661:                    }
0662:                    // generate the 'create table' statements
0663:                    int n = tables.size();
0664:                    for (int i = 0; i < n; i++) {
0665:                        JdbcTable t = (JdbcTable) tables.get(i);
0666:                        generateCreateTable(t, stat, out, comments);
0667:                    }
0668:                    // generate the 'create index' statements
0669:                    for (int i = 0; i < n; i++) {
0670:                        JdbcTable t = (JdbcTable) tables.get(i);
0671:                        generateCreateIndexes(t, stat, out, comments);
0672:                    }
0673:                    // generate the 'add constraint' statements
0674:                    for (int i = 0; i < n; i++) {
0675:                        JdbcTable t = (JdbcTable) tables.get(i);
0676:                        generateConstraints(t, stat, out, comments);
0677:                    }
0678:                } catch (SQLException x) {
0679:                    String msg;
0680:                    if (stat == null) {
0681:                        msg = x.toString();
0682:                    } else {
0683:                        msg = x + "\nMost recent SQL:\n" + stat.getLastSQL();
0684:                    }
0685:                    throw mapException(x, msg, false);
0686:                } finally {
0687:                    if (stat != null) {
0688:                        try {
0689:                            stat.close();
0690:                        } catch (SQLException e) {
0691:                            // ignore
0692:                        }
0693:                    }
0694:                }
0695:            }
0696:
0697:            /**
0698:             * Generate a 'create table' statement for t.
0699:             */
0700:            public void generateCreateTable(JdbcTable t, Statement stat,
0701:                    PrintWriter out, boolean comments) throws SQLException {
0702:                CharBuf s = new CharBuf();
0703:                if (comments && isCommentSupported() && t.comment != null) {
0704:                    s.append(comment(t.comment));
0705:                    s.append('\n');
0706:                }
0707:                s.append("CREATE TABLE ");
0708:                s.append(t.name);
0709:                s.append(" (\n");
0710:                JdbcColumn[] cols = t.getColsForCreateTable();
0711:                int nc = cols.length;
0712:                boolean first = true;
0713:                for (int i = 0; i < nc; i++) {
0714:                    if (first) {
0715:                        first = false;
0716:                    } else {
0717:                        s.append("\n");
0718:                    }
0719:                    s.append("    ");
0720:                    appendCreateColumn(t, cols[i], s, comments);
0721:                }
0722:                s.append("\n    ");
0723:                appendPrimaryKeyConstraint(t, s);
0724:                appendIndexesInCreateTable(t, s);
0725:                s.append("\n)");
0726:                appendTableType(t, s);
0727:                String sql = s.toString();
0728:                if (out != null) {
0729:                    print(out, sql);
0730:                }
0731:                if (stat != null) {
0732:                    stat.execute(sql);
0733:                }
0734:            }
0735:
0736:            /**
0737:             * Format a comment.
0738:             */
0739:            public String comment(String msg) {
0740:                return "-- " + msg;
0741:            }
0742:
0743:            /**
0744:             * Hook for drivers that have to append a table type to the create table
0745:             * statement (e.g. MySQL).
0746:             */
0747:            protected void appendTableType(JdbcTable t, CharBuf s) {
0748:            }
0749:
0750:            /**
0751:             * Hook for drivers that must create indexes in the create table
0752:             * statement (e.g. MySQL).
0753:             */
0754:            protected void appendIndexesInCreateTable(JdbcTable t, CharBuf s) {
0755:            }
0756:
0757:            /**
0758:             * Write an SQL statement to a script with appropriate separator.
0759:             */
0760:            protected void print(PrintWriter out, String sql) {
0761:                out.print(sql);
0762:                out.println(";");
0763:                out.println();
0764:            }
0765:
0766:            /**
0767:             * Append the part of a create table statement for a column.
0768:             */
0769:            protected void appendCreateColumn(JdbcTable t, JdbcColumn c,
0770:                    CharBuf s, boolean comments) {
0771:                int si = s.size();
0772:                s.append(c.name);
0773:                s.append(' ');
0774:                appendColumnType(c, s);
0775:                if (c.autoinc)
0776:                    appendCreateColumnAutoInc(t, c, s);
0777:                appendCreateColumnNulls(t, c, s);
0778:                s.append(',');
0779:                if (comments && isCommentSupported() && c.comment != null) {
0780:                    s.append(' ');
0781:                    si += COMMENT_COL;
0782:                    for (; s.size() < si; s.append(' '))
0783:                        ;
0784:                    s.append(comment(c.comment));
0785:                }
0786:            }
0787:
0788:            /**
0789:             * Append the column type part of a create table statement for a column.
0790:             */
0791:            protected void appendColumnType(JdbcColumn c, CharBuf s) {
0792:                appendColumnType(c, s, useZeroScale(c));
0793:            }
0794:
0795:            protected boolean useZeroScale(JdbcColumn c) {
0796:                return false;
0797:            }
0798:
0799:            /**
0800:             * Append the column type part of a create table statement for a column.
0801:             */
0802:            protected void appendColumnType(JdbcColumn c, CharBuf s,
0803:                    boolean useZeroScale) {
0804:                if (c.sqlType == null) {
0805:                    throw BindingSupportImpl.getInstance().internal(
0806:                            "sqlType is null: " + c);
0807:                }
0808:                s.append(c.sqlType);
0809:                if (c.length != 0 || c.scale != 0) {
0810:                    s.append('(');
0811:                    s.append(c.length);
0812:                    if (c.scale != 0 || useZeroScale) {
0813:                        s.append(',');
0814:                        s.append(c.scale);
0815:                    }
0816:                    s.append(')');
0817:                }
0818:            }
0819:
0820:            /**
0821:             * Get the database specific name for the jdbcType.
0822:             *
0823:             * @see Types
0824:             */
0825:            protected String getTypeName(int jdbcType) {
0826:                return JdbcTypes.toString(jdbcType);
0827:            }
0828:
0829:            /**
0830:             * Append the allow nulls part of the definition for a column in a
0831:             * create table statement.
0832:             */
0833:            protected void appendCreateColumnNulls(JdbcTable t, JdbcColumn c,
0834:                    CharBuf s) {
0835:                if (!c.nulls)
0836:                    s.append(" NOT NULL");
0837:            }
0838:
0839:            /**
0840:             * Append the column auto increment part of a create table statement for a
0841:             * column.
0842:             */
0843:            protected void appendCreateColumnAutoInc(JdbcTable t, JdbcColumn c,
0844:                    CharBuf s) {
0845:            }
0846:
0847:            /**
0848:             * Add the primary key constraint part of a create table statement to s.
0849:             */
0850:            protected void appendPrimaryKeyConstraint(JdbcTable t, CharBuf s) {
0851:                s.append("PRIMARY KEY (");
0852:                appendColumnNameList(t.pk, s);
0853:                s.append(") CONSTRAINT ");
0854:                s.append(t.pkConstraintName);
0855:            }
0856:
0857:            /**
0858:             * Append a comma separated list of column names to s.
0859:             */
0860:            protected void appendColumnNameList(JdbcColumn[] cols, CharBuf s) {
0861:                int colslen = cols.length;
0862:                for (int i = 0; i < colslen; i++) {
0863:                    if (i > 0)
0864:                        s.append(", ");
0865:                    s.append(cols[i].name);
0866:                }
0867:            }
0868:
0869:            /**
0870:             * Generate the 'create index' statements for t.
0871:             */
0872:            public void generateCreateIndexes(JdbcTable t, Statement stat,
0873:                    PrintWriter out, boolean comments) throws SQLException {
0874:                JdbcIndex[] a = t.indexes;
0875:                if (a == null)
0876:                    return;
0877:                CharBuf s = new CharBuf();
0878:                for (int i = 0; i < a.length; i++) {
0879:                    JdbcIndex idx = a[i];
0880:                    s.clear();
0881:                    appendCreateIndex(s, t, idx, comments);
0882:                    if (s.size() > 0) {
0883:                        String sql = s.toString();
0884:                        if (out != null)
0885:                            print(out, sql);
0886:                        if (stat != null)
0887:                            stat.execute(sql);
0888:                    }
0889:                }
0890:            }
0891:
0892:            /**
0893:             * Generate a 'create index' statement for idx.
0894:             */
0895:            protected void appendCreateIndex(CharBuf s, JdbcTable t,
0896:                    JdbcIndex idx, boolean comments) {
0897:                if (comments && isCommentSupported() && idx.comment != null) {
0898:                    s.append(comment(idx.comment));
0899:                    s.append('\n');
0900:                }
0901:                s.append("CREATE ");
0902:                if (idx.unique)
0903:                    s.append("UNIQUE ");
0904:                //if (idx.clustered) s.append("clustered ");
0905:                s.append("INDEX ");
0906:                s.append(idx.name);
0907:                s.append(" ON ");
0908:                s.append(t.name);
0909:                s.append('(');
0910:                s.append(idx.cols[0].name);
0911:                int n = idx.cols.length;
0912:                for (int i = 1; i < n; i++) {
0913:                    s.append(',');
0914:                    s.append(' ');
0915:                    s.append(idx.cols[i].name);
0916:                }
0917:                s.append(')');
0918:            }
0919:
0920:            /**
0921:             * Generate the 'add constraint' statements for t.
0922:             */
0923:            public void generateConstraints(JdbcTable t, Statement stat,
0924:                    PrintWriter out, boolean comments) throws SQLException {
0925:                JdbcConstraint[] cons = t.constraints;
0926:                if (cons == null)
0927:                    return;
0928:                CharBuf s = new CharBuf();
0929:                for (int i = 0; i < cons.length; i++) {
0930:                    JdbcConstraint c = cons[i];
0931:                    s.clear();
0932:                    appendRefConstraint(s, c);
0933:                    String sql = s.toString();
0934:                    if (!sql.equals("")) {
0935:                        if (out != null)
0936:                            print(out, sql);
0937:                        if (stat != null)
0938:                            stat.execute(sql);
0939:                    }
0940:                }
0941:            }
0942:
0943:            /**
0944:             * Append an 'add constraint' statement for c.
0945:             */
0946:            protected void appendRefConstraint(CharBuf s, JdbcConstraint c) {
0947:                s.append("ALTER TABLE ");
0948:                s.append(c.src.name);
0949:                s.append(" ADD CONSTRAINT (FOREIGN KEY (");
0950:                appendColumnNameList(c.srcCols, s);
0951:                s.append(") REFERENCES ");
0952:                s.append(c.dest.name);
0953:                s.append('(');
0954:                appendColumnNameList(c.dest.pk, s);
0955:                s.append(") CONSTRAINT ");
0956:                s.append(c.name);
0957:                s.append(')');
0958:            }
0959:
0960:            /**
0961:             * Get the names of all tables in the database con is connected to.
0962:             */
0963:            public ArrayList getTableNames(Connection con) throws SQLException {
0964:                ResultSet rs = null;
0965:                try {
0966:                    rs = con.getMetaData().getTables(null, getSchema(con),
0967:                            null, null);
0968:                    ArrayList a = new ArrayList();
0969:                    for (; rs.next();) {
0970:                        if (rs.getString(4).trim().equals("TABLE")) {
0971:                            a.add(rs.getString(3).trim());
0972:                        }
0973:                    }
0974:                    return a;
0975:                } finally {
0976:                    if (rs != null) {
0977:                        try {
0978:                            rs.close();
0979:                        } catch (SQLException x) {
0980:                            // ignore
0981:                        }
0982:                    }
0983:                }
0984:            }
0985:
0986:            //    /**
0987:            //     * Get the names of all tables in the database con is connected to.
0988:            //     */
0989:            //    public ArrayList getTableNames(Connection con) throws SQLException {
0990:            //        ResultSet rs = null;
0991:            //        try {
0992:            ////            getSchema(con);
0993:            //
0994:            //
0995:            //            rs = con.getMetaData().getTables(null, getSchema(con), null, null);
0996:            //            ArrayList a = new ArrayList();
0997:            //
0998:            //            String name = null;
0999:            //            String type = null;
1000:            //            String schema = null;
1001:            //            for (; rs.next();) {
1002:            //                type = rs.getString(4).trim();
1003:            //                name = rs.getString(3).trim();
1004:            //                schema = rs.getString(2).trim();
1005:            //                if (name.lastIndexOf('/') == -1 && name.lastIndexOf('$') == -1){
1006:            //
1007:            //                    System.out.println("SELECT * FROM "+
1008:            //                            (schema == null ? "": schema+".")+
1009:            //                            name +"; --"+ type);
1010:            //                }
1011:            //                if (type.equals("TABLE")) {
1012:            //                    a.add(name);
1013:            //                }
1014:            //            }
1015:            //            return a;
1016:            //        } finally {
1017:            //            if (rs != null) {
1018:            //                try {
1019:            //                    rs.close();
1020:            //                } catch (SQLException x) {
1021:            //                    // ignore
1022:            //                }
1023:            //            }
1024:            //        }
1025:            //    }
1026:
1027:            /**
1028:             * Drop the table and all its constraints etc. This must remove
1029:             * constraints to this table from other tables so it can be dropped.
1030:             */
1031:            public void dropTable(Connection con, String table)
1032:                    throws SQLException {
1033:                StatementWithLastSQL stat = null;
1034:                try {
1035:                    stat = new StatementWithLastSQL(con.createStatement());
1036:                    dropTable(con, table, stat);
1037:                } catch (SQLException x) {
1038:                    String msg;
1039:                    if (stat == null) {
1040:                        msg = x.toString();
1041:                    } else {
1042:                        msg = x + "\nMost recent SQL:\n" + stat.getLastSQL();
1043:                    }
1044:                    throw mapException(x, msg, false);
1045:                } finally {
1046:                    if (stat != null) {
1047:                        try {
1048:                            stat.close();
1049:                        } catch (SQLException e) {
1050:                            // ignore
1051:                        }
1052:                    }
1053:                }
1054:            }
1055:
1056:            /**
1057:             * Drop the table and all its constraints etc. This must remove
1058:             * constraints to this table from other tables so it can be dropped.
1059:             */
1060:            protected void dropTable(Connection con, String table,
1061:                    Statement stat) throws SQLException {
1062:                stat.execute("DROP TABLE " + table);
1063:            }
1064:
1065:            /**
1066:             * Append a replacable parameter part of a where clause for the column.
1067:             * This gives the driver a chance to embed type conversions and so on
1068:             * for types not handled well by the JDBC driver (e.g. BigDecimals and
1069:             * the postgres JDBC driver).
1070:             */
1071:            public void appendWhereParam(CharBuf s, JdbcColumn c) {
1072:                s.append("?");
1073:            }
1074:
1075:            /**
1076:             * Get the string form of a binary operator.
1077:             *
1078:             * @see BinaryOpExp
1079:             */
1080:            public String getSqlBinaryOp(int op) {
1081:                switch (op) {
1082:                case BinaryOpExp.EQUAL:
1083:                    return "=";
1084:                case BinaryOpExp.NOT_EQUAL:
1085:                    return "<>";
1086:                case BinaryOpExp.GT:
1087:                    return ">";
1088:                case BinaryOpExp.LT:
1089:                    return "<";
1090:                case BinaryOpExp.GE:
1091:                    return ">=";
1092:                case BinaryOpExp.LE:
1093:                    return "<=";
1094:                case BinaryOpExp.LIKE:
1095:                    return "LIKE";
1096:                case BinaryOpExp.CONCAT:
1097:                    return "||";
1098:                case BinaryOpExp.PLUS:
1099:                    return "+";
1100:                case BinaryOpExp.MINUS:
1101:                    return "-";
1102:                case BinaryOpExp.TIMES:
1103:                    return "*";
1104:                case BinaryOpExp.DIVIDE:
1105:                    return "/";
1106:                }
1107:                throw BindingSupportImpl.getInstance().internal(
1108:                        "Unknown op: " + op);
1109:            }
1110:
1111:            /**
1112:             * Append the value of the literal to s.
1113:             *
1114:             * @see LiteralExp
1115:             */
1116:            public void appendSqlLiteral(int type, String value, CharBuf s) {
1117:                if (type == LiteralExp.TYPE_STRING) {
1118:                    s.append('\'');
1119:                    int len = value.length();
1120:                    for (int i = 0; i < len; i++) {
1121:                        char c = value.charAt(i);
1122:                        if (c == '\'')
1123:                            s.append('\'');
1124:                        s.append(c);
1125:                    }
1126:                    s.append('\'');
1127:                } else {
1128:                    s.append(value);
1129:                }
1130:            }
1131:
1132:            /**
1133:             * Append the name of the column to s. If col is null then append '*'.
1134:             *
1135:             * @see ColumnExp
1136:             */
1137:            public void appendSqlColumn(JdbcColumn col, String alias, CharBuf s) {
1138:                if (alias != null) {
1139:                    s.append(alias);
1140:                    s.append('.');
1141:                }
1142:                if (col == null) {
1143:                    s.append('*');
1144:                } else {
1145:                    s.append(col.name);
1146:                }
1147:            }
1148:
1149:            /**
1150:             * Append the from list entry for a table.
1151:             */
1152:            public void appendSqlFrom(JdbcTable table, String alias, CharBuf s) {
1153:                s.append(table.name);
1154:                if (alias != null) {
1155:                    s.append(' ');
1156:                    s.append(alias);
1157:                }
1158:            }
1159:
1160:            /**
1161:             * Append the from list entry for a table that is the right hand table
1162:             * in a join i.e. it is being joined to.
1163:             *
1164:             * @param exp   This is the expression that joins the tables
1165:             * @param outer If true then this is an outer join
1166:             */
1167:            public void appendSqlFromJoin(JdbcTable table, String alias,
1168:                    SqlExp exp, boolean outer, CharBuf s) {
1169:                s.append(',');
1170:                s.append(' ');
1171:                if (outer)
1172:                    s.append("OUTER ");
1173:                s.append(table.name);
1174:                if (alias != null) {
1175:                    s.append(' ');
1176:                    s.append(alias);
1177:                }
1178:            }
1179:
1180:            /**
1181:             * Append a join expression.
1182:             */
1183:            public void appendSqlJoin(String leftAlias, JdbcColumn left,
1184:                    String rightAlias, JdbcColumn right, boolean outer,
1185:                    CharBuf s) {
1186:                s.append(leftAlias);
1187:                s.append('.');
1188:                s.append(left.name);
1189:                s.append(' ');
1190:                s.append('=');
1191:                s.append(' ');
1192:                s.append(rightAlias);
1193:                s.append('.');
1194:                s.append(right.name);
1195:            }
1196:
1197:            /**
1198:             * Get a String for a replacable parameter. This gives the driver a
1199:             * chance to embed type conversions and so on for types not handled well
1200:             * by the JDBC driver (e.g. BigDecimals and the postgres JDBC driver).
1201:             * <p/>
1202:             * If you override this method then you must also override {@link #getSqlParamStringChars(int)}.
1203:             */
1204:            public String getSqlParamString(int jdbcType) {
1205:                return "?";
1206:            }
1207:
1208:            /**
1209:             * Return a shared char[] of the sqlParamString. This array may not be modified.
1210:             * It is used as a stamp when creating a in list.
1211:             *
1212:             * @param jdbcType
1213:             * @return
1214:             */
1215:            public char[] getSqlParamStringChars(int jdbcType) {
1216:                return DEFAULT_PARAM_CHARS;
1217:            }
1218:
1219:            /**
1220:             * Get the name of a function that accepts one argument.
1221:             *
1222:             * @see UnaryFunctionExp
1223:             */
1224:            public String getSqlUnaryFunctionName(int func) {
1225:                switch (func) {
1226:                case UnaryFunctionExp.FUNC_TO_LOWER_CASE:
1227:                    return "lower";
1228:                }
1229:                throw BindingSupportImpl.getInstance().internal(
1230:                        "Unknown func: " + func);
1231:            }
1232:
1233:            /**
1234:             * Get default SQL to test a connection or null if none available. This
1235:             * must be a query that returns at least one row.
1236:             */
1237:            public String getConnectionValidateSQL() {
1238:                return null;
1239:            }
1240:
1241:            /**
1242:             * Get default SQL used to init a connection or null if none required.
1243:             */
1244:            public String getConnectionInitSQL() {
1245:                return null;
1246:            }
1247:
1248:            /**
1249:             * Get con ready for a getQueryPlan call. Example: On Sybase this will
1250:             * do a 'set showplan 1' and 'set noexec 1'. Also make whatever changes
1251:             * are necessary to sql to prepare it for a getQueryPlan call. Example:
1252:             * On Oracle this will prepend 'explain '. The cleanupForGetQueryPlan
1253:             * method must be called in a finally block if this method is called.
1254:             *
1255:             * @see #cleanupForGetQueryPlan
1256:             * @see #getQueryPlan
1257:             */
1258:            public String prepareForGetQueryPlan(Connection con, String sql) {
1259:                return sql;
1260:            }
1261:
1262:            /**
1263:             * Get the query plan for ps and cleanup anything done in
1264:             * prepareForGetQueryPlan. Return null if this is not supported.
1265:             *
1266:             * @see #prepareForGetQueryPlan
1267:             * @see #cleanupForGetQueryPlan
1268:             */
1269:            public String getQueryPlan(Connection con, PreparedStatement ps) {
1270:                return null;
1271:            }
1272:
1273:            /**
1274:             * Cleanup anything done in prepareForGetQueryPlan. Example: On Sybase this
1275:             * will do a 'set showplan 0' and 'set noexec 0'.
1276:             *
1277:             * @see #prepareForGetQueryPlan
1278:             * @see #getQueryPlan
1279:             */
1280:            public void cleanupForGetQueryPlan(Connection con) {
1281:            }
1282:
1283:            /**
1284:             * Get extra SQL to be appended to the insert statement for retrieving
1285:             * the value of an autoinc column after insert. Return null if none
1286:             * is required or a separate query is run.
1287:             *
1288:             * @see #getAutoIncColumnValue(JdbcTable, Connection, Statement)
1289:             */
1290:            public String getAutoIncPostInsertSQLSuffix(JdbcTable classTable) {
1291:                return null;
1292:            }
1293:
1294:            /**
1295:             * Retrieve the value of the autoinc or serial column for a row just
1296:             * inserted using stat on con.
1297:             *
1298:             * @see #getAutoIncPostInsertSQLSuffix(JdbcTable)
1299:             */
1300:            public Object getAutoIncColumnValue(JdbcTable classTable,
1301:                    Connection con, Statement stat) throws SQLException {
1302:                throw BindingSupportImpl.getInstance().internal(
1303:                        "autoincrement or identity columns "
1304:                                + "not supported for '" + getName()
1305:                                + "' table '" + classTable.name + "'");
1306:            }
1307:
1308:            /**
1309:             * Enable or disable identity insert for the given table if this is
1310:             * required to insert a value into an identity column.
1311:             */
1312:            public void enableIdentityInsert(Connection con, String table,
1313:                    boolean on) throws SQLException {
1314:            }
1315:
1316:            /**
1317:             * Get whatever needs to be appended to a SELECT statement to lock the
1318:             * rows if this makes sense for the database. This must have a leading
1319:             * space if not empty.
1320:             */
1321:            public char[] getSelectForUpdate() {
1322:                return FOR_UPDATE;
1323:            }
1324:
1325:            /**
1326:             * Does 'SELECT FOR UPDATE' require the main table of the query to be
1327:             * appended (ala postgres)?
1328:             */
1329:            public boolean isSelectForUpdateAppendTable() {
1330:                return false;
1331:            }
1332:
1333:            /**
1334:             * Can 'SELECT FOR UPDATE' be used with a DISTINCT?
1335:             */
1336:            public boolean isSelectForUpdateWithDistinctOk() {
1337:                return true;
1338:            }
1339:
1340:            public boolean isSelectForUpdateWithAggregateOk() {
1341:                return false;
1342:            }
1343:
1344:            /*########################################*/
1345:            /*# These are the schema migration stuff #*/
1346:            /*########################################*/
1347:
1348:            /**
1349:             * Append a column that needs to be added.
1350:             */
1351:            protected void appendAddNewColumn(JdbcTable t, JdbcColumn c,
1352:                    CharBuf s, boolean comments) {
1353:                if (comments && isCommentSupported() && c.comment != null) {
1354:                    s.append(comment("add column for field " + c.comment));
1355:                }
1356:
1357:                s.append("\n");
1358:                s.append("ALTER TABLE ");
1359:                s.append(t.name);
1360:                s.append(" ADD ");
1361:                s.append(c.name);
1362:                s.append(' ');
1363:                appendColumnType(c, s);
1364:                if (c.autoinc) {
1365:                    appendCreateColumnAutoInc(t, c, s);
1366:                }
1367:                if (c.nulls) {
1368:                    appendCreateColumnNulls(t, c, s);
1369:                    s.append(";\n");
1370:                } else {
1371:                    s.append(";\n");
1372:                    s.append("UPDATE ");
1373:                    s.append(t.name);
1374:                    s.append(" SET ");
1375:                    s.append(c.name);
1376:                    s.append(" = ");
1377:                    s.append(getDefaultForType(c));
1378:                    s.append(";\n");
1379:
1380:                    s.append("ALTER TABLE ");
1381:                    s.append(t.name);
1382:                    s.append(" MODIFY ");
1383:                    s.append(c.name);
1384:                    s.append(' ');
1385:                    appendColumnType(c, s);
1386:                    if (c.autoinc) {
1387:                        appendCreateColumnAutoInc(t, c, s);
1388:                    }
1389:                    appendCreateColumnNulls(t, c, s);
1390:                    s.append(";\n");
1391:                }
1392:            }
1393:
1394:            /**
1395:             * Append a column that needs to be added.
1396:             */
1397:            protected void appendModifyColumn(TableDiff tableDiff,
1398:                    ColumnDiff diff, CharBuf s, boolean comments) {
1399:                JdbcTable t = tableDiff.getOurTable();
1400:                JdbcColumn c = diff.getOurCol();
1401:                if (comments && isCommentSupported() && c.comment != null) {
1402:                    s.append(comment("modify column for field " + c.comment));
1403:                }
1404:                if (comments && isCommentSupported() && c.comment == null) {
1405:                    s.append(comment("modify column " + c.name));
1406:                }
1407:                s.append("\n");
1408:                s.append("ALTER TABLE ");
1409:                s.append(t.name);
1410:                s.append(" MODIFY ");
1411:                s.append(c.name);
1412:                s.append(' ');
1413:                appendColumnType(c, s);
1414:                if (c.autoinc) {
1415:                    appendCreateColumnAutoInc(t, c, s);
1416:                }
1417:                appendCreateColumnNulls(t, c, s);
1418:            }
1419:
1420:            /**
1421:             * Append a column that needs to be added.
1422:             */
1423:            protected void appendDropColumn(TableDiff tableDiff, JdbcColumn c,
1424:                    CharBuf s, boolean comments) {
1425:                if (comments && isCommentSupported()) {
1426:                    s.append(comment("dropping unknown column " + c.name));
1427:                }
1428:
1429:                s.append("\n");
1430:                s.append("ALTER TABLE ");
1431:                s.append(tableDiff.getOurTable().name);
1432:                s.append(" DROP COLUMN ");
1433:                s.append(c.name);
1434:
1435:            }
1436:
1437:            /**
1438:             * Append an 'drop constraint' statement for c.
1439:             */
1440:            protected void appendRefDropConstraint(CharBuf s, JdbcConstraint c,
1441:                    boolean comments) {
1442:                //        if (comments && isCommentSupported()) {
1443:                //            s.append(comment("dropping unknown constraint " + c.name));
1444:                //            s.append('\n');
1445:                //        }
1446:                s.append("ALTER TABLE ");
1447:                s.append(c.src.name);
1448:                s.append(" DROP CONSTRAINT ");
1449:                s.append(c.name);
1450:            }
1451:
1452:            /**
1453:             * Generate a 'drop index' statement for idx.
1454:             */
1455:            protected void appendDropIndex(CharBuf s, JdbcTable t,
1456:                    JdbcIndex idx, boolean comments) {
1457:                //        if (comments && isCommentSupported()) {
1458:                //            s.append(comment("dropping unknown index "+ idx.name));
1459:                //            s.append('\n');
1460:                //        }
1461:                s.append("DROP INDEX ");
1462:                s.append(idx.name);
1463:            }
1464:
1465:            /**
1466:             * Add the primary key constraint in isolation.
1467:             */
1468:            protected void addPrimaryKeyConstraint(JdbcTable t, CharBuf s) {
1469:                s.append("ALTER TABLE ");
1470:                s.append(t.name);
1471:                s.append(" ADD ");
1472:                appendPrimaryKeyConstraint(t, s);
1473:            }
1474:
1475:            /**
1476:             * Drop the primary key constraint in isolation.
1477:             */
1478:            protected void dropPrimaryKeyConstraint(JdbcTable t, CharBuf s) {
1479:                s.append("ALTER TABLE ");
1480:                s.append(t.name);
1481:                s.append(" DROP CONSTRAINT ");
1482:                s.append(t.pkConstraintName);
1483:            }
1484:
1485:            public String getRunCommand() {
1486:                return ";\n";
1487:            }
1488:
1489:            /**
1490:             * Make sure the database tables and columns exist. This is used as a
1491:             * quick check when the server starts.
1492:             */
1493:            public boolean checkDDLForStartup(ArrayList tables, Connection con,
1494:                    PrintWriter out, PrintWriter fix, ControlParams params)
1495:                    throws SQLException {
1496:                Statement stat = null;
1497:                boolean allIsWell = true;
1498:                try {
1499:                    con.rollback();
1500:                    con.setAutoCommit(true);
1501:                    stat = con.createStatement();
1502:                    int n = tables.size();
1503:                    for (int i = 0; i < n; i++) {
1504:                        JdbcTable t = (JdbcTable) tables.get(i);
1505:                        if (!checkTable(t, stat, out))
1506:                            allIsWell = false;
1507:                    }
1508:                } finally {
1509:                    if (stat != null) {
1510:                        try {
1511:                            stat.close();
1512:                        } catch (SQLException e) {
1513:                            // ignore
1514:                        }
1515:                    }
1516:                    con.setAutoCommit(false);
1517:                }
1518:                if (!allIsWell) {
1519:                    fix.println(comment("NOT IMPLEMENTED"));
1520:                }
1521:                return allIsWell;
1522:            }
1523:
1524:            /**
1525:             * Check that the columns of t match those in the database schema.
1526:             */
1527:            protected boolean checkTable(JdbcTable t, Statement stat,
1528:                    PrintWriter out) {
1529:                CharBuf s = new CharBuf();
1530:                s.append("select ");
1531:                int nc = t.cols.length;
1532:                for (int i = 0; i < nc; i++) {
1533:                    s.append(t.cols[i].name);
1534:                    if (i != (nc - 1)) {
1535:                        s.append(", ");
1536:                    } else {
1537:                        s.append(" from ");
1538:                    }
1539:                }
1540:                s.append(t.name);
1541:                s.append(" where 1 = 2");
1542:                String sql = s.toString();
1543:
1544:                try {
1545:                    stat.executeQuery(sql);
1546:                    return true;
1547:                } catch (SQLException x) {
1548:                    printError(out, t.name);
1549:                    // we have a error, now we check if the table exist
1550:                    boolean tableExist = false;
1551:                    try {
1552:                        s.clear();
1553:                        s.append("select * from ");
1554:                        s.append(t.name);
1555:                        s.append(" where 1 = 2");
1556:                        stat.executeQuery(s.toString());
1557:                        tableExist = true;
1558:                    } catch (SQLException tablex) {
1559:                        printErrorMsg(out, "Table '" + t.name
1560:                                + "' does not exist.");
1561:                    }
1562:                    if (tableExist) {
1563:                        // the table does exist, now we find the what column does not exist
1564:                        s.clear();
1565:                        s.append(" from ");
1566:                        s.append(t.name);
1567:                        s.append(" where 1 = 2");
1568:                        String from = s.toString();
1569:                        String column = null;
1570:                        for (int i = 0; i < nc; i++) {
1571:                            column = t.cols[i].name;
1572:                            s.clear();
1573:                            s.append("select ");
1574:                            s.append(column);
1575:                            s.append(from);
1576:                            try {
1577:                                stat.executeQuery(s.toString());
1578:                            } catch (SQLException columnx) {
1579:                                printErrorMsg(out, "Column '" + column
1580:                                        + "' does not exist.");
1581:                            }
1582:                        }
1583:                    }
1584:                    return false;
1585:                }
1586:            }
1587:
1588:            private static void printError(PrintWriter out, String tableName) {
1589:                out.print("\nTable ");
1590:                out.print(tableName);
1591:                out.println(" : FAIL");
1592:            }
1593:
1594:            private static void printErrorMsg(PrintWriter out, String error) {
1595:                out.print("    ");
1596:                out.println(error);
1597:            }
1598:
1599:            /**
1600:             * Get all the database tables and columns that is not system tables
1601:             * and that is filled with what field it belongs to.
1602:             */
1603:            public HashMap getDatabaseMetaData(ArrayList tables, Connection con)
1604:                    throws SQLException {
1605:                HashMap dbMap;
1606:                ControlParams params = new ControlParams();
1607:                params.setColumnsOnly(true);
1608:                try {
1609:                    customizeForServer(con);
1610:                    con.rollback();
1611:                    con.setAutoCommit(true);
1612:                    dbMap = getDBSchema(con, params);
1613:                    setAllTableAndViewNames(con);
1614:                } finally {
1615:                    con.setAutoCommit(false);
1616:                }
1617:
1618:                fillDatabaseMetaData(tables, dbMap);
1619:                return dbMap;
1620:            }
1621:
1622:            /**
1623:             * Fill the db classes with mapping info
1624:             */
1625:            public void fillDatabaseMetaData(ArrayList tables, HashMap dbMap) {
1626:                int n = tables.size();
1627:                for (int m = 0; m < n; m++) {
1628:                    JdbcTable ourTable = (JdbcTable) tables.get(m);
1629:                    JdbcTable dbTable = (JdbcTable) dbMap.get(ourTable.name
1630:                            .toLowerCase());
1631:                    if (dbTable != null) {
1632:                        dbTable.comment = ourTable.comment;
1633:                        if (ourTable.cols != null) {
1634:                            for (int i = 0; i < ourTable.cols.length; i++) {
1635:                                JdbcColumn ourCol = ourTable.cols[i];
1636:                                // check if our column is in there
1637:                                JdbcColumn dbCol = null;
1638:                                if (dbTable.cols != null) {
1639:                                    for (int j = 0; j < dbTable.cols.length; j++) {
1640:                                        JdbcColumn col = dbTable.cols[j];
1641:                                        if (ourCol.name
1642:                                                .equalsIgnoreCase(col.name)) {
1643:                                            dbCol = col;
1644:                                            dbCol.comment = ourCol.comment;
1645:                                            break;
1646:                                        }
1647:                                    }
1648:                                }
1649:                            }
1650:                        }
1651:                    }
1652:                }
1653:            }
1654:
1655:            public boolean checkDDL(ArrayList tables, Connection con,
1656:                    PrintWriter errors, PrintWriter fix, ControlParams params)
1657:                    throws SQLException {
1658:                HashMap dbMap;
1659:                try {
1660:                    customizeForServer(con);
1661:                    con.rollback();
1662:                    con.setAutoCommit(true);
1663:                    dbMap = getDBSchema(con, params);
1664:                    setAllTableAndViewNames(con);
1665:                } finally {
1666:                    con.setAutoCommit(false);
1667:                }
1668:                HashMap nameMap = new HashMap();
1669:                try {
1670:                    for (Iterator iterator = tables.iterator(); iterator
1671:                            .hasNext();) {
1672:                        JdbcTable ourTable = (JdbcTable) iterator.next();
1673:                        JdbcTable dbTable = (JdbcTable) dbMap.get(ourTable.name
1674:                                .toLowerCase());
1675:
1676:                        if (dbTable != null) {
1677:                            nameMap.put(ourTable.name, ourTable);
1678:                            ourTable.name = dbTable.name;
1679:                        }
1680:                    }
1681:
1682:                    ArrayList diffList = checkAllTables(tables, dbMap, params);
1683:
1684:                    if (diffList.isEmpty()) {
1685:                        allTableList = null;
1686:                        return true;
1687:                    } else {
1688:                        DiffUtil.reportErrors(diffList, errors);
1689:                        reportFixes(diffList, fix);
1690:                        allTableList = null;
1691:                        return false;
1692:                    }
1693:                } finally {
1694:                    Set set = nameMap.keySet();
1695:                    for (Iterator iter = set.iterator(); iter.hasNext();) {
1696:                        String name = (String) iter.next();
1697:                        JdbcTable table = (JdbcTable) nameMap.get(name);
1698:                        table.name = name;
1699:                    }
1700:                }
1701:            }
1702:
1703:            protected String getCatalog(Connection con) throws SQLException {
1704:                return null;
1705:            }
1706:
1707:            protected String getSchema(Connection con) {
1708:                return null;
1709:            }
1710:
1711:            protected boolean isValidSchemaTable(String tableName) {
1712:                return true;
1713:            }
1714:
1715:            /**
1716:             * Get the JdbcTable from the database for the given database connection and table name.
1717:             */
1718:            public HashMap getDBSchema(Connection con, ControlParams params)
1719:                    throws SQLException {
1720:                DatabaseMetaData meta = con.getMetaData();
1721:
1722:                HashMap jdbcTableMap = new HashMap(); // main map of jdbc tables
1723:
1724:                String catalog = getCatalog(con);
1725:                String schema = getSchema(con);
1726:
1727:                // now we do columns
1728:                String tableName = null;
1729:                ResultSet rsColumn = meta.getColumns(catalog, schema, null,
1730:                        null);
1731:                ArrayList currentColumns = null;
1732:
1733:                while (rsColumn.next()) {
1734:
1735:                    String temptableName = rsColumn.getString("TABLE_NAME");
1736:
1737:                    if (!isValidSchemaTable(temptableName)) {
1738:                        continue;
1739:                    }
1740:
1741:                    if (tableName == null) { // this is the first one
1742:                        tableName = temptableName;
1743:                        currentColumns = new ArrayList();
1744:                        JdbcTable jdbcTable = new JdbcTable();
1745:                        jdbcTable.name = tableName;
1746:                        jdbcTableMap.put(tableName, jdbcTable);
1747:                    }
1748:
1749:                    if (!temptableName.equals(tableName)) { // now we set everyting up for prev table
1750:                        JdbcColumn[] jdbcColumns = new JdbcColumn[currentColumns
1751:                                .size()];
1752:                        currentColumns.toArray(jdbcColumns);
1753:                        JdbcTable jdbcTable0 = (JdbcTable) jdbcTableMap
1754:                                .get(tableName);
1755:                        jdbcTable0.cols = jdbcColumns;
1756:
1757:                        tableName = temptableName;
1758:                        currentColumns.clear();
1759:                        JdbcTable jdbcTable1 = new JdbcTable();
1760:                        jdbcTable1.name = tableName;
1761:                        jdbcTableMap.put(tableName, jdbcTable1);
1762:                    }
1763:
1764:                    JdbcColumn col = new JdbcColumn();
1765:
1766:                    col.name = rsColumn.getString("COLUMN_NAME");
1767:                    col.sqlType = rsColumn.getString("TYPE_NAME");
1768:                    col.jdbcType = rsColumn.getInt("DATA_TYPE");
1769:                    col.length = rsColumn.getInt("COLUMN_SIZE");
1770:                    col.scale = rsColumn.getInt("DECIMAL_DIGITS");
1771:                    col.nulls = "YES".equals(rsColumn.getString("IS_NULLABLE"));
1772:
1773:                    //            if (tableName.equalsIgnoreCase("custom_types")){  //sqlType longtext
1774:                    //                System.out.println(col.name);
1775:                    //                System.out.println(col.sqlType);
1776:                    //                System.out.println(col.jdbcType);
1777:                    //                System.out.println(col.length);
1778:                    //                System.out.println(col.scale);
1779:                    //                System.out.println("---------------------");
1780:                    //            }
1781:
1782:                    if (col.jdbcType == java.sql.Types.OTHER
1783:                            && col.sqlType.equals("longtext")) {
1784:                        col.jdbcType = java.sql.Types.CLOB;
1785:                    }
1786:
1787:                    if (col.jdbcType == 16) {
1788:                        col.jdbcType = java.sql.Types.BIT;
1789:                    }
1790:
1791:                    switch (col.jdbcType) {
1792:                    case java.sql.Types.BIT:
1793:                    case java.sql.Types.TINYINT:
1794:                    case java.sql.Types.SMALLINT:
1795:                    case java.sql.Types.INTEGER:
1796:                    case java.sql.Types.BIGINT:
1797:                    case java.sql.Types.LONGVARBINARY:
1798:                    case java.sql.Types.BLOB:
1799:                    case java.sql.Types.LONGVARCHAR:
1800:                    case java.sql.Types.CLOB:
1801:                    case java.sql.Types.DATE:
1802:                    case java.sql.Types.TIME:
1803:                    case java.sql.Types.TIMESTAMP:
1804:                        col.length = 0;
1805:                        col.scale = 0;
1806:                    default:
1807:                    }
1808:
1809:                    currentColumns.add(col);
1810:                }
1811:                // we fin last table
1812:                if (currentColumns != null) {
1813:                    JdbcColumn[] lastJdbcColumns = new JdbcColumn[currentColumns
1814:                            .size()];
1815:                    if (lastJdbcColumns != null) {
1816:                        currentColumns.toArray(lastJdbcColumns);
1817:                        JdbcTable colJdbcTable = (JdbcTable) jdbcTableMap
1818:                                .get(tableName);
1819:                        colJdbcTable.cols = lastJdbcColumns;
1820:                        tableName = null;
1821:                        currentColumns.clear();
1822:                    }
1823:                }
1824:
1825:                if (rsColumn != null) {
1826:                    try {
1827:                        rsColumn.close();
1828:                    } catch (SQLException e) {
1829:                    }
1830:                }
1831:
1832:                if (!params.checkColumnsOnly()) {
1833:                    Set mainTableNames = jdbcTableMap.keySet();
1834:                    if (params.isCheckPK()) {
1835:                        // now we do primaryKeys ///////////////////////////////////////////////////////////////////////
1836:                        for (Iterator iterator = mainTableNames.iterator(); iterator
1837:                                .hasNext();) {
1838:                            tableName = (String) iterator.next();
1839:                            JdbcTable jdbcTable = (JdbcTable) jdbcTableMap
1840:                                    .get(tableName);
1841:                            HashMap pkMap = new HashMap();
1842:                            HashMap pkNames = new HashMap();
1843:                            ResultSet rsPKs = meta.getPrimaryKeys(catalog,
1844:                                    schema, tableName);
1845:                            int pkCount = 0;
1846:                            while (rsPKs.next()) {
1847:                                pkCount++;
1848:                                pkMap.put(rsPKs.getString("COLUMN_NAME"), null);
1849:                                String pkName = rsPKs.getString("PK_NAME");
1850:                                jdbcTable.pkConstraintName = pkName;
1851:                                pkNames.put(pkName, null);
1852:                            }
1853:                            rsPKs.close();
1854:                            if (pkCount != 0) {
1855:                                JdbcColumn[] pkColumns = new JdbcColumn[pkCount];
1856:                                if (pkColumns != null) {
1857:                                    int indexOfPKCount = 0;
1858:                                    for (int i = 0; i < jdbcTable.cols.length; i++) {
1859:                                        JdbcColumn jdbcColumn = jdbcTable.cols[i];
1860:                                        if (pkMap.containsKey(jdbcColumn.name)) {
1861:                                            pkColumns[indexOfPKCount] = jdbcColumn;
1862:                                            jdbcColumn.pk = true;
1863:                                            indexOfPKCount++;
1864:                                        }
1865:                                    }
1866:                                    jdbcTable.pk = pkColumns;
1867:                                }
1868:                            }
1869:
1870:                        }
1871:
1872:                        // end of primaryKeys ///////////////////////////////////////////////////////////////////////
1873:                    }
1874:                    if (params.isCheckIndex()) {
1875:                        // now we do index  /////////////////////////////////////////////////////////////////////////
1876:                        for (Iterator iterator = mainTableNames.iterator(); iterator
1877:                                .hasNext();) {
1878:                            tableName = (String) iterator.next();
1879:                            JdbcTable jdbcTable = (JdbcTable) jdbcTableMap
1880:                                    .get(tableName);
1881:                            ResultSet rsIndex = null;
1882:                            try {
1883:                                rsIndex = meta.getIndexInfo(catalog, schema,
1884:                                        tableName, false, false);
1885:                            } catch (SQLException e) {
1886:                                iterator.remove();
1887:                                continue;
1888:                            }
1889:
1890:                            HashMap indexNameMap = new HashMap();
1891:                            ArrayList indexes = new ArrayList();
1892:                            while (rsIndex.next()) {
1893:
1894:                                String indexName = rsIndex
1895:                                        .getString("INDEX_NAME");
1896:                                if (indexName != null
1897:                                        && !indexName
1898:                                                .equals(jdbcTable.pkConstraintName)
1899:                                        && !indexName.startsWith("SYS_IDX_")) {
1900:                                    if (indexNameMap.containsKey(indexName)) {
1901:                                        JdbcIndex index = null;
1902:                                        for (Iterator iter = indexes.iterator(); iter
1903:                                                .hasNext();) {
1904:                                            JdbcIndex jdbcIndex = (JdbcIndex) iter
1905:                                                    .next();
1906:                                            if (jdbcIndex.name
1907:                                                    .equals(indexName)) {
1908:                                                index = jdbcIndex;
1909:                                            }
1910:                                        }
1911:                                        if (index != null) {
1912:                                            JdbcColumn[] tempIndexColumns = index.cols;
1913:                                            JdbcColumn[] indexColumns = new JdbcColumn[tempIndexColumns.length + 1];
1914:                                            System.arraycopy(tempIndexColumns,
1915:                                                    0, indexColumns, 0,
1916:                                                    tempIndexColumns.length);
1917:                                            String colName = rsIndex
1918:                                                    .getString("COLUMN_NAME");
1919:                                            for (int i = 0; i < jdbcTable.cols.length; i++) {
1920:                                                JdbcColumn jdbcColumn = jdbcTable.cols[i];
1921:                                                if (colName
1922:                                                        .equals(jdbcColumn.name)) {
1923:                                                    indexColumns[tempIndexColumns.length] = jdbcColumn;
1924:                                                    jdbcColumn.partOfIndex = true;
1925:                                                }
1926:                                            }
1927:                                            index.setCols(indexColumns);
1928:                                        }
1929:                                    } else {
1930:                                        indexNameMap.put(indexName, null);
1931:                                        JdbcIndex index = new JdbcIndex();
1932:                                        index.name = indexName;
1933:                                        index.unique = !rsIndex
1934:                                                .getBoolean("NON_UNIQUE");
1935:                                        short indexType = rsIndex
1936:                                                .getShort("TYPE");
1937:                                        switch (indexType) {
1938:                                        case DatabaseMetaData.tableIndexClustered:
1939:                                            index.clustered = true;
1940:                                            break;
1941:                                        }
1942:                                        String colName = rsIndex
1943:                                                .getString("COLUMN_NAME");
1944:                                        JdbcColumn[] indexColumns = new JdbcColumn[1];
1945:                                        for (int i = 0; i < jdbcTable.cols.length; i++) {
1946:                                            JdbcColumn jdbcColumn = jdbcTable.cols[i];
1947:                                            if (colName.equals(jdbcColumn.name)) {
1948:                                                indexColumns[0] = jdbcColumn;
1949:                                                jdbcColumn.partOfIndex = true;
1950:                                            }
1951:                                        }
1952:                                        if (indexColumns[0] != null) {
1953:                                            index.setCols(indexColumns);
1954:                                            indexes.add(index);
1955:                                        }
1956:                                    }
1957:                                }
1958:                            }
1959:                            if (indexes != null) {
1960:                                JdbcIndex[] jdbcIndexes = new JdbcIndex[indexes
1961:                                        .size()];
1962:                                if (jdbcIndexes != null) {
1963:                                    indexes.toArray(jdbcIndexes);
1964:                                    jdbcTable.indexes = jdbcIndexes;
1965:                                }
1966:                            }
1967:                            if (rsIndex != null) {
1968:                                try {
1969:                                    rsIndex.close();
1970:                                } catch (SQLException e) {
1971:                                }
1972:                            }
1973:                        }
1974:
1975:                        // end of index ///////////////////////////////////////////////////////////////////////
1976:                    }
1977:                    if (params.isCheckConstraint()) {
1978:                        // now we do forign keys /////////////////////////////////////////////////////////////
1979:                        for (Iterator iterator = mainTableNames.iterator(); iterator
1980:                                .hasNext();) {
1981:                            tableName = (String) iterator.next();
1982:                            JdbcTable jdbcTable = (JdbcTable) jdbcTableMap
1983:                                    .get(tableName);
1984:                            ResultSet rsFKs = null;
1985:                            try {
1986:                                rsFKs = meta.getImportedKeys(catalog, schema,
1987:                                        tableName);
1988:                            } catch (SQLException e) {
1989:                                iterator.remove();
1990:                                continue;
1991:                            }
1992:                            HashMap constraintNameMap = new HashMap();
1993:                            ArrayList constraints = new ArrayList();
1994:                            while (rsFKs.next()) {
1995:
1996:                                String fkName = rsFKs.getString("FK_NAME");
1997:
1998:                                if (constraintNameMap.containsKey(fkName)) {
1999:                                    JdbcConstraint constraint = null;
2000:                                    for (Iterator iter = constraints.iterator(); iter
2001:                                            .hasNext();) {
2002:                                        JdbcConstraint jdbcConstraint = (JdbcConstraint) iter
2003:                                                .next();
2004:                                        if (jdbcConstraint.name.equals(fkName)) {
2005:                                            constraint = jdbcConstraint;
2006:                                        }
2007:                                    }
2008:
2009:                                    JdbcColumn[] tempConstraintColumns = constraint.srcCols;
2010:                                    JdbcColumn[] constraintColumns = new JdbcColumn[tempConstraintColumns.length + 1];
2011:                                    System.arraycopy(tempConstraintColumns, 0,
2012:                                            constraintColumns, 0,
2013:                                            tempConstraintColumns.length);
2014:                                    String colName = rsFKs
2015:                                            .getString("FKCOLUMN_NAME");
2016:                                    for (int i = 0; i < jdbcTable.cols.length; i++) {
2017:                                        JdbcColumn jdbcColumn = jdbcTable.cols[i];
2018:                                        if (colName.equals(jdbcColumn.name)) {
2019:                                            constraintColumns[tempConstraintColumns.length] = jdbcColumn;
2020:                                            jdbcColumn.foreignKey = true;
2021:                                        }
2022:                                    }
2023:                                    constraint.srcCols = constraintColumns;
2024:                                } else {
2025:                                    constraintNameMap.put(fkName, null);
2026:                                    JdbcConstraint constraint = new JdbcConstraint();
2027:                                    constraint.name = fkName;
2028:                                    constraint.src = jdbcTable;
2029:                                    String colName = rsFKs
2030:                                            .getString("FKCOLUMN_NAME");
2031:                                    JdbcColumn[] constraintColumns = new JdbcColumn[1];
2032:                                    for (int i = 0; i < jdbcTable.cols.length; i++) {
2033:                                        JdbcColumn jdbcColumn = jdbcTable.cols[i];
2034:                                        if (colName.equals(jdbcColumn.name)) {
2035:                                            constraintColumns[0] = jdbcColumn;
2036:                                            jdbcColumn.foreignKey = true;
2037:                                        }
2038:                                    }
2039:                                    constraint.srcCols = constraintColumns;
2040:                                    constraint.dest = (JdbcTable) jdbcTableMap
2041:                                            .get(rsFKs
2042:                                                    .getString("PKTABLE_NAME"));
2043:                                    constraints.add(constraint);
2044:                                }
2045:
2046:                            }
2047:                            if (constraints != null) {
2048:                                JdbcConstraint[] jdbcConstraints = new JdbcConstraint[constraints
2049:                                        .size()];
2050:                                if (jdbcConstraints != null) {
2051:                                    constraints.toArray(jdbcConstraints);
2052:                                    jdbcTable.constraints = jdbcConstraints;
2053:                                }
2054:                            }
2055:                            if (rsFKs != null) {
2056:                                try {
2057:                                    rsFKs.close();
2058:                                } catch (SQLException e) {
2059:                                }
2060:                            }
2061:                        }
2062:                        // end of forign keys /////////////////////////////////////////////////////////////
2063:                    }
2064:                }
2065:
2066:                HashMap returnMap = new HashMap();
2067:                Collection col = jdbcTableMap.values();
2068:                for (Iterator iterator = col.iterator(); iterator.hasNext();) {
2069:                    JdbcTable table = (JdbcTable) iterator.next();
2070:                    returnMap.put(table.name.toLowerCase(), table);
2071:                }
2072:                fixAllNames(returnMap);
2073:                return returnMap;
2074:            }
2075:
2076:            boolean isDirectDropColumnSupported() {
2077:                return true;
2078:            }
2079:
2080:            boolean isDirectAddColumnSupported(JdbcColumn ourCol) {
2081:                return true;
2082:            }
2083:
2084:            boolean isDirectNullColumnChangesSupported() {
2085:                return true;
2086:            }
2087:
2088:            boolean isDirectScaleColumnChangesSupported(JdbcColumn ourCol,
2089:                    JdbcColumn dbCol) {
2090:                return true;
2091:            }
2092:
2093:            boolean isDirectLenghtColumnChangesSupported(JdbcColumn ourCol,
2094:                    JdbcColumn dbCol) {
2095:                return true;
2096:            }
2097:
2098:            boolean isDirectTypeColumnChangesSupported(JdbcColumn ourCol,
2099:                    JdbcColumn dbCol) {
2100:                return true;
2101:            }
2102:
2103:            boolean isDropConstraintsForDropTableSupported() {
2104:                return true;
2105:            }
2106:
2107:            boolean isDropPrimaryKeySupported() {
2108:                return true;
2109:            }
2110:
2111:            /**
2112:             * Is this a sequence column from a List implementation that we are dropping to create a Set?
2113:             */
2114:            boolean isDropSequenceColumn(TableDiff tableDiff,
2115:                    JdbcColumn dropColumn) {
2116:                JdbcTable ourTable = tableDiff.getOurTable();
2117:                JdbcTable dbTable = tableDiff.getDbTable();
2118:                // we have a seq if the old col was in the old pk
2119:                // and the new pk includes another column
2120:                if (ourTable.getColsForCreateTable().length == 2
2121:                        && ourTable.getPkNames().length == 2) {
2122:                    try {
2123:                        if (dbTable.findPkColumn(dropColumn.name) != null) {
2124:                            return true;
2125:                        }
2126:                    } catch (Exception e) {
2127:                        return false;
2128:                    }
2129:                }
2130:                return false;
2131:            }
2132:
2133:            /**
2134:             * @param addColumn
2135:             * @return
2136:             */
2137:            boolean isAddSequenceColumn(JdbcColumn addColumn) {
2138:                if (addColumn.comment != null
2139:                        && addColumn.comment
2140:                                .equals(JdbcMetaDataBuilder.SEQUENCE_FIELDNAME)) {
2141:                    return true;
2142:                } else {
2143:                    return false;
2144:                }
2145:            }
2146:
2147:            private ArrayList checkAllTables(ArrayList tables, HashMap dbMap,
2148:                    ControlParams params) {
2149:                ArrayList diffList = new ArrayList();
2150:                int n = tables.size();
2151:                for (int i = 0; i < n; i++) {
2152:                    JdbcTable ourTable = (JdbcTable) tables.get(i);
2153:                    TableDiff diff = DiffUtil.checkTable(this , ourTable,
2154:                            (JdbcTable) dbMap.get(ourTable.name.toLowerCase()),
2155:                            params);
2156:                    if (diff != null) {
2157:                        diffList.add(diff);
2158:                    }
2159:                }
2160:
2161:                // if we have pks that we drop then we have to check if there are constraints that we
2162:                // have to drop first that refrences this pk.
2163:                ArrayList dropConsList = new ArrayList();
2164:                for (Iterator iter = diffList.iterator(); iter.hasNext();) {
2165:                    TableDiff tableDiff = (TableDiff) iter.next();
2166:                    JdbcTable destTable = tableDiff.getDbTable();
2167:                    for (Iterator iterIndex = tableDiff.getPkDiffs().iterator(); iterIndex
2168:                            .hasNext();) {
2169:                        PKDiff pkDiff = (PKDiff) iterIndex.next();
2170:                        if (!pkDiff.isMissingPK()) {
2171:                            for (Iterator mainTables = tables.iterator(); mainTables
2172:                                    .hasNext();) {
2173:                                JdbcTable ourJdbcTable = (JdbcTable) mainTables
2174:                                        .next();
2175:                                JdbcTable dbJdbcTable = (JdbcTable) dbMap
2176:                                        .get(ourJdbcTable.name.toLowerCase());
2177:                                if (dbJdbcTable != null
2178:                                        && dbJdbcTable.constraints != null) {
2179:                                    for (int i = 0; i < dbJdbcTable.constraints.length; i++) {
2180:                                        JdbcConstraint dbConstraint = dbJdbcTable.constraints[i];
2181:                                        if (dbConstraint.dest != null
2182:                                                && destTable != null) {
2183:                                            if (dbConstraint.dest.name
2184:                                                    .equalsIgnoreCase(destTable.name)) { // we found the constraint that we need to drop
2185:                                                if (!dropConsList
2186:                                                        .contains(dbConstraint)) {
2187:                                                    pkDiff
2188:                                                            .setDropConstraintsRefs(dbConstraint);
2189:                                                    dropConsList
2190:                                                            .add(dbConstraint);
2191:                                                    for (int j = 0; j < ourJdbcTable.constraints.length; j++) {
2192:                                                        JdbcConstraint ourConstraint = ourJdbcTable.constraints[j];
2193:                                                        if (ourConstraint.name
2194:                                                                .equalsIgnoreCase(dbConstraint.name)) {
2195:                                                            if (null == DiffUtil
2196:                                                                    .checkConstraint(
2197:                                                                            ourConstraint,
2198:                                                                            dbConstraint,
2199:                                                                            params)) {
2200:                                                                // we found the constraint in our schema that did not have a problem,
2201:                                                                // so we add it again
2202:                                                                pkDiff
2203:                                                                        .setAddConstraintsRefs(ourConstraint);
2204:                                                            }
2205:                                                        }
2206:                                                    }
2207:                                                }
2208:                                            }
2209:                                        }
2210:                                    }
2211:                                }
2212:                            }
2213:                        }
2214:                    }
2215:                }
2216:
2217:                for (Iterator iter = diffList.iterator(); iter.hasNext();) {
2218:                    TableDiff tableDiff = (TableDiff) iter.next();
2219:                    for (Iterator iterator = tableDiff.getConstraintDiffs()
2220:                            .iterator(); iterator.hasNext();) {
2221:                        ConstraintDiff diff = (ConstraintDiff) iterator.next();
2222:                        if (dropConsList.contains(diff.getDbConstraint())) {
2223:                            diff.setDrop(false); // don't drop this, it has already been dropped
2224:                        }
2225:                    }
2226:                }
2227:
2228:                // if we have tables that we are going to drop then we have to check if there are constraints that we
2229:                // have to recreate that refrences this table.
2230:                ArrayList dropTableList = new ArrayList();
2231:                for (Iterator iter = diffList.iterator(); iter.hasNext();) {
2232:                    TableDiff tableDiff = (TableDiff) iter.next();
2233:                    JdbcTable ourTable = tableDiff.getOurTable();
2234:                    boolean direct = true;
2235:                    for (Iterator iterCol = tableDiff.getColDiffs().iterator(); iterCol
2236:                            .hasNext();) {
2237:                        ColumnDiff diff = (ColumnDiff) iterCol.next();
2238:                        if (diff.isExtraCol()) {
2239:                            if (isDropSequenceColumn(tableDiff, diff.getDbCol())) {
2240:                                direct = false;
2241:                            } else if (!isDirectDropColumnSupported()) {
2242:                                direct = false;
2243:                            }
2244:                        }
2245:                        if (diff.isMissingCol()) {
2246:                            if (isAddSequenceColumn(diff.getOurCol())) {
2247:                                direct = false;
2248:                            } else if (!isDirectAddColumnSupported(diff
2249:                                    .getOurCol())) {
2250:                                direct = false;
2251:                            }
2252:                        }
2253:
2254:                        if (diff.isLenghtDiff()) {
2255:                            if (!isDirectLenghtColumnChangesSupported(diff
2256:                                    .getOurCol(), diff.getDbCol())) {
2257:                                direct = false;
2258:                            }
2259:                        }
2260:                        if (diff.isNullDiff()) {
2261:                            if (!isDirectNullColumnChangesSupported()) {
2262:                                direct = false;
2263:                            }
2264:                        }
2265:                        if (diff.isScaleDiff()) {
2266:                            if (!isDirectScaleColumnChangesSupported(diff
2267:                                    .getOurCol(), diff.getDbCol())) {
2268:                                direct = false;
2269:                            }
2270:                        }
2271:                        if (diff.isTypeDiff()) {
2272:                            if (!isDirectTypeColumnChangesSupported(diff
2273:                                    .getOurCol(), diff.getDbCol())) {
2274:                                direct = false;
2275:                            }
2276:                        }
2277:                    }
2278:                    if (!direct) {
2279:                        dropTableList.add(ourTable);
2280:                    }
2281:                }
2282:
2283:                for (Iterator iter = dropTableList.iterator(); iter.hasNext();) {
2284:                    JdbcTable jdbcTable = (JdbcTable) iter.next(); // this table will be droped
2285:                    // we must find all constraints that references this table and put them back
2286:                    for (Iterator iterator = tables.iterator(); iterator
2287:                            .hasNext();) {
2288:                        JdbcTable table = (JdbcTable) iterator.next();
2289:                        if (!dropTableList.contains(table)) {
2290:                            if (table.constraints != null) {
2291:                                for (int i = 0; i < table.constraints.length; i++) {
2292:                                    JdbcConstraint constraint = table.constraints[i];
2293:                                    if (constraint.dest == jdbcTable) {// this constraint will be dropped
2294:
2295:                                        TableDiff tableDiff = null;
2296:                                        for (Iterator iterDiff = diffList
2297:                                                .iterator(); iterDiff.hasNext();) {
2298:                                            TableDiff tempTableDiff = (TableDiff) iterDiff
2299:                                                    .next();
2300:                                            if (tempTableDiff.getOurTable() == constraint.src) {
2301:                                                tableDiff = tempTableDiff;
2302:                                            }
2303:                                        }
2304:                                        if (tableDiff == null) {
2305:                                            tableDiff = new TableDiff(
2306:                                                    constraint.src, null);
2307:                                            ConstraintDiff diff = new ConstraintDiff(
2308:                                                    constraint, null);
2309:
2310:                                            diff.setRecreate(true);
2311:                                            diff.setDrop(false);
2312:                                            tableDiff.getConstraintDiffs().add(
2313:                                                    diff);
2314:                                            // there are no real errors, so we set it
2315:                                            tableDiff.setHasRealErrors(false);
2316:                                            diffList.add(tableDiff);
2317:                                        } else {
2318:                                            ConstraintDiff ourConstDiff = null;
2319:                                            for (Iterator iterConstraint = tableDiff
2320:                                                    .getConstraintDiffs()
2321:                                                    .iterator(); iterConstraint
2322:                                                    .hasNext();) {
2323:                                                ConstraintDiff diff = (ConstraintDiff) iterConstraint
2324:                                                        .next();
2325:                                                if (diff.getOurConstraint() == constraint) {
2326:                                                    diff.setRecreate(true);
2327:                                                    diff.setDrop(false);
2328:                                                    ourConstDiff = diff;
2329:                                                }
2330:                                            }
2331:
2332:                                            if (ourConstDiff == null) {// we need to add it
2333:                                                ourConstDiff = new ConstraintDiff(
2334:                                                        constraint, null);
2335:                                                ourConstDiff.setRecreate(true);
2336:                                                ourConstDiff.setDrop(false);
2337:                                                tableDiff.getConstraintDiffs()
2338:                                                        .add(ourConstDiff);
2339:                                            }
2340:                                        }
2341:                                    }
2342:                                }
2343:                            }
2344:                        }
2345:                    }
2346:                }
2347:                if (!isDropConstraintsForDropTableSupported()) {
2348:
2349:                    for (Iterator iter = dropTableList.iterator(); iter
2350:                            .hasNext();) {
2351:                        JdbcTable jdbcTable = (JdbcTable) iter.next(); // this table will be droped
2352:                        // we must find all constraints that references this table and drop them
2353:                        for (Iterator iterator = dbMap.keySet().iterator(); iterator
2354:                                .hasNext();) {
2355:                            JdbcTable table = (JdbcTable) dbMap
2356:                                    .get(((String) iterator.next())
2357:                                            .toLowerCase());
2358:                            boolean isGoingToBeDroped = false;
2359:                            if (table != null) {
2360:                                for (Iterator myiter = dropTableList.iterator(); myiter
2361:                                        .hasNext();) {
2362:                                    JdbcTable tempJdbcTable = (JdbcTable) myiter
2363:                                            .next();
2364:                                    if (tempJdbcTable.name
2365:                                            .equalsIgnoreCase(table.name)) {
2366:                                        isGoingToBeDroped = true;
2367:                                    }
2368:                                }
2369:                            }
2370:
2371:                            if (!isGoingToBeDroped) {
2372:                                if (table.constraints != null) {
2373:                                    for (int i = 0; i < table.constraints.length; i++) {
2374:                                        JdbcConstraint constraint = table.constraints[i];
2375:                                        if (constraint.dest.name
2376:                                                .equalsIgnoreCase(jdbcTable.name)) {// this constraint must be dropped
2377:                                            TableDiff tableDiff = null;
2378:                                            for (Iterator iterDiff = diffList
2379:                                                    .iterator(); iterDiff
2380:                                                    .hasNext();) {
2381:                                                TableDiff tempTableDiff = (TableDiff) iterDiff
2382:                                                        .next();
2383:                                                if (tempTableDiff.getOurTable() == constraint.src) {
2384:                                                    tableDiff = tempTableDiff;
2385:                                                }
2386:                                            }
2387:                                            if (tableDiff == null) {
2388:                                                tableDiff = new TableDiff(null,
2389:                                                        constraint.src);
2390:                                                ConstraintDiff diff = new ConstraintDiff(
2391:                                                        null, constraint);
2392:                                                diff.setDrop(true);
2393:                                                tableDiff.getConstraintDiffs()
2394:                                                        .add(diff);
2395:                                                // there are no real errors, so we set it
2396:                                                tableDiff
2397:                                                        .setHasRealErrors(false);
2398:                                                diffList.add(tableDiff);
2399:                                            } else {
2400:                                                ConstraintDiff dbConstDiff = null;
2401:                                                for (Iterator iterConstraint = tableDiff
2402:                                                        .getConstraintDiffs()
2403:                                                        .iterator(); iterConstraint
2404:                                                        .hasNext();) {
2405:                                                    ConstraintDiff diff = (ConstraintDiff) iterConstraint
2406:                                                            .next();
2407:                                                    if (diff.getDbConstraint() == constraint) {
2408:                                                        diff.setDrop(true);
2409:                                                        dbConstDiff = diff;
2410:                                                    }
2411:                                                }
2412:
2413:                                                if (dbConstDiff == null) {// we need to add it
2414:                                                    dbConstDiff = new ConstraintDiff(
2415:                                                            null, constraint);
2416:                                                    dbConstDiff.setDrop(true);
2417:                                                    tableDiff
2418:                                                            .getConstraintDiffs()
2419:                                                            .add(dbConstDiff);
2420:                                                }
2421:                                            }
2422:                                        }
2423:                                    }
2424:                                }
2425:                            }
2426:                        }
2427:                    }
2428:                }
2429:
2430:                return diffList;
2431:            }
2432:
2433:            protected void fixCoulumns(TableDiff tableDiff, PrintWriter out) {
2434:                CharBuf buff = new CharBuf();
2435:                ArrayList colList = tableDiff.getColDiffs();
2436:                ArrayList pkList = tableDiff.getPkDiffs();
2437:                boolean isMissingPK = false; // flag, else we get multiple pk creations
2438:                boolean otherPKProblems = false;
2439:                for (Iterator iterator = pkList.iterator(); iterator.hasNext();) {
2440:                    PKDiff diff = (PKDiff) iterator.next();
2441:                    if (diff.isMissingPK()) {
2442:                        isMissingPK = true;
2443:                    } else if (diff.isMissingPKCol() || diff.isExtraPKCol()) {
2444:                        otherPKProblems = true;
2445:                        if (!diff.getDropConstraintsRefs().isEmpty()) {
2446:                            for (Iterator iter = diff.getDropConstraintsRefs()
2447:                                    .iterator(); iter.hasNext();) {
2448:                                JdbcConstraint constraint = (JdbcConstraint) iter
2449:                                        .next();
2450:                                buff.clear();
2451:                                appendRefDropConstraint(buff, constraint, true);
2452:                                String sql = buff.toString();
2453:                                print(out, sql);
2454:                            }
2455:                        }
2456:                    }
2457:                }
2458:
2459:                if (otherPKProblems && isDropPrimaryKeySupported()) {
2460:                    buff.clear();
2461:                    dropPrimaryKeyConstraint(tableDiff.getDbTable(), buff);
2462:                    print(out, buff.toString());
2463:                }
2464:                boolean direct = true; // check if we can do all the column changes direct
2465:                boolean sequence = false;
2466:                for (Iterator iterator = colList.iterator(); iterator.hasNext();) {
2467:                    ColumnDiff diff = (ColumnDiff) iterator.next();
2468:                    if (diff.isExtraCol()) {
2469:                        if (isDropSequenceColumn(tableDiff, diff.getDbCol())) {
2470:                            sequence = true;
2471:                        } else if (!isDirectDropColumnSupported()) {
2472:                            direct = false;
2473:                        }
2474:
2475:                    }
2476:                    if (diff.isMissingCol()) {
2477:                        if (isAddSequenceColumn(diff.getOurCol())) {
2478:                            sequence = true;
2479:                        } else if (!isDirectAddColumnSupported(diff.getOurCol())) {
2480:                            direct = false;
2481:                        }
2482:                    }
2483:                    if (diff.isLenghtDiff()) {
2484:                        if (!isDirectLenghtColumnChangesSupported(diff
2485:                                .getOurCol(), diff.getDbCol())) {
2486:                            direct = false;
2487:                        }
2488:                    }
2489:                    if (diff.isNullDiff()) {
2490:                        if (!isDirectNullColumnChangesSupported()) {
2491:                            direct = false;
2492:                        }
2493:                    }
2494:                    if (diff.isScaleDiff()) {
2495:                        if (!isDirectScaleColumnChangesSupported(diff
2496:                                .getOurCol(), diff.getDbCol())) {
2497:                            direct = false;
2498:                        }
2499:                    }
2500:                    if (diff.isTypeDiff()) {
2501:                        if (!isDirectTypeColumnChangesSupported(diff
2502:                                .getOurCol(), diff.getDbCol())) {
2503:                            direct = false;
2504:                        }
2505:                    }
2506:
2507:                }
2508:                if (sequence && direct) {
2509:                    if (!isDropConstraintsForDropTableSupported()) {
2510:                        fixConstraintsForNonDirectColumns(tableDiff, out, true);
2511:                        fixIndexForNonDirectColumns(tableDiff, out, true);
2512:                    }
2513:                    for (Iterator iterator = colList.iterator(); iterator
2514:                            .hasNext();) {
2515:                        ColumnDiff diff = (ColumnDiff) iterator.next();
2516:                        if (diff.isExtraCol()) {
2517:                            buff.clear();
2518:                            appendDropColumn(tableDiff, diff.getDbCol(), buff,
2519:                                    true);
2520:                            print(out, buff.toString());
2521:                        }
2522:                        if (diff.isMissingCol()) {
2523:                            buff.clear();
2524:                            appendAddNewColumn(tableDiff.getOurTable(), diff
2525:                                    .getOurCol(), buff, true);
2526:                            out.println(buff.toString());
2527:                        } else if (diff.isLenghtDiff() || diff.isNullDiff()
2528:                                || diff.isScaleDiff() || diff.isTypeDiff()) {
2529:                            buff.clear();
2530:                            appendModifyColumn(tableDiff, diff, buff, true);
2531:                            print(out, buff.toString());
2532:                        }
2533:
2534:                    }
2535:                    fixIndexForNonDirectColumns(tableDiff, out, false);
2536:                    fixConstraintsForNonDirectColumns(tableDiff, out, false);
2537:
2538:                } else if (direct) {
2539:                    for (Iterator iterator = colList.iterator(); iterator
2540:                            .hasNext();) {
2541:                        ColumnDiff diff = (ColumnDiff) iterator.next();
2542:                        if (diff.isExtraCol()) {
2543:                            buff.clear();
2544:                            appendDropColumn(tableDiff, diff.getDbCol(), buff,
2545:                                    true);
2546:                            print(out, buff.toString());
2547:                        }
2548:                        if (diff.isMissingCol()) {
2549:                            buff.clear();
2550:                            appendAddNewColumn(tableDiff.getOurTable(), diff
2551:                                    .getOurCol(), buff, true);
2552:                            out.println(buff.toString());
2553:                        } else if (diff.isLenghtDiff() || diff.isNullDiff()
2554:                                || diff.isScaleDiff() || diff.isTypeDiff()) {
2555:                            buff.clear();
2556:                            appendModifyColumn(tableDiff, diff, buff, true);
2557:                            print(out, buff.toString());
2558:                        }
2559:
2560:                    }
2561:
2562:                    if (isMissingPK || otherPKProblems) {
2563:                        buff.clear();
2564:                        addPrimaryKeyConstraint(tableDiff.getOurTable(), buff);
2565:                        print(out, buff.toString());
2566:                    }
2567:
2568:                } else {
2569:                    if (!isDropConstraintsForDropTableSupported()) {
2570:                        fixConstraintsForNonDirectColumns(tableDiff, out, true);
2571:                        fixIndexForNonDirectColumns(tableDiff, out, true);
2572:                    }
2573:                    fixColumnsNonDirect(tableDiff, out);
2574:                    fixIndexForNonDirectColumns(tableDiff, out, false);
2575:                    fixConstraintsForNonDirectColumns(tableDiff, out, false);
2576:                }
2577:            }
2578:
2579:            protected void fixConstraintsForNonDirectColumns(
2580:                    TableDiff tableDiff, PrintWriter out, boolean drop) {
2581:                // we need to create all the constraints that was droped during drop table,
2582:                // but only ones that did not have problems
2583:                JdbcConstraint[] constraints = null;
2584:                if (drop) {
2585:                    if (tableDiff.getDbTable() != null) {
2586:                        constraints = tableDiff.getDbTable().constraints;
2587:                    }
2588:                } else {
2589:                    constraints = tableDiff.getOurTable().constraints;
2590:                }
2591:
2592:                if (constraints != null) {
2593:                    for (int i = 0; i < constraints.length; i++) {
2594:                        JdbcConstraint constraint = constraints[i];
2595:                        ConstraintDiff diff = getConstraintDiffForName(
2596:                                tableDiff, constraint.name, drop);
2597:                        if (diff == null) {
2598:                            CharBuf buff = new CharBuf();
2599:                            if (drop) {
2600:                                appendRefDropConstraint(buff, constraint, false);
2601:                            } else {
2602:                                appendRefConstraint(buff, constraint);
2603:                            }
2604:                            String sql = buff.toString();
2605:                            print(out, sql);
2606:                        }
2607:                    }
2608:                }
2609:            }
2610:
2611:            /**
2612:             * Fixes all the names with spaces in
2613:             *
2614:             * @param nameMap
2615:             */
2616:            public void fixAllNames(HashMap nameMap) {
2617:                Collection col = nameMap.values();
2618:                for (Iterator iterator = col.iterator(); iterator.hasNext();) {
2619:                    JdbcTable table = (JdbcTable) iterator.next();
2620:                    String temptableName = table.name;
2621:                    if (temptableName.indexOf(' ') != -1) {
2622:                        table.name = "\"" + temptableName + "\"";
2623:                    }
2624:                    JdbcColumn[] cols = table.cols;
2625:                    if (cols != null) {
2626:                        for (int i = 0; i < cols.length; i++) {
2627:                            JdbcColumn jdbcColumn = cols[i];
2628:                            String tempColName = jdbcColumn.name;
2629:                            if (tempColName.indexOf(' ') != -1) {
2630:                                jdbcColumn.name = "\"" + tempColName + "\"";
2631:                            }
2632:                        }
2633:                    }
2634:                    JdbcIndex[] indexes = table.indexes;
2635:                    if (indexes != null) {
2636:                        for (int i = 0; i < indexes.length; i++) {
2637:                            JdbcIndex index = indexes[i];
2638:                            String tempIndexName = index.name;
2639:                            if (tempIndexName.indexOf(' ') != -1) {
2640:                                index.name = "\"" + tempIndexName + "\"";
2641:                            }
2642:                        }
2643:                    }
2644:                    JdbcConstraint[] constraints = table.constraints;
2645:                    if (constraints != null) {
2646:                        for (int i = 0; i < constraints.length; i++) {
2647:                            JdbcConstraint constraint = constraints[i];
2648:                            String tempConstraintName = constraint.name;
2649:                            if (tempConstraintName.indexOf(' ') != -1) {
2650:                                constraint.name = "\"" + tempConstraintName
2651:                                        + "\"";
2652:                            }
2653:
2654:                        }
2655:                    }
2656:                    String tempPkConstraintName = table.pkConstraintName;
2657:                    if (tempPkConstraintName != null) {
2658:                        if (tempPkConstraintName.indexOf(' ') != -1) {
2659:                            table.pkConstraintName = "\""
2660:                                    + tempPkConstraintName + "\"";
2661:                        }
2662:                    }
2663:                }
2664:
2665:            }
2666:
2667:            protected void fixIndexForNonDirectColumns(TableDiff tableDiff,
2668:                    PrintWriter out, boolean drop) {
2669:                // we need to create all the indexes that was droped during drop table,
2670:                // but only ones that did not have problems
2671:                JdbcIndex[] indexes = null;
2672:                if (drop) {
2673:                    if (tableDiff.getDbTable() != null) {
2674:                        indexes = tableDiff.getDbTable().indexes;
2675:                    }
2676:                } else {
2677:                    indexes = tableDiff.getOurTable().indexes;
2678:                }
2679:                if (indexes != null) {
2680:                    for (int i = 0; i < indexes.length; i++) {
2681:                        JdbcIndex index = indexes[i];
2682:                        IndexDiff diff = getIndexDiffForName(tableDiff,
2683:                                index.name, drop);
2684:                        if (diff == null) {
2685:                            CharBuf buff = new CharBuf();
2686:                            if (drop) {
2687:                                appendDropIndex(buff, tableDiff.getDbTable(),
2688:                                        index, false);
2689:                            } else {
2690:                                appendCreateIndex(buff,
2691:                                        tableDiff.getOurTable(), index, false);
2692:                            }
2693:                            String sql = buff.toString();
2694:                            print(out, sql);
2695:                        }
2696:                    }
2697:                }
2698:            }
2699:
2700:            protected void fixColumnsNonDirect(TableDiff tableDiff,
2701:                    PrintWriter out) {
2702:
2703:            }
2704:
2705:            protected void reportFixes(ArrayList diffList, PrintWriter out)
2706:                    throws SQLException {
2707:                // do all drop constraints
2708:                for (Iterator iter = diffList.iterator(); iter.hasNext();) {
2709:                    TableDiff tableDiff = (TableDiff) iter.next();
2710:                    ArrayList constraintList = tableDiff.getConstraintDiffs();
2711:                    for (Iterator iterator = constraintList.iterator(); iterator
2712:                            .hasNext();) {
2713:                        ConstraintDiff diff = (ConstraintDiff) iterator.next();
2714:                        if (diff.drop() && !diff.isMissingConstraint()) {
2715:                            JdbcConstraint constraint = diff.getDbConstraint();
2716:                            if (constraint == null) {
2717:                                constraint = diff.getOurConstraint();
2718:                            }
2719:
2720:                            CharBuf buff = new CharBuf();
2721:                            appendRefDropConstraint(buff, constraint, true);
2722:                            String sql = buff.toString();
2723:                            print(out, sql);
2724:                        }
2725:                    }
2726:                }
2727:
2728:                // do all drop index
2729:                for (Iterator iter = diffList.iterator(); iter.hasNext();) {
2730:                    TableDiff tableDiff = (TableDiff) iter.next();
2731:                    JdbcTable dbTable = tableDiff.getDbTable();
2732:                    ArrayList indexList = tableDiff.getIndexDiffs();
2733:                    for (Iterator iterator = indexList.iterator(); iterator
2734:                            .hasNext();) {
2735:                        IndexDiff diff = (IndexDiff) iterator.next();
2736:                        if (diff.isExtraIndex() || diff.isExtraCol()
2737:                                || diff.isMissingCol() || diff.isUniqueness()) {
2738:                            JdbcIndex idx = diff.getDbIndex();
2739:                            CharBuf buff = new CharBuf();
2740:                            if (idx != null) {
2741:                                appendDropIndex(buff, dbTable, idx, true);
2742:                                String sql = buff.toString();
2743:                                print(out, sql);
2744:                            }
2745:                        }
2746:                    }
2747:                }
2748:
2749:                for (Iterator iter = diffList.iterator(); iter.hasNext();) {
2750:                    TableDiff tableDiff = (TableDiff) iter.next();
2751:                    if (tableDiff.isMissingTable()) {
2752:                        generateCreateTable(tableDiff.getOurTable(), null, out,
2753:                                true);
2754:                    } else {
2755:                        fixCoulumns(tableDiff, out);
2756:                    }
2757:
2758:                }
2759:
2760:                // do all create index
2761:                for (Iterator iter = diffList.iterator(); iter.hasNext();) {
2762:                    TableDiff tableDiff = (TableDiff) iter.next();
2763:                    JdbcTable ourTable = tableDiff.getOurTable();
2764:                    ArrayList indexList = tableDiff.getIndexDiffs();
2765:                    for (Iterator iterator = indexList.iterator(); iterator
2766:                            .hasNext();) {
2767:                        IndexDiff diff = (IndexDiff) iterator.next();
2768:                        if (diff.isMissingIndex() || diff.isExtraCol()
2769:                                || diff.isMissingCol() || diff.isUniqueness()) {
2770:                            JdbcIndex idx = diff.getOurIndex();
2771:                            CharBuf buff = new CharBuf();
2772:                            appendCreateIndex(buff, ourTable, idx, false);
2773:                            String sql = buff.toString();
2774:                            print(out, sql);
2775:                        }
2776:                    }
2777:                }
2778:
2779:                // do all create constraints
2780:                for (Iterator iter = diffList.iterator(); iter.hasNext();) {
2781:                    TableDiff tableDiff = (TableDiff) iter.next();
2782:                    ArrayList constraintList = tableDiff.getConstraintDiffs();
2783:                    for (Iterator iterator = constraintList.iterator(); iterator
2784:                            .hasNext();) {
2785:                        ConstraintDiff diff = (ConstraintDiff) iterator.next();
2786:                        if (diff.isMissingConstraint() || diff.isExtraCol()
2787:                                || diff.isMissingCol() || diff.isRecreate()) {
2788:                            JdbcConstraint constraint = diff.getOurConstraint();
2789:                            CharBuf buff = new CharBuf();
2790:                            appendRefConstraint(buff, constraint);
2791:                            String sql = buff.toString();
2792:                            print(out, sql);
2793:                        }
2794:                    }
2795:                }
2796:
2797:                // do all create constraints that we had to drop to fix column's
2798:                for (Iterator iter = diffList.iterator(); iter.hasNext();) {
2799:                    TableDiff tableDiff = (TableDiff) iter.next();
2800:                    ArrayList pkList = tableDiff.getPkDiffs();
2801:                    for (Iterator iterator = pkList.iterator(); iterator
2802:                            .hasNext();) {
2803:                        PKDiff diff = (PKDiff) iterator.next();
2804:                        for (Iterator iterPk = diff.getAddConstraintsRefs()
2805:                                .iterator(); iterPk.hasNext();) {
2806:                            JdbcConstraint constraint = (JdbcConstraint) iterPk
2807:                                    .next();
2808:                            CharBuf buff = new CharBuf();
2809:                            appendRefConstraint(buff, constraint);
2810:                            String sql = buff.toString();
2811:                            print(out, sql);
2812:                        }
2813:                    }
2814:                }
2815:            }
2816:
2817:            public boolean checkType(JdbcColumn ourCol, JdbcColumn dbCol) {
2818:                String ourSqlType = ourCol.sqlType.toUpperCase();
2819:                String dbSqlType = dbCol.sqlType.toUpperCase();
2820:                if (ourCol.jdbcType == dbCol.jdbcType) {
2821:                    return true;
2822:                } else if (ourSqlType.startsWith(dbSqlType)) {
2823:                    return true;
2824:                } else {
2825:                    switch (ourCol.jdbcType) {
2826:                    case Types.BIT:
2827:                        switch (dbCol.jdbcType) {
2828:                        case Types.TINYINT:
2829:                        case Types.SMALLINT:
2830:                            return true;
2831:                        default:
2832:                            return false;
2833:                        }
2834:                    case Types.TINYINT:
2835:                        switch (dbCol.jdbcType) {
2836:                        case Types.BIT:
2837:                        case Types.SMALLINT:
2838:                            return true;
2839:                        default:
2840:                            return false;
2841:                        }
2842:                    case Types.SMALLINT:
2843:                        switch (dbCol.jdbcType) {
2844:                        case Types.BIT:
2845:                        case Types.TINYINT:
2846:                            return true;
2847:                        default:
2848:                            return false;
2849:                        }
2850:                    case Types.INTEGER:
2851:                        switch (dbCol.jdbcType) {
2852:                        case Types.NUMERIC:
2853:                            return true;
2854:                        default:
2855:                            return false;
2856:                        }
2857:                    case Types.BIGINT:
2858:                        switch (dbCol.jdbcType) {
2859:                        case Types.NUMERIC:
2860:                        case Types.DECIMAL:
2861:                            return true;
2862:                        default:
2863:                            return false;
2864:                        }
2865:                    case Types.FLOAT:
2866:                        switch (dbCol.jdbcType) {
2867:                        case Types.DOUBLE:
2868:                        case Types.REAL:
2869:                            return true;
2870:                        default:
2871:                            return false;
2872:                        }
2873:                    case Types.REAL:
2874:                        switch (dbCol.jdbcType) {
2875:                        case Types.DOUBLE:
2876:                        case Types.FLOAT:
2877:                            return true;
2878:                        default:
2879:                            return false;
2880:                        }
2881:                    case Types.DOUBLE:
2882:                        switch (dbCol.jdbcType) {
2883:                        case Types.FLOAT:
2884:                        case Types.REAL:
2885:                            return true;
2886:                        default:
2887:                            return false;
2888:                        }
2889:                    case Types.NUMERIC:
2890:                        switch (dbCol.jdbcType) {
2891:                        case Types.DECIMAL:
2892:                        case Types.BIGINT:
2893:                            return true;
2894:                        default:
2895:                            return false;
2896:                        }
2897:                    case Types.DECIMAL:
2898:                        switch (dbCol.jdbcType) {
2899:                        case Types.NUMERIC:
2900:                            return true;
2901:                        default:
2902:                            return false;
2903:                        }
2904:                    case Types.CHAR:
2905:                        switch (dbCol.jdbcType) {
2906:                        case Types.VARCHAR:
2907:                            return true;
2908:                        default:
2909:                            return false;
2910:                        }
2911:                    case Types.VARCHAR:
2912:                        switch (dbCol.jdbcType) {
2913:                        case Types.CHAR:
2914:                            return true;
2915:                        default:
2916:                            return false;
2917:                        }
2918:                    case Types.LONGVARCHAR:
2919:                        switch (dbCol.jdbcType) {
2920:                        case Types.CLOB:
2921:                            return true;
2922:                        default:
2923:                            return false;
2924:                        }
2925:                    case Types.DATE:
2926:                        switch (dbCol.jdbcType) {
2927:                        case Types.TIMESTAMP:
2928:                        case Types.TIME:
2929:                            return true;
2930:                        default:
2931:                            return false;
2932:                        }
2933:                    case Types.TIME:
2934:                        switch (dbCol.jdbcType) {
2935:                        case Types.TIMESTAMP:
2936:                        case Types.DATE:
2937:                            return true;
2938:                        default:
2939:                            return false;
2940:                        }
2941:                    case Types.TIMESTAMP:
2942:                        switch (dbCol.jdbcType) {
2943:                        case Types.DATE:
2944:                        case Types.TIME:
2945:                            return true;
2946:                        default:
2947:                            return false;
2948:                        }
2949:                    case Types.BINARY:
2950:                        switch (dbCol.jdbcType) {
2951:                        case Types.BINARY:
2952:                            return true;
2953:                        default:
2954:                            return false;
2955:                        }
2956:                    case Types.VARBINARY:
2957:                        switch (dbCol.jdbcType) {
2958:                        case Types.VARBINARY:
2959:                            return true;
2960:                        default:
2961:                            return false;
2962:                        }
2963:                    case Types.LONGVARBINARY:
2964:                        switch (dbCol.jdbcType) {
2965:                        case Types.BLOB:
2966:                            return true;
2967:                        default:
2968:                            return false;
2969:                        }
2970:                    case Types.BLOB:
2971:                        switch (dbCol.jdbcType) {
2972:                        case Types.LONGVARBINARY:
2973:                            return true;
2974:                        default:
2975:                            return false;
2976:                        }
2977:                    case Types.CLOB:
2978:                        switch (dbCol.jdbcType) {
2979:                        case Types.LONGVARCHAR:
2980:                            return true;
2981:                        default:
2982:                            return false;
2983:                        }
2984:                    case Types.NULL:
2985:                        switch (dbCol.jdbcType) {
2986:                        case Types.NULL:
2987:                            return true;
2988:                        default:
2989:                            return false;
2990:                        }
2991:                    case Types.OTHER:
2992:                        switch (dbCol.jdbcType) {
2993:                        case Types.OTHER:
2994:                            return true;
2995:                        default:
2996:                            return false;
2997:                        }
2998:                    case Types.DISTINCT:
2999:                        switch (dbCol.jdbcType) {
3000:                        case Types.DISTINCT:
3001:                            return true;
3002:                        default:
3003:                            return false;
3004:                        }
3005:                    case Types.STRUCT:
3006:                        switch (dbCol.jdbcType) {
3007:                        case Types.STRUCT:
3008:                            return true;
3009:                        default:
3010:                            return false;
3011:                        }
3012:                    case Types.REF:
3013:                        switch (dbCol.jdbcType) {
3014:                        case Types.REF:
3015:                            return true;
3016:                        default:
3017:                            return false;
3018:                        }
3019:                    case Types.JAVA_OBJECT:
3020:                        switch (dbCol.jdbcType) {
3021:                        case Types.JAVA_OBJECT:
3022:                            return true;
3023:                        default:
3024:                            return false;
3025:                        }
3026:                    default:
3027:                        return false;
3028:                    }
3029:                }
3030:            }
3031:
3032:            public boolean checkScale(JdbcColumn ourCol, JdbcColumn dbCol) {
3033:                switch (ourCol.jdbcType) {
3034:                case Types.DATE:
3035:                case Types.TIME:
3036:                case Types.TIMESTAMP:
3037:                    return true;
3038:                default:
3039:                    if (ourCol.scale != dbCol.scale) {
3040:                        return false;
3041:                    } else {
3042:                        return true;
3043:                    }
3044:                }
3045:            }
3046:
3047:            public boolean checkNulls(JdbcColumn ourCol, JdbcColumn dbCol) {
3048:                if (ourCol.nulls != dbCol.nulls) {
3049:                    return false;
3050:                }
3051:                return true;
3052:            }
3053:
3054:            public boolean checkLenght(JdbcColumn ourCol, JdbcColumn dbCol) {
3055:                if (ourCol.length != dbCol.length) {
3056:                    if (ourCol.length != 0) {
3057:                        return false;
3058:                    }
3059:                }
3060:                return true;
3061:            }
3062:
3063:            protected String getDefaultValueComment() {
3064:                return "  "
3065:                        + comment("Please enter your own default value here.");
3066:            }
3067:
3068:            protected String getDefaultForType(JdbcColumn ourCol) {
3069:                switch (ourCol.jdbcType) {
3070:                case Types.BIT:
3071:                case Types.TINYINT:
3072:                case Types.SMALLINT:
3073:                case Types.INTEGER:
3074:                case Types.BIGINT:
3075:                case Types.FLOAT:
3076:                case Types.REAL:
3077:                case Types.DOUBLE:
3078:                case Types.NUMERIC:
3079:                case Types.DECIMAL:
3080:                    return "0";
3081:                case Types.CHAR:
3082:                case Types.VARCHAR:
3083:                case Types.LONGVARCHAR:
3084:                case Types.CLOB:
3085:                    return "' '";
3086:                case Types.DATE:
3087:                case Types.TIME:
3088:                case Types.TIMESTAMP:
3089:                    return "' '";
3090:                case Types.BINARY:
3091:                case Types.VARBINARY:
3092:                case Types.LONGVARBINARY:
3093:                case Types.BLOB:
3094:                    return "' '";
3095:                case Types.NULL:
3096:                case Types.OTHER:
3097:                case Types.DISTINCT:
3098:                case Types.STRUCT:
3099:                case Types.REF:
3100:                case Types.JAVA_OBJECT:
3101:                    return "' '";
3102:                default:
3103:                    return "' '";
3104:                }
3105:
3106:            }
3107:
3108:            /**
3109:             * Gets the Column diff for the column name, else returns null
3110:             */
3111:            protected ColumnDiff getColumnDiffForName(TableDiff tableDiff,
3112:                    String name) {
3113:                for (Iterator iter = tableDiff.getColDiffs().iterator(); iter
3114:                        .hasNext();) {
3115:                    ColumnDiff diff = (ColumnDiff) iter.next();
3116:                    JdbcColumn our = diff.getOurCol();
3117:                    if (our != null) {
3118:                        if (our.name.equalsIgnoreCase(name)) {// we have the right column
3119:                            return diff;
3120:                        }
3121:                    }
3122:                }
3123:                return null;
3124:
3125:            }
3126:
3127:            /**
3128:             * Gets the Index diff for the index name, else returns null
3129:             */
3130:            protected IndexDiff getIndexDiffForName(TableDiff tableDiff,
3131:                    String name, boolean db) {
3132:                for (Iterator iter = tableDiff.getIndexDiffs().iterator(); iter
3133:                        .hasNext();) {
3134:                    IndexDiff diff = (IndexDiff) iter.next();
3135:                    JdbcIndex index = null;
3136:                    if (db) {
3137:                        index = diff.getDbIndex();
3138:                    } else {
3139:                        index = diff.getOurIndex();
3140:                    }
3141:                    if (index != null) {
3142:                        if (index.name.equalsIgnoreCase(name)) {// we have the right index
3143:                            return diff;
3144:                        }
3145:                    }
3146:                }
3147:                return null;
3148:
3149:            }
3150:
3151:            /**
3152:             * Gets the Constraint diff for the constraint name, else returns null
3153:             */
3154:            protected ConstraintDiff getConstraintDiffForName(
3155:                    TableDiff tableDiff, String name, boolean db) {
3156:                for (Iterator iter = tableDiff.getConstraintDiffs().iterator(); iter
3157:                        .hasNext();) {
3158:                    ConstraintDiff diff = (ConstraintDiff) iter.next();
3159:
3160:                    JdbcConstraint cons = null;
3161:                    if (db) {
3162:                        cons = diff.getDbConstraint();
3163:                    } else {
3164:                        cons = diff.getOurConstraint();
3165:                    }
3166:                    if (cons != null) {
3167:                        if (cons.name.equalsIgnoreCase(name)) {// we have the right index
3168:                            return diff;
3169:                        }
3170:                    }
3171:                }
3172:                return null;
3173:            }
3174:
3175:            /**
3176:             * Get the names of all tables in the database con is connected to.
3177:             */
3178:            public void setAllTableAndViewNames(Connection con)
3179:                    throws SQLException {
3180:                ResultSet rs = null;
3181:                try {
3182:                    rs = con.getMetaData().getTables(null, null, null, null);
3183:                    allTableList = new ArrayList();
3184:                    for (; rs.next();) {
3185:                        allTableList.add(rs.getString(3).trim().toUpperCase());
3186:                    }
3187:                } finally {
3188:                    if (rs != null) {
3189:                        try {
3190:                            rs.close();
3191:                        } catch (SQLException x) {
3192:                            // ignore
3193:                        }
3194:                    }
3195:                }
3196:            }
3197:
3198:            protected String getTempColumnName(JdbcTable table) {
3199:                char j = 'a';
3200:                CharBuf tempColName = new CharBuf("temp_column_" + j);
3201:
3202:                for (int i = 0; i < table.cols.length; i++) {
3203:                    JdbcColumn col = table.cols[i];
3204:                    if (col.name.equalsIgnoreCase(tempColName.toString())) {
3205:                        int lastIndex = tempColName.toString().lastIndexOf(j);
3206:                        tempColName.replace(lastIndex, lastIndex + 1, ++j);
3207:                        i = 0;
3208:                    }
3209:                }
3210:                return tempColName.toString();
3211:            }
3212:
3213:            protected String getTempTableName(JdbcTable table, int lenght) {
3214:                String temp = "temp_" + table.name;
3215:                if (lenght < temp.length()) {
3216:                    temp = shrinkName(temp, lenght);
3217:                }
3218:                char i = 'a';
3219:
3220:                while (allTableList.contains(temp.toUpperCase())) {
3221:                    if (i == 'a') {
3222:                        temp = temp + '_' + i;
3223:                        i++;
3224:                    } else {
3225:                        int lastIndex = temp.lastIndexOf('_');
3226:                        CharBuf buff = new CharBuf(temp);
3227:                        buff.replace(lastIndex + 1, lastIndex + 2, ++i);
3228:                        temp = buff.toString();
3229:                    }
3230:                    if (lenght < temp.length()) {
3231:                        temp = shrinkName(temp, lenght);
3232:                    }
3233:
3234:                }
3235:                allTableList.add(temp.toUpperCase());
3236:                return temp;
3237:            }
3238:
3239:            /**
3240:             * Shrink the supplied name to maxlen chars if it is longer than maxlen.
3241:             * This implementation removes vowels first and then truncates if it has
3242:             * to.
3243:             */
3244:            protected String shrinkName(String name, int maxlen) {
3245:                int len = name.length();
3246:                if (len <= maxlen)
3247:                    return name;
3248:                int todo = len - maxlen;
3249:                StringBuffer s = new StringBuffer();
3250:                s.append(name.charAt(0));
3251:                int i;
3252:                for (i = 1; todo > 0 && i < len;) {
3253:                    char c = name.charAt(i++);
3254:                    if (c == 'e' || c == 'a' || c == 'i' || c == 'o'
3255:                            || c == 'u') {
3256:                        --todo;
3257:                    } else {
3258:                        s.append(c);
3259:                    }
3260:                }
3261:                if (todo == 0) {
3262:                    s.append(name.substring(i));
3263:                }
3264:                if (s.length() > maxlen)
3265:                    s.setLength(maxlen);
3266:                return s.toString();
3267:            }
3268:
3269:            /**
3270:             * Get a string back with lengh i
3271:             */
3272:            protected String pad(int i) {
3273:                char[] spaces = new char[i];
3274:                for (int j = 0; j < spaces.length; j++) {
3275:                    spaces[j] = ' ';
3276:                }
3277:                return String.valueOf(spaces);
3278:            }
3279:
3280:            /**
3281:             * Use the index of the column in the 'group by' expression.
3282:             */
3283:            public boolean useColumnIndexForGroupBy() {
3284:                return false;
3285:            }
3286:
3287:            /**
3288:             * Calculate the typeCode for a aggregate expression.
3289:             *
3290:             * @param aggType         The aggregate type.
3291:             * @param currentTypeCode The currenct calculated typeCode.
3292:             * @see MDStatics
3293:             */
3294:            public int getAggregateTypeCode(int aggType, int currentTypeCode) {
3295:                switch (aggType) {
3296:                case AggregateNode.TYPE_AVG:
3297:                    if (MDStaticUtils.isIntegerType(currentTypeCode)) {
3298:
3299:                        return MDStatics.BIGDECIMAL;
3300:
3301:                    } else if (currentTypeCode == MDStatics.FLOATW
3302:                            || currentTypeCode == MDStatics.DOUBLEW) {
3303:
3304:                        return MDStatics.DOUBLEW;
3305:
3306:                    } else {
3307:                        return currentTypeCode;
3308:                    }
3309:                case AggregateNode.TYPE_COUNT:
3310:                    return MDStatics.LONGW;
3311:                case AggregateNode.TYPE_MAX:
3312:                    return currentTypeCode;
3313:                case AggregateNode.TYPE_MIN:
3314:                    return currentTypeCode;
3315:                case AggregateNode.TYPE_SUM:
3316:                    if (MDStaticUtils.isSignedIntegerType(currentTypeCode)) {
3317:
3318:                        return MDStatics.LONGW;
3319:
3320:                    } else {
3321:                        return currentTypeCode;
3322:                    }
3323:                default:
3324:                    throw BindingSupportImpl.getInstance().internal(
3325:                            "Aggregate type '" + aggType
3326:                                    + "' is not supported.");
3327:                }
3328:            }
3329:
3330:            /**
3331:             * Should columns be added to groupBy in appear in orderby and not in groupBy.
3332:             */
3333:            public boolean putOrderColsInGroupBy() {
3334:                return true;
3335:            }
3336:
3337:            /**
3338:             * Provide an oportunity for the driver to update the column's
3339:             * used for post insert keygen.
3340:             */
3341:            public void updateClassForPostInsertKeyGen(ClassMetaData cmd,
3342:                    JdbcMappingResolver mappingResolver) {
3343:            }
3344:
3345:            /**
3346:             * Should we use the col alias for columns that was added to the select
3347:             * list because they are in the orderby and not in the selectList.
3348:             *
3349:             * @return
3350:             */
3351:            public boolean useColAliasForAddedCols() {
3352:                return false;
3353:            }
3354:
3355:            public boolean isOracleStoreProcs() {
3356:                return false;
3357:            }
3358:
3359:            /**
3360:             * Maps a backend exception to a specific JDO exception
3361:             *
3362:             * @param cause   the backend exception
3363:             * @param message error message. if null, the error message is
3364:             *                taken from the backend exception
3365:             * @param isFatal is the error fatal or not
3366:             */
3367:            public RuntimeException mapException(Throwable cause,
3368:                    String message, boolean isFatal) {
3369:                return defaultMapException(cause, message, isFatal);
3370:            }
3371:
3372:            /**
3373:             * Maps a backend exception to a specific JDO exception.
3374:             * This is the default implementation which is used if no SqlDriver
3375:             * instance is available.
3376:             *
3377:             * @param cause   the backend exception
3378:             * @param message error message. if null, the error message is
3379:             *                taken from the backend exception
3380:             * @param isFatal is the error fatal or not
3381:             */
3382:            public static RuntimeException defaultMapException(Throwable cause,
3383:                    String message, boolean isFatal) {
3384:                BindingSupportImpl bsi = BindingSupportImpl.getInstance();
3385:                if (bsi.isOwnException(cause)) {
3386:                    return (RuntimeException) cause;
3387:                } else {
3388:                    if (Debug.DEBUG) {
3389:                        cause.printStackTrace(System.out);
3390:                    }
3391:                    if (bsi.isError(cause)) {
3392:                        if (bsi.isOutOfMemoryError(cause)) {
3393:                            return bsi.exception(cause.toString(), cause);
3394:                        }
3395:                        throw (Error) cause;
3396:                    }
3397:                    if (isFatal) {
3398:                        return bsi.fatalDatastore(message == null ? JdbcUtils
3399:                                .toString(cause) : message, cause);
3400:                    } else {
3401:                        return bsi.datastore(message == null ? JdbcUtils
3402:                                .toString(cause) : message, cause);
3403:                    }
3404:                }
3405:            }
3406:
3407:            /**
3408:             * Convenience method, which gets the SqlDriver instance from the
3409:             * store and calls its mapException() method. isFatal defaults to true.
3410:             * If no SqlDriver is set, SqlDriver.defaultMapException() is called.
3411:             *
3412:             * @param sqlDriver
3413:             * @param cause   the backend exception
3414:             * @param message error message. if null, the error message is
3415:             */
3416:            public static RuntimeException mapException(SqlDriver sqlDriver,
3417:                    Throwable cause, String message) {
3418:                return SqlDriver.mapException(sqlDriver, cause, message, true);
3419:            }
3420:
3421:            /**
3422:             * Convenience method, which gets the SqlDriver instance from the
3423:             * store and calls its mapException() method.
3424:             * If no SqlDriver is set, SqlDriver.defaultMapException() is called.
3425:             *
3426:             * @param sqlDriver
3427:             * @param cause   the backend exception
3428:             * @param message error message. if null, the error message is
3429:             *                taken from the backend exception
3430:             * @param isFatal is the error fatal or not
3431:             */
3432:            public static RuntimeException mapException(SqlDriver sqlDriver,
3433:                    Throwable cause, String message, boolean isFatal) {
3434:                if (sqlDriver != null) {
3435:                    return sqlDriver.mapException(cause, message, isFatal);
3436:                } else {
3437:                    return SqlDriver.defaultMapException(cause, message,
3438:                            isFatal);
3439:                }
3440:            }
3441:
3442:            /**
3443:             * Does the driver detect and handle exceptions caused by
3444:             * lock timeouts?
3445:             */
3446:            public boolean isHandleLockTimeout() {
3447:                return false;
3448:            }
3449:
3450:            /**
3451:             * Does the driver detect and handle exceptions caused by
3452:             * duplicate primary keys?
3453:             */
3454:            public boolean isHandleDuplicateKey() {
3455:                return false;
3456:            }
3457:
3458:            /**
3459:             * Is this a lock timeout exception?
3460:             */
3461:            public boolean isLockTimeout(Throwable e) {
3462:                return false;
3463:            }
3464:
3465:            /**
3466:             * Is this a duplicate key exception?
3467:             */
3468:            public boolean isDuplicateKey(Throwable e) {
3469:                return false;
3470:            }
3471:
3472:            /**
3473:             * Convert d to a String suitable for embedding as a literal in an SQL
3474:             * statement.
3475:             */
3476:            public String toSqlLiteral(double d) {
3477:                return doubleFormat.format(d);
3478:            }
3479:
3480:            /**
3481:             * Convert l to a String suitable for embedding as a literal in an SQL
3482:             * statement.
3483:             */
3484:            public String toSqlLiteral(long l) {
3485:                return Long.toString(l);
3486:            }
3487:
3488:            /**
3489:             * Convert s to a String suitable for embedding as a literal in an SQL
3490:             * statement.
3491:             */
3492:            public String toSqlLiteral(String s) {
3493:                return '\'' + s + '\'';
3494:            }
3495:
3496:            /**
3497:             * Convert s to a String suitable for embedding as a literal in an SQL
3498:             * statement.
3499:             */
3500:            public String toSqlLiteral(boolean b) {
3501:                return b ? "TRUE" : "FALSE";
3502:            }
3503:
3504:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.