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