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