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