1
22
23 package com.liferay.portal.convert;
24
25 import com.liferay.counter.model.Counter;
26 import com.liferay.mail.model.CyrusUser;
27 import com.liferay.mail.model.CyrusVirtual;
28 import com.liferay.portal.dao.jdbc.util.DataSourceFactoryBean;
29 import com.liferay.portal.kernel.dao.db.DB;
30 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
31 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
32 import com.liferay.portal.kernel.log.Log;
33 import com.liferay.portal.kernel.log.LogFactoryUtil;
34 import com.liferay.portal.kernel.util.InstancePool;
35 import com.liferay.portal.kernel.util.StringPool;
36 import com.liferay.portal.kernel.util.StringUtil;
37 import com.liferay.portal.kernel.util.Tuple;
38 import com.liferay.portal.model.ModelHintsUtil;
39 import com.liferay.portal.spring.hibernate.DialectDetector;
40 import com.liferay.portal.upgrade.util.Table;
41 import com.liferay.portal.util.MaintenanceUtil;
42 import com.liferay.portal.util.ShutdownUtil;
43
44 import java.lang.reflect.Field;
45
46 import java.sql.Connection;
47
48 import java.util.ArrayList;
49 import java.util.List;
50 import java.util.Properties;
51
52 import javax.sql.DataSource;
53
54 import org.hibernate.dialect.Dialect;
55
56
61 public class ConvertDatabase extends ConvertProcess {
62
63 public String getDescription() {
64 return "migrate-data-from-one-database-to-another";
65 }
66
67 public String getParameterDescription() {
68 return "please-enter-jdbc-information-for-new-database";
69 }
70
71 public String[] getParameterNames() {
72 return new String[] {
73 "jdbc-driver-class-name", "jdbc-url", "jdbc-user-name",
74 "jdbc-password"
75 };
76 }
77
78 public boolean isEnabled() {
79 return true;
80 }
81
82 protected void doConvert() throws Exception {
83 DataSource dataSource = getDataSource();
84
85 Dialect dialect = DialectDetector.getDialect(dataSource);
86
87 DB db = DBFactoryUtil.getDB(dialect);
88
89 List<String> modelNames = ModelHintsUtil.getModels();
90
91 List<Tuple> tableDetails = new ArrayList<Tuple>();
92
93 Connection connection = dataSource.getConnection();
94
95 try {
96 MaintenanceUtil.appendStatus(
97 "Collecting information for database tables to migration");
98
99 for (String modelName : modelNames) {
100 String implClassName = modelName.replaceFirst(
101 "(\\.model\\.)(\\p{Upper}.*)", "$1impl.$2Impl");
102
103 Class<?> implClass = InstancePool.get(implClassName).getClass();
104
105 Field[] fields = implClass.getFields();
106
107 for (Field field : fields) {
108 Tuple tuple = null;
109
110 String fieldName = field.getName();
111
112 if (fieldName.equals("TABLE_NAME")) {
113 tuple = getTableDetails(implClass, field, fieldName);
114 }
115 else if (fieldName.startsWith("MAPPING_TABLE_") &&
116 fieldName.endsWith("_NAME")) {
117
118 tuple = getTableDetails(implClass, field, fieldName);
119 }
120
121 if (tuple != null) {
122 tableDetails.add(tuple);
123 }
124 }
125 }
126
127 for (Tuple tuple : _UNMAPPED_TABLES) {
128 tableDetails.add(tuple);
129 }
130
131 if (_log.isDebugEnabled()) {
132 _log.debug("Migrating database tables");
133 }
134
135 for (int i = 0; i < tableDetails.size(); i++) {
136 if ((i > 0) && (i % (tableDetails.size() / 4) == 0)) {
137 MaintenanceUtil.appendStatus(
138 (i * 100 / tableDetails.size()) + "%");
139 }
140
141 Tuple tuple = tableDetails.get(i);
142
143 String table = (String)tuple.getObject(0);
144 Object[][] columns = (Object[][])tuple.getObject(1);
145 String sqlCreate = (String)tuple.getObject(2);
146
147 migrateTable(db, connection, table, columns, sqlCreate);
148 }
149 }
150 finally {
151 DataAccess.cleanUp(connection);
152 }
153
154 MaintenanceUtil.appendStatus(
155 "Please change your JDBC settings before restarting server");
156
157 ShutdownUtil.shutdown(0);
158 }
159
160 protected DataSource getDataSource() throws Exception {
161 String[] values = getParameterValues();
162
163 String jdbcDriverClassName = values[0];
164 String jdbcURL = values[1];
165 String jdbcUserName = values[2];
166 String jdbcPassword = values[3];
167
168 Properties properties = new Properties();
169
170 properties.setProperty(
171 _JDBC_PREFIX + "driverClassName", jdbcDriverClassName);
172 properties.setProperty(_JDBC_PREFIX + "url", jdbcURL);
173 properties.setProperty(_JDBC_PREFIX + "username", jdbcUserName);
174 properties.setProperty(_JDBC_PREFIX + "password", jdbcPassword);
175
176 DataSourceFactoryBean dataSourceFactory = new DataSourceFactoryBean();
177
178 dataSourceFactory.setProperties(properties);
179 dataSourceFactory.setPropertyPrefix(_JDBC_PREFIX);
180
181 return (DataSource)dataSourceFactory.createInstance();
182 }
183
184 protected Tuple getTableDetails(
185 Class<?> implClass, Field tableField, String tableFieldVar) {
186
187 try {
188 String columnsFieldVar = StringUtil.replace(
189 tableFieldVar, "_NAME", "_COLUMNS");
190 String sqlCreateFieldVar = StringUtil.replace(
191 tableFieldVar, "_NAME", "_SQL_CREATE");
192
193 Field columnsField = implClass.getField(columnsFieldVar);
194 Field sqlCreateField = implClass.getField(sqlCreateFieldVar);
195
196 String table = (String)tableField.get(StringPool.BLANK);
197 Object[][] columns = (Object[][])columnsField.get(new Object[0][0]);
198 String sqlCreate = (String)sqlCreateField.get(StringPool.BLANK);
199
200 return new Tuple(table, columns, sqlCreate);
201 }
202 catch (Exception e) {
203 }
204
205 return null;
206 }
207
208 protected void migrateTable(
209 DB db, Connection connection, String tableName, Object[][] columns,
210 String sqlCreate)
211 throws Exception {
212
213 Table table = new Table(tableName, columns);
214
215 String tempFileName = table.generateTempFile();
216
217 db.runSQL(connection, sqlCreate);
218
219 if (tempFileName != null) {
220 table.populateTable(tempFileName, connection);
221 }
222 }
223
224 private static final String _JDBC_PREFIX = "jdbc.upgrade.";
225
226 private static final Tuple[] _UNMAPPED_TABLES = new Tuple[] {
227 new Tuple(
228 Counter.TABLE_NAME, Counter.TABLE_COLUMNS,
229 Counter.TABLE_SQL_CREATE),
230 new Tuple(
231 CyrusUser.TABLE_NAME, CyrusUser.TABLE_COLUMNS,
232 CyrusUser.TABLE_SQL_CREATE),
233 new Tuple(
234 CyrusVirtual.TABLE_NAME, CyrusVirtual.TABLE_COLUMNS,
235 CyrusVirtual.TABLE_SQL_CREATE)
236 };
237
238 private static Log _log = LogFactoryUtil.getLog(ConvertDatabase.class);
239
240 }