mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-09-10 14:11:58 +00:00
Compare commits
9 Commits
25.2.0.16
...
feature/AC
Author | SHA1 | Date | |
---|---|---|---|
|
0e5b66c637 | ||
|
0c17a1c617 | ||
|
87ecfc9290 | ||
|
520e06dd49 | ||
|
f271697a8e | ||
|
e106502363 | ||
|
8811a73a8d | ||
|
44bca1d416 | ||
|
3b476670e0 |
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -90,6 +90,8 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
protected static final Log logger = LogFactory.getLog(DBQueryEngine.class);
|
protected static final Log logger = LogFactory.getLog(DBQueryEngine.class);
|
||||||
|
|
||||||
protected static final String SELECT_BY_DYNAMIC_QUERY = "alfresco.metadata.query.select_byDynamicQuery";
|
protected static final String SELECT_BY_DYNAMIC_QUERY = "alfresco.metadata.query.select_byDynamicQuery";
|
||||||
|
protected static final String COUNT_BY_DYNAMIC_QUERY = "alfresco.metadata.query.count_byDynamicQuery";
|
||||||
|
protected static final QueryTemplate QUERY_TEMPLATE = new QueryTemplate(SELECT_BY_DYNAMIC_QUERY, COUNT_BY_DYNAMIC_QUERY);
|
||||||
|
|
||||||
private static final int DEFAULT_MIN_PAGING_BATCH_SIZE = 2500;
|
private static final int DEFAULT_MIN_PAGING_BATCH_SIZE = 2500;
|
||||||
|
|
||||||
@@ -252,7 +254,7 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
*
|
*
|
||||||
* @see org.alfresco.repo.search.impl.querymodel.QueryEngine#executeQuery(org.alfresco.repo.search.impl.querymodel.Query, org.alfresco.repo.search.impl.querymodel.QueryOptions, org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext) */
|
* @see org.alfresco.repo.search.impl.querymodel.QueryEngine#executeQuery(org.alfresco.repo.search.impl.querymodel.Query, org.alfresco.repo.search.impl.querymodel.QueryOptions, org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext) */
|
||||||
@Override
|
@Override
|
||||||
public QueryEngineResults executeQuery(Query query, QueryOptions options, FunctionEvaluationContext functionContext)
|
public QueryEngineResults executeQuery(Query query, QueryOptions options, FunctionEvaluationContext functionContext)
|
||||||
@@ -331,10 +333,10 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
return asQueryEngineResults(resultSet);
|
return asQueryEngineResults(resultSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String pickQueryTemplate(QueryOptions options, DBQuery dbQuery)
|
protected QueryTemplate pickQueryTemplate(QueryOptions options, DBQuery dbQuery)
|
||||||
{
|
{
|
||||||
logger.debug("- using standard table for the query");
|
logger.debug("- using standard table for the query");
|
||||||
return SELECT_BY_DYNAMIC_QUERY;
|
return QUERY_TEMPLATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResultSet selectNodesWithPermissions(QueryOptions options, DBQuery dbQuery)
|
private ResultSet selectNodesWithPermissions(QueryOptions options, DBQuery dbQuery)
|
||||||
@@ -370,7 +372,8 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
int requiredNodes = computeRequiredNodesCount(options);
|
int requiredNodes = computeRequiredNodesCount(options);
|
||||||
|
|
||||||
logger.debug("- query sent to the database");
|
logger.debug("- query sent to the database");
|
||||||
performTmdqSelect(pickQueryTemplate(options, dbQuery), dbQuery, requiredNodes, new ResultHandler<Node>() {
|
QueryTemplate queryTemplate = pickQueryTemplate(options, dbQuery);
|
||||||
|
performTmdqSelect(queryTemplate, dbQuery, requiredNodes, new ResultHandler<Node>() {
|
||||||
@Override
|
@Override
|
||||||
public void handleResult(ResultContext<? extends Node> context)
|
public void handleResult(ResultContext<? extends Node> context)
|
||||||
{
|
{
|
||||||
@@ -425,8 +428,7 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
int numberFound = countSelectedNodes(queryTemplate, dbQuery);
|
||||||
int numberFound = nodes.size();
|
|
||||||
nodes.removeAll(Collections.singleton(null));
|
nodes.removeAll(Collections.singleton(null));
|
||||||
|
|
||||||
DBResultSet rs = createResultSet(options, nodes, numberFound);
|
DBResultSet rs = createResultSet(options, nodes, numberFound);
|
||||||
@@ -437,8 +439,17 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
return frs;
|
return frs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performTmdqSelect(String statement, DBQuery dbQuery, int requiredNodes, ResultHandler<Node> handler)
|
protected int countSelectedNodes(QueryTemplate queryTemplate, DBQuery dbQuery)
|
||||||
{
|
{
|
||||||
|
dbQuery.setLimit(0);
|
||||||
|
dbQuery.setOffset(0);
|
||||||
|
String countQuery = queryTemplate.count();
|
||||||
|
return template.selectOne(countQuery, dbQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performTmdqSelect(QueryTemplate queryTemplate, DBQuery dbQuery, int requiredNodes, ResultHandler<Node> handler)
|
||||||
|
{
|
||||||
|
String statement = queryTemplate.select();
|
||||||
if (usePagingQuery)
|
if (usePagingQuery)
|
||||||
{
|
{
|
||||||
performTmdqSelectPaging(statement, dbQuery, requiredNodes, handler);
|
performTmdqSelectPaging(statement, dbQuery, requiredNodes, handler);
|
||||||
@@ -457,8 +468,7 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
private void performTmdqSelectPaging(String statement, DBQuery dbQuery, int requiredNodes, ResultHandler<Node> handler)
|
private void performTmdqSelectPaging(String statement, DBQuery dbQuery, int requiredNodes, ResultHandler<Node> handler)
|
||||||
{
|
{
|
||||||
int batchStart = 0;
|
int batchStart = 0;
|
||||||
int batchSize = requiredNodes * 2;
|
int batchSize = calculateBatchSize(requiredNodes);
|
||||||
batchSize = Math.min(Math.max(batchSize, minPagingBatchSize), maxPagingBatchSize);
|
|
||||||
DefaultResultContext<Node> resultCtx = new DefaultResultContext<>();
|
DefaultResultContext<Node> resultCtx = new DefaultResultContext<>();
|
||||||
while (!resultCtx.isStopped())
|
while (!resultCtx.isStopped())
|
||||||
{
|
{
|
||||||
@@ -485,6 +495,21 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int calculateBatchSize(int requiredNodes)
|
||||||
|
{
|
||||||
|
int batchSize;
|
||||||
|
if (requiredNodes > Integer.MAX_VALUE / 2)
|
||||||
|
{
|
||||||
|
// preventing overflow
|
||||||
|
batchSize = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
batchSize = requiredNodes * 2;
|
||||||
|
}
|
||||||
|
return Math.min(Math.max(batchSize, minPagingBatchSize), maxPagingBatchSize);
|
||||||
|
}
|
||||||
|
|
||||||
private DBResultSet createResultSet(QueryOptions options, List<Node> nodes, int numberFound)
|
private DBResultSet createResultSet(QueryOptions options, List<Node> nodes, int numberFound)
|
||||||
{
|
{
|
||||||
DBResultSet dbResultSet = new DBResultSet(options.getAsSearchParmeters(), nodes, nodeDAO, nodeService, tenantService, Integer.MAX_VALUE);
|
DBResultSet dbResultSet = new DBResultSet(options.getAsSearchParmeters(), nodes, nodeDAO, nodeService, tenantService, Integer.MAX_VALUE);
|
||||||
@@ -524,7 +549,7 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
*
|
*
|
||||||
* @see org.alfresco.repo.search.impl.querymodel.QueryEngine#getQueryModelFactory() */
|
* @see org.alfresco.repo.search.impl.querymodel.QueryEngine#getQueryModelFactory() */
|
||||||
@Override
|
@Override
|
||||||
public QueryModelFactory getQueryModelFactory()
|
public QueryModelFactory getQueryModelFactory()
|
||||||
@@ -534,7 +559,7 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection of nodes cache for clean-up and warm up when required
|
* Injection of nodes cache for clean-up and warm up when required
|
||||||
*
|
*
|
||||||
* @param cache
|
* @param cache
|
||||||
* The node cache to set
|
* The node cache to set
|
||||||
*/
|
*/
|
||||||
@@ -588,4 +613,7 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected record QueryTemplate(String select, String count)
|
||||||
|
{}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -203,9 +203,8 @@ public class VirtualQueryImpl implements VirtualQuery
|
|||||||
start = 0;
|
start = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final int totlaSecond = !hasMore ? (int) result.getNumberFound() : (int) (start + result.getNumberFound() + 1);
|
final int totalSecond = !hasMore ? (int) result.getNumberFound() : (int) (start + result.getNumberFound());
|
||||||
final Pair<Integer, Integer> total = new Pair<Integer, Integer>(totalFirst,
|
final Pair<Integer, Integer> total = new Pair<>(totalFirst, totalSecond);
|
||||||
totlaSecond);
|
|
||||||
return new PagingResults<Reference>() {
|
return new PagingResults<Reference>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -8,4 +8,10 @@
|
|||||||
<include refid="sql_select_byDynamicQuery"/>
|
<include refid="sql_select_byDynamicQuery"/>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</mapper>
|
<select id="count_byDynamicQuery" parameterType="org.alfresco.repo.search.impl.querymodel.impl.db.DBQuery" resultType="int">
|
||||||
|
SELECT COUNT(DISTINCT nodes.id)
|
||||||
|
FROM (
|
||||||
|
<include refid="sql_select_byDynamicQuery"/>
|
||||||
|
) nodes
|
||||||
|
</select>
|
||||||
|
</mapper>
|
||||||
|
@@ -8,4 +8,10 @@
|
|||||||
<include refid="sql_select_byDynamicQuery"/>
|
<include refid="sql_select_byDynamicQuery"/>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</mapper>
|
<select id="count_byDynamicQuery" parameterType="org.alfresco.repo.search.impl.querymodel.impl.db.DBQuery" resultType="int">
|
||||||
|
SELECT COUNT(DISTINCT nodes.id)
|
||||||
|
FROM (
|
||||||
|
<include refid="sql_select_byDynamicQuery"/>
|
||||||
|
) nodes
|
||||||
|
</select>
|
||||||
|
</mapper>
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -80,6 +80,7 @@ import org.alfresco.util.testing.category.NonBuildTests;
|
|||||||
|
|
||||||
// ACS-1907
|
// ACS-1907
|
||||||
org.alfresco.repo.search.impl.querymodel.impl.db.ACS1907Test.class,
|
org.alfresco.repo.search.impl.querymodel.impl.db.ACS1907Test.class,
|
||||||
|
org.alfresco.repo.search.impl.querymodel.impl.db.ACS9167Test.class,
|
||||||
|
|
||||||
// REPO-2963 : Tests causing a cascade of failures in AllDBTestsTestSuite on PostgreSQL/MySQL
|
// REPO-2963 : Tests causing a cascade of failures in AllDBTestsTestSuite on PostgreSQL/MySQL
|
||||||
// Moved at the bottom of the suite because DbNodeServiceImplTest.testNodeCleanupRegistry() takes a long time on a clean DB.
|
// Moved at the bottom of the suite because DbNodeServiceImplTest.testNodeCleanupRegistry() takes a long time on a clean DB.
|
||||||
|
@@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.search.impl.querymodel.impl.db;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.cache.TransactionalCache;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.QueryConsistency;
|
||||||
|
import org.alfresco.service.cmr.search.ResultSet;
|
||||||
|
import org.alfresco.service.cmr.search.SearchParameters;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
|
import org.alfresco.test_category.OwnJVMTestsCategory;
|
||||||
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
|
import org.alfresco.util.testing.category.DBTests;
|
||||||
|
|
||||||
|
@Category({OwnJVMTestsCategory.class, DBTests.class})
|
||||||
|
@SuppressWarnings({"PMD.JUnitTestsShouldIncludeAssert"})
|
||||||
|
public class ACS9167Test
|
||||||
|
{
|
||||||
|
private NodeService nodeService;
|
||||||
|
private AuthenticationComponent authenticationComponent;
|
||||||
|
private SearchService pubSearchService;
|
||||||
|
private TransactionService transactionService;
|
||||||
|
private RetryingTransactionHelper txnHelper;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception
|
||||||
|
{
|
||||||
|
setupServices();
|
||||||
|
txnHelper = new RetryingTransactionHelper();
|
||||||
|
txnHelper.setTransactionService(transactionService);
|
||||||
|
txnHelper.setReadOnly(false);
|
||||||
|
txnHelper.setMaxRetries(1);
|
||||||
|
authenticationComponent.setSystemUserAsCurrentUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupServices()
|
||||||
|
{
|
||||||
|
ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||||
|
nodeService = (NodeService) ctx.getBean("dbNodeService");
|
||||||
|
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
|
||||||
|
pubSearchService = (SearchService) ctx.getBean("SearchService");
|
||||||
|
transactionService = (TransactionService) ctx.getBean("TransactionService");
|
||||||
|
|
||||||
|
List<TransactionalCache<?, ?>> cachesToClear = new ArrayList<>();
|
||||||
|
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("propertyValueCache"));
|
||||||
|
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("node.nodesCache"));
|
||||||
|
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("node.propertiesCache"));
|
||||||
|
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("aclCache"));
|
||||||
|
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("aclEntityCache"));
|
||||||
|
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("permissionEntityCache"));
|
||||||
|
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("nodeOwnerCache"));
|
||||||
|
|
||||||
|
for (TransactionalCache<?, ?> transactionalCache : cachesToClear)
|
||||||
|
{
|
||||||
|
transactionalCache.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception
|
||||||
|
{
|
||||||
|
authenticationComponent.clearCurrentSecurityContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPagination()
|
||||||
|
{
|
||||||
|
String searchMarker = UUID.randomUUID().toString();
|
||||||
|
int contentFilesCount = 185;
|
||||||
|
createFolderWithContentNodes(searchMarker, contentFilesCount);
|
||||||
|
|
||||||
|
prepareParametersQueryAndAssertResult(searchMarker, 0, 50, 50, contentFilesCount);
|
||||||
|
prepareParametersQueryAndAssertResult(searchMarker, 50, 50, 50, contentFilesCount);
|
||||||
|
prepareParametersQueryAndAssertResult(searchMarker, 150, 50, 35, contentFilesCount);
|
||||||
|
prepareParametersQueryAndAssertResult(searchMarker, 200, 50, 0, contentFilesCount);
|
||||||
|
|
||||||
|
prepareParametersQueryAndAssertResult(searchMarker, 0, 100, 100, contentFilesCount);
|
||||||
|
prepareParametersQueryAndAssertResult(searchMarker, 100, 100, 85, contentFilesCount);
|
||||||
|
prepareParametersQueryAndAssertResult(searchMarker, 200, 100, 0, contentFilesCount);
|
||||||
|
|
||||||
|
prepareParametersQueryAndAssertResult(searchMarker, 0, 200, contentFilesCount, contentFilesCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLargeFilesCount()
|
||||||
|
{
|
||||||
|
String searchMarker = UUID.randomUUID().toString();
|
||||||
|
int contentFilesCount = 10_000;
|
||||||
|
createFolderWithContentNodes(searchMarker, contentFilesCount);
|
||||||
|
|
||||||
|
prepareParametersQueryAndAssertResult(searchMarker, 0, Integer.MAX_VALUE, contentFilesCount, contentFilesCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createFolderWithContentNodes(String searchMarker, int contentFilesCount)
|
||||||
|
{
|
||||||
|
NodeRef testFolder = txnHelper.doInTransaction(this::createFolderNode, false, false);
|
||||||
|
int batchSize = 1000;
|
||||||
|
int fullBatches = contentFilesCount / batchSize;
|
||||||
|
int remainingItems = contentFilesCount % batchSize;
|
||||||
|
|
||||||
|
for (int i = 0; i < fullBatches; i++)
|
||||||
|
{
|
||||||
|
txnHelper.doInTransaction(() -> {
|
||||||
|
for (int j = 0; j < batchSize; j++)
|
||||||
|
{
|
||||||
|
createContentNode(searchMarker, testFolder);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remainingItems > 0)
|
||||||
|
{
|
||||||
|
txnHelper.doInTransaction(() -> {
|
||||||
|
for (int j = 0; j < remainingItems; j++)
|
||||||
|
{
|
||||||
|
createContentNode(searchMarker, testFolder);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareParametersQueryAndAssertResult(String searchMarker, int parameterSkipCount, int parameterMaxItems, int expectedLength, int expectedNumberFound)
|
||||||
|
{
|
||||||
|
txnHelper.doInTransaction(() -> {
|
||||||
|
// given
|
||||||
|
SearchParameters sp = new SearchParameters();
|
||||||
|
sp.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
|
||||||
|
sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
|
||||||
|
sp.setQueryConsistency(QueryConsistency.TRANSACTIONAL);
|
||||||
|
sp.setQuery("(+TYPE:'cm:content') and !ASPECT:'cm:checkedOut' and !TYPE:'fm:forum' and !TYPE:'fm:topic' and !TYPE:'cm:systemfolder' and !TYPE:'fm:post' and !TYPE:'fm:forums' and =cm:description:'" + searchMarker + "'");
|
||||||
|
sp.setSkipCount(parameterSkipCount);
|
||||||
|
sp.setMaxItems(parameterMaxItems);
|
||||||
|
sp.setMaxPermissionChecks(Integer.MAX_VALUE);
|
||||||
|
sp.setMaxPermissionCheckTimeMillis(Duration.ofMinutes(10).toMillis());
|
||||||
|
// when
|
||||||
|
ResultSet resultSet = pubSearchService.query(sp);
|
||||||
|
// then
|
||||||
|
assertEquals(expectedLength, resultSet.length());
|
||||||
|
assertEquals(expectedNumberFound, resultSet.getNumberFound());
|
||||||
|
return null;
|
||||||
|
}, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeRef createFolderNode()
|
||||||
|
{
|
||||||
|
NodeRef rootNodeRef = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
|
||||||
|
Map<QName, Serializable> testFolderProps = new HashMap<>();
|
||||||
|
String folderName = "folder" + UUID.randomUUID();
|
||||||
|
testFolderProps.put(ContentModel.PROP_NAME, folderName);
|
||||||
|
return nodeService.createNode(
|
||||||
|
rootNodeRef,
|
||||||
|
ContentModel.ASSOC_CHILDREN,
|
||||||
|
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, folderName),
|
||||||
|
ContentModel.TYPE_FOLDER,
|
||||||
|
testFolderProps).getChildRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createContentNode(String searchMarker, NodeRef testFolder)
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> testContentProps = new HashMap<>();
|
||||||
|
String fileName = "content" + UUID.randomUUID();
|
||||||
|
testContentProps.put(ContentModel.PROP_NAME, fileName);
|
||||||
|
testContentProps.put(ContentModel.PROP_DESCRIPTION, searchMarker);
|
||||||
|
nodeService.createNode(
|
||||||
|
testFolder,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, fileName),
|
||||||
|
ContentModel.TYPE_CONTENT,
|
||||||
|
testContentProps);
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -60,7 +60,8 @@ import org.alfresco.util.Pair;
|
|||||||
|
|
||||||
public class DBQueryEngineTest
|
public class DBQueryEngineTest
|
||||||
{
|
{
|
||||||
private static final String SQL_TEMPLATE_PATH = "alfresco.metadata.query.select_byDynamicQuery";
|
private static final String SQL_SELECT_TEMPLATE_PATH = "alfresco.metadata.query.select_byDynamicQuery";
|
||||||
|
private static final String SQL_COUNT_TEMPLATE_PATH = "alfresco.metadata.query.count_byDynamicQuery";
|
||||||
|
|
||||||
private DBQueryEngine engine;
|
private DBQueryEngine engine;
|
||||||
private SqlSessionTemplate template;
|
private SqlSessionTemplate template;
|
||||||
@@ -94,6 +95,7 @@ public class DBQueryEngineTest
|
|||||||
public void shouldGetAFilteringResultSetFromAcceleratedNodeSelection()
|
public void shouldGetAFilteringResultSetFromAcceleratedNodeSelection()
|
||||||
{
|
{
|
||||||
withMaxItems(10);
|
withMaxItems(10);
|
||||||
|
when(template.selectOne(any(), eq(dbQuery))).thenReturn(10);
|
||||||
|
|
||||||
ResultSet result = engine.acceleratedNodeSelection(options, dbQuery, assessor);
|
ResultSet result = engine.acceleratedNodeSelection(options, dbQuery, assessor);
|
||||||
|
|
||||||
@@ -226,7 +228,9 @@ public class DBQueryEngineTest
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}).when(template).select(eq(SQL_TEMPLATE_PATH), eq(dbQuery), any());
|
}).when(template).select(eq(SQL_SELECT_TEMPLATE_PATH), eq(dbQuery), any());
|
||||||
|
|
||||||
|
when(template.selectOne(eq(SQL_COUNT_TEMPLATE_PATH), eq(dbQuery))).thenReturn(nodes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryOptions createQueryOptions()
|
private QueryOptions createQueryOptions()
|
||||||
|
Reference in New Issue
Block a user