001
014
015 package com.liferay.portal.convert.util;
016
017 import com.liferay.portal.events.StartupHelperUtil;
018 import com.liferay.portal.kernel.dao.db.DB;
019 import com.liferay.portal.kernel.dao.db.DBManagerUtil;
020 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.kernel.util.Tuple;
026 import com.liferay.portal.model.BaseModel;
027 import com.liferay.portal.model.ServiceComponent;
028 import com.liferay.portal.service.ServiceComponentLocalServiceUtil;
029 import com.liferay.portal.spring.hibernate.DialectDetector;
030 import com.liferay.portal.upgrade.util.Table;
031 import com.liferay.portal.util.MaintenanceUtil;
032
033 import java.io.IOException;
034
035 import java.lang.reflect.Field;
036
037 import java.sql.Connection;
038 import java.sql.SQLException;
039
040 import java.util.HashMap;
041 import java.util.HashSet;
042 import java.util.LinkedHashMap;
043 import java.util.List;
044 import java.util.Map;
045 import java.util.Set;
046
047 import javax.sql.DataSource;
048
049 import org.hibernate.dialect.Dialect;
050
051
055 public class ModelMigratorImpl implements ModelMigrator {
056
057 @Override
058 public void migrate(
059 DataSource dataSource, List<Class<? extends BaseModel<?>>> models)
060 throws IOException, SQLException {
061
062 Dialect dialect = DialectDetector.getDialect(dataSource);
063
064 Connection connection = dataSource.getConnection();
065
066 try {
067 if (_log.isDebugEnabled()) {
068 _log.debug("Migrating database tables");
069 }
070
071 Map<String, Tuple> modelTableDetails = new HashMap<>();
072
073 for (Class<? extends BaseModel<?>> model : models) {
074 modelTableDetails.putAll(getModelTableDetails(model));
075 }
076
077 MaintenanceUtil.appendStatus(
078 "Processing " + modelTableDetails.size() + " models");
079
080 migrateModel(
081 modelTableDetails, DBManagerUtil.getDB(dialect, dataSource),
082 connection);
083 }
084 finally {
085 DataAccess.cleanUp(connection);
086 }
087 }
088
089 protected Map<String, Tuple> getModelTableDetails(Class<?> implClass) {
090 Map<String, Tuple> modelTableDetails = new LinkedHashMap<>();
091
092 Field[] fields = implClass.getFields();
093
094 for (Field field : fields) {
095 Tuple tuple = null;
096
097 String fieldName = field.getName();
098
099 if (fieldName.equals("TABLE_NAME") ||
100 (fieldName.startsWith("MAPPING_TABLE_") &&
101 fieldName.endsWith("_NAME"))) {
102
103 tuple = getTableDetails(implClass, field, fieldName);
104 }
105
106 if (tuple != null) {
107 String table = (String)tuple.getObject(0);
108
109 modelTableDetails.put(table, tuple);
110 }
111 }
112
113 return modelTableDetails;
114 }
115
116 protected Tuple getTableDetails(
117 Class<?> implClass, Field tableField, String tableFieldVar) {
118
119 try {
120 String columnsFieldVar = StringUtil.replace(
121 tableFieldVar, "_NAME", "_COLUMNS");
122 String sqlCreateFieldVar = StringUtil.replace(
123 tableFieldVar, "_NAME", "_SQL_CREATE");
124
125 Field columnsField = implClass.getField(columnsFieldVar);
126 Field sqlCreateField = implClass.getField(sqlCreateFieldVar);
127
128 String table = (String)tableField.get(StringPool.BLANK);
129 Object[][] columns = (Object[][])columnsField.get(new Object[0][0]);
130 String sqlCreate = (String)sqlCreateField.get(StringPool.BLANK);
131
132 return new Tuple(table, columns, sqlCreate);
133 }
134 catch (Exception e) {
135 }
136
137 return null;
138 }
139
140 protected void migrateModel(
141 Map<String, Tuple> modelTableDetails, DB db, Connection connection)
142 throws IOException {
143
144 MaintenanceUtil.appendStatus("<ul>");
145
146 for (Tuple tuple : modelTableDetails.values()) {
147 String table = (String)tuple.getObject(0);
148 Object[][] columns = (Object[][])tuple.getObject(1);
149 String sqlCreate = (String)tuple.getObject(2);
150
151 MaintenanceUtil.appendStatus(
152 "<li>Migrating table " + table + "</li>");
153
154 migrateTable(db, connection, table, columns, sqlCreate);
155 }
156
157 MaintenanceUtil.appendStatus("</ul>");
158
159 if (_log.isDebugEnabled()) {
160 _log.debug("Migrating database indexes");
161 }
162
163 StartupHelperUtil.updateIndexes(db, connection, false);
164
165 List<ServiceComponent> serviceComponents =
166 ServiceComponentLocalServiceUtil.getLatestServiceComponents();
167
168 Set<String> validIndexNames = new HashSet<>();
169
170 for (ServiceComponent serviceComponent : serviceComponents) {
171 String indexesSQL = serviceComponent.getIndexesSQL();
172
173 db.addIndexes(connection, indexesSQL, validIndexNames);
174 }
175 }
176
177 protected void migrateTable(
178 DB db, Connection connection, String tableName, Object[][] columns,
179 String sqlCreate) {
180
181 Table table = new Table(tableName, columns);
182
183 try {
184 table.generateTempFile();
185
186 db.runSQL(connection, sqlCreate);
187
188 table.populateTable(connection);
189 }
190 catch (Exception e) {
191 _log.error(e, e);
192
193 MaintenanceUtil.appendStatus(e.getMessage());
194 }
195 }
196
197 private static final Log _log = LogFactoryUtil.getLog(
198 ModelMigratorImpl.class);
199
200 }