/**
* 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.upgrade.v7_0_3;
import com.liferay.portal.kernel.dao.db.DB;
import com.liferay.portal.kernel.dao.db.DBManagerUtil;
import com.liferay.portal.kernel.dao.db.DBType;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.ReleaseConstants;
import com.liferay.portal.kernel.upgrade.UpgradeProcess;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.LoggingTimer;
import com.liferay.portal.kernel.util.ReleaseInfo;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringUtil;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* @author Alberto Chaparro
*/
public class UpgradeOracle extends UpgradeProcess {
protected void alterVarchar2Columns() throws Exception {
try (LoggingTimer loggingTimer = new LoggingTimer();
PreparedStatement ps = connection.prepareStatement(
"select table_name, column_name, data_length from " +
"user_tab_columns where data_type = 'VARCHAR2' and " +
"char_used = 'B'");
ResultSet rs = ps.executeQuery()) {
int buildNumber = getBuildNumber();
while (rs.next()) {
String tableName = rs.getString(1);
if (!_tableNames.contains(StringUtil.toLowerCase(tableName))) {
continue;
}
String columnName = rs.getString(2);
int dataLength = rs.getInt(3);
if (isBetweenBuildNumbers(
buildNumber, ReleaseInfo.RELEASE_5_2_9_BUILD_NUMBER,
ReleaseInfo.RELEASE_6_0_0_BUILD_NUMBER) ||
isBetweenBuildNumbers(
buildNumber, ReleaseInfo.RELEASE_6_0_5_BUILD_NUMBER,
ReleaseInfo.RELEASE_6_2_0_BUILD_NUMBER)) {
// LPS-33903
if (!ArrayUtil.contains(
_ORIGINAL_DATA_LENGTH_VALUES, dataLength)) {
dataLength = dataLength / 4;
}
}
try {
runSQL(
"alter table " + tableName + " modify " + columnName +
" varchar2(" + dataLength + " char)");
}
catch (SQLException sqle) {
if (sqle.getErrorCode() == 1441) {
if (_log.isWarnEnabled()) {
StringBundler sb = new StringBundler(6);
sb.append("Unable to alter length of column ");
sb.append(columnName);
sb.append(" for table ");
sb.append(tableName);
sb.append(" because it contains values that are ");
sb.append("larger than the new column length");
_log.warn(sb.toString());
}
}
else {
throw sqle;
}
}
}
}
}
@Override
protected void doUpgrade() throws Exception {
DB db = DBManagerUtil.getDB();
if (db.getDBType() != DBType.ORACLE) {
return;
}
alterVarchar2Columns();
}
protected int getBuildNumber() throws Exception {
try (PreparedStatement ps = connection.prepareStatement(
"select buildNumber from Release_ where servletContextName = " +
"?")) {
ps.setString(1, ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME);
try (ResultSet rs = ps.executeQuery()) {
rs.next();
return rs.getInt(1);
}
}
}
protected boolean isBetweenBuildNumbers(
int buildNumber, int startBuildNumber, int endBuildNumber) {
if ((buildNumber >= startBuildNumber) &&
(buildNumber < endBuildNumber)) {
return true;
}
return false;
}
private static final int[] _ORIGINAL_DATA_LENGTH_VALUES = {
75, 100, 150, 200, 255, 500, 1000, 1024, 2000, 4000
};
private static final Log _log = LogFactoryUtil.getLog(UpgradeOracle.class);
private static final Set<String> _tableNames = new HashSet<>(
Arrays.asList(
"account_", "address", "announcementsdelivery",
"announcementsentry", "announcementsflag", "assetcategory",
"assetcategoryproperty", "assetentries_assetcategories",
"assetentries_assettags", "assetentry", "assetlink", "assettag",
"assettagstats", "assetvocabulary", "backgroundtask", "blogsentry",
"blogsstatsuser", "bookmarksentry", "bookmarksfolder",
"browsertracker", "classname_", "clustergroup", "company",
"contact_", "counter", "country", "ddlrecord", "ddlrecordset",
"ddlrecordversion", "ddmcontent", "ddmstoragelink", "ddmstructure",
"ddmstructurelink", "ddmtemplate", "dlcontent", "dlfileentry",
"dlfileentrymetadata", "dlfileentrytype",
"dlfileentrytypes_dlfolders", "dlfilerank", "dlfileshortcut",
"dlfileversion", "dlfolder", "dlsyncevent", "emailaddress",
"expandocolumn", "expandorow", "expandotable", "expandovalue",
"exportimportconfiguration", "group_", "groups_orgs",
"groups_roles", "groups_usergroups", "image", "journalarticle",
"journalarticleimage", "journalarticleresource",
"journalcontentsearch", "journalfeed", "journalfolder", "layout",
"layoutbranch", "layoutfriendlyurl", "layoutprototype",
"layoutrevision", "layoutset", "layoutsetbranch",
"layoutsetprototype", "listtype", "lock_", "mbban", "mbcategory",
"mbdiscussion", "mbmailinglist", "mbmessage", "mbstatsuser",
"mbthread", "mbthreadflag", "mdraction", "mdrrule", "mdrrulegroup",
"mdrrulegroupinstance", "membershiprequest", "organization_",
"orggrouprole", "orglabor", "passwordpolicy", "passwordpolicyrel",
"passwordtracker", "phone", "pluginsetting", "pollschoice",
"pollsquestion", "pollsvote", "portalpreferences", "portlet",
"portletitem", "portletpreferences", "ratingsentry", "ratingsstats",
"recentlayoutbranch", "recentlayoutrevision",
"recentlayoutsetbranch", "region", "release_", "repository",
"repositoryentry", "resourceaction", "resourceblock",
"resourceblockpermission", "resourcepermission",
"resourcetypepermission", "role_", "servicecomponent",
"shoppingcart", "shoppingcategory", "shoppingcoupon",
"shoppingitem", "shoppingitemfield", "shoppingitemprice",
"shoppingorder", "shoppingorderitem", "socialactivity",
"socialactivityachievement", "socialactivitycounter",
"socialactivitylimit", "socialactivityset", "socialactivitysetting",
"socialrelation", "socialrequest", "subscription", "systemevent",
"team", "ticket", "trashentry", "trashversion",
"usernotificationdelivery", "user_", "usergroup",
"usergroupgrouprole", "usergrouprole", "usergroups_teams",
"useridmapper", "usernotificationevent", "users_groups",
"users_orgs", "users_roles", "users_teams", "users_usergroups",
"usertracker", "usertrackerpath", "virtualhost", "webdavprops",
"website", "wikinode", "wikipage", "wikipageresource",
"workflowdefinitionlink", "workflowinstancelink"));
}