mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
CE-882 Change doesSelectClauseRequireDistinct to work with multilocks
This commit is contained in:
@ -27,6 +27,7 @@ import java.sql.Connection;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -63,6 +64,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinType;
|
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.security.MultiRecordSecurityLock;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.security.RecordSecurityLock;
|
import com.kingsrook.qqq.backend.core.model.metadata.security.RecordSecurityLock;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.security.RecordSecurityLockFilters;
|
import com.kingsrook.qqq.backend.core.model.metadata.security.RecordSecurityLockFilters;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
@ -70,6 +72,7 @@ import com.kingsrook.qqq.backend.core.model.querystats.QueryStat;
|
|||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.memoization.Memoization;
|
||||||
import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager;
|
import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager;
|
||||||
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
|
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
|
||||||
import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData;
|
import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData;
|
||||||
@ -89,6 +92,9 @@ public abstract class AbstractRDBMSAction
|
|||||||
protected PreparedStatement statement;
|
protected PreparedStatement statement;
|
||||||
protected boolean isCancelled = false;
|
protected boolean isCancelled = false;
|
||||||
|
|
||||||
|
private static Memoization<String, Boolean> doesSelectClauseRequireDistinctMemoization = new Memoization<String, Boolean>()
|
||||||
|
.withTimeout(Duration.ofDays(365));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -852,6 +858,7 @@ public abstract class AbstractRDBMSAction
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Make it easy (e.g., for tests) to turn on logging of SQL
|
** Make it easy (e.g., for tests) to turn on logging of SQL
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -938,14 +945,42 @@ public abstract class AbstractRDBMSAction
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** method that looks at security lock joins, and if a one-to-many is found where
|
** method that looks at security lock joins, and if a one-to-many is found where
|
||||||
** the specified field name is on the 'right side' of the join, then a distinct
|
** the specified field name is on the 'right side' of the join, then a distinct
|
||||||
** needs added to select clause
|
** needs added to select clause.
|
||||||
|
**
|
||||||
|
** Memoized because it's a lot of gyrations, and it never ever changes for a
|
||||||
|
** running server.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
protected boolean doesSelectClauseRequireDistinct(QTableMetaData table)
|
protected boolean doesSelectClauseRequireDistinct(QTableMetaData table)
|
||||||
{
|
{
|
||||||
if(table != null)
|
if(table == null)
|
||||||
{
|
{
|
||||||
for(RecordSecurityLock recordSecurityLock : RecordSecurityLockFilters.filterForReadLocks(CollectionUtils.nonNullList(table.getRecordSecurityLocks())))
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return doesSelectClauseRequireDistinctMemoization.getResult(table.getName(), (name) ->
|
||||||
{
|
{
|
||||||
|
MultiRecordSecurityLock multiRecordSecurityLock = RecordSecurityLockFilters.filterForReadLockTree(CollectionUtils.nonNullList(table.getRecordSecurityLocks()));
|
||||||
|
return doesMultiLockRequireDistinct(multiRecordSecurityLock, table);
|
||||||
|
}).orElse(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private boolean doesMultiLockRequireDistinct(MultiRecordSecurityLock multiRecordSecurityLock, QTableMetaData table)
|
||||||
|
{
|
||||||
|
for(RecordSecurityLock recordSecurityLock : multiRecordSecurityLock.getLocks())
|
||||||
|
{
|
||||||
|
if(recordSecurityLock instanceof MultiRecordSecurityLock childMultiLock)
|
||||||
|
{
|
||||||
|
if(doesMultiLockRequireDistinct(childMultiLock, table))
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(String joinName : CollectionUtils.nonNullList(recordSecurityLock.getJoinNameChain()))
|
for(String joinName : CollectionUtils.nonNullList(recordSecurityLock.getJoinNameChain()))
|
||||||
{
|
{
|
||||||
QJoinMetaData joinMetaData = QContext.getQInstance().getJoin(joinName);
|
QJoinMetaData joinMetaData = QContext.getQInstance().getJoin(joinName);
|
||||||
@ -959,7 +994,6 @@ public abstract class AbstractRDBMSAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user