1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.jumpmind.symmetric.db;
22
23 import java.sql.Connection;
24 import java.sql.DatabaseMetaData;
25 import java.sql.SQLException;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.ddlutils.Platform;
30 import org.apache.ddlutils.PlatformFactory;
31 import org.apache.ddlutils.platform.db2.Db2Platform;
32 import org.apache.ddlutils.platform.derby.DerbyPlatform;
33 import org.apache.ddlutils.platform.firebird.FirebirdPlatform;
34 import org.apache.ddlutils.platform.hsqldb.HsqlDbPlatform;
35 import org.apache.ddlutils.platform.mssql.MSSqlPlatform;
36 import org.apache.ddlutils.platform.mysql.MySqlPlatform;
37 import org.apache.ddlutils.platform.oracle.Oracle10Platform;
38 import org.apache.ddlutils.platform.oracle.Oracle8Platform;
39 import org.apache.ddlutils.platform.postgresql.PostgreSqlPlatform;
40 import org.springframework.beans.factory.BeanFactory;
41 import org.springframework.beans.factory.BeanFactoryAware;
42 import org.springframework.beans.factory.FactoryBean;
43 import org.springframework.dao.DataAccessException;
44 import org.springframework.jdbc.CannotGetJdbcConnectionException;
45 import org.springframework.jdbc.core.ConnectionCallback;
46 import org.springframework.jdbc.core.JdbcTemplate;
47 import org.springframework.transaction.support.TransactionTemplate;
48
49 public class DbDialectFactory implements FactoryBean, BeanFactoryAware {
50
51 private static final Log logger = LogFactory.getLog(DbDialectFactory.class);
52
53 private JdbcTemplate jdbcTemplate;
54
55 private BeanFactory beanFactory;
56
57 public Object getObject() throws Exception {
58
59 waitForAvailableDatabase();
60
61 String productName = getDbProductName();
62 int majorVersion = getDbMajorVersion();
63
64
65
66 String productString = productName + majorVersion;
67 if (productName.startsWith("DB2")) {
68 productString = "DB2v8";
69 }
70 Platform pf = PlatformFactory.createNewPlatformInstance(productString);
71 if (pf == null) {
72 pf = PlatformFactory.createNewPlatformInstance(jdbcTemplate.getDataSource());
73 } else {
74 pf.setDataSource(jdbcTemplate.getDataSource());
75 }
76
77 AbstractDbDialect dialect = null;
78
79 if (pf instanceof MySqlPlatform) {
80 dialect = (AbstractDbDialect) beanFactory.getBean("mysqlDialect");
81 } else if (pf instanceof Oracle8Platform) {
82 dialect = (AbstractDbDialect) beanFactory.getBean("oracleDialect");
83 } else if (pf instanceof Oracle10Platform) {
84 dialect = (AbstractDbDialect) beanFactory.getBean("oracleDialect");
85 } else if (pf instanceof MSSqlPlatform) {
86 dialect = (AbstractDbDialect) beanFactory.getBean("msSqlDialect");
87 } else if (pf instanceof PostgreSqlPlatform) {
88 dialect = (AbstractDbDialect) beanFactory.getBean("postgresqlDialect");
89 } else if (pf instanceof DerbyPlatform) {
90 dialect = (AbstractDbDialect) beanFactory.getBean("derbyDialect");
91 } else if (pf instanceof HsqlDbPlatform) {
92 dialect = (AbstractDbDialect) beanFactory.getBean("hsqldbDialect");
93 } else if (pf instanceof Db2Platform) {
94 dialect = (AbstractDbDialect) beanFactory.getBean("db2Dialect");
95 } else if (pf instanceof FirebirdPlatform) {
96 dialect = (AbstractDbDialect) beanFactory.getBean("firebirdDialect");
97 } else {
98 throw new DbNotSupportedException();
99 }
100
101 dialect.init(pf);
102 dialect.setTransactionTemplate((TransactionTemplate) beanFactory.getBean("currentTransactionTemplate"));
103 return dialect;
104 }
105
106 private void waitForAvailableDatabase() {
107 boolean success = false;
108 while (!success) {
109 try {
110 jdbcTemplate.execute(new ConnectionCallback() {
111 public Object doInConnection(Connection con) throws SQLException, DataAccessException {
112 return null;
113 }
114 });
115 success = true;
116 } catch (CannotGetJdbcConnectionException ex) {
117 logger.error("Could not get a connection to the database: " + ex.getMessage()
118 + ". Waiting for 10 seconds, before trying to connect to the database again.");
119 try {
120 Thread.sleep(10000);
121 } catch (InterruptedException e) {
122 }
123 }
124 }
125 }
126
127 private int getDbMajorVersion() {
128 return (Integer) new JdbcTemplate(jdbcTemplate.getDataSource()).execute(new ConnectionCallback() {
129 public Object doInConnection(Connection c) throws SQLException, DataAccessException {
130 DatabaseMetaData metaData = c.getMetaData();
131 return metaData.getDatabaseMajorVersion();
132 }
133 });
134 }
135
136 private String getDbProductName() {
137 return (String) new JdbcTemplate(jdbcTemplate.getDataSource()).execute(new ConnectionCallback() {
138 public Object doInConnection(Connection c) throws SQLException, DataAccessException {
139 DatabaseMetaData metaData = c.getMetaData();
140 return metaData.getDatabaseProductName();
141 }
142 });
143 }
144
145 public Class<IDbDialect> getObjectType() {
146 return IDbDialect.class;
147 }
148
149 public boolean isSingleton() {
150 return true;
151 }
152
153 public void setBeanFactory(BeanFactory beanFactory) {
154 this.beanFactory = beanFactory;
155 }
156
157 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
158 this.jdbcTemplate = jdbcTemplate;
159 }
160
161 }