/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.kernel.upgrade;
import com.liferay.portal.kernel.dao.jdbc.DataAccess;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.LoggingTimer;
import com.liferay.portal.kernel.util.StringBundler;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* @author Brian Wing Shun Chan
*/
public abstract class BaseUpgradeCompanyId extends UpgradeProcess {
@Override
protected void doUpgrade() throws Exception {
List<Callable<Void>> callables = new ArrayList<>();
for (TableUpdater tableUpdater : getTableUpdaters()) {
if (!hasColumn(tableUpdater.getTableName(), "companyId")) {
tableUpdater.setCreateCompanyIdColumn(true);
}
callables.add(tableUpdater);
}
ExecutorService executorService = Executors.newFixedThreadPool(
callables.size());
try {
List<Future<Void>> futures = executorService.invokeAll(callables);
for (Future<Void> future : futures) {
future.get();
}
}
finally {
executorService.shutdown();
}
}
protected abstract TableUpdater[] getTableUpdaters();
protected class TableUpdater implements Callable<Void> {
public TableUpdater(
String tableName, String foreignTableName,
String foreignColumnName) {
_tableName = tableName;
_columnName = foreignColumnName;
_foreignNamesArray = new String[][] {
new String[] {foreignTableName, foreignColumnName}
};
}
public TableUpdater(
String tableName, String columnName, String[][] foreignNamesArray) {
_tableName = tableName;
_columnName = columnName;
_foreignNamesArray = foreignNamesArray;
}
@Override
public final Void call() throws Exception {
try (LoggingTimer loggingTimer = new LoggingTimer(_tableName);
Connection connection =
DataAccess.getUpgradeOptimizedConnection()) {
if (_createCompanyIdColumn) {
if (_log.isInfoEnabled()) {
_log.info(
"Adding column companyId to table " + _tableName);
}
runSQL(
connection,
"alter table " + _tableName + " add companyId LONG");
}
else {
if (_log.isInfoEnabled()) {
_log.info(
"Skipping the creation of companyId column for " +
"table " + _tableName);
}
}
update(connection);
}
return null;
}
public String getTableName() {
return _tableName;
}
public void setCreateCompanyIdColumn(boolean createCompanyIdColumn) {
_createCompanyIdColumn = createCompanyIdColumn;
}
public void update(Connection connection)
throws IOException, SQLException {
for (String[] foreignNames : _foreignNamesArray) {
runSQL(
connection,
getUpdateSQL(connection, foreignNames[0], foreignNames[1]));
}
}
protected List<Long> getCompanyIds(Connection connection)
throws SQLException {
List<Long> companyIds = new ArrayList<>();
try (PreparedStatement ps = connection.prepareStatement(
"select companyId from Company");
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
long companyId = rs.getLong(1);
companyIds.add(companyId);
}
}
return companyIds;
}
protected String getSelectSQL(
Connection connection, String foreignTableName,
String foreignColumnName)
throws SQLException {
List<Long> companyIds = getCompanyIds(connection);
if (companyIds.size() == 1) {
return String.valueOf(companyIds.get(0));
}
StringBundler sb = new StringBundler(10);
sb.append("select max(companyId) from ");
sb.append(foreignTableName);
sb.append(" where ");
sb.append(foreignTableName);
sb.append(".");
sb.append(foreignColumnName);
sb.append(" = ");
sb.append(_tableName);
sb.append(".");
sb.append(_columnName);
return sb.toString();
}
protected String getUpdateSQL(
Connection connection, String foreignTableName,
String foreignColumnName)
throws SQLException {
return getUpdateSQL(
getSelectSQL(connection, foreignTableName, foreignColumnName));
}
protected String getUpdateSQL(String selectSQL) {
StringBundler sb = new StringBundler(5);
sb.append("update ");
sb.append(_tableName);
sb.append(" set companyId = (");
sb.append(selectSQL);
sb.append(")");
return sb.toString();
}
private final String _columnName;
private boolean _createCompanyIdColumn;
private final String[][] _foreignNamesArray;
private final String _tableName;
}
private static final Log _log = LogFactoryUtil.getLog(
BaseUpgradeCompanyId.class);
}