mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-08 14:51:49 +00:00
Merged 5.1.N (5.1.2) to 5.2.N (5.2.1)
127078 rneamtu: Merged 5.0.N (5.0.4) to 5.1.N (5.1.2) 127046 amorarasu: MNT-16277: Merged V4.2-BUG-FIX (4.2.7) to 5.0.N (5.0.4) 126884 amorarasu: MNT-15710: No invalid synchronizations should appear in the cloud sync manager (step 2 - clean invalid synchronizations already created). git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@127124 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -184,6 +184,11 @@
|
|||||||
<association property="node" resultMap="alfresco.node.result_Node"/>
|
<association property="node" resultMap="alfresco.node.result_Node"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
|
<resultMap id="result_nodeIdInterval" type="java.util.HashMap">
|
||||||
|
<result property="minId" column="min_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
|
<result property="maxId" column="max_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- Parameter Maps -->
|
<!-- Parameter Maps -->
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@@ -1433,4 +1438,46 @@
|
|||||||
<if test="sortOrderAscending == false">order by childNode.id DESC</if>
|
<if test="sortOrderAscending == false">order by childNode.id DESC</if>
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
|
<select id="select_ChildAssocsOfParentWithoutNodeAssocsOfType" parameterType="Ids" resultMap="result_NodeRef">
|
||||||
|
select
|
||||||
|
childNode.id as id,
|
||||||
|
childStore.protocol as protocol,
|
||||||
|
childStore.identifier as identifier,
|
||||||
|
childNode.uuid as uuid
|
||||||
|
from
|
||||||
|
alf_child_assoc assoc
|
||||||
|
join alf_node childNode on (childNode.id = assoc.child_node_id)
|
||||||
|
join alf_store childStore on (childStore.id = childNode.store_id)
|
||||||
|
where
|
||||||
|
assoc.parent_node_id = #{idOne}
|
||||||
|
<if test="idTwo != null"><![CDATA[and childNode.id >= #{idTwo} ]]></if>
|
||||||
|
<if test="idThree != null"><![CDATA[and childNode.id < #{idThree}]]></if>
|
||||||
|
<if test="ids != null">
|
||||||
|
and not exists
|
||||||
|
(
|
||||||
|
select 1
|
||||||
|
from alf_node_assoc nodeAssoc
|
||||||
|
where
|
||||||
|
nodeAssoc.source_node_id = childNode.id
|
||||||
|
and nodeAssoc.type_qname_id in
|
||||||
|
<foreach item="item" index="index" collection="ids" open="(" separator="," close=")"> #{item} </foreach>
|
||||||
|
)
|
||||||
|
</if>
|
||||||
|
<include refid="alfresco.node.select_ChildAssoc_OrderBy"/>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="select_MinMaxNodeIdForNodeType" parameterType="TransactionQuery" resultMap="result_nodeIdInterval">
|
||||||
|
select
|
||||||
|
min(node.id) as min_id,
|
||||||
|
max(node.id) as max_id
|
||||||
|
from
|
||||||
|
alf_node node
|
||||||
|
join alf_transaction txn on (node.transaction_id = txn.id)
|
||||||
|
where
|
||||||
|
1 = 1
|
||||||
|
<if test="typeQNameId != null"><![CDATA[and node.type_qname_id = #{typeQNameId}]]></if>
|
||||||
|
<if test="maxCommitTime != null"><![CDATA[and txn.commit_time_ms <= #{maxCommitTime}]]></if>
|
||||||
|
<if test="minCommitTime != null"><![CDATA[and txn.commit_time_ms >= #{minCommitTime}]]></if>
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
@@ -702,6 +702,19 @@ public interface NodeDAO extends NodeBulkLoader
|
|||||||
final QName assocTypeQName,
|
final QName assocTypeQName,
|
||||||
ChildAssocRefQueryCallback resultsCallback);
|
ChildAssocRefQueryCallback resultsCallback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param parentNodeId the parent node id
|
||||||
|
* @param minNodeId the minimum node ID (inclusive), <tt>null</tt> for no limitation on the minimum value of the node id
|
||||||
|
* @param maxNodeId the maximum node ID (exclusive), <tt>null</tt> for no limitation on the maximum value of the node id
|
||||||
|
* @param assocToExcludeTypeQNames the node associations to exclude, <tt>null</tt> for no filtering of the associations types
|
||||||
|
* @return list of child nodes
|
||||||
|
*/
|
||||||
|
public List<Node> selectChildAssocsWithoutNodeAssocsOfTypes(
|
||||||
|
final Long parentNodeId,
|
||||||
|
final Long minNodeId,
|
||||||
|
final Long maxNodeId,
|
||||||
|
final Set<QName> assocToExcludeTypeQNames);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the association between the node's primary parent and the node itself
|
* Finds the association between the node's primary parent and the node itself
|
||||||
*
|
*
|
||||||
@@ -873,6 +886,16 @@ public interface NodeDAO extends NodeBulkLoader
|
|||||||
*/
|
*/
|
||||||
public Long getMaxNodeId();
|
public Long getMaxNodeId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the [minId, maxId] interval for nodes of a type, with the transaction time in the given window time.
|
||||||
|
*
|
||||||
|
* @param type the node type
|
||||||
|
* @param startTxnTime the starting transaction time, <tt>null</tt> is allowed, case in which no minimum transaction time is considered
|
||||||
|
* @param endTxnTime the end transaction time, <tt>null</tt> is allowed, case in which no maximum transaction time is considered
|
||||||
|
* @return the interval, as a pair
|
||||||
|
*/
|
||||||
|
public Pair<Long, Long> getNodeIdsIntervalForType(QName type, Long startTxnTime, Long endTxnTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select children by property values
|
* Select children by property values
|
||||||
*/
|
*/
|
||||||
|
@@ -114,6 +114,7 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
|
|||||||
private static final String DELETE_NODE_PROPERTIES = "alfresco.node.delete_NodeProperties";
|
private static final String DELETE_NODE_PROPERTIES = "alfresco.node.delete_NodeProperties";
|
||||||
private static final String SELECT_NODE_MIN_ID = "alfresco.node.select_NodeMinId";
|
private static final String SELECT_NODE_MIN_ID = "alfresco.node.select_NodeMinId";
|
||||||
private static final String SELECT_NODE_MAX_ID = "alfresco.node.select_NodeMaxId";
|
private static final String SELECT_NODE_MAX_ID = "alfresco.node.select_NodeMaxId";
|
||||||
|
private static final String SELECT_NODE_INTERVAL_BY_TYPE = "alfresco.node.select_MinMaxNodeIdForNodeType";
|
||||||
private static final String SELECT_NODES_WITH_ASPECT_IDS = "alfresco.node.select_NodesWithAspectIds";
|
private static final String SELECT_NODES_WITH_ASPECT_IDS = "alfresco.node.select_NodesWithAspectIds";
|
||||||
private static final String INSERT_NODE_ASSOC = "alfresco.node.insert.insert_NodeAssoc";
|
private static final String INSERT_NODE_ASSOC = "alfresco.node.insert.insert_NodeAssoc";
|
||||||
private static final String UPDATE_NODE_ASSOC = "alfresco.node.update_NodeAssoc";
|
private static final String UPDATE_NODE_ASSOC = "alfresco.node.update_NodeAssoc";
|
||||||
@@ -138,6 +139,8 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
|
|||||||
private static final String SELECT_CHILD_ASSOC_OF_PARENT_BY_NAME = "alfresco.node.select_ChildAssocOfParentByName";
|
private static final String SELECT_CHILD_ASSOC_OF_PARENT_BY_NAME = "alfresco.node.select_ChildAssocOfParentByName";
|
||||||
private static final String SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_PARENT_ASSOCS_OF_TYPE =
|
private static final String SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_PARENT_ASSOCS_OF_TYPE =
|
||||||
"alfresco.node.select_ChildAssocsOfParentWithoutParentAssocsOfType";
|
"alfresco.node.select_ChildAssocsOfParentWithoutParentAssocsOfType";
|
||||||
|
private static final String SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_NODE_ASSOCS_OF_TYPE =
|
||||||
|
"alfresco.node.select_ChildAssocsOfParentWithoutNodeAssocsOfType";
|
||||||
private static final String SELECT_PARENT_ASSOCS_OF_CHILD = "alfresco.node.select_ParentAssocsOfChild";
|
private static final String SELECT_PARENT_ASSOCS_OF_CHILD = "alfresco.node.select_ParentAssocsOfChild";
|
||||||
private static final String UPDATE_PARENT_ASSOCS_OF_CHILD = "alfresco.node.update_ParentAssocsOfChild";
|
private static final String UPDATE_PARENT_ASSOCS_OF_CHILD = "alfresco.node.update_ParentAssocsOfChild";
|
||||||
private static final String DELETE_SUBSCRIPTIONS = "alfresco.node.delete_NodeSubscriptions";
|
private static final String DELETE_SUBSCRIPTIONS = "alfresco.node.delete_NodeSubscriptions";
|
||||||
@@ -373,6 +376,38 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
|
|||||||
return (Long) template.selectOne(SELECT_NODE_MAX_ID);
|
return (Long) template.selectOne(SELECT_NODE_MAX_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pair<Long, Long> getNodeIdsIntervalForType(QName type, Long startTxnTime, Long endTxnTime)
|
||||||
|
{
|
||||||
|
final Pair<Long, Long> intervalPair = new Pair<Long, Long>(LONG_ZERO, LONG_ZERO);
|
||||||
|
Pair<Long, QName> typePair = qnameDAO.getQName(type);
|
||||||
|
if (typePair == null)
|
||||||
|
{
|
||||||
|
// Return default
|
||||||
|
return intervalPair;
|
||||||
|
}
|
||||||
|
TransactionQueryEntity txnQuery = new TransactionQueryEntity();
|
||||||
|
txnQuery.setTypeQNameId(typePair.getFirst());
|
||||||
|
txnQuery.setMinCommitTime(startTxnTime);
|
||||||
|
txnQuery.setMaxCommitTime(endTxnTime);
|
||||||
|
|
||||||
|
ResultHandler resultHandler = new ResultHandler()
|
||||||
|
{
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void handleResult(ResultContext context)
|
||||||
|
{
|
||||||
|
Map<Long, Long> result = (Map<Long, Long>) context.getResultObject();
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
intervalPair.setFirst(result.get("minId"));
|
||||||
|
intervalPair.setSecond(result.get("maxId"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template.select(SELECT_NODE_INTERVAL_BY_TYPE, txnQuery, resultHandler);
|
||||||
|
return intervalPair;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updatePrimaryChildrenSharedAclId(
|
protected void updatePrimaryChildrenSharedAclId(
|
||||||
Long txnId,
|
Long txnId,
|
||||||
@@ -1385,7 +1420,30 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
|
|||||||
resultsCallback.done();
|
resultsCallback.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@Override
|
||||||
|
public List<Node> selectChildAssocsWithoutNodeAssocsOfTypes(Long parentNodeId, Long minNodeId, Long maxNodeId, Set<QName> assocTypeQNames)
|
||||||
|
{
|
||||||
|
IdsEntity idsEntity = new IdsEntity();
|
||||||
|
|
||||||
|
// Parent node id
|
||||||
|
Assert.notNull(parentNodeId, "The parent node id must not be null.");
|
||||||
|
idsEntity.setIdOne(parentNodeId);
|
||||||
|
// Node ids selection interval
|
||||||
|
idsEntity.setIdTwo(minNodeId);
|
||||||
|
idsEntity.setIdThree(maxNodeId);
|
||||||
|
// Associations types to exclude
|
||||||
|
if (assocTypeQNames != null)
|
||||||
|
{
|
||||||
|
Set<Long> childNodeTypeQNameIds = qnameDAO.convertQNamesToIds(assocTypeQNames, false);
|
||||||
|
if (childNodeTypeQNameIds.size() > 0)
|
||||||
|
{
|
||||||
|
idsEntity.setIds(new ArrayList<Long>(childNodeTypeQNameIds));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return template.selectList(SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_NODE_ASSOCS_OF_TYPE, idsEntity);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<ChildAssocEntity> selectPrimaryParentAssocs(Long childNodeId)
|
protected List<ChildAssocEntity> selectPrimaryParentAssocs(Long childNodeId)
|
||||||
{
|
{
|
||||||
@@ -1665,7 +1723,7 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
|
|||||||
if (deletedTypePair == null)
|
if (deletedTypePair == null)
|
||||||
{
|
{
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
return 0L;
|
return LONG_ZERO;
|
||||||
}
|
}
|
||||||
TransactionQueryEntity txnQuery = new TransactionQueryEntity();
|
TransactionQueryEntity txnQuery = new TransactionQueryEntity();
|
||||||
txnQuery.setTypeQNameId(deletedTypePair.getFirst());
|
txnQuery.setTypeQNameId(deletedTypePair.getFirst());
|
||||||
|
@@ -189,6 +189,79 @@ public class NodeDAOTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testGetNodeIdsIntervalForType() throws Exception
|
||||||
|
{
|
||||||
|
// Different calls with equivalent parameters should return the same values
|
||||||
|
Pair<Long, Long> interval1 = getNodeIdsInterval(0L, System.currentTimeMillis());
|
||||||
|
Pair<Long, Long> interval2 = getNodeIdsInterval(null, System.currentTimeMillis());
|
||||||
|
Pair<Long, Long> interval3 = getNodeIdsInterval(null, null);
|
||||||
|
|
||||||
|
assertEquals(interval1.getFirst(), interval2.getFirst());
|
||||||
|
assertEquals(interval2.getFirst(), interval3.getFirst());
|
||||||
|
|
||||||
|
assertEquals(interval1.getSecond(), interval2.getSecond());
|
||||||
|
assertEquals(interval2.getSecond(), interval3.getSecond());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<Long, Long> getNodeIdsInterval(final Long minTxnTime, final Long maxTxnTime)
|
||||||
|
{
|
||||||
|
RetryingTransactionCallback<Pair<Long, Long>> callback = new RetryingTransactionCallback<Pair<Long, Long>>()
|
||||||
|
{
|
||||||
|
public Pair<Long, Long> execute() throws Throwable
|
||||||
|
{
|
||||||
|
return nodeDAO.getNodeIdsIntervalForType(ContentModel.TYPE_FOLDER, minTxnTime, maxTxnTime);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return txnHelper.doInTransaction(callback, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSelectChildAssocsWithoutNodeAssocsOfTypes()
|
||||||
|
{
|
||||||
|
final StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
|
||||||
|
final Long parentId = nodeDAO.getRootNode(storeRef).getFirst();
|
||||||
|
|
||||||
|
final AtomicLong min = new AtomicLong(0L);
|
||||||
|
final AtomicLong max = new AtomicLong(0L);
|
||||||
|
final Set<QName> typeAssocsToExclude = Collections.singleton(QName.createQName("noType"));
|
||||||
|
|
||||||
|
RetryingTransactionCallback<List<Node>> callback = new RetryingTransactionCallback<List<Node>>()
|
||||||
|
{
|
||||||
|
public List<Node> execute() throws Throwable
|
||||||
|
{
|
||||||
|
long minNodeId = min.get();
|
||||||
|
long maxNodeId = max.get();
|
||||||
|
return nodeDAO.selectChildAssocsWithoutNodeAssocsOfTypes(parentId, minNodeId, maxNodeId, typeAssocsToExclude);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the current node range
|
||||||
|
Pair<Long, Long> nodeRange = getNodeIdsInterval(0L, System.currentTimeMillis());
|
||||||
|
|
||||||
|
Long minNodeId = nodeRange.getFirst();
|
||||||
|
Long maxNodeId = nodeRange.getSecond();
|
||||||
|
|
||||||
|
min.set(minNodeId.longValue());
|
||||||
|
|
||||||
|
// Iterate across the nodes in the [minNodeId, maxNodeId] interval
|
||||||
|
while (min.longValue() <= maxNodeId.longValue())
|
||||||
|
{
|
||||||
|
max.set(min.get() + 100L); // 100 increments
|
||||||
|
// Get the nodes
|
||||||
|
List<Node> nodes = txnHelper.doInTransaction(callback, true);
|
||||||
|
for (Node node : nodes)
|
||||||
|
{
|
||||||
|
Long nodeId = node.getId();
|
||||||
|
assertNotNull(nodeId);
|
||||||
|
assertTrue("the min should be inclusive.", min.longValue() <= nodeId.longValue());
|
||||||
|
assertTrue("the max should be exclusive.", max.longValue() > nodeId.longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift the window up
|
||||||
|
min.set(max.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testGetNodesWithAspects() throws Throwable
|
public void testGetNodesWithAspects() throws Throwable
|
||||||
{
|
{
|
||||||
final NodeRefQueryCallback callback = new NodeRefQueryCallback()
|
final NodeRefQueryCallback callback = new NodeRefQueryCallback()
|
||||||
|
Reference in New Issue
Block a user