Merged DEV to HEAD (5.0)

87810: ACE-2030: Moved retired patches into retired-patches-context.xml
  87811: ACE-2030: Clean up unused PatchDAO methods and SQL mappings


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@87814 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2014-10-11 21:00:25 +00:00
parent 89a179e2d7
commit 33da30e3b8
7 changed files with 1297 additions and 2128 deletions

View File

@@ -1,147 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.Map;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.domain.control.ControlDAO;
import org.alfresco.repo.domain.patch.PatchDAO;
import org.alfresco.repo.domain.permissions.AccessControlListDAO;
import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Migrate permissions from the OLD format to defining, shared and layered
*/
public class DmPermissionsPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.updateDmPermissions.result";
private static Log logger = LogFactory.getLog(DmPermissionsPatch.class);
private AccessControlListDAO accessControlListDao;
private PatchDAO patchDAO;
private ControlDAO controlDAO;
public void setAccessControlListDao(AccessControlListDAO accessControlListDao)
{
this.accessControlListDao = accessControlListDao;
}
public void setPatchDAO(PatchDAO patchDAO)
{
this.patchDAO = patchDAO;
}
public void setControlDAO(ControlDAO controlDAO)
{
this.controlDAO = controlDAO;
}
@Override
protected String applyInternal() throws Exception
{
Thread progressThread = null;
progressThread = new Thread(new ProgressWatcher(), "DMPatchProgressWatcher");
progressThread.start();
try
{
Map<ACLType, Integer> summary = this.accessControlListDao.patchAcls();
// build the result message
String msg = I18NUtil.getMessage(DmPermissionsPatch.MSG_SUCCESS, summary.get(ACLType.DEFINING));
// done
return msg;
}
finally
{
progressThread.interrupt();
progressThread.join();
}
}
private class ProgressWatcher implements Runnable
{
private boolean running = true;
Long toDo;
Long max;
public void run()
{
while (this.running)
{
if (this.running)
{
RetryingTransactionHelper txHelper = transactionService.getRetryingTransactionHelper();
txHelper.setMaxRetries(1);
txHelper.setForceWritable(true);
RetryingTransactionCallback<Long> callback = new RetryingTransactionCallback<Long>()
{
public Long execute() throws Throwable
{
// Change isolation level
try
{
controlDAO.setTransactionIsolationLevel(1);
}
catch (IllegalStateException e)
{
// Can't be set. We're done here.
toDo = 0L;
running = false;
return 0L;
}
if (toDo == null)
{
toDo = patchDAO.getDmNodeCount();
max = patchDAO.getMaxAclId();
}
return patchDAO.getDmNodeCountWithNewACLs(ProgressWatcher.this.max);
}
};
try
{
Long done = txHelper.doInTransaction(callback, true, true);
reportProgress(this.toDo, done);
}
catch (Throwable e)
{
logger.error("Failure in ProgressWatcher", e);
this.running = false;
}
}
try
{
Thread.sleep(60000);
}
catch (InterruptedException e)
{
this.running = false;
}
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2014 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -18,168 +18,20 @@
*/
package org.alfresco.repo.domain.patch;
import java.util.List;
import java.util.Map;
import org.alfresco.ibatis.BatchingDAO;
import org.alfresco.repo.domain.contentdata.ContentDataDAO;
import org.alfresco.service.cmr.repository.ContentData;
import org.apache.ibatis.session.ResultHandler;
/**
* Abstract implementation for Patch DAO.
* <p>
* This provides additional queries used by patches.
*
* @author Derek Hulley
* @author janv
* @since 3.2
*/
public abstract class AbstractPatchDAOImpl implements PatchDAO, BatchingDAO
{
private ContentDataDAO contentDataDAO;
protected AbstractPatchDAOImpl()
{
}
/**
* Set the DAO that supplies {@link ContentData} IDs
*/
public void setContentDataDAO(ContentDataDAO contentDataDAO)
{
this.contentDataDAO = contentDataDAO;
}
@Override
public long getMaxAclId()
{
return getMaxAclEntityId();
}
@Override
public long getDmNodeCount()
{
return getDmNodeEntitiesCount();
}
@Override
public long getDmNodeCountWithNewACLs(Long above)
{
return getDmNodeEntitiesCountWithNewACLs(above);
}
/**
* {@inheritDoc}
* <p>
* @see #getAdmOldContentProperties(Long, Long)
*/
@Override
public void updateAdmV31ContentProperties(Long minNodeId, Long maxNodeId)
{
List<Map<String, Object>> props = getAdmOldContentProperties(minNodeId, maxNodeId);
// Do a first pass to create the ContentData IDs
for (Map<String, Object> prop : props)
{
String stringValue = (String) prop.get("stringValue");
ContentData contentData = ContentData.createContentProperty(stringValue);
Long contentDataId = contentDataDAO.createContentData(contentData).getFirst();
prop.put("contentDataId", contentDataId);
}
// Now do the updates in the context of a batch
try
{
// Run using a batch
startBatch();
for (Map<String, Object> prop : props)
{
Long nodeId = (Long) prop.get("nodeId");
Long qnameId = (Long) prop.get("qnameId");
Integer listIndex = (Integer) prop.get("listIndex");
Long localeId = (Long) prop.get("localeId");
Long contentDataId = (Long) prop.get("contentDataId");
// Update
updateAdmOldContentProperty(nodeId, qnameId, listIndex, localeId, contentDataId);
}
}
finally
{
executeBatch();
}
}
/**
* Results are of the form:
* <pre>
* nodeId: java.lang.Long
* qnameId: java.lang.Long
* listIndex: java.lang.Integer
* localeId: java.lang.Long
* stringValue: java.lang.String
* </pre>
*
*
* @param minNodeId inclusive lower bound for Node ID
* @param maxNodeId exclusive upper bound for Node ID
* @return Returns a map of query results
*/
protected abstract List<Map<String, Object>> getAdmOldContentProperties(Long minNodeId, Long maxNodeId);
/**
*
* @param nodeId part of the unique key
* @param qnameId part of the unique key
* @param listIndex part of the unique key
* @param localeId part of the unique key
* @param longValue the new ContentData ID
* @return Returns the row update count
*/
protected abstract void updateAdmOldContentProperty(
Long nodeId,
Long qnameId,
Integer listIndex,
Long localeId,
Long longValue);
protected abstract long getMaxAclEntityId();
protected abstract long getDmNodeEntitiesCount();
protected abstract long getDmNodeEntitiesCountWithNewACLs(Long above);
// note: caller's row handler is expected to migrate the attrs
@Override
public void migrateOldAttrTenants(ResultHandler resultHandler)
{
getOldAttrTenantsImpl(resultHandler);
}
protected abstract void getOldAttrTenantsImpl(ResultHandler resultHandler);
// note: caller's row handler is expected to migrate the attrs
@Override
public void migrateOldAttrPropertyBackedBeans(ResultHandler resultHandler)
{
getOldAttrPropertyBackedBeansImpl(resultHandler);
}
protected abstract void getOldAttrPropertyBackedBeansImpl(ResultHandler resultHandler);
// note: caller's row handler is expected to migrate the attrs
@Override
public void migrateOldAttrChainingURS(ResultHandler resultHandler)
{
getOldAttrChainingURSImpl(resultHandler);
}
protected abstract void getOldAttrChainingURSImpl(ResultHandler resultHandler);
@Override
public List<String> getOldAttrCustomNames()
{
return getOldAttrCustomNamesImpl();
}
protected abstract List<String> getOldAttrCustomNamesImpl();
}

View File

@@ -22,12 +22,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.repo.domain.contentdata.ContentDataDAO;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.apache.ibatis.session.ResultHandler;
/**
* Additional DAO services for patches
@@ -42,15 +39,6 @@ public interface PatchDAO
public long getMaxAdmNodeID();
/**
* Migrates DM content properties from the old V3.1 format (String-based {@link ContentData#toString()})
* to the new V3.2 format (ID based storage using {@link ContentDataDAO}).
*
* @param minNodeId the inclusive node ID to limit the updates to
* @param maxNodeId the exclusive node ID to limit the updates to
*/
public void updateAdmV31ContentProperties(Long minNodeId, Long maxNodeId);
/**
* Update all <b>alf_content_data</b> mimetype references.
*
@@ -60,92 +48,6 @@ public interface PatchDAO
*/
public int updateContentMimetypeIds(Long oldMimetypeId, Long newMimetypeId);
/**
* A callback handler for iterating over the string results
*/
public interface StringHandler
{
void handle(String string);
}
/**
* Add a <b>cm:sizeCurrent</b> property to person nodes that don't have it.
*/
public int addSizeCurrentProp();
// ACL-related
/**
* Get the max acl id
*
* @return - max acl id
*/
public long getMaxAclId();
/**
* How many DM nodes are there?
*
* @return - the count
*/
public long getDmNodeCount();
/**
* How many DM nodes are three with new ACls (to track patch progress)
*
* @param above
* @return - the count
*/
public long getDmNodeCountWithNewACLs(Long above);
/**
* @return Returns the names of authorities with incorrect CRC values
*/
public List<String> getAuthoritiesWithNonUtf8Crcs();
/**
* @return Returns the number child association rows
*/
public int getChildAssocCount();
/**
*
* @return Returns the maximum child assoc ID or <tt>0</tt> if there are none
*/
Long getMaxChildAssocId();
/**
* The results map contains:
* <pre>
* <![CDATA[
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="typeQNameId" column="type_qname_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="qnameNamespaceId" column="qname_ns_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="qnameLocalName" column="qname_localname" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="childNodeNameCrc" column="child_node_name_crc" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="qnameCrc" column="qname_crc" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="childNodeUuid" column="child_node_uuid" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="childNodeName" column="child_node_name" jdbcType="VARCHAR" javaType="java.lang.String"/>
]]>
* </pre>
* @param minAssocId the minimum child assoc ID
* @param stopAtAssocId the child assoc ID to stop at i.e. once this ID has been reached,
* pull back no results
* @param rangeMultiplier the ration of IDs to actual rows (how many IDs to select to get a row)
* @param maxIdRange the largest ID range to use for selects. Normally, the ID range should be
* allowed to grow in accordance with the general distribution of rows, but
* if memory problems are encountered, then the range will need to be set down.
* @param maxResults the number of child associations to fetch
* @return Returns child associations <b>that need fixing</b>
*/
public List<Map<String, Object>> getChildAssocsForCrcFix(
Long minAssocId,
Long stopAtAssocId,
long rangeMultiplier,
long maxIdRange,
int maxResults);
public int updateChildAssocCrc(Long assocId, Long childNodeNameCrc, Long qnameCrc);
/**
* Query for a list of nodes that have a given type and share the same name pattern (SQL LIKE syntax)
*
@@ -155,31 +57,11 @@ public interface PatchDAO
*/
public List<Pair<NodeRef, String>> getNodesOfTypeWithNamePattern(QName typeQName, String namePattern);
/**
* Migrate old Tenant attributes (if any)
*/
public void migrateOldAttrTenants(ResultHandler resultHandler);
/**
* Migrate old Property-Backed Bean attributes (if any)
*/
public void migrateOldAttrPropertyBackedBeans(ResultHandler resultHandler);
/**
* Migrate old Chaining User Registry Synchronizer attributes (if any)
*/
public void migrateOldAttrChainingURS(ResultHandler resultHandler);
/**
* Drop old attribute alf_*attribute* tables
*/
public void migrateOldAttrDropTables();
/**
* Get custom global attribute names (if any)
*/
public List<String> getOldAttrCustomNames();
/**
* Get shared acls with inheritance issues
*/
@@ -216,7 +98,7 @@ public interface PatchDAO
* @param typeQNameId - the id of the type qname
* @param minNodeId - min node id in the result set - inclusive
* @param maxNodeId - max node id in the result set - exclusive
* @return
* @return IDs of the nodes
*/
public List<Long> getNodesByTypeQNameId(Long typeQNameId, Long minNodeId, Long maxNodeId);
@@ -225,7 +107,7 @@ public interface PatchDAO
* @param uriId - the id of the type qname uri
* @param minNodeId - min node id in the result set - inclusive
* @param maxNodeId - max node id in the result set - exclusive
* @return
* @return IDs of the nodes
*/
public List<Long> getNodesByTypeUriId(Long uriId, Long minNodeId, Long maxNodeId);
@@ -234,7 +116,7 @@ public interface PatchDAO
* @param aspectQNameId - the id of the aspect qname
* @param minNodeId - min node id in the result set - inclusive
* @param maxNodeId - max node id in the result set - exclusive
* @return
* @return IDs of the nodes
*/
public List<Long> getNodesByAspectQNameId(Long aspectQNameId, Long minNodeId, Long maxNodeId);
@@ -243,7 +125,7 @@ public interface PatchDAO
* @param mimetypeId - the id of the content data mimetype
* @param minNodeId - min node id in the result set - inclusive
* @param maxNodeId - max node id in the result set - exclusive
* @return
* @return IDs of the nodes
*/
public List<Long> getNodesByContentPropertyMimetypeId(Long mimetypeId, Long minNodeId, Long maxNodeId);

View File

@@ -27,7 +27,7 @@ import java.util.Set;
import org.alfresco.ibatis.IdsEntity;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.CrcHelper;
import org.alfresco.repo.domain.contentdata.ContentDataDAO;
import org.alfresco.repo.domain.locale.LocaleDAO;
import org.alfresco.repo.domain.node.ChildAssocEntity;
import org.alfresco.repo.domain.patch.AbstractPatchDAOImpl;
@@ -38,12 +38,10 @@ import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.mybatis.spring.SqlSessionTemplate;
/**
@@ -54,28 +52,13 @@ import org.mybatis.spring.SqlSessionTemplate;
*/
public class PatchDAOImpl extends AbstractPatchDAOImpl
{
@SuppressWarnings("unused")
private static Log logger = LogFactory.getLog(PatchDAOImpl.class);
private static final String SELECT_ADM_MAX_NODE_ID = "alfresco.patch.select_admMaxNodeId";
private static final String SELECT_ADM_OLD_CONTENT_PROPERTIES = "alfresco.patch.select_admOldContentProperties";
private static final String SELECT_AUTHORITIES_AND_CRC = "alfresco.patch.select_authoritiesAndCrc";
private static final String SELECT_PERMISSIONS_MAX_ACL_ID = "alfresco.patch.select_MaxAclId";
private static final String SELECT_PERMISSIONS_DM_NODE_COUNT = "alfresco.patch.select_DmNodeCount";
private static final String SELECT_PERMISSIONS_DM_NODE_COUNT_WITH_NEW_ACLS = "alfresco.patch.select_DmNodeCountWherePermissionsHaveChanged";
private static final String SELECT_CHILD_ASSOCS_COUNT = "alfresco.patch.select_allChildAssocsCount";
private static final String SELECT_CHILD_ASSOCS_MAX_ID = "alfresco.patch.select_maxChildAssocId";
private static final String SELECT_CHILD_ASSOCS_FOR_CRCS = "alfresco.patch.select_allChildAssocsForCrcs";
private static final String SELECT_NODES_BY_TYPE_AND_NAME_PATTERN = "alfresco.patch.select_nodesByTypeAndNamePattern";
private static final String UPDATE_ADM_OLD_CONTENT_PROPERTY = "alfresco.patch.update_admOldContentProperty";
private static final String UPDATE_CONTENT_MIMETYPE_ID = "alfresco.patch.update_contentMimetypeId";
private static final String UPDATE_CHILD_ASSOC_CRC = "alfresco.patch.update_childAssocCrc";
private static final String UPDATE_CREATE_SIZE_CURRENT_PROPERTY = "alfresco.patch.update_CreateSizeCurrentProperty";
private static final String SELECT_OLD_ATTR_TENANTS = "alfresco.patch.select_oldAttrTenants";
private static final String SELECT_OLD_ATTR_PBBS = "alfresco.patch.select_oldAttrPropertyBackedBeans";
private static final String SELECT_OLD_ATTR_CHAINING_URS = "alfresco.patch.select_oldAttrChainingURS";
private static final String SELECT_OLD_ATTR_CUSTOM_NAMES = "alfresco.patch.select_oldAttrCustomNames";
private static final String DROP_OLD_ATTR_LIST = "alfresco.patch.drop_oldAttrAlfListAttributeEntries";
private static final String DROP_OLD_ATTR_MAP = "alfresco.patch.drop_oldAttrAlfMapAttributeEntries";
@@ -99,7 +82,11 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
private static final String SELECT_COUNT_NODES_WITH_TYPE_ID = "alfresco.patch.select_CountNodesWithTypeId";
private static final String SELECT_CHILDREN_OF_THE_SHARED_SURFCONFIG_FOLDER = "alfresco.patch.select_ChildrenOfTheSharedSurfConfigFolder";
private QNameDAO qnameDAO;
@SuppressWarnings("unused")
private LocaleDAO localeDAO;
@SuppressWarnings("unused")
private ContentDataDAO contentDataDAO;
protected SqlSessionTemplate template;
@@ -108,19 +95,20 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
this.template = sqlSessionTemplate;
}
private QNameDAO qnameDAO;
public void setQnameDAO(QNameDAO qnameDAO)
{
this.qnameDAO = qnameDAO;
}
public void setLocaleDAO(LocaleDAO localeDAO)
{
this.localeDAO = localeDAO;
}
public void setContentDataDAO(ContentDataDAO contentDataDAO)
{
this.contentDataDAO = contentDataDAO;
}
@Override
public void startBatch()
{
// TODO
@@ -136,6 +124,7 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
*/
}
@Override
public void executeBatch()
{
// TODO
@@ -151,34 +140,14 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
*/
}
@Override
public long getMaxAdmNodeID()
{
Long count = template.selectOne(SELECT_ADM_MAX_NODE_ID);
return count == null ? 0L : count;
}
@SuppressWarnings("unchecked")
@Override
protected List<Map<String, Object>> getAdmOldContentProperties(Long minNodeId, Long maxNodeId)
{
IdsEntity ids = new IdsEntity();
ids.setIdOne(minNodeId);
ids.setIdTwo(maxNodeId);
return template.selectList(SELECT_ADM_OLD_CONTENT_PROPERTIES, ids);
}
@Override
protected void updateAdmOldContentProperty(Long nodeId, Long qnameId, Integer listIndex, Long localeId, Long longValue)
{
Map<String, Object> params = new HashMap<String, Object>(11);
params.put("nodeId", nodeId);
params.put("qnameId", qnameId);
params.put("listIndex", listIndex);
params.put("localeId", localeId);
params.put("longValue", longValue);
template.update(UPDATE_ADM_OLD_CONTENT_PROPERTY, params);
}
public int updateContentMimetypeIds(Long oldMimetypeId, Long newMimetypeId)
{
Map<String, Object> params = new HashMap<String, Object>(11);
@@ -188,175 +157,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
}
@Override
public int addSizeCurrentProp()
{
Long sizeCurrentPropQNameId = qnameDAO.getOrCreateQName(ContentModel.PROP_SIZE_CURRENT).getFirst();
Long defaultLocaleId = localeDAO.getOrCreateDefaultLocalePair().getFirst();
Long personTypeQNameId = qnameDAO.getOrCreateQName(ContentModel.TYPE_PERSON).getFirst();
SizeCurrentParams params = new SizeCurrentParams();
params.setSizeCurrentQNameId(sizeCurrentPropQNameId);
params.setDefaultLocaleId(defaultLocaleId);
params.setPersonTypeQNameId(personTypeQNameId);
int rowsAffected = template.update(UPDATE_CREATE_SIZE_CURRENT_PROPERTY, params);
if (logger.isDebugEnabled())
{
logger.debug("Added " + rowsAffected + " cm:sizeCurrent properties.");
}
return rowsAffected;
}
@Override
protected long getMaxAclEntityId()
{
Long count = template.selectOne(SELECT_PERMISSIONS_MAX_ACL_ID, null);
return count == null ? 0L : count;
}
@Override
protected long getDmNodeEntitiesCount()
{
Long count = template.selectOne(SELECT_PERMISSIONS_DM_NODE_COUNT, null);
return count == null ? 0L : count;
}
@Override
protected long getDmNodeEntitiesCountWithNewACLs(Long above)
{
Map<String, Object> params = new HashMap<String, Object>(1);
params.put("id", above);
Long count = template.selectOne(SELECT_PERMISSIONS_DM_NODE_COUNT_WITH_NEW_ACLS, params);
return count == null ? 0L : count;
}
public List<String> getAuthoritiesWithNonUtf8Crcs()
{
final List<String> results = new ArrayList<String>(1000);
ResultHandler resultHandler = new ResultHandler()
{
@SuppressWarnings("unchecked")
public void handleResult(ResultContext context)
{
Map<String, Object> result = (Map<String, Object>) context.getResultObject();
String authority = (String) result.get("authority");
Long crc = (Long) result.get("crc");
Long crcShouldBe = CrcHelper.getStringCrcPair(authority, 32, true, true).getSecond();
if (!crcShouldBe.equals(crc))
{
// One to fix
results.add(authority);
}
}
};
template.select(SELECT_AUTHORITIES_AND_CRC, resultHandler);
// Done
return results;
}
public int getChildAssocCount()
{
return template.selectOne(SELECT_CHILD_ASSOCS_COUNT);
}
@Override
public Long getMaxChildAssocId()
{
Long maxAssocId = template.selectOne(SELECT_CHILD_ASSOCS_MAX_ID);
return maxAssocId == null ? 0L : maxAssocId;
}
@SuppressWarnings("unchecked")
public List<Map<String, Object>> getChildAssocsForCrcFix(
Long minAssocId,
Long stopAtAssocId,
long rangeMultiplier,
long maxIdRange,
int maxResults)
{
ParameterCheck.mandatory("minAssocId", minAssocId);
ParameterCheck.mandatory("stopAtAssocId", stopAtAssocId);
/*
* ALF-4529: Database connection problems when upgrading large sample 2.1.x data set
* We have to set an upper bound on the query that is driven by an index
* otherwise we get OOM on the resultset, even with a limit.
* Since there can be voids in the sequence, we have to check if we have hit the max ID, yet.
*/
Long qnameId = qnameDAO.getOrCreateQName(ContentModel.PROP_NAME).getFirst();
int queryMaxResults = maxResults;
List<Map<String, Object>> results = new ArrayList<Map<String,Object>>(maxResults);
while (results.size() < maxResults && minAssocId <= stopAtAssocId)
{
// Avoid getting too few results because of voids.
// On the other hand, the distribution of child assoc types can result in swathes of
// the table containing voids and rows of no interest. So we ramp up the multiplier
// to take larger and larger ID ranges in order to quickly walk through these zones.
Long maxAssocId = minAssocId + Math.min(maxResults * rangeMultiplier, maxIdRange);
IdsEntity entity = new IdsEntity();
entity.setIdOne(qnameId);
entity.setIdTwo(minAssocId);
entity.setIdThree(maxAssocId);
try
{
List<Map<String, Object>> rows = template.selectList(SELECT_CHILD_ASSOCS_FOR_CRCS, entity, new RowBounds(0, queryMaxResults));
if (results.size() == 0 && rows.size() >= maxResults)
{
// We have all we need
results = rows;
break;
}
// Add these rows to the result
results.addAll(rows);
// Calculate new maxResults
queryMaxResults = maxResults - results.size();
// Move the minAssocId up to ensure we get new results
// If we got fewer results than queryMaxResults, then there were too many voids and we
// requery using the previous maxAssocId
minAssocId = maxAssocId;
// Double the range multiplier if we have a low hit-rate (<50% of desired size)
// and we can avoid integer overflow
if (rows.size() < queryMaxResults / 2 )
{
long newRangeMultiplier = rangeMultiplier * 2L;
long newIdRange = maxResults * newRangeMultiplier;
if (newIdRange > 0 && newIdRange < maxIdRange)
{
rangeMultiplier = newRangeMultiplier;
}
}
}
catch (Throwable e)
{
// Hit a DB problem. Log all the details of the query so that parameters can be adjusted externally.
String msg =
"Failed to query for batch of alf_child_assoc rows; use a lower 'maxIdRange': \n" +
" minAssocId: " + minAssocId + "\n" +
" maxAssocId: " + maxAssocId + "\n" +
" maxIdRange: " + maxIdRange + "\n" +
" stopAtAssocId: " + stopAtAssocId + "\n" +
" rangeMultiplier: " + rangeMultiplier + "\n" +
" queryMaxResults: " + queryMaxResults;
logger.error(msg);
throw new RuntimeException(msg, e);
}
}
// Done
return results;
}
public int updateChildAssocCrc(Long assocId, Long childNodeNameCrc, Long qnameCrc)
{
Map<String, Object> params = new HashMap<String, Object>();
params.put("id", assocId);
params.put("childNodeNameCrc", childNodeNameCrc);
params.put("qnameCrc", qnameCrc);
return template.update(UPDATE_CHILD_ASSOC_CRC, params);
}
public List<Pair<NodeRef, String>> getNodesOfTypeWithNamePattern(QName typeQName, String namePattern)
{
Pair<Long, QName> typeQNamePair = qnameDAO.getQName(typeQName);
@@ -399,31 +199,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
return results;
}
@Override
protected void getOldAttrTenantsImpl(ResultHandler resultHandler)
{
template.select(SELECT_OLD_ATTR_TENANTS, resultHandler);
}
@Override
protected void getOldAttrPropertyBackedBeansImpl(ResultHandler resultHandler)
{
template.select(SELECT_OLD_ATTR_PBBS, resultHandler);
}
@Override
protected void getOldAttrChainingURSImpl(ResultHandler resultHandler)
{
template.select(SELECT_OLD_ATTR_CHAINING_URS, resultHandler);
}
@SuppressWarnings("unchecked")
@Override
protected List<String> getOldAttrCustomNamesImpl()
{
return template.selectList(SELECT_OLD_ATTR_CUSTOM_NAMES);
}
@Override
public void migrateOldAttrDropTables()
{
@@ -432,40 +207,7 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
template.update(DROP_OLD_ATTR_GLOBAL);
template.update(DROP_OLD_ATTR);
}
/**
* PostgreSQL-specific DAO
*
* @author Derek Hulley
* @since 4.0
*/
public static class PostgreSQL extends PatchDAOImpl
{
@Override
public void migrateOldAttrDropTables()
{
super.migrateOldAttrDropTables();
template.update(DROP_OLD_ATTR_SEQ);
}
}
/**
* Oracle-specific DAO
*
* @author Derek Hulley
* @since 4.0
*/
public static class Oracle extends PatchDAOImpl
{
@Override
public void migrateOldAttrDropTables()
{
super.migrateOldAttrDropTables();
template.update(DROP_OLD_ATTR_SEQ);
}
}
@SuppressWarnings("unchecked")
@Override
public List<Map<String, Object>> getAclsThatInheritFromNonPrimaryParent()
{
@@ -475,7 +217,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
return rows;
}
@SuppressWarnings("unchecked")
@Override
public List<Map<String, Object>> getAclsThatInheritWithInheritanceUnset()
{
@@ -485,7 +226,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
return rows;
}
@SuppressWarnings("unchecked")
@Override
public List<Map<String, Object>> getDefiningAclsThatDoNotInheritCorrectlyFromThePrimaryParent()
{
@@ -495,7 +235,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
return rows;
}
@SuppressWarnings("unchecked")
@Override
public List<Map<String, Object>> getSharedAclsThatDoNotInheritCorrectlyFromThePrimaryParent()
{
@@ -505,7 +244,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
return rows;
}
@SuppressWarnings("unchecked")
@Override
public List<Map<String, Object>> getSharedAclsThatDoNotInheritCorrectlyFromTheirDefiningAcl()
{
@@ -537,8 +275,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
}
}
@SuppressWarnings("unchecked")
@Override
public List<Long> getNodesByTypeQNameId(Long typeQNameId, Long minNodeId, Long maxNodeId)
{
@@ -549,7 +285,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
return template.selectList(SELECT_NODES_BY_TYPE_QNAME, params);
}
@SuppressWarnings("unchecked")
@Override
public List<Long> getNodesByTypeUriId(Long nsId, Long minNodeId, Long maxNodeId)
{
@@ -560,7 +295,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
return template.selectList(SELECT_NODES_BY_TYPE_URI, params);
}
@SuppressWarnings("unchecked")
@Override
public List<Long> getNodesByAspectQNameId(Long aspectQNameId, Long minNodeId, Long maxNodeId)
{
@@ -571,7 +305,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
return template.selectList(SELECT_NODES_BY_ASPECT_QNAME, params);
}
@SuppressWarnings("unchecked")
@Override
public List<Long> getNodesByContentPropertyMimetypeId(Long mimetypeId, Long minNodeId, Long maxNodeId)
{
@@ -604,7 +337,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
}
}
@Override
public List<NodeRef> getChildrenOfTheSharedSurfConfigFolder(Long minNodeId, Long maxNodeId)
{
@@ -647,4 +379,36 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
template.select(SELECT_CHILDREN_OF_THE_SHARED_SURFCONFIG_FOLDER, params, resultHandler);
return results;
}
/**
* PostgreSQL-specific DAO
*
* @author Derek Hulley
* @since 4.0
*/
public static class PostgreSQL extends PatchDAOImpl
{
@Override
public void migrateOldAttrDropTables()
{
super.migrateOldAttrDropTables();
template.update(DROP_OLD_ATTR_SEQ);
}
}
/**
* Oracle-specific DAO
*
* @author Derek Hulley
* @since 4.0
*/
public static class Oracle extends PatchDAOImpl
{
@Override
public void migrateOldAttrDropTables()
{
super.migrateOldAttrDropTables();
template.update(DROP_OLD_ATTR_SEQ);
}
}
}