diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/HistoryService.java b/modules/activiti-engine/src/main/java/org/activiti/engine/HistoryService.java index 380d31109ea792b611f2f99286c27a02340403ad..ece9693483db5cdd8995f0deeb4bedacb4b4380d 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/HistoryService.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/HistoryService.java @@ -28,8 +28,10 @@ import org.activiti.engine.history.HistoricTaskInstanceQuery; import org.activiti.engine.history.HistoricVariableInstance; import org.activiti.engine.history.HistoricVariableInstanceQuery; import org.activiti.engine.history.NativeHistoricActivityInstanceQuery; +import org.activiti.engine.history.NativeHistoricDetailQuery; import org.activiti.engine.history.NativeHistoricProcessInstanceQuery; import org.activiti.engine.history.NativeHistoricTaskInstanceQuery; +import org.activiti.engine.history.NativeHistoricVariableInstanceQuery; import org.activiti.engine.task.IdentityLink; /** @@ -56,10 +58,20 @@ public interface HistoryService { /** Creates a new programmatic query to search for {@link HistoricDetail}s. */ HistoricDetailQuery createHistoricDetailQuery(); + + /** + * Returns a new {@link org.activiti.engine.query.NativeQuery} for process definitions. + */ + NativeHistoricDetailQuery createNativeHistoricDetailQuery(); /** Creates a new programmatic query to search for {@link HistoricVariableInstance}s. */ HistoricVariableInstanceQuery createHistoricVariableInstanceQuery(); + /** + * Returns a new {@link org.activiti.engine.query.NativeQuery} for process definitions. + */ + NativeHistoricVariableInstanceQuery createNativeHistoricVariableInstanceQuery(); + /** Deletes historic task instance. This might be useful for tasks that are * {@link TaskService#newTask() dynamically created} and then {@link TaskService#complete(String) completed}. * If the historic task instance doesn't exist, no exception is thrown and the diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/history/NativeHistoricDetailQuery.java b/modules/activiti-engine/src/main/java/org/activiti/engine/history/NativeHistoricDetailQuery.java new file mode 100644 index 0000000000000000000000000000000000000000..b126a79a40b5368122004c640cd6ab446b293acf --- /dev/null +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/history/NativeHistoricDetailQuery.java @@ -0,0 +1,11 @@ +package org.activiti.engine.history; + +import org.activiti.engine.query.NativeQuery; + +/** + * Allows querying of {@link org.activiti.engine.history.HistoricDetail}s via native (SQL) queries + * @author Henry Yan(http://www.kafeitu.me) + */ +public interface NativeHistoricDetailQuery extends NativeQuery { + +} \ No newline at end of file diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/history/NativeHistoricVariableInstanceQuery.java b/modules/activiti-engine/src/main/java/org/activiti/engine/history/NativeHistoricVariableInstanceQuery.java new file mode 100644 index 0000000000000000000000000000000000000000..1b382a161e2ec0e5c1d188293b33e4ae0b8cc48c --- /dev/null +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/history/NativeHistoricVariableInstanceQuery.java @@ -0,0 +1,12 @@ +package org.activiti.engine.history; + +import org.activiti.engine.query.NativeQuery; + +/** + * Allows querying of {@link org.activiti.engine.history.HistoricVariableInstance}s via native (SQL) queries + * @author Henry Yan(http://www.kafeitu.me) + */ +public interface NativeHistoricVariableInstanceQuery + extends NativeQuery { + +} \ No newline at end of file diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/HistoryServiceImpl.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/HistoryServiceImpl.java index cc357ef2adbb056cc08eed7d9049a02c1e9031c5..d2a1bf26b3f5d2b0d3885e31ed2dca10ac6c203e 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/HistoryServiceImpl.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/HistoryServiceImpl.java @@ -24,8 +24,10 @@ import org.activiti.engine.history.HistoricProcessInstanceQuery; import org.activiti.engine.history.HistoricTaskInstanceQuery; import org.activiti.engine.history.HistoricVariableInstanceQuery; import org.activiti.engine.history.NativeHistoricActivityInstanceQuery; +import org.activiti.engine.history.NativeHistoricDetailQuery; import org.activiti.engine.history.NativeHistoricProcessInstanceQuery; import org.activiti.engine.history.NativeHistoricTaskInstanceQuery; +import org.activiti.engine.history.NativeHistoricVariableInstanceQuery; import org.activiti.engine.impl.cmd.DeleteHistoricProcessInstanceCmd; import org.activiti.engine.impl.cmd.DeleteHistoricTaskInstanceCmd; import org.activiti.engine.impl.cmd.GetHistoricIdentityLinksForTaskCmd; @@ -53,10 +55,20 @@ public class HistoryServiceImpl extends ServiceImpl implements HistoryService { return new HistoricDetailQueryImpl(commandExecutor); } + @Override + public NativeHistoricDetailQuery createNativeHistoricDetailQuery() { + return new NativeHistoricDetailQueryImpl(commandExecutor); + } + public HistoricVariableInstanceQuery createHistoricVariableInstanceQuery() { return new HistoricVariableInstanceQueryImpl(commandExecutor); } - + + @Override + public NativeHistoricVariableInstanceQuery createNativeHistoricVariableInstanceQuery() { + return new NativeHistoricVariableInstanceQueryImpl(commandExecutor); + } + public void deleteHistoricTaskInstance(String taskId) { commandExecutor.execute(new DeleteHistoricTaskInstanceCmd(taskId)); } diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/NativeHistoricDetailQueryImpl.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/NativeHistoricDetailQueryImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..e7139fc778268fe7aabfba7f2053409ed2074198 --- /dev/null +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/NativeHistoricDetailQueryImpl.java @@ -0,0 +1,37 @@ +package org.activiti.engine.impl; + +import java.util.List; +import java.util.Map; + +import org.activiti.engine.history.HistoricDetail; +import org.activiti.engine.history.NativeHistoricDetailQuery; +import org.activiti.engine.impl.interceptor.CommandContext; +import org.activiti.engine.impl.interceptor.CommandExecutor; + +public class NativeHistoricDetailQueryImpl extends AbstractNativeQuery implements NativeHistoricDetailQuery { + + private static final long serialVersionUID = 1L; + + public NativeHistoricDetailQueryImpl(CommandContext commandContext) { + super(commandContext); + } + + public NativeHistoricDetailQueryImpl(CommandExecutor commandExecutor) { + super(commandExecutor); + } + + //results //////////////////////////////////////////////////////////////// + + public List executeList(CommandContext commandContext, Map parameterMap, int firstResult, int maxResults) { + return commandContext + .getHistoricDetailEntityManager() + .findHistoricDetailsByNativeQuery(parameterMap, firstResult, maxResults); + } + + public long executeCount(CommandContext commandContext, Map parameterMap) { + return commandContext + .getHistoricDetailEntityManager() + .findHistoricDetailCountByNativeQuery(parameterMap); + } + +} \ No newline at end of file diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/NativeHistoricVariableInstanceQueryImpl.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/NativeHistoricVariableInstanceQueryImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..52eb1558b7d73d3914a33e9900d8a0cca906d66d --- /dev/null +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/NativeHistoricVariableInstanceQueryImpl.java @@ -0,0 +1,37 @@ +package org.activiti.engine.impl; + +import java.util.List; +import java.util.Map; + +import org.activiti.engine.history.HistoricVariableInstance; +import org.activiti.engine.history.NativeHistoricVariableInstanceQuery; +import org.activiti.engine.impl.interceptor.CommandContext; +import org.activiti.engine.impl.interceptor.CommandExecutor; + +public class NativeHistoricVariableInstanceQueryImpl extends AbstractNativeQuery implements NativeHistoricVariableInstanceQuery { + + private static final long serialVersionUID = 1L; + + public NativeHistoricVariableInstanceQueryImpl(CommandContext commandContext) { + super(commandContext); + } + + public NativeHistoricVariableInstanceQueryImpl(CommandExecutor commandExecutor) { + super(commandExecutor); + } + + //results //////////////////////////////////////////////////////////////// + + public List executeList(CommandContext commandContext, Map parameterMap, int firstResult, int maxResults) { + return commandContext + .getHistoricVariableInstanceEntityManager() + .findHistoricVariableInstancesByNativeQuery(parameterMap, firstResult, maxResults); + } + + public long executeCount(CommandContext commandContext, Map parameterMap) { + return commandContext + .getHistoricVariableInstanceEntityManager() + .findHistoricVariableInstanceCountByNativeQuery(parameterMap); + } + +} \ No newline at end of file diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/db/DbSqlSessionFactory.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/db/DbSqlSessionFactory.java index 0ebfc051346c751702aafbf68cfa199045356055..9f15c41eaa511a93322e93a6a48f677b5df67bc5 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/db/DbSqlSessionFactory.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/db/DbSqlSessionFactory.java @@ -99,6 +99,13 @@ public class DbSqlSessionFactory implements SessionFactory { addDatabaseSpecificStatement("db2", "selectHistoricProcessInstanceByNativeQuery", "selectHistoricProcessInstanceByNativeQuery_mssql_or_db2"); addDatabaseSpecificStatement("db2", "selectHistoricTaskInstanceByNativeQuery", "selectHistoricTaskInstanceByNativeQuery_mssql_or_db2"); addDatabaseSpecificStatement("db2", "selectTaskByNativeQuery", "selectTaskByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("db2", "selectProcessDefinitionByNativeQuery", "selectProcessDefinitionByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("db2", "selectDeploymentByNativeQuery", "selectDeploymentByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("db2", "selectGroupByNativeQuery", "selectGroupByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("db2", "selectUserByNativeQuery", "selectUserByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("db2", "selectModelByNativeQuery", "selectModelByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("db2", "selectHistoricDetailByNativeQuery", "selectHistoricDetailByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("db2", "selectHistoricVariableInstanceByNativeQuery", "selectHistoricVariableInstanceByNativeQuery_mssql_or_db2"); // mssql databaseSpecificLimitBeforeStatements.put("mssql", "SELECT SUB.* FROM ("); @@ -112,6 +119,13 @@ public class DbSqlSessionFactory implements SessionFactory { addDatabaseSpecificStatement("mssql", "selectHistoricProcessInstanceByNativeQuery", "selectHistoricProcessInstanceByNativeQuery_mssql_or_db2"); addDatabaseSpecificStatement("mssql", "selectHistoricTaskInstanceByNativeQuery", "selectHistoricTaskInstanceByNativeQuery_mssql_or_db2"); addDatabaseSpecificStatement("mssql", "selectTaskByNativeQuery", "selectTaskByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("mssql", "selectProcessDefinitionByNativeQuery", "selectProcessDefinitionByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("mssql", "selectDeploymentByNativeQuery", "selectDeploymentByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("mssql", "selectGroupByNativeQuery", "selectGroupByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("mssql", "selectUserByNativeQuery", "selectUserByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("mssql", "selectModelByNativeQuery", "selectModelByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("mssql", "selectHistoricDetailByNativeQuery", "selectHistoricDetailByNativeQuery_mssql_or_db2"); + addDatabaseSpecificStatement("mssql", "selectHistoricVariableInstanceByNativeQuery", "selectHistoricVariableInstanceByNativeQuery_mssql_or_db2"); } diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/HistoricDetailEntityManager.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/HistoricDetailEntityManager.java index ed441d3e5f6b2a4f7cde896a82ba2a530dc09cd1..0df403ad4a9e81e89119c0d19757e4fb11894ee5 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/HistoricDetailEntityManager.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/HistoricDetailEntityManager.java @@ -14,6 +14,7 @@ package org.activiti.engine.impl.persistence.entity; import java.util.List; +import java.util.Map; import org.activiti.engine.history.HistoricDetail; import org.activiti.engine.impl.HistoricDetailQueryImpl; @@ -60,4 +61,13 @@ public class HistoricDetailEntityManager extends AbstractManager { } } } + + @SuppressWarnings("unchecked") + public List findHistoricDetailsByNativeQuery(Map parameterMap, int firstResult, int maxResults) { + return getDbSqlSession().selectListWithRawParameter("selectHistoricDetailByNativeQuery", parameterMap, firstResult, maxResults); + } + + public long findHistoricDetailCountByNativeQuery(Map parameterMap) { + return (Long) getDbSqlSession().selectOne("selectHistoricDetailCountByNativeQuery", parameterMap); + } } diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/HistoricVariableInstanceEntityManager.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/HistoricVariableInstanceEntityManager.java index 080b9acb8930e5d9701dab9258b477c423d5470c..e3f159306c520d3c241fd14bc4ad2c66edd2c43b 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/HistoricVariableInstanceEntityManager.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/HistoricVariableInstanceEntityManager.java @@ -14,6 +14,7 @@ package org.activiti.engine.impl.persistence.entity; import java.util.List; +import java.util.Map; import org.activiti.engine.history.HistoricVariableInstance; import org.activiti.engine.impl.HistoricVariableInstanceQueryImpl; @@ -74,4 +75,13 @@ public class HistoricVariableInstanceEntityManager extends AbstractManager { } } } + + @SuppressWarnings("unchecked") + public List findHistoricVariableInstancesByNativeQuery(Map parameterMap, int firstResult, int maxResults) { + return getDbSqlSession().selectListWithRawParameter("selectHistoricVariableInstanceByNativeQuery", parameterMap, firstResult, maxResults); + } + + public long findHistoricVariableInstanceCountByNativeQuery(Map parameterMap) { + return (Long) getDbSqlSession().selectOne("selectHistoricVariableInstanceCountByNativeQuery", parameterMap); + } } diff --git a/modules/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/HistoricDetail.xml b/modules/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/HistoricDetail.xml index e0a0355f3ffb6ab827f9a37f62a6d566ad41fa81..060f4cf6b0ded7fe0b39b7513e37d87c9aa047c1 100644 --- a/modules/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/HistoricDetail.xml +++ b/modules/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/HistoricDetail.xml @@ -154,5 +154,29 @@ + + + + + + diff --git a/modules/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/HistoricVariableInstance.xml b/modules/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/HistoricVariableInstance.xml index 622f1ac88f6f46110b3da9f2e481e904adca6e62..cd10302bb682848b7c0c86ec715cbb3ea973611f 100644 --- a/modules/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/HistoricVariableInstance.xml +++ b/modules/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/HistoricVariableInstance.xml @@ -169,5 +169,29 @@ + + + + + + diff --git a/modules/activiti-engine/src/test/java/org/activiti/engine/test/history/HistoricVariableInstanceTest.java b/modules/activiti-engine/src/test/java/org/activiti/engine/test/history/HistoricVariableInstanceTest.java index 1d5465463e91ad50a0d5f0e6bb5edf2e852e7953..a6f21d2acd93f94aa85f9ac8838805be902897a7 100644 --- a/modules/activiti-engine/src/test/java/org/activiti/engine/test/history/HistoricVariableInstanceTest.java +++ b/modules/activiti-engine/src/test/java/org/activiti/engine/test/history/HistoricVariableInstanceTest.java @@ -13,16 +13,11 @@ package org.activiti.engine.test.history; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - import java.util.HashMap; import java.util.List; import java.util.Map; -import org.activiti.engine.HistoryService; import org.activiti.engine.ProcessEngineConfiguration; -import org.activiti.engine.RuntimeService; import org.activiti.engine.history.HistoricActivityInstance; import org.activiti.engine.history.HistoricDetail; import org.activiti.engine.history.HistoricVariableInstance; @@ -313,5 +308,80 @@ public class HistoricVariableInstanceTest extends AbstractActivitiTestCase { assertEquals(2, count); } + + @Deployment(resources = "org/activiti/engine/test/history/HistoricVariableInstanceTest.testSimple.bpmn20.xml") + public void testNativeHistoricVariableInstanceQuery() { + assertEquals("ACT_HI_VARINST", managementService.getTableName(HistoricVariableInstance.class)); + assertEquals("ACT_HI_VARINST", managementService.getTableName(HistoricVariableInstanceEntity.class)); + + String tableName = managementService.getTableName(HistoricVariableInstance.class); + String baseQuerySql = "SELECT * FROM " + tableName; + + Map variables = new HashMap(); + variables.put("var1", "value1"); + variables.put("var2", "value2"); + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProc", variables); + assertNotNull(processInstance); + + assertEquals(3, historyService.createNativeHistoricVariableInstanceQuery().sql(baseQuerySql).list().size()); + + String sqlWithConditions = baseQuerySql + " where NAME_ = #{name}"; + assertEquals("test123", historyService.createNativeHistoricVariableInstanceQuery().sql(sqlWithConditions) + .parameter("name", "myVar").singleResult().getValue()); + + sqlWithConditions = baseQuerySql + " where NAME_ like #{name}"; + assertEquals(2, historyService.createNativeHistoricVariableInstanceQuery().sql(sqlWithConditions) + .parameter("name", "var%").list().size()); + + // paging + assertEquals(3, historyService.createNativeHistoricVariableInstanceQuery().sql(baseQuerySql).listPage(0, 3).size()); + assertEquals(2, historyService.createNativeHistoricVariableInstanceQuery().sql(baseQuerySql).listPage(1, 3).size()); + assertEquals(2, historyService.createNativeHistoricVariableInstanceQuery().sql(sqlWithConditions) + .parameter("name", "var%").listPage(0, 2).size()); + + } + + @Deployment(resources = "org/activiti/engine/test/history/HistoricVariableInstanceTest.testSimple.bpmn20.xml") + public void testNativeHistoricDetailQuery() { + assertEquals("ACT_HI_DETAIL", managementService.getTableName(HistoricDetail.class)); + assertEquals("ACT_HI_DETAIL", managementService.getTableName(HistoricVariableUpdate.class)); + + String tableName = managementService.getTableName(HistoricDetail.class); + String baseQuerySql = "SELECT * FROM " + tableName; + + Map variables = new HashMap(); + variables.put("var1", "value1"); + variables.put("var2", "value2"); + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProc", variables); + assertNotNull(processInstance); + + assertEquals(3, historyService.createNativeHistoricDetailQuery().sql(baseQuerySql).list().size()); + + String sqlWithConditions = baseQuerySql + " where NAME_ = #{name} and TYPE_ = #{type}"; + assertNotNull(historyService.createNativeHistoricDetailQuery().sql(sqlWithConditions) + .parameter("name", "myVar").parameter("type", "VariableUpdate").singleResult()); + + sqlWithConditions = baseQuerySql + " where NAME_ like #{name}"; + assertEquals(2, historyService.createNativeHistoricDetailQuery().sql(sqlWithConditions) + .parameter("name", "var%").list().size()); + + Task task = taskService.createTaskQuery().singleResult(); + Map formDatas = new HashMap(); + formDatas.put("field1", "field value 1"); + formDatas.put("field2", "field value 2"); + formService.submitTaskFormData(task.getId(), formDatas); + + String countSql = "select count(*) from " + tableName + " where TYPE_ = #{type} and PROC_INST_ID_ = #{pid}"; + assertEquals(2, historyService.createNativeHistoricDetailQuery().sql(countSql) + .parameter("type", "FormProperty").parameter("pid", processInstance.getId()).count()); + + + // paging + assertEquals(3, historyService.createNativeHistoricDetailQuery().sql(baseQuerySql).listPage(0, 3).size()); + assertEquals(3, historyService.createNativeHistoricDetailQuery().sql(baseQuerySql).listPage(1, 3).size()); + sqlWithConditions = baseQuerySql + " where TYPE_ = #{type} and PROC_INST_ID_ = #{pid}"; + assertEquals(2, historyService.createNativeHistoricDetailQuery().sql(sqlWithConditions) + .parameter("type", "FormProperty").parameter("pid", processInstance.getId()).listPage(0, 2).size()); + } }