Commit f66210e57dcdaaf22085c92614c07c93ffa2f511
1 parent
a970ea93
fix(bpm): 按 Flowable 版本重整 DM8 适配补丁
支持 Flowable 6.8.0 和 8.0.0,移除原类覆盖,统一各 Spring 引擎的达梦方言与插入配置。 修复 Liquibase SPI 注册冲突及事件、DMN 子引擎批量插入失败,补充独立回归工程。
Showing
21 changed files
with
811 additions
and
2853 deletions
sql/dm/flowable-patch-6.8.0/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/DmFlowableConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.config; | ||
| 2 | + | ||
| 3 | +import org.flowable.common.engine.impl.AbstractEngineConfiguration; | ||
| 4 | +import org.springframework.beans.factory.config.BeanPostProcessor; | ||
| 5 | +import org.springframework.context.annotation.Bean; | ||
| 6 | +import org.springframework.context.annotation.Configuration; | ||
| 7 | + | ||
| 8 | +import java.sql.Connection; | ||
| 9 | +import java.sql.SQLException; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 达梦数据库的 Flowable 配置 | ||
| 13 | + * | ||
| 14 | + * @author 芋道源码 | ||
| 15 | + */ | ||
| 16 | +@Configuration(proxyBeanMethods = false) | ||
| 17 | +public class DmFlowableConfiguration { | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * 在 Spring 管理的各个 Flowable 引擎初始化前设置达梦方言与插入策略 | ||
| 21 | + */ | ||
| 22 | + @Bean | ||
| 23 | + public static BeanPostProcessor dmEngineConfigurationBeanPostProcessor() { | ||
| 24 | + return new BeanPostProcessor() { | ||
| 25 | + | ||
| 26 | + @Override | ||
| 27 | + public Object postProcessBeforeInitialization(Object bean, String beanName) { | ||
| 28 | + if (!(bean instanceof AbstractEngineConfiguration)) { | ||
| 29 | + return bean; | ||
| 30 | + } | ||
| 31 | + AbstractEngineConfiguration configuration = (AbstractEngineConfiguration) bean; | ||
| 32 | + if (configuration.getDataSource() == null) { | ||
| 33 | + return bean; | ||
| 34 | + } | ||
| 35 | + // 在各个 Spring 引擎初始化前处理,避免子引擎重新开启批量插入;使用实际数据源识别达梦 | ||
| 36 | + try (Connection connection = configuration.getDataSource().getConnection()) { | ||
| 37 | + if ("DM DBMS".equalsIgnoreCase(connection.getMetaData().getDatabaseProductName())) { | ||
| 38 | + configuration.setDatabaseType("oracle"); | ||
| 39 | + // 特殊:达梦普通用户执行 Oracle INSERT ALL 时可能访问 SYS.SYSDUAL2,改为普通插入,避免扩大数据库权限 | ||
| 40 | + configuration.setBulkInsertEnabled(false); | ||
| 41 | + } | ||
| 42 | + } catch (SQLException e) { | ||
| 43 | + throw new IllegalStateException("读取 Flowable 数据库类型失败", e); | ||
| 44 | + } | ||
| 45 | + return bean; | ||
| 46 | + } | ||
| 47 | + }; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | +} |
sql/dm/flowable-patch-6.8.0/src/main/java/liquibase/database/core/DmDatabase.java
0 → 100644
| 1 | +package liquibase.database.core; | ||
| 2 | + | ||
| 3 | +import liquibase.database.DatabaseConnection; | ||
| 4 | +import liquibase.exception.DatabaseException; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 达梦数据库的 Liquibase 适配,复用 Oracle 的字段类型与建表语法 | ||
| 8 | + * | ||
| 9 | + * @author 芋道源码 | ||
| 10 | + */ | ||
| 11 | +public class DmDatabase extends OracleDatabase { | ||
| 12 | + | ||
| 13 | + @Override | ||
| 14 | + public String getShortName() { | ||
| 15 | + // 独立注册达梦,避免与 Oracle 的 SPI 注册键及优先级冲突 | ||
| 16 | + return "dm"; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + @Override | ||
| 20 | + protected String getDefaultDatabaseProductName() { | ||
| 21 | + return "DM DBMS"; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + public boolean isCorrectDatabaseImplementation(DatabaseConnection connection) throws DatabaseException { | ||
| 26 | + return "DM DBMS".equalsIgnoreCase(connection.getDatabaseProductName()); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + @Override | ||
| 30 | + public String getDefaultDriver(String url) { | ||
| 31 | + return url != null && url.startsWith("jdbc:dm:") ? "dm.jdbc.driver.DmDriver" : null; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + @Override | ||
| 35 | + public Integer getDefaultPort() { | ||
| 36 | + return 5236; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + @Override | ||
| 40 | + public int getDatabaseMinorVersion() throws DatabaseException { | ||
| 41 | + // 特殊:部分达梦驱动返回非数字次版本号,避免 Oracle 版本判断时解析失败 | ||
| 42 | + try { | ||
| 43 | + return super.getDatabaseMinorVersion(); | ||
| 44 | + } catch (DatabaseException e) { | ||
| 45 | + return 0; | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | +} |
sql/dm/flowable-patch-6.8.0/src/main/resources/META-INF/services/liquibase.database.Database
0 → 100644
| 1 | +liquibase.database.core.DmDatabase |
sql/dm/flowable-patch-8.0.0/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/DmFlowableConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.config; | ||
| 2 | + | ||
| 3 | +import org.flowable.common.engine.impl.AbstractEngineConfiguration; | ||
| 4 | +import org.springframework.beans.factory.config.BeanPostProcessor; | ||
| 5 | +import org.springframework.context.annotation.Bean; | ||
| 6 | +import org.springframework.context.annotation.Configuration; | ||
| 7 | + | ||
| 8 | +import java.sql.Connection; | ||
| 9 | +import java.sql.SQLException; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 达梦数据库的 Flowable 配置 | ||
| 13 | + * | ||
| 14 | + * @author 芋道源码 | ||
| 15 | + */ | ||
| 16 | +@Configuration(proxyBeanMethods = false) | ||
| 17 | +public class DmFlowableConfiguration { | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * 在 Spring 管理的各个 Flowable 引擎初始化前设置达梦方言与插入策略 | ||
| 21 | + */ | ||
| 22 | + @Bean | ||
| 23 | + public static BeanPostProcessor dmEngineConfigurationBeanPostProcessor() { | ||
| 24 | + return new BeanPostProcessor() { | ||
| 25 | + | ||
| 26 | + @Override | ||
| 27 | + public Object postProcessBeforeInitialization(Object bean, String beanName) { | ||
| 28 | + if (!(bean instanceof AbstractEngineConfiguration)) { | ||
| 29 | + return bean; | ||
| 30 | + } | ||
| 31 | + AbstractEngineConfiguration configuration = (AbstractEngineConfiguration) bean; | ||
| 32 | + if (configuration.getDataSource() == null) { | ||
| 33 | + return bean; | ||
| 34 | + } | ||
| 35 | + // 在各个 Spring 引擎初始化前处理,避免子引擎重新开启批量插入;使用实际数据源识别达梦 | ||
| 36 | + try (Connection connection = configuration.getDataSource().getConnection()) { | ||
| 37 | + if ("DM DBMS".equalsIgnoreCase(connection.getMetaData().getDatabaseProductName())) { | ||
| 38 | + configuration.setDatabaseType("oracle"); | ||
| 39 | + // 特殊:达梦普通用户执行 Oracle INSERT ALL 时可能访问 SYS.SYSDUAL2,改为普通插入,避免扩大数据库权限 | ||
| 40 | + configuration.setBulkInsertEnabled(false); | ||
| 41 | + } | ||
| 42 | + } catch (SQLException e) { | ||
| 43 | + throw new IllegalStateException("读取 Flowable 数据库类型失败", e); | ||
| 44 | + } | ||
| 45 | + return bean; | ||
| 46 | + } | ||
| 47 | + }; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | +} |
sql/dm/flowable-patch-tests/README.md
0 → 100644
| 1 | +# Flowable 达梦补丁回归测试 | ||
| 2 | + | ||
| 3 | +本目录是独立的 Maven 测试工程,直接编译同级 `flowable-patch-${flowable.version}` 补丁目录的源码,验证补丁本身。它不加入主工程模块,不参与业务默认构建,也不要复制到业务模块。 | ||
| 4 | + | ||
| 5 | +补丁安装请阅读项目文档《工作流(达梦适配)》,本文只说明如何测试。 | ||
| 6 | + | ||
| 7 | +## 1. 版本矩阵 | ||
| 8 | + | ||
| 9 | +| Profile | JDK | Spring Boot | Flowable | 被测补丁 | | ||
| 10 | +| --- | --- | --- | --- | --- | | ||
| 11 | +| `jdk8` | JDK8 | 2.7.18 | 6.8.0 | `flowable-patch-6.8.0` | | ||
| 12 | +| 默认 | JDK17 或 JDK25 | 3.5.15 | 8.0.0 | `flowable-patch-8.0.0` | | ||
| 13 | +| `sb4` | JDK25 | 4.1.1 | 8.0.0 | `flowable-patch-8.0.0` | | ||
| 14 | + | ||
| 15 | +各组合的编译输出位于 `target/<Spring Boot 版本>-<Flowable 版本>`,互不覆盖。 | ||
| 16 | + | ||
| 17 | +## 2. 准备数据库 | ||
| 18 | + | ||
| 19 | +先创建独立的非生产测试账号,只授予该测试 schema 的建表权限,**不要使用生产库**。6.8.0 与 8.0.0 请使用不同账号/schema 分别测试,不能在同一工作流 schema 混跑两个 Flowable 版本。 | ||
| 20 | + | ||
| 21 | +通过环境变量指定数据库,密码由本地环境提供,不写入 Git: | ||
| 22 | + | ||
| 23 | +```bash | ||
| 24 | +export DM_JDBC_URL='jdbc:dm://127.0.0.1:15236' | ||
| 25 | +export DM_JDBC_USER='FLOWABLE_TEST' | ||
| 26 | +export DM_JDBC_PASSWORD='本地测试密码' | ||
| 27 | +``` | ||
| 28 | + | ||
| 29 | +## 3. 执行测试 | ||
| 30 | + | ||
| 31 | +在 `ruoyi-vue-pro` 仓库根目录(包含 `sql/` 目录的一级)执行: | ||
| 32 | + | ||
| 33 | +```bash | ||
| 34 | +# 使用 JDK8:Spring Boot 2.7.18 + Flowable 6.8.0 | ||
| 35 | +mvn -f sql/dm/flowable-patch-tests/pom.xml -Pjdk8 test | ||
| 36 | + | ||
| 37 | +# 使用 JDK17 或 JDK25:Spring Boot 3.5.15 + Flowable 8.0.0 | ||
| 38 | +mvn -f sql/dm/flowable-patch-tests/pom.xml test | ||
| 39 | + | ||
| 40 | +# 使用 JDK25:Spring Boot 4.1.1 + Flowable 8.0.0 | ||
| 41 | +mvn -f sql/dm/flowable-patch-tests/pom.xml -Psb4 test | ||
| 42 | +``` | ||
| 43 | + | ||
| 44 | +未配置 `DM_JDBC_URL` 时,只运行基于 H2 的非达梦检查(其它数据库不受补丁影响;6.8.0 另检查 SPI 注册顺序),真实达梦用例会在 Maven 输出中显示为 `Skipped`。此时**不能据此认定达梦适配通过**;验收时应确认真实达梦用例没有被跳过。 | ||
| 45 | + | ||
| 46 | +## 4. 测试覆盖与边界 | ||
| 47 | + | ||
| 48 | +覆盖 Spring Boot 自动装配(不手工关闭应用级 Liquibase)、首次建表与保持 `flowable.database-schema-update: true` 的重复启动、流程部署/发起/两级审批、退回与拒绝、取消、长文本和布尔变量、历史与分页、事务回滚、并行网关、定时 Job 执行、DMN 建表与决策,以及自动装配后一次部署多个 DMN/事件定义。6.8.0 另覆盖 Oracle/DM 两种 SPI 注册顺序,以及 DM 元数据与布尔类型识别。 | ||
| 49 | + | ||
| 50 | +不包含完整芋道 Web 服务(微服务的网关、注册中心等)及前端浏览器验收,也不代表已验证所有流程模型、并发性能、跨版本历史库升级,或所有第三方 Flowable 用法。补丁合并到业务模块后,仍需在实际项目中验证启动及流程功能。 | ||
| 51 | + | ||
| 52 | +## 5. 实现说明 | ||
| 53 | + | ||
| 54 | +- 两个版本的 `DmFlowableConfiguration` 保持一致。通过 Spring `BeanPostProcessor`,在各个 Flowable 引擎配置 Bean 初始化前,按引擎实际连接的 JDBC 元数据识别达梦,设置工作流 Oracle 方言及普通插入,覆盖主引擎和 Spring 事件/DMN 子引擎。不修改 Flowable 原类,不替换全局 MyBatis `DatabaseIdProvider`,不依赖数据源名称或 `yudao.dameng.enabled` 开关。 | ||
| 55 | +- 对达梦关闭 `INSERT ALL` 批量插入,避免部分 DM8 环境下普通用户访问 `SYS.SYSDUAL2` 失败,无需给业务账号授予 DBA。仅关闭主引擎不够,子引擎会将自己的批量实体重新注册到共享 SQL 工厂。代价是批量写入吞吐可能降低,需按实际负载压测。 | ||
| 56 | +- 补丁只处理 Spring 管理的 Flowable 配置 Bean。手动 `new` 的非 Bean 配置、独立接入的其它引擎不会被自动覆盖,需要自行设置方言及插入策略。 | ||
| 57 | +- 仅 6.8.0 使用 Liquibase SPI 注册 `DmDatabase extends OracleDatabase`,复用 Oracle 的字段、布尔值及 schema 识别逻辑,不覆盖 `BooleanType`。注册短名为独立的 `dm`,避免与原生 Oracle 实现竞争同一个注册键;Flowable 方言仍为 `oracle`,两者是不同机制。Flowable 6.8.0 自带的环境后处理器默认关闭 Spring Boot 应用级 Liquibase,内部事件/DMN 的 Liquibase 建表仍正常执行。 | ||
| 58 | +- 8.0.0 的事件/DMN 已改用 SQL 脚本,补丁仅包含 Spring 配置,不引入 Liquibase。若额外加入 Liquibase 依赖,Boot 3 会默认查找应用级 changelog 导致启动失败;不要用 `spring.liquibase.enabled=false` 掩盖该问题。 | ||
| 59 | +- DM 的 `COMPATIBLE_MODE` 是数据库配置,`oracle` 是 Flowable 方言,两者不是同一设置。不要在已有库上直接更换方言、重建表或混用两个 Flowable 版本;升级现有工作流数据库须另行备份、验证官方升级脚本,补丁不是升级脚本。 |
sql/dm/flowable-patch-tests/pom.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | + <modelVersion>4.0.0</modelVersion> | ||
| 6 | + <groupId>cn.iocoder.boot</groupId> | ||
| 7 | + <artifactId>dm-flowable-patch-tests</artifactId> | ||
| 8 | + <version>1.0-SNAPSHOT</version> | ||
| 9 | + <properties> | ||
| 10 | + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
| 11 | + <flowable.version>8.0.0</flowable.version> | ||
| 12 | + <spring.boot.version>3.5.15</spring.boot.version> | ||
| 13 | + <maven.compiler.release>17</maven.compiler.release> | ||
| 14 | + </properties> | ||
| 15 | + <dependencyManagement> | ||
| 16 | + <dependencies> | ||
| 17 | + <dependency> | ||
| 18 | + <groupId>org.springframework.boot</groupId> | ||
| 19 | + <artifactId>spring-boot-dependencies</artifactId> | ||
| 20 | + <version>${spring.boot.version}</version> | ||
| 21 | + <type>pom</type> | ||
| 22 | + <scope>import</scope> | ||
| 23 | + </dependency> | ||
| 24 | + </dependencies> | ||
| 25 | + </dependencyManagement> | ||
| 26 | + <dependencies> | ||
| 27 | + <dependency> | ||
| 28 | + <groupId>org.flowable</groupId> | ||
| 29 | + <artifactId>flowable-spring-boot-starter-process</artifactId> | ||
| 30 | + <version>${flowable.version}</version> | ||
| 31 | + </dependency> | ||
| 32 | + <dependency> | ||
| 33 | + <groupId>org.flowable</groupId> | ||
| 34 | + <artifactId>flowable-dmn-spring-configurator</artifactId> | ||
| 35 | + <version>${flowable.version}</version> | ||
| 36 | + </dependency> | ||
| 37 | + <dependency> | ||
| 38 | + <groupId>com.dameng</groupId> | ||
| 39 | + <artifactId>DmJdbcDriver18</artifactId> | ||
| 40 | + <version>8.1.3.140</version> | ||
| 41 | + <scope>test</scope> | ||
| 42 | + </dependency> | ||
| 43 | + <dependency> | ||
| 44 | + <groupId>com.h2database</groupId> | ||
| 45 | + <artifactId>h2</artifactId> | ||
| 46 | + <scope>test</scope> | ||
| 47 | + </dependency> | ||
| 48 | + <dependency> | ||
| 49 | + <groupId>org.junit.jupiter</groupId> | ||
| 50 | + <artifactId>junit-jupiter</artifactId> | ||
| 51 | + <scope>test</scope> | ||
| 52 | + </dependency> | ||
| 53 | + </dependencies> | ||
| 54 | + <build> | ||
| 55 | + <directory>${project.basedir}/target/${spring.boot.version}-${flowable.version}</directory> | ||
| 56 | + <sourceDirectory>../flowable-patch-${flowable.version}/src/main/java</sourceDirectory> | ||
| 57 | + <resources> | ||
| 58 | + <resource> | ||
| 59 | + <directory>../flowable-patch-${flowable.version}/src/main/resources</directory> | ||
| 60 | + </resource> | ||
| 61 | + </resources> | ||
| 62 | + <plugins> | ||
| 63 | + <plugin> | ||
| 64 | + <groupId>org.apache.maven.plugins</groupId> | ||
| 65 | + <artifactId>maven-compiler-plugin</artifactId> | ||
| 66 | + <version>3.13.0</version> | ||
| 67 | + </plugin> | ||
| 68 | + <plugin> | ||
| 69 | + <groupId>org.apache.maven.plugins</groupId> | ||
| 70 | + <artifactId>maven-surefire-plugin</artifactId> | ||
| 71 | + <version>3.5.3</version> | ||
| 72 | + </plugin> | ||
| 73 | + </plugins> | ||
| 74 | + </build> | ||
| 75 | + <profiles> | ||
| 76 | + <profile> | ||
| 77 | + <id>jdk8</id> | ||
| 78 | + <properties> | ||
| 79 | + <flowable.version>6.8.0</flowable.version> | ||
| 80 | + <spring.boot.version>2.7.18</spring.boot.version> | ||
| 81 | + <maven.compiler.release>8</maven.compiler.release> | ||
| 82 | + </properties> | ||
| 83 | + <dependencies> | ||
| 84 | + <dependency> | ||
| 85 | + <groupId>org.liquibase</groupId> | ||
| 86 | + <artifactId>liquibase-core</artifactId> | ||
| 87 | + </dependency> | ||
| 88 | + </dependencies> | ||
| 89 | + <build> | ||
| 90 | + <plugins> | ||
| 91 | + <plugin> | ||
| 92 | + <groupId>org.codehaus.mojo</groupId> | ||
| 93 | + <artifactId>build-helper-maven-plugin</artifactId> | ||
| 94 | + <version>3.6.1</version> | ||
| 95 | + <executions> | ||
| 96 | + <execution> | ||
| 97 | + <id>liquibase-patch-tests</id> | ||
| 98 | + <phase>generate-test-sources</phase> | ||
| 99 | + <goals><goal>add-test-source</goal></goals> | ||
| 100 | + <configuration> | ||
| 101 | + <sources><source>src/test/liquibase</source></sources> | ||
| 102 | + </configuration> | ||
| 103 | + </execution> | ||
| 104 | + </executions> | ||
| 105 | + </plugin> | ||
| 106 | + </plugins> | ||
| 107 | + </build> | ||
| 108 | + </profile> | ||
| 109 | + <profile> | ||
| 110 | + <id>sb4</id> | ||
| 111 | + <properties> | ||
| 112 | + <spring.boot.version>4.1.1</spring.boot.version> | ||
| 113 | + <maven.compiler.release>25</maven.compiler.release> | ||
| 114 | + </properties> | ||
| 115 | + </profile> | ||
| 116 | + </profiles> | ||
| 117 | +</project> |
sql/dm/flowable-patch-tests/src/test/java/cn/iocoder/yudao/module/bpm/DmFlowablePatchTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.bpm.framework.flowable.config.DmFlowableConfiguration; | ||
| 4 | +import org.flowable.engine.ProcessEngine; | ||
| 5 | +import org.flowable.engine.history.HistoricProcessInstance; | ||
| 6 | +import org.flowable.engine.runtime.ProcessInstance; | ||
| 7 | +import org.flowable.dmn.engine.DmnEngine; | ||
| 8 | +import org.flowable.dmn.spring.SpringDmnEngineConfiguration; | ||
| 9 | +import org.flowable.eventregistry.impl.EventRegistryEngine; | ||
| 10 | +import org.flowable.eventregistry.api.EventDeployment; | ||
| 11 | +import org.flowable.spring.SpringProcessEngineConfiguration; | ||
| 12 | +import org.flowable.task.api.Task; | ||
| 13 | +import org.junit.jupiter.api.Test; | ||
| 14 | +import org.springframework.boot.WebApplicationType; | ||
| 15 | +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | ||
| 16 | +import org.springframework.boot.builder.SpringApplicationBuilder; | ||
| 17 | +import org.springframework.context.ConfigurableApplicationContext; | ||
| 18 | +import org.springframework.context.annotation.Bean; | ||
| 19 | +import org.springframework.context.annotation.Configuration; | ||
| 20 | +import org.springframework.context.annotation.Import; | ||
| 21 | +import org.springframework.jdbc.datasource.DataSourceTransactionManager; | ||
| 22 | +import org.springframework.jdbc.datasource.DriverManagerDataSource; | ||
| 23 | +import org.springframework.transaction.support.TransactionTemplate; | ||
| 24 | + | ||
| 25 | +import javax.sql.DataSource; | ||
| 26 | +import java.sql.Connection; | ||
| 27 | +import java.util.Collections; | ||
| 28 | +import java.util.List; | ||
| 29 | +import java.util.Map; | ||
| 30 | +import java.util.UUID; | ||
| 31 | +import java.nio.charset.StandardCharsets; | ||
| 32 | +import java.io.ByteArrayOutputStream; | ||
| 33 | +import java.io.InputStream; | ||
| 34 | + | ||
| 35 | +import static org.junit.jupiter.api.Assertions.*; | ||
| 36 | +import static org.junit.jupiter.api.Assumptions.assumeTrue; | ||
| 37 | + | ||
| 38 | +/** | ||
| 39 | + * 达梦补丁的版本兼容与真实数据库回归测试 | ||
| 40 | + * | ||
| 41 | + * @author 芋道源码 | ||
| 42 | + */ | ||
| 43 | +class DmFlowablePatchTest { | ||
| 44 | + | ||
| 45 | + @Test | ||
| 46 | + void testOtherDatabaseUnchanged() throws Exception { | ||
| 47 | + DriverManagerDataSource dataSource = new DriverManagerDataSource("jdbc:h2:mem:dm_patch_regression", "sa", ""); | ||
| 48 | + SpringProcessEngineConfiguration configuration = configuration(dataSource); | ||
| 49 | + configureDm(configuration); | ||
| 50 | + assertNull(configuration.getDatabaseType()); | ||
| 51 | + assertTrue(configuration.isBulkInsertEnabled()); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + @Test | ||
| 55 | + void testDmSchemaAndProcess() throws Exception { | ||
| 56 | + DataSource dataSource = dmDataSource(); | ||
| 57 | + try (Connection connection = dataSource.getConnection()) { | ||
| 58 | + assertEquals("DM DBMS", connection.getMetaData().getDatabaseProductName()); | ||
| 59 | + } | ||
| 60 | + String instanceId; | ||
| 61 | + SpringProcessEngineConfiguration first = configuration(dataSource); | ||
| 62 | + first.setDatabaseSchemaUpdate("true"); | ||
| 63 | + configureDm(first); | ||
| 64 | + assertEquals("oracle", first.getDatabaseType()); | ||
| 65 | + ProcessEngine engine = first.buildProcessEngine(); | ||
| 66 | + try { | ||
| 67 | + engine.getRepositoryService().createDeployment().addClasspathResource("approval.bpmn20.xml").deploy(); | ||
| 68 | + ProcessInstance instance = engine.getRuntimeService().startProcessInstanceByKey("dmApproval", "dm-test", | ||
| 69 | + Collections.<String, Object>singletonMap("amount", 100)); | ||
| 70 | + instanceId = instance.getId(); | ||
| 71 | + Task task = engine.getTaskService().createTaskQuery().processInstanceId(instanceId).singleResult(); | ||
| 72 | + assertEquals("审批一", task.getName()); | ||
| 73 | + engine.getTaskService().setAssignee(task.getId(), "1"); | ||
| 74 | + engine.getTaskService().complete(task.getId()); | ||
| 75 | + assertEquals("审批二", engine.getTaskService().createTaskQuery().processInstanceId(instanceId).singleResult().getName()); | ||
| 76 | + } finally { | ||
| 77 | + engine.close(); | ||
| 78 | + } | ||
| 79 | + // 再次开启 schema-update,验证已存在的工作流表不会重复创建 | ||
| 80 | + SpringProcessEngineConfiguration second = configuration(dataSource); | ||
| 81 | + second.setDatabaseSchemaUpdate("true"); | ||
| 82 | + configureDm(second); | ||
| 83 | + engine = second.buildProcessEngine(); | ||
| 84 | + try { | ||
| 85 | + Task task = engine.getTaskService().createTaskQuery().processInstanceId(instanceId).singleResult(); | ||
| 86 | + engine.getTaskService().complete(task.getId()); | ||
| 87 | + assertNull(engine.getRuntimeService().createProcessInstanceQuery().processInstanceId(instanceId).singleResult()); | ||
| 88 | + HistoricProcessInstance history = engine.getHistoryService().createHistoricProcessInstanceQuery() | ||
| 89 | + .processInstanceId(instanceId).singleResult(); | ||
| 90 | + assertNotNull(history.getEndTime()); | ||
| 91 | + assertEquals(2, engine.getHistoryService().createHistoricTaskInstanceQuery().processInstanceId(instanceId).finished().count()); | ||
| 92 | + assertEquals(1, engine.getRepositoryService().createProcessDefinitionQuery().processDefinitionKey("dmApproval").listPage(0, 1).size()); | ||
| 93 | + } finally { | ||
| 94 | + engine.close(); | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + @Test | ||
| 99 | + void testDmReturnAndReject() { | ||
| 100 | + ProcessEngine engine = dmEngine(); | ||
| 101 | + try { | ||
| 102 | + engine.getRepositoryService().createDeployment().addClasspathResource("approval.bpmn20.xml").deploy(); | ||
| 103 | + ProcessInstance instance = engine.getRuntimeService().startProcessInstanceByKey("dmApproval"); | ||
| 104 | + Task task = engine.getTaskService().createTaskQuery().processInstanceId(instance.getId()).singleResult(); | ||
| 105 | + engine.getTaskService().complete(task.getId()); | ||
| 106 | + engine.getRuntimeService().createChangeActivityStateBuilder().processInstanceId(instance.getId()) | ||
| 107 | + .moveActivityIdTo("second", "first").changeState(); | ||
| 108 | + assertEquals("审批一", engine.getTaskService().createTaskQuery().processInstanceId(instance.getId()).singleResult().getName()); | ||
| 109 | + engine.getRuntimeService().deleteProcessInstance(instance.getId(), "审批拒绝"); | ||
| 110 | + assertEquals("审批拒绝", engine.getHistoryService().createHistoricProcessInstanceQuery() | ||
| 111 | + .processInstanceId(instance.getId()).singleResult().getDeleteReason()); | ||
| 112 | + } finally { | ||
| 113 | + engine.close(); | ||
| 114 | + } | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + @Test | ||
| 118 | + void testDmCancelAndVariables() { | ||
| 119 | + ProcessEngine engine = dmEngine(); | ||
| 120 | + try { | ||
| 121 | + engine.getRepositoryService().createDeployment().addClasspathResource("approval.bpmn20.xml").deploy(); | ||
| 122 | + String longText = String.join("", Collections.nCopies(3000, "达梦🙂")); | ||
| 123 | + ProcessInstance instance = engine.getRuntimeService().startProcessInstanceByKey("dmApproval", "cancel-test", | ||
| 124 | + Collections.<String, Object>singletonMap("longText", longText)); | ||
| 125 | + engine.getRuntimeService().setVariable(instance.getId(), "approved", true); | ||
| 126 | + assertEquals(longText, engine.getRuntimeService().getVariable(instance.getId(), "longText")); | ||
| 127 | + assertEquals(true, engine.getRuntimeService().getVariable(instance.getId(), "approved")); | ||
| 128 | + engine.getRuntimeService().deleteProcessInstance(instance.getId(), "发起人取消"); | ||
| 129 | + assertEquals("发起人取消", engine.getHistoryService().createHistoricProcessInstanceQuery() | ||
| 130 | + .processInstanceBusinessKey("cancel-test").orderByProcessInstanceStartTime().desc().listPage(0, 1).get(0).getDeleteReason()); | ||
| 131 | + assertEquals(longText, engine.getHistoryService().createHistoricVariableInstanceQuery() | ||
| 132 | + .processInstanceId(instance.getId()).variableName("longText").singleResult().getValue()); | ||
| 133 | + } finally { | ||
| 134 | + engine.close(); | ||
| 135 | + } | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + @Test | ||
| 139 | + void testDmParallelGateway() { | ||
| 140 | + ProcessEngine engine = dmEngine(); | ||
| 141 | + try { | ||
| 142 | + engine.getRepositoryService().createDeployment().addClasspathResource("parallel.bpmn20.xml").deploy(); | ||
| 143 | + ProcessInstance instance = engine.getRuntimeService().startProcessInstanceByKey("dmParallel"); | ||
| 144 | + List<Task> tasks = engine.getTaskService().createTaskQuery().processInstanceId(instance.getId()).list(); | ||
| 145 | + assertEquals(2, tasks.size()); | ||
| 146 | + engine.getTaskService().complete(tasks.get(0).getId()); | ||
| 147 | + assertEquals(1, engine.getRuntimeService().createProcessInstanceQuery().processInstanceId(instance.getId()).count()); | ||
| 148 | + engine.getTaskService().complete(tasks.get(1).getId()); | ||
| 149 | + assertEquals(0, engine.getRuntimeService().createProcessInstanceQuery().processInstanceId(instance.getId()).count()); | ||
| 150 | + } finally { | ||
| 151 | + engine.close(); | ||
| 152 | + } | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + @Test | ||
| 156 | + void testDmTimer() { | ||
| 157 | + ProcessEngine engine = dmEngine(); | ||
| 158 | + try { | ||
| 159 | + engine.getRepositoryService().createDeployment().addClasspathResource("timer.bpmn20.xml").deploy(); | ||
| 160 | + ProcessInstance instance = engine.getRuntimeService().startProcessInstanceByKey("dmTimer"); | ||
| 161 | + String timerId = engine.getManagementService().createTimerJobQuery().processInstanceId(instance.getId()).singleResult().getId(); | ||
| 162 | + String jobId = engine.getManagementService().moveTimerToExecutableJob(timerId).getId(); | ||
| 163 | + engine.getManagementService().executeJob(jobId); | ||
| 164 | + assertEquals(0, engine.getManagementService().createTimerJobQuery().processInstanceId(instance.getId()).count()); | ||
| 165 | + assertEquals("定时后审批", engine.getTaskService().createTaskQuery().processInstanceId(instance.getId()).singleResult().getName()); | ||
| 166 | + engine.getRuntimeService().deleteProcessInstance(instance.getId(), "测试结束"); | ||
| 167 | + } finally { | ||
| 168 | + engine.close(); | ||
| 169 | + } | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + @Test | ||
| 173 | + void testDmDmnSchemaAndDecision() { | ||
| 174 | + DataSource dataSource = dmDataSource(); | ||
| 175 | + SpringDmnEngineConfiguration configuration = new SpringDmnEngineConfiguration(); | ||
| 176 | + configuration.setDataSource(dataSource); | ||
| 177 | + configuration.setTransactionManager(new DataSourceTransactionManager(dataSource)); | ||
| 178 | + configureDm(configuration); | ||
| 179 | + configuration.setDatabaseSchemaUpdate("true"); | ||
| 180 | + DmnEngine engine = configuration.buildDmnEngine(); | ||
| 181 | + try { | ||
| 182 | + engine.getDmnRepositoryService().createDeployment().addClasspathResource("amount.dmn").deploy(); | ||
| 183 | + Map<String, Object> result = engine.getDmnDecisionService().createExecuteDecisionBuilder() | ||
| 184 | + .decisionKey("dmAmount").variable("amount", 100).executeWithSingleResult(); | ||
| 185 | + assertEquals("通过", result.get("result")); | ||
| 186 | + } finally { | ||
| 187 | + engine.close(); | ||
| 188 | + } | ||
| 189 | + // DMN 在 6.8.0 使用 Liquibase,重复启动必须能识别已存在的 changelog 表 | ||
| 190 | + configuration = new SpringDmnEngineConfiguration(); | ||
| 191 | + configuration.setDataSource(dataSource); | ||
| 192 | + configuration.setTransactionManager(new DataSourceTransactionManager(dataSource)); | ||
| 193 | + configureDm(configuration); | ||
| 194 | + configuration.setDatabaseSchemaUpdate("true"); | ||
| 195 | + engine = configuration.buildDmnEngine(); | ||
| 196 | + engine.close(); | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + @Test | ||
| 200 | + void testBootAutoConfiguration() { | ||
| 201 | + dmDataSource(); | ||
| 202 | + try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestApplication.class) | ||
| 203 | + .web(WebApplicationType.NONE) | ||
| 204 | + .properties("flowable.database-schema-update=true", "flowable.async-executor-activate=false", | ||
| 205 | + "logging.level.root=WARN", "spring.main.banner-mode=off") | ||
| 206 | + .run()) { | ||
| 207 | + ProcessEngine engine = context.getBean(ProcessEngine.class); | ||
| 208 | + assertEquals("oracle", engine.getProcessEngineConfiguration().getDatabaseType()); | ||
| 209 | + assertFalse(((SpringProcessEngineConfiguration) engine.getProcessEngineConfiguration()).isBulkInsertEnabled()); | ||
| 210 | + assertNotNull(engine.getRepositoryService().createDeploymentQuery().listPage(0, 1)); | ||
| 211 | + DmnEngine dmn = context.getBean(DmnEngine.class); | ||
| 212 | + assertEquals("oracle", dmn.getDmnEngineConfiguration().getDatabaseType()); | ||
| 213 | + assertFalse(dmn.getDmnEngineConfiguration().isBulkInsertEnabled()); | ||
| 214 | + assertEquals("通过", dmn.getDmnDecisionService().createExecuteDecisionBuilder() | ||
| 215 | + .decisionKey("dmAutoTwo").variable("amount", 100).executeWithSingleResult().get("result")); | ||
| 216 | + String model = resourceText("/amount.dmn"); | ||
| 217 | + dmn.getDmnRepositoryService().createDeployment().addString("one.dmn", model) | ||
| 218 | + .addString("two.dmn", model.replace("dmAmount", "dmAmountTwo")).deploy(); | ||
| 219 | + assertEquals("通过", dmn.getDmnDecisionService().createExecuteDecisionBuilder() | ||
| 220 | + .decisionKey("dmAmountTwo").variable("amount", 100).executeWithSingleResult().get("result")); | ||
| 221 | + EventRegistryEngine event = context.getBean(EventRegistryEngine.class); | ||
| 222 | + assertEquals("oracle", event.getEventRegistryEngineConfiguration().getDatabaseType()); | ||
| 223 | + assertFalse(event.getEventRegistryEngineConfiguration().isBulkInsertEnabled()); | ||
| 224 | + assertTrue(event.getEventRepositoryService().createEventDefinitionQuery().eventDefinitionKey("dmAutoEventOne").count() > 0); | ||
| 225 | + assertTrue(event.getEventRepositoryService().createEventDefinitionQuery().eventDefinitionKey("dmAutoEventTwo").count() > 0); | ||
| 226 | + EventDeployment deployment = event.getEventRepositoryService().createDeployment() | ||
| 227 | + .addString("one.event", "{\"key\":\"dmEventOne\",\"name\":\"One\",\"payload\":[]}") | ||
| 228 | + .addString("two.event", "{\"key\":\"dmEventTwo\",\"name\":\"Two\",\"payload\":[]}").deploy(); | ||
| 229 | + assertEquals(2, event.getEventRepositoryService().createEventDefinitionQuery().deploymentId(deployment.getId()).count()); | ||
| 230 | + } | ||
| 231 | + } | ||
| 232 | + | ||
| 233 | + private ProcessEngine dmEngine() { | ||
| 234 | + SpringProcessEngineConfiguration configuration = configuration(dmDataSource()); | ||
| 235 | + configuration.setDatabaseSchemaUpdate("true"); | ||
| 236 | + configureDm(configuration); | ||
| 237 | + return configuration.buildProcessEngine(); | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + private static DataSource dmDataSource() { | ||
| 241 | + assumeTrue(System.getenv("DM_JDBC_URL") != null, "设置 DM_JDBC_URL 后执行真实达梦测试"); | ||
| 242 | + return new DriverManagerDataSource(System.getenv("DM_JDBC_URL"), | ||
| 243 | + System.getenv("DM_JDBC_USER"), System.getenv("DM_JDBC_PASSWORD")); | ||
| 244 | + } | ||
| 245 | + | ||
| 246 | + @Test | ||
| 247 | + void testDmTransactionRollback() { | ||
| 248 | + ProcessEngine engine = dmEngine(); | ||
| 249 | + try { | ||
| 250 | + engine.getRepositoryService().createDeployment().addClasspathResource("approval.bpmn20.xml").deploy(); | ||
| 251 | + String businessKey = UUID.randomUUID().toString(); | ||
| 252 | + SpringProcessEngineConfiguration configuration = (SpringProcessEngineConfiguration) engine.getProcessEngineConfiguration(); | ||
| 253 | + TransactionTemplate transaction = new TransactionTemplate(configuration.getTransactionManager()); | ||
| 254 | + assertThrows(IllegalStateException.class, () -> transaction.execute(status -> { | ||
| 255 | + engine.getRuntimeService().startProcessInstanceByKey("dmApproval", businessKey); | ||
| 256 | + throw new IllegalStateException("回滚测试"); | ||
| 257 | + })); | ||
| 258 | + assertEquals(0, engine.getRuntimeService().createProcessInstanceQuery().processInstanceBusinessKey(businessKey).count()); | ||
| 259 | + assertEquals(0, engine.getHistoryService().createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey).count()); | ||
| 260 | + } finally { | ||
| 261 | + engine.close(); | ||
| 262 | + } | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | + private void configureDm(Object configuration) { | ||
| 266 | + DmFlowableConfiguration.dmEngineConfigurationBeanPostProcessor().postProcessBeforeInitialization(configuration, "testEngineConfiguration"); | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | + private String resourceText(String name) { | ||
| 270 | + try (InputStream input = getClass().getResourceAsStream(name); | ||
| 271 | + ByteArrayOutputStream output = new ByteArrayOutputStream()) { | ||
| 272 | + byte[] buffer = new byte[1024]; | ||
| 273 | + int count; | ||
| 274 | + while ((count = input.read(buffer)) != -1) { | ||
| 275 | + output.write(buffer, 0, count); | ||
| 276 | + } | ||
| 277 | + return new String(output.toByteArray(), StandardCharsets.UTF_8); | ||
| 278 | + } catch (java.io.IOException e) { | ||
| 279 | + throw new IllegalStateException(e); | ||
| 280 | + } | ||
| 281 | + } | ||
| 282 | + | ||
| 283 | + private SpringProcessEngineConfiguration configuration(DataSource dataSource) { | ||
| 284 | + SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration(); | ||
| 285 | + configuration.setDataSource(dataSource); | ||
| 286 | + configuration.setTransactionManager(new DataSourceTransactionManager(dataSource)); | ||
| 287 | + configuration.setAsyncExecutorActivate(false); | ||
| 288 | + return configuration; | ||
| 289 | + } | ||
| 290 | + | ||
| 291 | + @Configuration(proxyBeanMethods = false) | ||
| 292 | + @EnableAutoConfiguration | ||
| 293 | + @Import(DmFlowableConfiguration.class) | ||
| 294 | + static class TestApplication { | ||
| 295 | + | ||
| 296 | + @Bean | ||
| 297 | + public DataSource dataSource() { | ||
| 298 | + return dmDataSource(); | ||
| 299 | + } | ||
| 300 | + | ||
| 301 | + } | ||
| 302 | + | ||
| 303 | +} |
sql/dm/flowable-patch-tests/src/test/liquibase/cn/iocoder/yudao/module/bpm/DmDatabaseTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm; | ||
| 2 | + | ||
| 3 | +import liquibase.database.DatabaseConnection; | ||
| 4 | +import liquibase.database.DatabaseFactory; | ||
| 5 | +import liquibase.database.core.DmDatabase; | ||
| 6 | +import liquibase.database.core.H2Database; | ||
| 7 | +import liquibase.database.core.MySQLDatabase; | ||
| 8 | +import liquibase.database.core.OracleDatabase; | ||
| 9 | +import liquibase.database.jvm.JdbcConnection; | ||
| 10 | +import liquibase.datatype.DataTypeFactory; | ||
| 11 | +import liquibase.datatype.core.BooleanType; | ||
| 12 | +import org.junit.jupiter.api.AfterEach; | ||
| 13 | +import org.junit.jupiter.api.Test; | ||
| 14 | +import org.springframework.jdbc.datasource.DriverManagerDataSource; | ||
| 15 | + | ||
| 16 | +import java.lang.reflect.Proxy; | ||
| 17 | +import java.sql.Connection; | ||
| 18 | + | ||
| 19 | +import static org.junit.jupiter.api.Assertions.*; | ||
| 20 | +import static org.junit.jupiter.api.Assumptions.assumeTrue; | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * Flowable 6.8.0 的达梦 Liquibase SPI 测试 | ||
| 24 | + * | ||
| 25 | + * @author 芋道源码 | ||
| 26 | + */ | ||
| 27 | +class DmDatabaseTest { | ||
| 28 | + | ||
| 29 | + @AfterEach | ||
| 30 | + void tearDown() { | ||
| 31 | + DatabaseFactory.reset(); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + @Test | ||
| 35 | + void testDriverAndOtherDatabases() throws Exception { | ||
| 36 | + DmDatabase database = new DmDatabase(); | ||
| 37 | + assertEquals("dm", database.getShortName()); | ||
| 38 | + assertEquals("dm.jdbc.driver.DmDriver", database.getDefaultDriver("jdbc:dm://localhost:5236")); | ||
| 39 | + assertNull(database.getDefaultDriver(null)); | ||
| 40 | + assertNull(database.getDefaultDriver("jdbc:mysql://localhost/test")); | ||
| 41 | + assertEquals(5236, database.getDefaultPort()); | ||
| 42 | + DriverManagerDataSource dataSource = new DriverManagerDataSource("jdbc:h2:mem:dm_spi_regression", "sa", ""); | ||
| 43 | + try (Connection connection = dataSource.getConnection()) { | ||
| 44 | + assertInstanceOf(H2Database.class, DatabaseFactory.getInstance() | ||
| 45 | + .findCorrectDatabaseImplementation(new JdbcConnection(connection))); | ||
| 46 | + } | ||
| 47 | + assertEquals(new BooleanType().toDatabaseDataType(new MySQLDatabase()).toString(), | ||
| 48 | + DataTypeFactory.getInstance().fromDescription("boolean", new MySQLDatabase()) | ||
| 49 | + .toDatabaseDataType(new MySQLDatabase()).toString()); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + @Test | ||
| 53 | + void testOracleAndDmRegistrationOrder() throws Exception { | ||
| 54 | + for (boolean dmFirst : new boolean[]{true, false}) { | ||
| 55 | + DatabaseFactory factory = DatabaseFactory.getInstance(); | ||
| 56 | + factory.clearRegistry(); | ||
| 57 | + factory.register(dmFirst ? new DmDatabase() : new OracleDatabase()); | ||
| 58 | + factory.register(dmFirst ? new OracleDatabase() : new DmDatabase()); | ||
| 59 | + assertInstanceOf(DmDatabase.class, factory.findCorrectDatabaseImplementation(metadata("DM DBMS"))); | ||
| 60 | + assertEquals(OracleDatabase.class, factory.findCorrectDatabaseImplementation(metadata("Oracle")).getClass()); | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + @Test | ||
| 65 | + void testDmMetadataAndBooleanType() throws Exception { | ||
| 66 | + assumeTrue(System.getenv("DM_JDBC_URL") != null, "设置 DM_JDBC_URL 后执行真实达梦测试"); | ||
| 67 | + DriverManagerDataSource dataSource = new DriverManagerDataSource(System.getenv("DM_JDBC_URL"), | ||
| 68 | + System.getenv("DM_JDBC_USER"), System.getenv("DM_JDBC_PASSWORD")); | ||
| 69 | + try (Connection connection = dataSource.getConnection()) { | ||
| 70 | + liquibase.database.Database database = DatabaseFactory.getInstance() | ||
| 71 | + .findCorrectDatabaseImplementation(new JdbcConnection(connection)); | ||
| 72 | + assertInstanceOf(DmDatabase.class, database); | ||
| 73 | + assertEquals("NUMBER(1)", DataTypeFactory.getInstance().fromDescription("boolean", database) | ||
| 74 | + .toDatabaseDataType(database).toString()); | ||
| 75 | + } | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + private DatabaseConnection metadata(String product) { | ||
| 79 | + return (DatabaseConnection) Proxy.newProxyInstance(getClass().getClassLoader(), | ||
| 80 | + new Class[]{DatabaseConnection.class}, (proxy, method, arguments) -> { | ||
| 81 | + if ("getDatabaseProductName".equals(method.getName())) return product; | ||
| 82 | + if ("getConnectionUserName".equals(method.getName())) return "TEST_USER"; | ||
| 83 | + if ("getURL".equals(method.getName())) return "DM DBMS".equals(product) ? "jdbc:dm://test" : "jdbc:oracle:thin:@test"; | ||
| 84 | + if (method.getReturnType() == int.class) return 8; | ||
| 85 | + if (method.getReturnType() == boolean.class) return false; | ||
| 86 | + return null; | ||
| 87 | + }); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | +} |
sql/dm/flowable-patch-tests/src/test/resources/amount.dmn
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" | ||
| 3 | + id="dmRules" name="达梦决策测试" namespace="http://www.iocoder.cn/dm-test"> | ||
| 4 | + <decision id="dmAmount" name="金额审核"> | ||
| 5 | + <decisionTable id="amountTable" hitPolicy="FIRST"> | ||
| 6 | + <input id="inputAmount"><inputExpression id="amountExpression" typeRef="number"><text>amount</text></inputExpression></input> | ||
| 7 | + <output id="outputResult" name="result" typeRef="string"/> | ||
| 8 | + <rule id="accepted"> | ||
| 9 | + <inputEntry id="amountCondition"><text>>= 0</text></inputEntry> | ||
| 10 | + <outputEntry id="resultValue"><text>"通过"</text></outputEntry> | ||
| 11 | + </rule> | ||
| 12 | + </decisionTable> | ||
| 13 | + </decision> | ||
| 14 | +</definitions> |
sql/dm/flowable-patch-tests/src/test/resources/approval.bpmn20.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" | ||
| 3 | + targetNamespace="http://www.iocoder.cn/dm-test"> | ||
| 4 | + <process id="dmApproval" name="达梦审批回归" isExecutable="true"> | ||
| 5 | + <startEvent id="start"/> | ||
| 6 | + <userTask id="first" name="审批一"/> | ||
| 7 | + <userTask id="second" name="审批二"/> | ||
| 8 | + <endEvent id="end"/> | ||
| 9 | + <sequenceFlow id="f1" sourceRef="start" targetRef="first"/> | ||
| 10 | + <sequenceFlow id="f2" sourceRef="first" targetRef="second"/> | ||
| 11 | + <sequenceFlow id="f3" sourceRef="second" targetRef="end"/> | ||
| 12 | + </process> | ||
| 13 | +</definitions> |
sql/dm/flowable-patch-tests/src/test/resources/dmn/auto.dmn
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" | ||
| 3 | + id="autoRules" name="自动部署测试" namespace="http://www.iocoder.cn/dm-test"> | ||
| 4 | + <decision id="dmAutoOne" name="自动决策一"> | ||
| 5 | + <decisionTable id="tableOne" hitPolicy="FIRST"> | ||
| 6 | + <input id="inputOne"><inputExpression id="expressionOne" typeRef="number"><text>amount</text></inputExpression></input> | ||
| 7 | + <output id="outputOne" name="result" typeRef="string"/> | ||
| 8 | + <rule id="ruleOne"> | ||
| 9 | + <inputEntry id="conditionOne"><text>>= 0</text></inputEntry> | ||
| 10 | + <outputEntry id="valueOne"><text>"通过"</text></outputEntry> | ||
| 11 | + </rule> | ||
| 12 | + </decisionTable> | ||
| 13 | + </decision> | ||
| 14 | + <decision id="dmAutoTwo" name="自动决策二"> | ||
| 15 | + <decisionTable id="tableTwo" hitPolicy="FIRST"> | ||
| 16 | + <input id="inputTwo"><inputExpression id="expressionTwo" typeRef="number"><text>amount</text></inputExpression></input> | ||
| 17 | + <output id="outputTwo" name="result" typeRef="string"/> | ||
| 18 | + <rule id="ruleTwo"> | ||
| 19 | + <inputEntry id="conditionTwo"><text>>= 0</text></inputEntry> | ||
| 20 | + <outputEntry id="valueTwo"><text>"通过"</text></outputEntry> | ||
| 21 | + </rule> | ||
| 22 | + </decisionTable> | ||
| 23 | + </decision> | ||
| 24 | +</definitions> |
sql/dm/flowable-patch-tests/src/test/resources/eventregistry/one.event
0 → 100644
| 1 | +{"key":"dmAutoEventOne","name":"自动事件一","payload":[]} |
sql/dm/flowable-patch-tests/src/test/resources/eventregistry/two.event
0 → 100644
| 1 | +{"key":"dmAutoEventTwo","name":"自动事件二","payload":[]} |
sql/dm/flowable-patch-tests/src/test/resources/logback-test.xml
0 → 100644
sql/dm/flowable-patch-tests/src/test/resources/parallel.bpmn20.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" | ||
| 3 | + targetNamespace="http://www.iocoder.cn/dm-test"> | ||
| 4 | + <process id="dmParallel" isExecutable="true"> | ||
| 5 | + <startEvent id="start"/> | ||
| 6 | + <parallelGateway id="fork"/> | ||
| 7 | + <userTask id="left" name="并行审批一"/> | ||
| 8 | + <userTask id="right" name="并行审批二"/> | ||
| 9 | + <parallelGateway id="join"/> | ||
| 10 | + <endEvent id="end"/> | ||
| 11 | + <sequenceFlow id="f1" sourceRef="start" targetRef="fork"/> | ||
| 12 | + <sequenceFlow id="f2" sourceRef="fork" targetRef="left"/> | ||
| 13 | + <sequenceFlow id="f3" sourceRef="fork" targetRef="right"/> | ||
| 14 | + <sequenceFlow id="f4" sourceRef="left" targetRef="join"/> | ||
| 15 | + <sequenceFlow id="f5" sourceRef="right" targetRef="join"/> | ||
| 16 | + <sequenceFlow id="f6" sourceRef="join" targetRef="end"/> | ||
| 17 | + </process> | ||
| 18 | +</definitions> |
sql/dm/flowable-patch-tests/src/test/resources/timer.bpmn20.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" | ||
| 3 | + targetNamespace="http://www.iocoder.cn/dm-test"> | ||
| 4 | + <process id="dmTimer" isExecutable="true"> | ||
| 5 | + <startEvent id="start"/> | ||
| 6 | + <intermediateCatchEvent id="wait"> | ||
| 7 | + <timerEventDefinition><timeDuration>P1D</timeDuration></timerEventDefinition> | ||
| 8 | + </intermediateCatchEvent> | ||
| 9 | + <userTask id="approval" name="定时后审批"/> | ||
| 10 | + <endEvent id="end"/> | ||
| 11 | + <sequenceFlow id="f1" sourceRef="start" targetRef="wait"/> | ||
| 12 | + <sequenceFlow id="f2" sourceRef="wait" targetRef="approval"/> | ||
| 13 | + <sequenceFlow id="f3" sourceRef="approval" targetRef="end"/> | ||
| 14 | + </process> | ||
| 15 | +</definitions> |
sql/dm/flowable-patch/src/main/java/liquibase/database/core/DmDatabase.java deleted
| 1 | -package liquibase.database.core; | ||
| 2 | - | ||
| 3 | -import java.lang.reflect.Method; | ||
| 4 | -import java.sql.Connection; | ||
| 5 | -import java.sql.ResultSet; | ||
| 6 | -import java.sql.SQLException; | ||
| 7 | -import java.sql.Statement; | ||
| 8 | -import java.util.ArrayList; | ||
| 9 | -import java.util.Arrays; | ||
| 10 | -import java.util.HashSet; | ||
| 11 | -import java.util.List; | ||
| 12 | -import java.util.Locale; | ||
| 13 | -import java.util.Map; | ||
| 14 | -import java.util.Properties; | ||
| 15 | -import java.util.Set; | ||
| 16 | -import java.util.regex.Matcher; | ||
| 17 | -import java.util.regex.Pattern; | ||
| 18 | -import liquibase.CatalogAndSchema; | ||
| 19 | -import liquibase.Scope; | ||
| 20 | -import liquibase.database.AbstractJdbcDatabase; | ||
| 21 | -import liquibase.database.DatabaseConnection; | ||
| 22 | -import liquibase.database.OfflineConnection; | ||
| 23 | -import liquibase.database.jvm.JdbcConnection; | ||
| 24 | -import liquibase.exception.DatabaseException; | ||
| 25 | -import liquibase.exception.UnexpectedLiquibaseException; | ||
| 26 | -import liquibase.exception.ValidationErrors; | ||
| 27 | -import liquibase.executor.ExecutorService; | ||
| 28 | -import liquibase.statement.DatabaseFunction; | ||
| 29 | -import liquibase.statement.SequenceCurrentValueFunction; | ||
| 30 | -import liquibase.statement.SequenceNextValueFunction; | ||
| 31 | -import liquibase.statement.core.RawCallStatement; | ||
| 32 | -import liquibase.statement.core.RawSqlStatement; | ||
| 33 | -import liquibase.structure.DatabaseObject; | ||
| 34 | -import liquibase.structure.core.Catalog; | ||
| 35 | -import liquibase.structure.core.Index; | ||
| 36 | -import liquibase.structure.core.PrimaryKey; | ||
| 37 | -import liquibase.structure.core.Schema; | ||
| 38 | -import liquibase.util.JdbcUtils; | ||
| 39 | -import liquibase.util.StringUtil; | ||
| 40 | - | ||
| 41 | -public class DmDatabase extends AbstractJdbcDatabase { | ||
| 42 | - private static final String PRODUCT_NAME = "DM DBMS"; | ||
| 43 | - | ||
| 44 | - @Override | ||
| 45 | - protected String getDefaultDatabaseProductName() { | ||
| 46 | - return PRODUCT_NAME; | ||
| 47 | - } | ||
| 48 | - | ||
| 49 | - /** | ||
| 50 | - * Is this AbstractDatabase subclass the correct one to use for the given connection. | ||
| 51 | - * | ||
| 52 | - * @param conn | ||
| 53 | - */ | ||
| 54 | - @Override | ||
| 55 | - public boolean isCorrectDatabaseImplementation(DatabaseConnection conn) throws DatabaseException { | ||
| 56 | - return PRODUCT_NAME.equalsIgnoreCase(conn.getDatabaseProductName()); | ||
| 57 | - } | ||
| 58 | - | ||
| 59 | - /** | ||
| 60 | - * If this database understands the given url, return the default driver class name. Otherwise return null. | ||
| 61 | - * | ||
| 62 | - * @param url | ||
| 63 | - */ | ||
| 64 | - @Override | ||
| 65 | - public String getDefaultDriver(String url) { | ||
| 66 | - if(url.startsWith("jdbc:dm")) { | ||
| 67 | - return "dm.jdbc.driver.DmDriver"; | ||
| 68 | - } | ||
| 69 | - | ||
| 70 | - return null; | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - /** | ||
| 74 | - * Returns an all-lower-case short name of the product. Used for end-user selecting of database type | ||
| 75 | - * such as the DBMS precondition. | ||
| 76 | - */ | ||
| 77 | - @Override | ||
| 78 | - public String getShortName() { | ||
| 79 | - return "dm"; | ||
| 80 | - } | ||
| 81 | - | ||
| 82 | - @Override | ||
| 83 | - public Integer getDefaultPort() { | ||
| 84 | - return 5236; | ||
| 85 | - } | ||
| 86 | - | ||
| 87 | - /** | ||
| 88 | - * Returns whether this database support initially deferrable columns. | ||
| 89 | - */ | ||
| 90 | - @Override | ||
| 91 | - public boolean supportsInitiallyDeferrableColumns() { | ||
| 92 | - return true; | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | - @Override | ||
| 96 | - public boolean supportsTablespaces() { | ||
| 97 | - return true; | ||
| 98 | - } | ||
| 99 | - | ||
| 100 | - @Override | ||
| 101 | - public int getPriority() { | ||
| 102 | - return PRIORITY_DEFAULT; | ||
| 103 | - } | ||
| 104 | - | ||
| 105 | - private static final Pattern PROXY_USER = Pattern.compile(".*(?:thin|oci)\\:(.+)/@.*"); | ||
| 106 | - | ||
| 107 | - protected final int SHORT_IDENTIFIERS_LENGTH = 30; | ||
| 108 | - protected final int LONG_IDENTIFIERS_LEGNTH = 128; | ||
| 109 | - public static final int ORACLE_12C_MAJOR_VERSION = 12; | ||
| 110 | - | ||
| 111 | - private Set<String> reservedWords = new HashSet<>(); | ||
| 112 | - private Set<String> userDefinedTypes; | ||
| 113 | - private Map<String, String> savedSessionNlsSettings; | ||
| 114 | - | ||
| 115 | - private Boolean canAccessDbaRecycleBin; | ||
| 116 | - private Integer databaseMajorVersion; | ||
| 117 | - private Integer databaseMinorVersion; | ||
| 118 | - | ||
| 119 | - /** | ||
| 120 | - * Default constructor for an object that represents the Oracle Database DBMS. | ||
| 121 | - */ | ||
| 122 | - public DmDatabase() { | ||
| 123 | - super.unquotedObjectsAreUppercased = true; | ||
| 124 | - //noinspection HardCodedStringLiteral | ||
| 125 | - super.setCurrentDateTimeFunction("SYSTIMESTAMP"); | ||
| 126 | - // Setting list of Oracle's native functions | ||
| 127 | - //noinspection HardCodedStringLiteral | ||
| 128 | - dateFunctions.add(new DatabaseFunction("SYSDATE")); | ||
| 129 | - //noinspection HardCodedStringLiteral | ||
| 130 | - dateFunctions.add(new DatabaseFunction("SYSTIMESTAMP")); | ||
| 131 | - //noinspection HardCodedStringLiteral | ||
| 132 | - dateFunctions.add(new DatabaseFunction("CURRENT_TIMESTAMP")); | ||
| 133 | - //noinspection HardCodedStringLiteral | ||
| 134 | - super.sequenceNextValueFunction = "%s.nextval"; | ||
| 135 | - //noinspection HardCodedStringLiteral | ||
| 136 | - super.sequenceCurrentValueFunction = "%s.currval"; | ||
| 137 | - } | ||
| 138 | - | ||
| 139 | - private void tryProxySession(final String url, final Connection con) { | ||
| 140 | - Matcher m = PROXY_USER.matcher(url); | ||
| 141 | - if (m.matches()) { | ||
| 142 | - Properties props = new Properties(); | ||
| 143 | - props.put("PROXY_USER_NAME", m.group(1)); | ||
| 144 | - try { | ||
| 145 | - Method method = con.getClass().getMethod("openProxySession", int.class, Properties.class); | ||
| 146 | - method.setAccessible(true); | ||
| 147 | - method.invoke(con, 1, props); | ||
| 148 | - } catch (Exception e) { | ||
| 149 | - Scope.getCurrentScope().getLog(getClass()).info("Could not open proxy session on OracleDatabase: " + e.getCause().getMessage()); | ||
| 150 | - } | ||
| 151 | - } | ||
| 152 | - } | ||
| 153 | - | ||
| 154 | - @Override | ||
| 155 | - public int getDatabaseMajorVersion() throws DatabaseException { | ||
| 156 | - if (databaseMajorVersion == null) { | ||
| 157 | - return super.getDatabaseMajorVersion(); | ||
| 158 | - } else { | ||
| 159 | - return databaseMajorVersion; | ||
| 160 | - } | ||
| 161 | - } | ||
| 162 | - | ||
| 163 | - @Override | ||
| 164 | - public int getDatabaseMinorVersion() throws DatabaseException { | ||
| 165 | - if (databaseMinorVersion == null) { | ||
| 166 | - return super.getDatabaseMinorVersion(); | ||
| 167 | - } else { | ||
| 168 | - return databaseMinorVersion; | ||
| 169 | - } | ||
| 170 | - } | ||
| 171 | - | ||
| 172 | - @Override | ||
| 173 | - public String getJdbcCatalogName(CatalogAndSchema schema) { | ||
| 174 | - return null; | ||
| 175 | - } | ||
| 176 | - | ||
| 177 | - @Override | ||
| 178 | - public String getJdbcSchemaName(CatalogAndSchema schema) { | ||
| 179 | - return correctObjectName((schema.getCatalogName() == null) ? schema.getSchemaName() : schema.getCatalogName(), Schema.class); | ||
| 180 | - } | ||
| 181 | - | ||
| 182 | - @Override | ||
| 183 | - protected String getAutoIncrementClause(final String generationType, final Boolean defaultOnNull) { | ||
| 184 | - if (StringUtil.isEmpty(generationType)) { | ||
| 185 | - return super.getAutoIncrementClause(); | ||
| 186 | - } | ||
| 187 | - | ||
| 188 | - String autoIncrementClause = "GENERATED %s AS IDENTITY"; // %s -- [ ALWAYS | BY DEFAULT [ ON NULL ] ] | ||
| 189 | - String generationStrategy = generationType; | ||
| 190 | - if (Boolean.TRUE.equals(defaultOnNull) && generationType.toUpperCase().equals("BY DEFAULT")) { | ||
| 191 | - generationStrategy += " ON NULL"; | ||
| 192 | - } | ||
| 193 | - return String.format(autoIncrementClause, generationStrategy); | ||
| 194 | - } | ||
| 195 | - | ||
| 196 | - @Override | ||
| 197 | - public String generatePrimaryKeyName(String tableName) { | ||
| 198 | - if (tableName.length() > 27) { | ||
| 199 | - //noinspection HardCodedStringLiteral | ||
| 200 | - return "PK_" + tableName.toUpperCase(Locale.US).substring(0, 27); | ||
| 201 | - } else { | ||
| 202 | - //noinspection HardCodedStringLiteral | ||
| 203 | - return "PK_" + tableName.toUpperCase(Locale.US); | ||
| 204 | - } | ||
| 205 | - } | ||
| 206 | - | ||
| 207 | - @Override | ||
| 208 | - public boolean isReservedWord(String objectName) { | ||
| 209 | - return reservedWords.contains(objectName.toUpperCase()); | ||
| 210 | - } | ||
| 211 | - | ||
| 212 | - @Override | ||
| 213 | - public boolean supportsSequences() { | ||
| 214 | - return true; | ||
| 215 | - } | ||
| 216 | - | ||
| 217 | - /** | ||
| 218 | - * Oracle supports catalogs in liquibase terms | ||
| 219 | - * | ||
| 220 | - * @return false | ||
| 221 | - */ | ||
| 222 | - @Override | ||
| 223 | - public boolean supportsSchemas() { | ||
| 224 | - return false; | ||
| 225 | - } | ||
| 226 | - | ||
| 227 | - @Override | ||
| 228 | - protected String getConnectionCatalogName() throws DatabaseException { | ||
| 229 | - if (getConnection() instanceof OfflineConnection) { | ||
| 230 | - return getConnection().getCatalog(); | ||
| 231 | - } | ||
| 232 | - try { | ||
| 233 | - //noinspection HardCodedStringLiteral | ||
| 234 | - return Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", this).queryForObject(new RawCallStatement("select sys_context( 'userenv', 'current_schema' ) from dual"), String.class); | ||
| 235 | - } catch (Exception e) { | ||
| 236 | - //noinspection HardCodedStringLiteral | ||
| 237 | - Scope.getCurrentScope().getLog(getClass()).info("Error getting default schema", e); | ||
| 238 | - } | ||
| 239 | - return null; | ||
| 240 | - } | ||
| 241 | - | ||
| 242 | - @Override | ||
| 243 | - public String getDefaultCatalogName() {//NOPMD | ||
| 244 | - return (super.getDefaultCatalogName() == null) ? null : super.getDefaultCatalogName().toUpperCase(Locale.US); | ||
| 245 | - } | ||
| 246 | - | ||
| 247 | - /** | ||
| 248 | - * <p>Returns an Oracle date literal with the same value as a string formatted using ISO 8601.</p> | ||
| 249 | - * | ||
| 250 | - * <p>Convert an ISO8601 date string to one of the following results: | ||
| 251 | - * to_date('1995-05-23', 'YYYY-MM-DD') | ||
| 252 | - * to_date('1995-05-23 09:23:59', 'YYYY-MM-DD HH24:MI:SS')</p> | ||
| 253 | - * <p> | ||
| 254 | - * Implementation restriction:<br> | ||
| 255 | - * Currently, only the following subsets of ISO8601 are supported:<br> | ||
| 256 | - * <ul> | ||
| 257 | - * <li>YYYY-MM-DD</li> | ||
| 258 | - * <li>YYYY-MM-DDThh:mm:ss</li> | ||
| 259 | - * </ul> | ||
| 260 | - */ | ||
| 261 | - @Override | ||
| 262 | - public String getDateLiteral(String isoDate) { | ||
| 263 | - String normalLiteral = super.getDateLiteral(isoDate); | ||
| 264 | - | ||
| 265 | - if (isDateOnly(isoDate)) { | ||
| 266 | - return "TO_DATE(" + normalLiteral + ", 'YYYY-MM-DD')"; | ||
| 267 | - } else if (isTimeOnly(isoDate)) { | ||
| 268 | - return "TO_DATE(" + normalLiteral + ", 'HH24:MI:SS')"; | ||
| 269 | - } else if (isTimestamp(isoDate)) { | ||
| 270 | - return "TO_TIMESTAMP(" + normalLiteral + ", 'YYYY-MM-DD HH24:MI:SS.FF')"; | ||
| 271 | - } else if (isDateTime(isoDate)) { | ||
| 272 | - int seppos = normalLiteral.lastIndexOf('.'); | ||
| 273 | - if (seppos != -1) { | ||
| 274 | - normalLiteral = normalLiteral.substring(0, seppos) + "'"; | ||
| 275 | - } | ||
| 276 | - return "TO_DATE(" + normalLiteral + ", 'YYYY-MM-DD HH24:MI:SS')"; | ||
| 277 | - } | ||
| 278 | - return "UNSUPPORTED:" + isoDate; | ||
| 279 | - } | ||
| 280 | - | ||
| 281 | - @Override | ||
| 282 | - public boolean isSystemObject(DatabaseObject example) { | ||
| 283 | - if (example == null) { | ||
| 284 | - return false; | ||
| 285 | - } | ||
| 286 | - | ||
| 287 | - if (this.isLiquibaseObject(example)) { | ||
| 288 | - return false; | ||
| 289 | - } | ||
| 290 | - | ||
| 291 | - if (example instanceof Schema) { | ||
| 292 | - //noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral | ||
| 293 | - if ("SYSTEM".equals(example.getName()) || "SYS".equals(example.getName()) || "CTXSYS".equals(example.getName()) || "XDB".equals(example.getName())) { | ||
| 294 | - return true; | ||
| 295 | - } | ||
| 296 | - //noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral | ||
| 297 | - if ("SYSTEM".equals(example.getSchema().getCatalogName()) || "SYS".equals(example.getSchema().getCatalogName()) || "CTXSYS".equals(example.getSchema().getCatalogName()) || "XDB".equals(example.getSchema().getCatalogName())) { | ||
| 298 | - return true; | ||
| 299 | - } | ||
| 300 | - } else if (isSystemObject(example.getSchema())) { | ||
| 301 | - return true; | ||
| 302 | - } | ||
| 303 | - if (example instanceof Catalog) { | ||
| 304 | - //noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral | ||
| 305 | - if (("SYSTEM".equals(example.getName()) || "SYS".equals(example.getName()) || "CTXSYS".equals(example.getName()) || "XDB".equals(example.getName()))) { | ||
| 306 | - return true; | ||
| 307 | - } | ||
| 308 | - } else if (example.getName() != null) { | ||
| 309 | - //noinspection HardCodedStringLiteral | ||
| 310 | - if (example.getName().startsWith("BIN$")) { //oracle deleted table | ||
| 311 | - boolean filteredInOriginalQuery = this.canAccessDbaRecycleBin(); | ||
| 312 | - if (!filteredInOriginalQuery) { | ||
| 313 | - filteredInOriginalQuery = StringUtil.trimToEmpty(example.getSchema().getName()).equalsIgnoreCase(this.getConnection().getConnectionUserName()); | ||
| 314 | - } | ||
| 315 | - | ||
| 316 | - if (filteredInOriginalQuery) { | ||
| 317 | - return !((example instanceof PrimaryKey) || (example instanceof Index) || (example instanceof | ||
| 318 | - liquibase.statement.UniqueConstraint)); | ||
| 319 | - } else { | ||
| 320 | - return true; | ||
| 321 | - } | ||
| 322 | - } else //noinspection HardCodedStringLiteral | ||
| 323 | - if (example.getName().startsWith("AQ$")) { //oracle AQ tables | ||
| 324 | - return true; | ||
| 325 | - } else //noinspection HardCodedStringLiteral | ||
| 326 | - if (example.getName().startsWith("DR$")) { //oracle index tables | ||
| 327 | - return true; | ||
| 328 | - } else //noinspection HardCodedStringLiteral | ||
| 329 | - if (example.getName().startsWith("SYS_IOT_OVER")) { //oracle system table | ||
| 330 | - return true; | ||
| 331 | - } else //noinspection HardCodedStringLiteral,HardCodedStringLiteral | ||
| 332 | - if ((example.getName().startsWith("MDRT_") || example.getName().startsWith("MDRS_")) && example.getName().endsWith("$")) { | ||
| 333 | - // CORE-1768 - Oracle creates these for spatial indices and will remove them when the index is removed. | ||
| 334 | - return true; | ||
| 335 | - } else //noinspection HardCodedStringLiteral | ||
| 336 | - if (example.getName().startsWith("MLOG$_")) { //Created by materliaized view logs for every table that is part of a materialized view. Not available for DDL operations. | ||
| 337 | - return true; | ||
| 338 | - } else //noinspection HardCodedStringLiteral | ||
| 339 | - if (example.getName().startsWith("RUPD$_")) { //Created by materialized view log tables using primary keys. Not available for DDL operations. | ||
| 340 | - return true; | ||
| 341 | - } else //noinspection HardCodedStringLiteral | ||
| 342 | - if (example.getName().startsWith("WM$_")) { //Workspace Manager backup tables. | ||
| 343 | - return true; | ||
| 344 | - } else //noinspection HardCodedStringLiteral | ||
| 345 | - if ("CREATE$JAVA$LOB$TABLE".equals(example.getName())) { //This table contains the name of the Java object, the date it was loaded, and has a BLOB column to store the Java object. | ||
| 346 | - return true; | ||
| 347 | - } else //noinspection HardCodedStringLiteral | ||
| 348 | - if ("JAVA$CLASS$MD5$TABLE".equals(example.getName())) { //This is a hash table that tracks the loading of Java objects into a schema. | ||
| 349 | - return true; | ||
| 350 | - } else //noinspection HardCodedStringLiteral | ||
| 351 | - if (example.getName().startsWith("ISEQ$$_")) { //System-generated sequence | ||
| 352 | - return true; | ||
| 353 | - } else //noinspection HardCodedStringLiteral | ||
| 354 | - if (example.getName().startsWith("USLOG$")) { //for update materialized view | ||
| 355 | - return true; | ||
| 356 | - } else if (example.getName().startsWith("SYS_FBA")) { //for Flashback tables | ||
| 357 | - return true; | ||
| 358 | - } | ||
| 359 | - } | ||
| 360 | - | ||
| 361 | - return super.isSystemObject(example); | ||
| 362 | - } | ||
| 363 | - | ||
| 364 | - @Override | ||
| 365 | - public boolean supportsAutoIncrement() { | ||
| 366 | - // Oracle supports Identity beginning with version 12c | ||
| 367 | - boolean isAutoIncrementSupported = false; | ||
| 368 | - | ||
| 369 | - try { | ||
| 370 | - if (getDatabaseMajorVersion() >= 12) { | ||
| 371 | - isAutoIncrementSupported = true; | ||
| 372 | - } | ||
| 373 | - | ||
| 374 | - // Returning true will generate create table command with 'IDENTITY' clause, example: | ||
| 375 | - // CREATE TABLE AutoIncTest (IDPrimaryKey NUMBER(19) GENERATED BY DEFAULT AS IDENTITY NOT NULL, TypeID NUMBER(3) NOT NULL, Description NVARCHAR2(50), CONSTRAINT PK_AutoIncTest PRIMARY KEY (IDPrimaryKey)); | ||
| 376 | - | ||
| 377 | - // While returning false will continue to generate create table command without 'IDENTITY' clause, example: | ||
| 378 | - // CREATE TABLE AutoIncTest (IDPrimaryKey NUMBER(19) NOT NULL, TypeID NUMBER(3) NOT NULL, Description NVARCHAR2(50), CONSTRAINT PK_AutoIncTest PRIMARY KEY (IDPrimaryKey)); | ||
| 379 | - | ||
| 380 | - } catch (DatabaseException ex) { | ||
| 381 | - isAutoIncrementSupported = false; | ||
| 382 | - } | ||
| 383 | - | ||
| 384 | - return isAutoIncrementSupported; | ||
| 385 | - } | ||
| 386 | - | ||
| 387 | - | ||
| 388 | -// public Set<UniqueConstraint> findUniqueConstraints(String schema) throws DatabaseException { | ||
| 389 | -// Set<UniqueConstraint> returnSet = new HashSet<UniqueConstraint>(); | ||
| 390 | -// | ||
| 391 | -// List<Map> maps = new Executor(this).queryForList(new RawSqlStatement("SELECT UC.CONSTRAINT_NAME, UCC.TABLE_NAME, UCC.COLUMN_NAME FROM USER_CONSTRAINTS UC, USER_CONS_COLUMNS UCC WHERE UC.CONSTRAINT_NAME=UCC.CONSTRAINT_NAME AND CONSTRAINT_TYPE='U' ORDER BY UC.CONSTRAINT_NAME")); | ||
| 392 | -// | ||
| 393 | -// UniqueConstraint constraint = null; | ||
| 394 | -// for (Map map : maps) { | ||
| 395 | -// if (constraint == null || !constraint.getName().equals(constraint.getName())) { | ||
| 396 | -// returnSet.add(constraint); | ||
| 397 | -// Table table = new Table((String) map.get("TABLE_NAME")); | ||
| 398 | -// constraint = new UniqueConstraint(map.get("CONSTRAINT_NAME").toString(), table); | ||
| 399 | -// } | ||
| 400 | -// } | ||
| 401 | -// if (constraint != null) { | ||
| 402 | -// returnSet.add(constraint); | ||
| 403 | -// } | ||
| 404 | -// | ||
| 405 | -// return returnSet; | ||
| 406 | -// } | ||
| 407 | - | ||
| 408 | - @Override | ||
| 409 | - public boolean supportsRestrictForeignKeys() { | ||
| 410 | - return false; | ||
| 411 | - } | ||
| 412 | - | ||
| 413 | - @Override | ||
| 414 | - public int getDataTypeMaxParameters(String dataTypeName) { | ||
| 415 | - //noinspection HardCodedStringLiteral | ||
| 416 | - if ("BINARY_FLOAT".equals(dataTypeName.toUpperCase())) { | ||
| 417 | - return 0; | ||
| 418 | - } | ||
| 419 | - //noinspection HardCodedStringLiteral | ||
| 420 | - if ("BINARY_DOUBLE".equals(dataTypeName.toUpperCase())) { | ||
| 421 | - return 0; | ||
| 422 | - } | ||
| 423 | - return super.getDataTypeMaxParameters(dataTypeName); | ||
| 424 | - } | ||
| 425 | - | ||
| 426 | - public String getSystemTableWhereClause(String tableNameColumn) { | ||
| 427 | - List<String> clauses = new ArrayList<String>(Arrays.asList("BIN$", | ||
| 428 | - "AQ$", | ||
| 429 | - "DR$", | ||
| 430 | - "SYS_IOT_OVER", | ||
| 431 | - "MLOG$_", | ||
| 432 | - "RUPD$_", | ||
| 433 | - "WM$_", | ||
| 434 | - "ISEQ$$_", | ||
| 435 | - "USLOG$", | ||
| 436 | - "SYS_FBA")); | ||
| 437 | - | ||
| 438 | - for (int i = 0;i<clauses.size(); i++) { | ||
| 439 | - clauses.set(i, tableNameColumn+" NOT LIKE '"+clauses.get(i)+"%'"); | ||
| 440 | - } | ||
| 441 | - return "("+ StringUtil.join(clauses, " AND ") + ")"; | ||
| 442 | - } | ||
| 443 | - | ||
| 444 | - @Override | ||
| 445 | - public boolean jdbcCallsCatalogsSchemas() { | ||
| 446 | - return true; | ||
| 447 | - } | ||
| 448 | - | ||
| 449 | - public Set<String> getUserDefinedTypes() { | ||
| 450 | - if (userDefinedTypes == null) { | ||
| 451 | - userDefinedTypes = new HashSet<>(); | ||
| 452 | - if ((getConnection() != null) && !(getConnection() instanceof OfflineConnection)) { | ||
| 453 | - try { | ||
| 454 | - try { | ||
| 455 | - //noinspection HardCodedStringLiteral | ||
| 456 | - userDefinedTypes.addAll(Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", this).queryForList(new RawSqlStatement("SELECT DISTINCT TYPE_NAME FROM ALL_TYPES"), String.class)); | ||
| 457 | - } catch (DatabaseException e) { //fall back to USER_TYPES if the user cannot see ALL_TYPES | ||
| 458 | - //noinspection HardCodedStringLiteral | ||
| 459 | - userDefinedTypes.addAll(Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", this).queryForList(new RawSqlStatement("SELECT TYPE_NAME FROM USER_TYPES"), String.class)); | ||
| 460 | - } | ||
| 461 | - } catch (DatabaseException e) { | ||
| 462 | - //ignore error | ||
| 463 | - } | ||
| 464 | - } | ||
| 465 | - } | ||
| 466 | - | ||
| 467 | - return userDefinedTypes; | ||
| 468 | - } | ||
| 469 | - | ||
| 470 | - @Override | ||
| 471 | - public String generateDatabaseFunctionValue(DatabaseFunction databaseFunction) { | ||
| 472 | - //noinspection HardCodedStringLiteral | ||
| 473 | - if ((databaseFunction != null) && "current_timestamp".equalsIgnoreCase(databaseFunction.toString())) { | ||
| 474 | - return databaseFunction.toString(); | ||
| 475 | - } | ||
| 476 | - if ((databaseFunction instanceof SequenceNextValueFunction) || (databaseFunction instanceof | ||
| 477 | - SequenceCurrentValueFunction)) { | ||
| 478 | - String quotedSeq = super.generateDatabaseFunctionValue(databaseFunction); | ||
| 479 | - // replace "myschema.my_seq".nextval with "myschema"."my_seq".nextval | ||
| 480 | - return quotedSeq.replaceFirst("\"([^\\.\"]+)\\.([^\\.\"]+)\"", "\"$1\".\"$2\""); | ||
| 481 | - | ||
| 482 | - } | ||
| 483 | - | ||
| 484 | - return super.generateDatabaseFunctionValue(databaseFunction); | ||
| 485 | - } | ||
| 486 | - | ||
| 487 | - @Override | ||
| 488 | - public ValidationErrors validate() { | ||
| 489 | - ValidationErrors errors = super.validate(); | ||
| 490 | - DatabaseConnection connection = getConnection(); | ||
| 491 | - if ((connection == null) || (connection instanceof OfflineConnection)) { | ||
| 492 | - //noinspection HardCodedStringLiteral | ||
| 493 | - Scope.getCurrentScope().getLog(getClass()).info("Cannot validate offline database"); | ||
| 494 | - return errors; | ||
| 495 | - } | ||
| 496 | - | ||
| 497 | - if (!canAccessDbaRecycleBin()) { | ||
| 498 | - errors.addWarning(getDbaRecycleBinWarning()); | ||
| 499 | - } | ||
| 500 | - | ||
| 501 | - return errors; | ||
| 502 | - | ||
| 503 | - } | ||
| 504 | - | ||
| 505 | - public String getDbaRecycleBinWarning() { | ||
| 506 | - //noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral, | ||
| 507 | - // HardCodedStringLiteral | ||
| 508 | - //noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral | ||
| 509 | - return "Liquibase needs to access the DBA_RECYCLEBIN table so we can automatically handle the case where " + | ||
| 510 | - "constraints are deleted and restored. Since Oracle doesn't properly restore the original table names " + | ||
| 511 | - "referenced in the constraint, we use the information from the DBA_RECYCLEBIN to automatically correct this" + | ||
| 512 | - " issue.\n" + | ||
| 513 | - "\n" + | ||
| 514 | - "The user you used to connect to the database (" + getConnection().getConnectionUserName() + | ||
| 515 | - ") needs to have \"SELECT ON SYS.DBA_RECYCLEBIN\" permissions set before we can perform this operation. " + | ||
| 516 | - "Please run the following SQL to set the appropriate permissions, and try running the command again.\n" + | ||
| 517 | - "\n" + | ||
| 518 | - " GRANT SELECT ON SYS.DBA_RECYCLEBIN TO " + getConnection().getConnectionUserName() + ";"; | ||
| 519 | - } | ||
| 520 | - | ||
| 521 | - public boolean canAccessDbaRecycleBin() { | ||
| 522 | - if (canAccessDbaRecycleBin == null) { | ||
| 523 | - DatabaseConnection connection = getConnection(); | ||
| 524 | - if ((connection == null) || (connection instanceof OfflineConnection)) { | ||
| 525 | - return false; | ||
| 526 | - } | ||
| 527 | - | ||
| 528 | - Statement statement = null; | ||
| 529 | - try { | ||
| 530 | - statement = ((JdbcConnection) connection).createStatement(); | ||
| 531 | - @SuppressWarnings("HardCodedStringLiteral") ResultSet resultSet = statement.executeQuery("select 1 from dba_recyclebin where 0=1"); | ||
| 532 | - resultSet.close(); //don't need to do anything with the result set, just make sure statement ran. | ||
| 533 | - this.canAccessDbaRecycleBin = true; | ||
| 534 | - } catch (Exception e) { | ||
| 535 | - //noinspection HardCodedStringLiteral | ||
| 536 | - if ((e instanceof SQLException) && e.getMessage().startsWith("ORA-00942")) { //ORA-00942: table or view does not exist | ||
| 537 | - this.canAccessDbaRecycleBin = false; | ||
| 538 | - } else { | ||
| 539 | - //noinspection HardCodedStringLiteral | ||
| 540 | - Scope.getCurrentScope().getLog(getClass()).warning("Cannot check dba_recyclebin access", e); | ||
| 541 | - this.canAccessDbaRecycleBin = false; | ||
| 542 | - } | ||
| 543 | - } finally { | ||
| 544 | - JdbcUtils.close(null, statement); | ||
| 545 | - } | ||
| 546 | - } | ||
| 547 | - | ||
| 548 | - return canAccessDbaRecycleBin; | ||
| 549 | - } | ||
| 550 | - | ||
| 551 | - @Override | ||
| 552 | - public boolean supportsNotNullConstraintNames() { | ||
| 553 | - return true; | ||
| 554 | - } | ||
| 555 | - | ||
| 556 | - /** | ||
| 557 | - * Tests if the given String would be a valid identifier in Oracle DBMS. In Oracle, a valid identifier has | ||
| 558 | - * the following form (case-insensitive comparison): | ||
| 559 | - * 1st character: A-Z | ||
| 560 | - * 2..n characters: A-Z0-9$_# | ||
| 561 | - * The maximum length of an identifier differs by Oracle version and object type. | ||
| 562 | - */ | ||
| 563 | - public boolean isValidOracleIdentifier(String identifier, Class<? extends DatabaseObject> type) { | ||
| 564 | - if ((identifier == null) || (identifier.length() < 1)) | ||
| 565 | - return false; | ||
| 566 | - | ||
| 567 | - if (!identifier.matches("^(i?)[A-Z][A-Z0-9\\$\\_\\#]*$")) | ||
| 568 | - return false; | ||
| 569 | - | ||
| 570 | - /* | ||
| 571 | - * @todo It seems we currently do not have a class for tablespace identifiers, and all other classes | ||
| 572 | - * we do know seem to be supported as 12cR2 long identifiers, so: | ||
| 573 | - */ | ||
| 574 | - return (identifier.length() <= LONG_IDENTIFIERS_LEGNTH); | ||
| 575 | - } | ||
| 576 | - | ||
| 577 | - /** | ||
| 578 | - * Returns the maximum number of bytes (NOT: characters) for an identifier. For Oracle <=12c Release 20, this | ||
| 579 | - * is 30 bytes, and starting from 12cR2, up to 128 (except for tablespaces, PDB names and some other rather rare | ||
| 580 | - * object types). | ||
| 581 | - * | ||
| 582 | - * @return the maximum length of an object identifier, in bytes | ||
| 583 | - */ | ||
| 584 | - public int getIdentifierMaximumLength() { | ||
| 585 | - try { | ||
| 586 | - if (getDatabaseMajorVersion() < ORACLE_12C_MAJOR_VERSION) { | ||
| 587 | - return SHORT_IDENTIFIERS_LENGTH; | ||
| 588 | - } else if ((getDatabaseMajorVersion() == ORACLE_12C_MAJOR_VERSION) && (getDatabaseMinorVersion() <= 1)) { | ||
| 589 | - return SHORT_IDENTIFIERS_LENGTH; | ||
| 590 | - } else { | ||
| 591 | - return LONG_IDENTIFIERS_LEGNTH; | ||
| 592 | - } | ||
| 593 | - } catch (DatabaseException ex) { | ||
| 594 | - throw new UnexpectedLiquibaseException("Cannot determine the Oracle database version number", ex); | ||
| 595 | - } | ||
| 596 | - | ||
| 597 | - } | ||
| 598 | -} |
sql/dm/flowable-patch/src/main/java/liquibase/datatype/core/BooleanType.java deleted
| 1 | -package liquibase.datatype.core; | ||
| 2 | - | ||
| 3 | -import liquibase.change.core.LoadDataChange; | ||
| 4 | -import liquibase.database.Database; | ||
| 5 | -import liquibase.database.core.*; | ||
| 6 | -import liquibase.datatype.DataTypeInfo; | ||
| 7 | -import liquibase.datatype.DatabaseDataType; | ||
| 8 | -import liquibase.datatype.LiquibaseDataType; | ||
| 9 | -import liquibase.exception.UnexpectedLiquibaseException; | ||
| 10 | -import liquibase.statement.DatabaseFunction; | ||
| 11 | -import liquibase.util.StringUtil; | ||
| 12 | - | ||
| 13 | -import java.util.Locale; | ||
| 14 | -import java.util.regex.Pattern; | ||
| 15 | - | ||
| 16 | -@DataTypeInfo(name = "boolean", aliases = {"java.sql.Types.BOOLEAN", "java.lang.Boolean", "bit", "bool"}, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT) | ||
| 17 | -public class BooleanType extends LiquibaseDataType { | ||
| 18 | - | ||
| 19 | - @Override | ||
| 20 | - public DatabaseDataType toDatabaseDataType(Database database) { | ||
| 21 | - String originalDefinition = StringUtil.trimToEmpty(getRawDefinition()); | ||
| 22 | - if ((database instanceof Firebird3Database)) { | ||
| 23 | - return new DatabaseDataType("BOOLEAN"); | ||
| 24 | - } | ||
| 25 | - | ||
| 26 | - if ((database instanceof Db2zDatabase) || (database instanceof FirebirdDatabase)) { | ||
| 27 | - return new DatabaseDataType("SMALLINT"); | ||
| 28 | - } else if (database instanceof MSSQLDatabase) { | ||
| 29 | - return new DatabaseDataType(database.escapeDataTypeName("bit")); | ||
| 30 | - } else if (database instanceof MySQLDatabase) { | ||
| 31 | - if (originalDefinition.toLowerCase(Locale.US).startsWith("bit")) { | ||
| 32 | - return new DatabaseDataType("BIT", getParameters()); | ||
| 33 | - } | ||
| 34 | - return new DatabaseDataType("BIT", 1); | ||
| 35 | - } else if (database instanceof OracleDatabase) { | ||
| 36 | - return new DatabaseDataType("NUMBER", 1); | ||
| 37 | - } else if ((database instanceof SybaseASADatabase) || (database instanceof SybaseDatabase)) { | ||
| 38 | - return new DatabaseDataType("BIT"); | ||
| 39 | - } else if (database instanceof DerbyDatabase) { | ||
| 40 | - if (((DerbyDatabase) database).supportsBooleanDataType()) { | ||
| 41 | - return new DatabaseDataType("BOOLEAN"); | ||
| 42 | - } else { | ||
| 43 | - return new DatabaseDataType("SMALLINT"); | ||
| 44 | - } | ||
| 45 | - } else if (database instanceof DB2Database) { | ||
| 46 | - if (((DB2Database) database).supportsBooleanDataType()) | ||
| 47 | - return new DatabaseDataType("BOOLEAN"); | ||
| 48 | - else | ||
| 49 | - return new DatabaseDataType("SMALLINT"); | ||
| 50 | - } else if (database instanceof HsqlDatabase) { | ||
| 51 | - return new DatabaseDataType("BOOLEAN"); | ||
| 52 | - } else if (database instanceof PostgresDatabase) { | ||
| 53 | - if (originalDefinition.toLowerCase(Locale.US).startsWith("bit")) { | ||
| 54 | - return new DatabaseDataType("BIT", getParameters()); | ||
| 55 | - } | ||
| 56 | - } else if (database instanceof DmDatabase) { // dhb52: DM Support | ||
| 57 | - return new DatabaseDataType("bit"); | ||
| 58 | - } | ||
| 59 | - | ||
| 60 | - return super.toDatabaseDataType(database); | ||
| 61 | - } | ||
| 62 | - | ||
| 63 | - @Override | ||
| 64 | - public String objectToSql(Object value, Database database) { | ||
| 65 | - if ((value == null) || "null".equals(value.toString().toLowerCase(Locale.US))) { | ||
| 66 | - return null; | ||
| 67 | - } | ||
| 68 | - | ||
| 69 | - String returnValue; | ||
| 70 | - if (value instanceof String) { | ||
| 71 | - value = ((String) value).replaceAll("'", ""); | ||
| 72 | - if ("true".equals(((String) value).toLowerCase(Locale.US)) || "1".equals(value) || "b'1'".equals(((String) value).toLowerCase(Locale.US)) || "t".equals(((String) value).toLowerCase(Locale.US)) || ((String) value).toLowerCase(Locale.US).equals(this.getTrueBooleanValue(database).toLowerCase(Locale.US))) { | ||
| 73 | - returnValue = this.getTrueBooleanValue(database); | ||
| 74 | - } else if ("false".equals(((String) value).toLowerCase(Locale.US)) || "0".equals(value) || "b'0'".equals( | ||
| 75 | - ((String) value).toLowerCase(Locale.US)) || "f".equals(((String) value).toLowerCase(Locale.US)) || ((String) value).toLowerCase(Locale.US).equals(this.getFalseBooleanValue(database).toLowerCase(Locale.US))) { | ||
| 76 | - returnValue = this.getFalseBooleanValue(database); | ||
| 77 | - } else if (database instanceof PostgresDatabase && Pattern.matches("b?([01])\\1*(::bit|::\"bit\")?", (String) value)) { | ||
| 78 | - returnValue = "b'" | ||
| 79 | - + value.toString() | ||
| 80 | - .replace("b", "") | ||
| 81 | - .replace("\"", "") | ||
| 82 | - .replace("::it", "") | ||
| 83 | - + "'::\"bit\""; | ||
| 84 | - } else { | ||
| 85 | - throw new UnexpectedLiquibaseException("Unknown boolean value: " + value); | ||
| 86 | - } | ||
| 87 | - } else if (value instanceof Long) { | ||
| 88 | - if (Long.valueOf(1).equals(value)) { | ||
| 89 | - returnValue = this.getTrueBooleanValue(database); | ||
| 90 | - } else { | ||
| 91 | - returnValue = this.getFalseBooleanValue(database); | ||
| 92 | - } | ||
| 93 | - } else if (value instanceof Number) { | ||
| 94 | - if (value.equals(1) || "1".equals(value.toString()) || "1.0".equals(value.toString())) { | ||
| 95 | - returnValue = this.getTrueBooleanValue(database); | ||
| 96 | - } else { | ||
| 97 | - returnValue = this.getFalseBooleanValue(database); | ||
| 98 | - } | ||
| 99 | - } else if (value instanceof DatabaseFunction) { | ||
| 100 | - return value.toString(); | ||
| 101 | - } else if (value instanceof Boolean) { | ||
| 102 | - if (((Boolean) value)) { | ||
| 103 | - returnValue = this.getTrueBooleanValue(database); | ||
| 104 | - } else { | ||
| 105 | - returnValue = this.getFalseBooleanValue(database); | ||
| 106 | - } | ||
| 107 | - } else { | ||
| 108 | - throw new UnexpectedLiquibaseException("Cannot convert type " + value.getClass() + " to a boolean value"); | ||
| 109 | - } | ||
| 110 | - | ||
| 111 | - return returnValue; | ||
| 112 | - } | ||
| 113 | - | ||
| 114 | - protected boolean isNumericBoolean(Database database) { | ||
| 115 | - if (database instanceof Firebird3Database) { | ||
| 116 | - return false; | ||
| 117 | - } | ||
| 118 | - if (database instanceof DerbyDatabase) { | ||
| 119 | - return !((DerbyDatabase) database).supportsBooleanDataType(); | ||
| 120 | - } else if (database instanceof DB2Database) { | ||
| 121 | - return !((DB2Database) database).supportsBooleanDataType(); | ||
| 122 | - } | ||
| 123 | - return (database instanceof Db2zDatabase) | ||
| 124 | - || (database instanceof FirebirdDatabase) | ||
| 125 | - || (database instanceof MSSQLDatabase) | ||
| 126 | - || (database instanceof MySQLDatabase) | ||
| 127 | - || (database instanceof OracleDatabase) | ||
| 128 | - || (database instanceof SQLiteDatabase) | ||
| 129 | - || (database instanceof SybaseASADatabase) | ||
| 130 | - || (database instanceof SybaseDatabase) | ||
| 131 | - || (database instanceof DmDatabase); // dhb52: DM Support | ||
| 132 | - } | ||
| 133 | - | ||
| 134 | - /** | ||
| 135 | - * The database-specific value to use for "false" "boolean" columns. | ||
| 136 | - */ | ||
| 137 | - public String getFalseBooleanValue(Database database) { | ||
| 138 | - if (isNumericBoolean(database)) { | ||
| 139 | - return "0"; | ||
| 140 | - } | ||
| 141 | - if (database instanceof InformixDatabase) { | ||
| 142 | - return "'f'"; | ||
| 143 | - } | ||
| 144 | - return "FALSE"; | ||
| 145 | - } | ||
| 146 | - | ||
| 147 | - /** | ||
| 148 | - * The database-specific value to use for "true" "boolean" columns. | ||
| 149 | - */ | ||
| 150 | - public String getTrueBooleanValue(Database database) { | ||
| 151 | - if (isNumericBoolean(database)) { | ||
| 152 | - return "1"; | ||
| 153 | - } | ||
| 154 | - if (database instanceof InformixDatabase) { | ||
| 155 | - return "'t'"; | ||
| 156 | - } | ||
| 157 | - return "TRUE"; | ||
| 158 | - } | ||
| 159 | - | ||
| 160 | - @Override | ||
| 161 | - public LoadDataChange.LOAD_DATA_TYPE getLoadTypeName() { | ||
| 162 | - return LoadDataChange.LOAD_DATA_TYPE.BOOLEAN; | ||
| 163 | - } | ||
| 164 | - | ||
| 165 | -} |
sql/dm/flowable-patch/src/main/java/org/flowable/common/engine/impl/AbstractEngineConfiguration.java deleted
| 1 | -/* Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 2 | - * you may not use this file except in compliance with the License. | ||
| 3 | - * You may obtain a copy of the License at | ||
| 4 | - * | ||
| 5 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 6 | - * | ||
| 7 | - * Unless required by applicable law or agreed to in writing, software | ||
| 8 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 9 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 10 | - * See the License for the specific language governing permissions and | ||
| 11 | - * limitations under the License. | ||
| 12 | - */ | ||
| 13 | -package org.flowable.common.engine.impl; | ||
| 14 | - | ||
| 15 | -import java.io.InputStream; | ||
| 16 | -import java.io.InputStreamReader; | ||
| 17 | -import java.io.Reader; | ||
| 18 | -import java.sql.Connection; | ||
| 19 | -import java.sql.DatabaseMetaData; | ||
| 20 | -import java.sql.PreparedStatement; | ||
| 21 | -import java.sql.ResultSet; | ||
| 22 | -import java.sql.SQLException; | ||
| 23 | -import java.time.Duration; | ||
| 24 | -import java.util.ArrayList; | ||
| 25 | -import java.util.Collection; | ||
| 26 | -import java.util.Collections; | ||
| 27 | -import java.util.Comparator; | ||
| 28 | -import java.util.HashMap; | ||
| 29 | -import java.util.List; | ||
| 30 | -import java.util.Map; | ||
| 31 | -import java.util.Properties; | ||
| 32 | -import java.util.ServiceLoader; | ||
| 33 | -import java.util.Set; | ||
| 34 | - | ||
| 35 | -import javax.naming.InitialContext; | ||
| 36 | -import javax.sql.DataSource; | ||
| 37 | - | ||
| 38 | -import org.apache.commons.lang3.StringUtils; | ||
| 39 | -import org.apache.ibatis.builder.xml.XMLConfigBuilder; | ||
| 40 | -import org.apache.ibatis.builder.xml.XMLMapperBuilder; | ||
| 41 | -import org.apache.ibatis.datasource.pooled.PooledDataSource; | ||
| 42 | -import org.apache.ibatis.mapping.Environment; | ||
| 43 | -import org.apache.ibatis.plugin.Interceptor; | ||
| 44 | -import org.apache.ibatis.session.Configuration; | ||
| 45 | -import org.apache.ibatis.session.SqlSessionFactory; | ||
| 46 | -import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory; | ||
| 47 | -import org.apache.ibatis.transaction.TransactionFactory; | ||
| 48 | -import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; | ||
| 49 | -import org.apache.ibatis.transaction.managed.ManagedTransactionFactory; | ||
| 50 | -import org.apache.ibatis.type.ArrayTypeHandler; | ||
| 51 | -import org.apache.ibatis.type.BigDecimalTypeHandler; | ||
| 52 | -import org.apache.ibatis.type.BlobInputStreamTypeHandler; | ||
| 53 | -import org.apache.ibatis.type.BlobTypeHandler; | ||
| 54 | -import org.apache.ibatis.type.BooleanTypeHandler; | ||
| 55 | -import org.apache.ibatis.type.ByteTypeHandler; | ||
| 56 | -import org.apache.ibatis.type.ClobTypeHandler; | ||
| 57 | -import org.apache.ibatis.type.DateOnlyTypeHandler; | ||
| 58 | -import org.apache.ibatis.type.DateTypeHandler; | ||
| 59 | -import org.apache.ibatis.type.DoubleTypeHandler; | ||
| 60 | -import org.apache.ibatis.type.FloatTypeHandler; | ||
| 61 | -import org.apache.ibatis.type.IntegerTypeHandler; | ||
| 62 | -import org.apache.ibatis.type.JdbcType; | ||
| 63 | -import org.apache.ibatis.type.LongTypeHandler; | ||
| 64 | -import org.apache.ibatis.type.NClobTypeHandler; | ||
| 65 | -import org.apache.ibatis.type.NStringTypeHandler; | ||
| 66 | -import org.apache.ibatis.type.ShortTypeHandler; | ||
| 67 | -import org.apache.ibatis.type.SqlxmlTypeHandler; | ||
| 68 | -import org.apache.ibatis.type.StringTypeHandler; | ||
| 69 | -import org.apache.ibatis.type.TimeOnlyTypeHandler; | ||
| 70 | -import org.apache.ibatis.type.TypeHandlerRegistry; | ||
| 71 | -import org.flowable.common.engine.api.FlowableException; | ||
| 72 | -import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; | ||
| 73 | -import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher; | ||
| 74 | -import org.flowable.common.engine.api.delegate.event.FlowableEventListener; | ||
| 75 | -import org.flowable.common.engine.api.engine.EngineLifecycleListener; | ||
| 76 | -import org.flowable.common.engine.impl.agenda.AgendaOperationRunner; | ||
| 77 | -import org.flowable.common.engine.impl.cfg.CommandExecutorImpl; | ||
| 78 | -import org.flowable.common.engine.impl.cfg.IdGenerator; | ||
| 79 | -import org.flowable.common.engine.impl.cfg.TransactionContextFactory; | ||
| 80 | -import org.flowable.common.engine.impl.cfg.standalone.StandaloneMybatisTransactionContextFactory; | ||
| 81 | -import org.flowable.common.engine.impl.db.CommonDbSchemaManager; | ||
| 82 | -import org.flowable.common.engine.impl.db.DbSqlSessionFactory; | ||
| 83 | -import org.flowable.common.engine.impl.db.LogSqlExecutionTimePlugin; | ||
| 84 | -import org.flowable.common.engine.impl.db.MybatisTypeAliasConfigurator; | ||
| 85 | -import org.flowable.common.engine.impl.db.MybatisTypeHandlerConfigurator; | ||
| 86 | -import org.flowable.common.engine.impl.db.SchemaManager; | ||
| 87 | -import org.flowable.common.engine.impl.event.EventDispatchAction; | ||
| 88 | -import org.flowable.common.engine.impl.event.FlowableEventDispatcherImpl; | ||
| 89 | -import org.flowable.common.engine.impl.interceptor.Command; | ||
| 90 | -import org.flowable.common.engine.impl.interceptor.CommandConfig; | ||
| 91 | -import org.flowable.common.engine.impl.interceptor.CommandContextFactory; | ||
| 92 | -import org.flowable.common.engine.impl.interceptor.CommandContextInterceptor; | ||
| 93 | -import org.flowable.common.engine.impl.interceptor.CommandExecutor; | ||
| 94 | -import org.flowable.common.engine.impl.interceptor.CommandInterceptor; | ||
| 95 | -import org.flowable.common.engine.impl.interceptor.CrDbRetryInterceptor; | ||
| 96 | -import org.flowable.common.engine.impl.interceptor.DefaultCommandInvoker; | ||
| 97 | -import org.flowable.common.engine.impl.interceptor.LogInterceptor; | ||
| 98 | -import org.flowable.common.engine.impl.interceptor.SessionFactory; | ||
| 99 | -import org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor; | ||
| 100 | -import org.flowable.common.engine.impl.lock.LockManager; | ||
| 101 | -import org.flowable.common.engine.impl.lock.LockManagerImpl; | ||
| 102 | -import org.flowable.common.engine.impl.logging.LoggingListener; | ||
| 103 | -import org.flowable.common.engine.impl.logging.LoggingSession; | ||
| 104 | -import org.flowable.common.engine.impl.logging.LoggingSessionFactory; | ||
| 105 | -import org.flowable.common.engine.impl.persistence.GenericManagerFactory; | ||
| 106 | -import org.flowable.common.engine.impl.persistence.StrongUuidGenerator; | ||
| 107 | -import org.flowable.common.engine.impl.persistence.cache.EntityCache; | ||
| 108 | -import org.flowable.common.engine.impl.persistence.cache.EntityCacheImpl; | ||
| 109 | -import org.flowable.common.engine.impl.persistence.entity.ByteArrayEntityManager; | ||
| 110 | -import org.flowable.common.engine.impl.persistence.entity.ByteArrayEntityManagerImpl; | ||
| 111 | -import org.flowable.common.engine.impl.persistence.entity.Entity; | ||
| 112 | -import org.flowable.common.engine.impl.persistence.entity.PropertyEntityManager; | ||
| 113 | -import org.flowable.common.engine.impl.persistence.entity.PropertyEntityManagerImpl; | ||
| 114 | -import org.flowable.common.engine.impl.persistence.entity.TableDataManager; | ||
| 115 | -import org.flowable.common.engine.impl.persistence.entity.TableDataManagerImpl; | ||
| 116 | -import org.flowable.common.engine.impl.persistence.entity.data.ByteArrayDataManager; | ||
| 117 | -import org.flowable.common.engine.impl.persistence.entity.data.PropertyDataManager; | ||
| 118 | -import org.flowable.common.engine.impl.persistence.entity.data.impl.MybatisByteArrayDataManager; | ||
| 119 | -import org.flowable.common.engine.impl.persistence.entity.data.impl.MybatisPropertyDataManager; | ||
| 120 | -import org.flowable.common.engine.impl.runtime.Clock; | ||
| 121 | -import org.flowable.common.engine.impl.service.CommonEngineServiceImpl; | ||
| 122 | -import org.flowable.common.engine.impl.util.DefaultClockImpl; | ||
| 123 | -import org.flowable.common.engine.impl.util.IoUtil; | ||
| 124 | -import org.flowable.common.engine.impl.util.ReflectUtil; | ||
| 125 | -import org.flowable.eventregistry.api.EventRegistryEventConsumer; | ||
| 126 | -import org.slf4j.Logger; | ||
| 127 | -import org.slf4j.LoggerFactory; | ||
| 128 | - | ||
| 129 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
| 130 | -import com.fasterxml.jackson.databind.SerializationFeature; | ||
| 131 | - | ||
| 132 | -public abstract class AbstractEngineConfiguration { | ||
| 133 | - | ||
| 134 | - protected final Logger logger = LoggerFactory.getLogger(getClass()); | ||
| 135 | - | ||
| 136 | - /** The tenant id indicating 'no tenant' */ | ||
| 137 | - public static final String NO_TENANT_ID = ""; | ||
| 138 | - | ||
| 139 | - /** | ||
| 140 | - * Checks the version of the DB schema against the library when the form engine is being created and throws an exception if the versions don't match. | ||
| 141 | - */ | ||
| 142 | - public static final String DB_SCHEMA_UPDATE_FALSE = "false"; | ||
| 143 | - public static final String DB_SCHEMA_UPDATE_CREATE = "create"; | ||
| 144 | - public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop"; | ||
| 145 | - | ||
| 146 | - /** | ||
| 147 | - * Creates the schema when the form engine is being created and drops the schema when the form engine is being closed. | ||
| 148 | - */ | ||
| 149 | - public static final String DB_SCHEMA_UPDATE_DROP_CREATE = "drop-create"; | ||
| 150 | - | ||
| 151 | - /** | ||
| 152 | - * Upon building of the process engine, a check is performed and an update of the schema is performed if it is necessary. | ||
| 153 | - */ | ||
| 154 | - public static final String DB_SCHEMA_UPDATE_TRUE = "true"; | ||
| 155 | - | ||
| 156 | - protected boolean forceCloseMybatisConnectionPool = true; | ||
| 157 | - | ||
| 158 | - protected String databaseType; | ||
| 159 | - protected String jdbcDriver = "org.h2.Driver"; | ||
| 160 | - protected String jdbcUrl = "jdbc:h2:tcp://localhost/~/flowable"; | ||
| 161 | - protected String jdbcUsername = "sa"; | ||
| 162 | - protected String jdbcPassword = ""; | ||
| 163 | - protected String dataSourceJndiName; | ||
| 164 | - protected int jdbcMaxActiveConnections = 16; | ||
| 165 | - protected int jdbcMaxIdleConnections = 8; | ||
| 166 | - protected int jdbcMaxCheckoutTime; | ||
| 167 | - protected int jdbcMaxWaitTime; | ||
| 168 | - protected boolean jdbcPingEnabled; | ||
| 169 | - protected String jdbcPingQuery; | ||
| 170 | - protected int jdbcPingConnectionNotUsedFor; | ||
| 171 | - protected int jdbcDefaultTransactionIsolationLevel; | ||
| 172 | - protected DataSource dataSource; | ||
| 173 | - protected SchemaManager commonSchemaManager; | ||
| 174 | - protected SchemaManager schemaManager; | ||
| 175 | - protected Command<Void> schemaManagementCmd; | ||
| 176 | - | ||
| 177 | - protected String databaseSchemaUpdate = DB_SCHEMA_UPDATE_FALSE; | ||
| 178 | - | ||
| 179 | - /** | ||
| 180 | - * Whether to use a lock when performing the database schema create or update operations. | ||
| 181 | - */ | ||
| 182 | - protected boolean useLockForDatabaseSchemaUpdate = false; | ||
| 183 | - | ||
| 184 | - protected String xmlEncoding = "UTF-8"; | ||
| 185 | - | ||
| 186 | - // COMMAND EXECUTORS /////////////////////////////////////////////// | ||
| 187 | - | ||
| 188 | - protected CommandExecutor commandExecutor; | ||
| 189 | - protected Collection<? extends CommandInterceptor> defaultCommandInterceptors; | ||
| 190 | - protected CommandConfig defaultCommandConfig; | ||
| 191 | - protected CommandConfig schemaCommandConfig; | ||
| 192 | - protected CommandContextFactory commandContextFactory; | ||
| 193 | - protected CommandInterceptor commandInvoker; | ||
| 194 | - | ||
| 195 | - protected AgendaOperationRunner agendaOperationRunner = (commandContext, runnable) -> runnable.run(); | ||
| 196 | - | ||
| 197 | - protected List<CommandInterceptor> customPreCommandInterceptors; | ||
| 198 | - protected List<CommandInterceptor> customPostCommandInterceptors; | ||
| 199 | - protected List<CommandInterceptor> commandInterceptors; | ||
| 200 | - | ||
| 201 | - protected Map<String, AbstractEngineConfiguration> engineConfigurations = new HashMap<>(); | ||
| 202 | - protected Map<String, AbstractServiceConfiguration> serviceConfigurations = new HashMap<>(); | ||
| 203 | - | ||
| 204 | - protected ClassLoader classLoader; | ||
| 205 | - /** | ||
| 206 | - * Either use Class.forName or ClassLoader.loadClass for class loading. See http://forums.activiti.org/content/reflectutilloadclass-and-custom- classloader | ||
| 207 | - */ | ||
| 208 | - protected boolean useClassForNameClassLoading = true; | ||
| 209 | - | ||
| 210 | - protected List<EngineLifecycleListener> engineLifecycleListeners; | ||
| 211 | - | ||
| 212 | - // Event Registry ////////////////////////////////////////////////// | ||
| 213 | - protected Map<String, EventRegistryEventConsumer> eventRegistryEventConsumers = new HashMap<>(); | ||
| 214 | - | ||
| 215 | - // MYBATIS SQL SESSION FACTORY ///////////////////////////////////// | ||
| 216 | - | ||
| 217 | - protected boolean isDbHistoryUsed = true; | ||
| 218 | - protected DbSqlSessionFactory dbSqlSessionFactory; | ||
| 219 | - protected SqlSessionFactory sqlSessionFactory; | ||
| 220 | - protected TransactionFactory transactionFactory; | ||
| 221 | - protected TransactionContextFactory transactionContextFactory; | ||
| 222 | - | ||
| 223 | - /** | ||
| 224 | - * If set to true, enables bulk insert (grouping sql inserts together). Default true. | ||
| 225 | - * For some databases (eg DB2+z/OS) needs to be set to false. | ||
| 226 | - */ | ||
| 227 | - protected boolean isBulkInsertEnabled = true; | ||
| 228 | - | ||
| 229 | - /** | ||
| 230 | - * Some databases have a limit of how many parameters one sql insert can have (eg SQL Server, 2000 params (!= insert statements) ). Tweak this parameter in case of exceptions indicating too much | ||
| 231 | - * is being put into one bulk insert, or make it higher if your database can cope with it and there are inserts with a huge amount of data. | ||
| 232 | - * <p> | ||
| 233 | - * By default: 100 (55 for mssql server as it has a hard limit of 2000 parameters in a statement) | ||
| 234 | - */ | ||
| 235 | - protected int maxNrOfStatementsInBulkInsert = 100; | ||
| 236 | - | ||
| 237 | - public int DEFAULT_MAX_NR_OF_STATEMENTS_BULK_INSERT_SQL_SERVER = 55; // currently Execution has most params (35). 2000 / 35 = 57. | ||
| 238 | - | ||
| 239 | - protected String mybatisMappingFile; | ||
| 240 | - protected Set<Class<?>> customMybatisMappers; | ||
| 241 | - protected Set<String> customMybatisXMLMappers; | ||
| 242 | - protected List<Interceptor> customMybatisInterceptors; | ||
| 243 | - | ||
| 244 | - protected Set<String> dependentEngineMyBatisXmlMappers; | ||
| 245 | - protected List<MybatisTypeAliasConfigurator> dependentEngineMybatisTypeAliasConfigs; | ||
| 246 | - protected List<MybatisTypeHandlerConfigurator> dependentEngineMybatisTypeHandlerConfigs; | ||
| 247 | - | ||
| 248 | - // SESSION FACTORIES /////////////////////////////////////////////// | ||
| 249 | - protected List<SessionFactory> customSessionFactories; | ||
| 250 | - protected Map<Class<?>, SessionFactory> sessionFactories; | ||
| 251 | - | ||
| 252 | - protected boolean enableEventDispatcher = true; | ||
| 253 | - protected FlowableEventDispatcher eventDispatcher; | ||
| 254 | - protected List<FlowableEventListener> eventListeners; | ||
| 255 | - protected Map<String, List<FlowableEventListener>> typedEventListeners; | ||
| 256 | - protected List<EventDispatchAction> additionalEventDispatchActions; | ||
| 257 | - | ||
| 258 | - protected LoggingListener loggingListener; | ||
| 259 | - | ||
| 260 | - protected boolean transactionsExternallyManaged; | ||
| 261 | - | ||
| 262 | - /** | ||
| 263 | - * Flag that can be set to configure or not a relational database is used. This is useful for custom implementations that do not use relational databases at all. | ||
| 264 | - * | ||
| 265 | - * If true (default), the {@link AbstractEngineConfiguration#getDatabaseSchemaUpdate()} value will be used to determine what needs to happen wrt the database schema. | ||
| 266 | - * | ||
| 267 | - * If false, no validation or schema creation will be done. That means that the database schema must have been created 'manually' before but the engine does not validate whether the schema is | ||
| 268 | - * correct. The {@link AbstractEngineConfiguration#getDatabaseSchemaUpdate()} value will not be used. | ||
| 269 | - */ | ||
| 270 | - protected boolean usingRelationalDatabase = true; | ||
| 271 | - | ||
| 272 | - /** | ||
| 273 | - * Flag that can be set to configure whether or not a schema is used. This is useful for custom implementations that do not use relational databases at all. | ||
| 274 | - * Setting {@link #usingRelationalDatabase} to true will automatically imply using a schema. | ||
| 275 | - */ | ||
| 276 | - protected boolean usingSchemaMgmt = true; | ||
| 277 | - | ||
| 278 | - /** | ||
| 279 | - * Allows configuring a database table prefix which is used for all runtime operations of the process engine. For example, if you specify a prefix named 'PRE1.', Flowable will query for executions | ||
| 280 | - * in a table named 'PRE1.ACT_RU_EXECUTION_'. | ||
| 281 | - * | ||
| 282 | - * <p> | ||
| 283 | - * <strong>NOTE: the prefix is not respected by automatic database schema management. If you use {@link AbstractEngineConfiguration#DB_SCHEMA_UPDATE_CREATE_DROP} or | ||
| 284 | - * {@link AbstractEngineConfiguration#DB_SCHEMA_UPDATE_TRUE}, Flowable will create the database tables using the default names, regardless of the prefix configured here.</strong> | ||
| 285 | - */ | ||
| 286 | - protected String databaseTablePrefix = ""; | ||
| 287 | - | ||
| 288 | - /** | ||
| 289 | - * Escape character for doing wildcard searches. | ||
| 290 | - * | ||
| 291 | - * This will be added at then end of queries that include for example a LIKE clause. For example: SELECT * FROM table WHERE column LIKE '%\%%' ESCAPE '\'; | ||
| 292 | - */ | ||
| 293 | - protected String databaseWildcardEscapeCharacter; | ||
| 294 | - | ||
| 295 | - /** | ||
| 296 | - * database catalog to use | ||
| 297 | - */ | ||
| 298 | - protected String databaseCatalog = ""; | ||
| 299 | - | ||
| 300 | - /** | ||
| 301 | - * In some situations you want to set the schema to use for table checks / generation if the database metadata doesn't return that correctly, see https://jira.codehaus.org/browse/ACT-1220, | ||
| 302 | - * https://jira.codehaus.org/browse/ACT-1062 | ||
| 303 | - */ | ||
| 304 | - protected String databaseSchema; | ||
| 305 | - | ||
| 306 | - /** | ||
| 307 | - * Set to true in case the defined databaseTablePrefix is a schema-name, instead of an actual table name prefix. This is relevant for checking if Flowable-tables exist, the databaseTablePrefix | ||
| 308 | - * will not be used here - since the schema is taken into account already, adding a prefix for the table-check will result in wrong table-names. | ||
| 309 | - */ | ||
| 310 | - protected boolean tablePrefixIsSchema; | ||
| 311 | - | ||
| 312 | - /** | ||
| 313 | - * Set to true if the latest version of a definition should be retrieved, ignoring a possible parent deployment id value | ||
| 314 | - */ | ||
| 315 | - protected boolean alwaysLookupLatestDefinitionVersion; | ||
| 316 | - | ||
| 317 | - /** | ||
| 318 | - * Set to true if by default lookups should fallback to the default tenant (an empty string by default or a defined tenant value) | ||
| 319 | - */ | ||
| 320 | - protected boolean fallbackToDefaultTenant; | ||
| 321 | - | ||
| 322 | - /** | ||
| 323 | - * Default tenant provider that is executed when looking up definitions, in case the global or local fallback to default tenant value is true | ||
| 324 | - */ | ||
| 325 | - protected DefaultTenantProvider defaultTenantProvider = (tenantId, scope, scopeKey) -> NO_TENANT_ID; | ||
| 326 | - | ||
| 327 | - /** | ||
| 328 | - * Enables the MyBatis plugin that logs the execution time of sql statements. | ||
| 329 | - */ | ||
| 330 | - protected boolean enableLogSqlExecutionTime; | ||
| 331 | - | ||
| 332 | - protected Properties databaseTypeMappings = getDefaultDatabaseTypeMappings(); | ||
| 333 | - | ||
| 334 | - /** | ||
| 335 | - * Duration between the checks when acquiring a lock. | ||
| 336 | - */ | ||
| 337 | - protected Duration lockPollRate = Duration.ofSeconds(10); | ||
| 338 | - | ||
| 339 | - /** | ||
| 340 | - * Duration to wait for the DB Schema lock before giving up. | ||
| 341 | - */ | ||
| 342 | - protected Duration schemaLockWaitTime = Duration.ofMinutes(5); | ||
| 343 | - | ||
| 344 | - // DATA MANAGERS ////////////////////////////////////////////////////////////////// | ||
| 345 | - | ||
| 346 | - protected PropertyDataManager propertyDataManager; | ||
| 347 | - protected ByteArrayDataManager byteArrayDataManager; | ||
| 348 | - protected TableDataManager tableDataManager; | ||
| 349 | - | ||
| 350 | - // ENTITY MANAGERS //////////////////////////////////////////////////////////////// | ||
| 351 | - | ||
| 352 | - protected PropertyEntityManager propertyEntityManager; | ||
| 353 | - protected ByteArrayEntityManager byteArrayEntityManager; | ||
| 354 | - | ||
| 355 | - protected List<EngineDeployer> customPreDeployers; | ||
| 356 | - protected List<EngineDeployer> customPostDeployers; | ||
| 357 | - protected List<EngineDeployer> deployers; | ||
| 358 | - | ||
| 359 | - // CONFIGURATORS //////////////////////////////////////////////////////////// | ||
| 360 | - | ||
| 361 | - protected boolean enableConfiguratorServiceLoader = true; // Enabled by default. In certain environments this should be set to false (eg osgi) | ||
| 362 | - protected List<EngineConfigurator> configurators; // The injected configurators | ||
| 363 | - protected List<EngineConfigurator> allConfigurators; // Including auto-discovered configurators | ||
| 364 | - protected EngineConfigurator idmEngineConfigurator; | ||
| 365 | - protected EngineConfigurator eventRegistryConfigurator; | ||
| 366 | - | ||
| 367 | - public static final String PRODUCT_NAME_POSTGRES = "PostgreSQL"; | ||
| 368 | - public static final String PRODUCT_NAME_CRDB = "CockroachDB"; | ||
| 369 | - | ||
| 370 | - public static final String DATABASE_TYPE_H2 = "h2"; | ||
| 371 | - public static final String DATABASE_TYPE_HSQL = "hsql"; | ||
| 372 | - public static final String DATABASE_TYPE_MYSQL = "mysql"; | ||
| 373 | - public static final String DATABASE_TYPE_ORACLE = "oracle"; | ||
| 374 | - public static final String DATABASE_TYPE_POSTGRES = "postgres"; | ||
| 375 | - public static final String DATABASE_TYPE_MSSQL = "mssql"; | ||
| 376 | - public static final String DATABASE_TYPE_DB2 = "db2"; | ||
| 377 | - public static final String DATABASE_TYPE_COCKROACHDB = "cockroachdb"; | ||
| 378 | - | ||
| 379 | - public static Properties getDefaultDatabaseTypeMappings() { | ||
| 380 | - Properties databaseTypeMappings = new Properties(); | ||
| 381 | - databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2); | ||
| 382 | - databaseTypeMappings.setProperty("HSQL Database Engine", DATABASE_TYPE_HSQL); | ||
| 383 | - databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL); | ||
| 384 | - databaseTypeMappings.setProperty("MariaDB", DATABASE_TYPE_MYSQL); | ||
| 385 | - databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE); | ||
| 386 | - databaseTypeMappings.setProperty(PRODUCT_NAME_POSTGRES, DATABASE_TYPE_POSTGRES); | ||
| 387 | - databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL); | ||
| 388 | - databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2); | ||
| 389 | - databaseTypeMappings.setProperty("DB2", DATABASE_TYPE_DB2); | ||
| 390 | - databaseTypeMappings.setProperty("DB2/NT", DATABASE_TYPE_DB2); | ||
| 391 | - databaseTypeMappings.setProperty("DB2/NT64", DATABASE_TYPE_DB2); | ||
| 392 | - databaseTypeMappings.setProperty("DB2 UDP", DATABASE_TYPE_DB2); | ||
| 393 | - databaseTypeMappings.setProperty("DB2/LINUX", DATABASE_TYPE_DB2); | ||
| 394 | - databaseTypeMappings.setProperty("DB2/LINUX390", DATABASE_TYPE_DB2); | ||
| 395 | - databaseTypeMappings.setProperty("DB2/LINUXX8664", DATABASE_TYPE_DB2); | ||
| 396 | - databaseTypeMappings.setProperty("DB2/LINUXZ64", DATABASE_TYPE_DB2); | ||
| 397 | - databaseTypeMappings.setProperty("DB2/LINUXPPC64", DATABASE_TYPE_DB2); | ||
| 398 | - databaseTypeMappings.setProperty("DB2/LINUXPPC64LE", DATABASE_TYPE_DB2); | ||
| 399 | - databaseTypeMappings.setProperty("DB2/400 SQL", DATABASE_TYPE_DB2); | ||
| 400 | - databaseTypeMappings.setProperty("DB2/6000", DATABASE_TYPE_DB2); | ||
| 401 | - databaseTypeMappings.setProperty("DB2 UDB iSeries", DATABASE_TYPE_DB2); | ||
| 402 | - databaseTypeMappings.setProperty("DB2/AIX64", DATABASE_TYPE_DB2); | ||
| 403 | - databaseTypeMappings.setProperty("DB2/HPUX", DATABASE_TYPE_DB2); | ||
| 404 | - databaseTypeMappings.setProperty("DB2/HP64", DATABASE_TYPE_DB2); | ||
| 405 | - databaseTypeMappings.setProperty("DB2/SUN", DATABASE_TYPE_DB2); | ||
| 406 | - databaseTypeMappings.setProperty("DB2/SUN64", DATABASE_TYPE_DB2); | ||
| 407 | - databaseTypeMappings.setProperty("DB2/PTX", DATABASE_TYPE_DB2); | ||
| 408 | - databaseTypeMappings.setProperty("DB2/2", DATABASE_TYPE_DB2); | ||
| 409 | - databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2); | ||
| 410 | - databaseTypeMappings.setProperty(PRODUCT_NAME_CRDB, DATABASE_TYPE_COCKROACHDB); | ||
| 411 | - databaseTypeMappings.setProperty("DM DBMS", DATABASE_TYPE_ORACLE); // dhb52: DM support | ||
| 412 | - return databaseTypeMappings; | ||
| 413 | - } | ||
| 414 | - | ||
| 415 | - protected Map<Object, Object> beans; | ||
| 416 | - | ||
| 417 | - protected IdGenerator idGenerator; | ||
| 418 | - protected boolean usePrefixId; | ||
| 419 | - | ||
| 420 | - protected Clock clock; | ||
| 421 | - protected ObjectMapper objectMapper; | ||
| 422 | - | ||
| 423 | - // Variables | ||
| 424 | - | ||
| 425 | - public static final int DEFAULT_GENERIC_MAX_LENGTH_STRING = 4000; | ||
| 426 | - public static final int DEFAULT_ORACLE_MAX_LENGTH_STRING = 2000; | ||
| 427 | - | ||
| 428 | - /** | ||
| 429 | - * Define a max length for storing String variable types in the database. Mainly used for the Oracle NVARCHAR2 limit of 2000 characters | ||
| 430 | - */ | ||
| 431 | - protected int maxLengthStringVariableType = -1; | ||
| 432 | - | ||
| 433 | - protected void initEngineConfigurations() { | ||
| 434 | - addEngineConfiguration(getEngineCfgKey(), getEngineScopeType(), this); | ||
| 435 | - } | ||
| 436 | - | ||
| 437 | - // DataSource | ||
| 438 | - // /////////////////////////////////////////////////////////////// | ||
| 439 | - | ||
| 440 | - protected void initDataSource() { | ||
| 441 | - if (dataSource == null) { | ||
| 442 | - if (dataSourceJndiName != null) { | ||
| 443 | - try { | ||
| 444 | - dataSource = (DataSource) new InitialContext().lookup(dataSourceJndiName); | ||
| 445 | - } catch (Exception e) { | ||
| 446 | - throw new FlowableException("couldn't lookup datasource from " + dataSourceJndiName + ": " + e.getMessage(), e); | ||
| 447 | - } | ||
| 448 | - | ||
| 449 | - } else if (jdbcUrl != null) { | ||
| 450 | - if ((jdbcDriver == null) || (jdbcUsername == null)) { | ||
| 451 | - throw new FlowableException("DataSource or JDBC properties have to be specified in a process engine configuration"); | ||
| 452 | - } | ||
| 453 | - | ||
| 454 | - logger.debug("initializing datasource to db: {}", jdbcUrl); | ||
| 455 | - | ||
| 456 | - if (logger.isInfoEnabled()) { | ||
| 457 | - logger.info("Configuring Datasource with following properties (omitted password for security)"); | ||
| 458 | - logger.info("datasource driver : {}", jdbcDriver); | ||
| 459 | - logger.info("datasource url : {}", jdbcUrl); | ||
| 460 | - logger.info("datasource user name : {}", jdbcUsername); | ||
| 461 | - } | ||
| 462 | - | ||
| 463 | - PooledDataSource pooledDataSource = new PooledDataSource(this.getClass().getClassLoader(), jdbcDriver, jdbcUrl, jdbcUsername, jdbcPassword); | ||
| 464 | - | ||
| 465 | - if (jdbcMaxActiveConnections > 0) { | ||
| 466 | - pooledDataSource.setPoolMaximumActiveConnections(jdbcMaxActiveConnections); | ||
| 467 | - } | ||
| 468 | - if (jdbcMaxIdleConnections > 0) { | ||
| 469 | - pooledDataSource.setPoolMaximumIdleConnections(jdbcMaxIdleConnections); | ||
| 470 | - } | ||
| 471 | - if (jdbcMaxCheckoutTime > 0) { | ||
| 472 | - pooledDataSource.setPoolMaximumCheckoutTime(jdbcMaxCheckoutTime); | ||
| 473 | - } | ||
| 474 | - if (jdbcMaxWaitTime > 0) { | ||
| 475 | - pooledDataSource.setPoolTimeToWait(jdbcMaxWaitTime); | ||
| 476 | - } | ||
| 477 | - if (jdbcPingEnabled) { | ||
| 478 | - pooledDataSource.setPoolPingEnabled(true); | ||
| 479 | - if (jdbcPingQuery != null) { | ||
| 480 | - pooledDataSource.setPoolPingQuery(jdbcPingQuery); | ||
| 481 | - } | ||
| 482 | - pooledDataSource.setPoolPingConnectionsNotUsedFor(jdbcPingConnectionNotUsedFor); | ||
| 483 | - } | ||
| 484 | - if (jdbcDefaultTransactionIsolationLevel > 0) { | ||
| 485 | - pooledDataSource.setDefaultTransactionIsolationLevel(jdbcDefaultTransactionIsolationLevel); | ||
| 486 | - } | ||
| 487 | - dataSource = pooledDataSource; | ||
| 488 | - } | ||
| 489 | - } | ||
| 490 | - | ||
| 491 | - if (databaseType == null) { | ||
| 492 | - initDatabaseType(); | ||
| 493 | - } | ||
| 494 | - } | ||
| 495 | - | ||
| 496 | - public void initDatabaseType() { | ||
| 497 | - Connection connection = null; | ||
| 498 | - try { | ||
| 499 | - connection = dataSource.getConnection(); | ||
| 500 | - DatabaseMetaData databaseMetaData = connection.getMetaData(); | ||
| 501 | - String databaseProductName = databaseMetaData.getDatabaseProductName(); | ||
| 502 | - logger.debug("database product name: '{}'", databaseProductName); | ||
| 503 | - | ||
| 504 | - // CRDB does not expose the version through the jdbc driver, so we need to fetch it through version(). | ||
| 505 | - if (PRODUCT_NAME_POSTGRES.equalsIgnoreCase(databaseProductName)) { | ||
| 506 | - try (PreparedStatement preparedStatement = connection.prepareStatement("select version() as version;"); | ||
| 507 | - ResultSet resultSet = preparedStatement.executeQuery()) { | ||
| 508 | - String version = null; | ||
| 509 | - if (resultSet.next()) { | ||
| 510 | - version = resultSet.getString("version"); | ||
| 511 | - } | ||
| 512 | - | ||
| 513 | - if (StringUtils.isNotEmpty(version) && version.toLowerCase().startsWith(PRODUCT_NAME_CRDB.toLowerCase())) { | ||
| 514 | - databaseProductName = PRODUCT_NAME_CRDB; | ||
| 515 | - logger.info("CockroachDB version '{}' detected", version); | ||
| 516 | - } | ||
| 517 | - } | ||
| 518 | - } | ||
| 519 | - | ||
| 520 | - databaseType = databaseTypeMappings.getProperty(databaseProductName); | ||
| 521 | - if (databaseType == null) { | ||
| 522 | - throw new FlowableException("couldn't deduct database type from database product name '" + databaseProductName + "'"); | ||
| 523 | - } | ||
| 524 | - logger.debug("using database type: {}", databaseType); | ||
| 525 | - | ||
| 526 | - } catch (SQLException e) { | ||
| 527 | - throw new RuntimeException("Exception while initializing Database connection", e); | ||
| 528 | - } finally { | ||
| 529 | - try { | ||
| 530 | - if (connection != null) { | ||
| 531 | - connection.close(); | ||
| 532 | - } | ||
| 533 | - } catch (SQLException e) { | ||
| 534 | - logger.error("Exception while closing the Database connection", e); | ||
| 535 | - } | ||
| 536 | - } | ||
| 537 | - | ||
| 538 | - // Special care for MSSQL, as it has a hard limit of 2000 params per statement (incl bulk statement). | ||
| 539 | - // Especially with executions, with 100 as default, this limit is passed. | ||
| 540 | - if (DATABASE_TYPE_MSSQL.equals(databaseType)) { | ||
| 541 | - maxNrOfStatementsInBulkInsert = DEFAULT_MAX_NR_OF_STATEMENTS_BULK_INSERT_SQL_SERVER; | ||
| 542 | - } | ||
| 543 | - } | ||
| 544 | - | ||
| 545 | - public void initSchemaManager() { | ||
| 546 | - if (this.commonSchemaManager == null) { | ||
| 547 | - this.commonSchemaManager = new CommonDbSchemaManager(); | ||
| 548 | - } | ||
| 549 | - } | ||
| 550 | - | ||
| 551 | - // session factories //////////////////////////////////////////////////////// | ||
| 552 | - | ||
| 553 | - public void addSessionFactory(SessionFactory sessionFactory) { | ||
| 554 | - sessionFactories.put(sessionFactory.getSessionType(), sessionFactory); | ||
| 555 | - } | ||
| 556 | - | ||
| 557 | - public void initCommandContextFactory() { | ||
| 558 | - if (commandContextFactory == null) { | ||
| 559 | - commandContextFactory = new CommandContextFactory(); | ||
| 560 | - } | ||
| 561 | - } | ||
| 562 | - | ||
| 563 | - public void initTransactionContextFactory() { | ||
| 564 | - if (transactionContextFactory == null) { | ||
| 565 | - transactionContextFactory = new StandaloneMybatisTransactionContextFactory(); | ||
| 566 | - } | ||
| 567 | - } | ||
| 568 | - | ||
| 569 | - public void initCommandExecutors() { | ||
| 570 | - initDefaultCommandConfig(); | ||
| 571 | - initSchemaCommandConfig(); | ||
| 572 | - initCommandInvoker(); | ||
| 573 | - initCommandInterceptors(); | ||
| 574 | - initCommandExecutor(); | ||
| 575 | - } | ||
| 576 | - | ||
| 577 | - | ||
| 578 | - public void initDefaultCommandConfig() { | ||
| 579 | - if (defaultCommandConfig == null) { | ||
| 580 | - defaultCommandConfig = new CommandConfig(); | ||
| 581 | - } | ||
| 582 | - } | ||
| 583 | - | ||
| 584 | - public void initSchemaCommandConfig() { | ||
| 585 | - if (schemaCommandConfig == null) { | ||
| 586 | - schemaCommandConfig = new CommandConfig(); | ||
| 587 | - } | ||
| 588 | - } | ||
| 589 | - | ||
| 590 | - public void initCommandInvoker() { | ||
| 591 | - if (commandInvoker == null) { | ||
| 592 | - commandInvoker = new DefaultCommandInvoker(); | ||
| 593 | - } | ||
| 594 | - } | ||
| 595 | - | ||
| 596 | - public void initCommandInterceptors() { | ||
| 597 | - if (commandInterceptors == null) { | ||
| 598 | - commandInterceptors = new ArrayList<>(); | ||
| 599 | - if (customPreCommandInterceptors != null) { | ||
| 600 | - commandInterceptors.addAll(customPreCommandInterceptors); | ||
| 601 | - } | ||
| 602 | - commandInterceptors.addAll(getDefaultCommandInterceptors()); | ||
| 603 | - if (customPostCommandInterceptors != null) { | ||
| 604 | - commandInterceptors.addAll(customPostCommandInterceptors); | ||
| 605 | - } | ||
| 606 | - commandInterceptors.add(commandInvoker); | ||
| 607 | - } | ||
| 608 | - } | ||
| 609 | - | ||
| 610 | - public Collection<? extends CommandInterceptor> getDefaultCommandInterceptors() { | ||
| 611 | - if (defaultCommandInterceptors == null) { | ||
| 612 | - List<CommandInterceptor> interceptors = new ArrayList<>(); | ||
| 613 | - interceptors.add(new LogInterceptor()); | ||
| 614 | - | ||
| 615 | - if (DATABASE_TYPE_COCKROACHDB.equals(databaseType)) { | ||
| 616 | - interceptors.add(new CrDbRetryInterceptor()); | ||
| 617 | - } | ||
| 618 | - | ||
| 619 | - CommandInterceptor transactionInterceptor = createTransactionInterceptor(); | ||
| 620 | - if (transactionInterceptor != null) { | ||
| 621 | - interceptors.add(transactionInterceptor); | ||
| 622 | - } | ||
| 623 | - | ||
| 624 | - if (commandContextFactory != null) { | ||
| 625 | - String engineCfgKey = getEngineCfgKey(); | ||
| 626 | - CommandContextInterceptor commandContextInterceptor = new CommandContextInterceptor(commandContextFactory, | ||
| 627 | - classLoader, useClassForNameClassLoading, clock, objectMapper); | ||
| 628 | - engineConfigurations.put(engineCfgKey, this); | ||
| 629 | - commandContextInterceptor.setEngineCfgKey(engineCfgKey); | ||
| 630 | - commandContextInterceptor.setEngineConfigurations(engineConfigurations); | ||
| 631 | - interceptors.add(commandContextInterceptor); | ||
| 632 | - } | ||
| 633 | - | ||
| 634 | - if (transactionContextFactory != null) { | ||
| 635 | - interceptors.add(new TransactionContextInterceptor(transactionContextFactory)); | ||
| 636 | - } | ||
| 637 | - | ||
| 638 | - List<CommandInterceptor> additionalCommandInterceptors = getAdditionalDefaultCommandInterceptors(); | ||
| 639 | - if (additionalCommandInterceptors != null) { | ||
| 640 | - interceptors.addAll(additionalCommandInterceptors); | ||
| 641 | - } | ||
| 642 | - | ||
| 643 | - defaultCommandInterceptors = interceptors; | ||
| 644 | - } | ||
| 645 | - return defaultCommandInterceptors; | ||
| 646 | - } | ||
| 647 | - | ||
| 648 | - public abstract String getEngineCfgKey(); | ||
| 649 | - | ||
| 650 | - public abstract String getEngineScopeType(); | ||
| 651 | - | ||
| 652 | - public List<CommandInterceptor> getAdditionalDefaultCommandInterceptors() { | ||
| 653 | - return null; | ||
| 654 | - } | ||
| 655 | - | ||
| 656 | - public void initCommandExecutor() { | ||
| 657 | - if (commandExecutor == null) { | ||
| 658 | - CommandInterceptor first = initInterceptorChain(commandInterceptors); | ||
| 659 | - commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first); | ||
| 660 | - } | ||
| 661 | - } | ||
| 662 | - | ||
| 663 | - public CommandInterceptor initInterceptorChain(List<CommandInterceptor> chain) { | ||
| 664 | - if (chain == null || chain.isEmpty()) { | ||
| 665 | - throw new FlowableException("invalid command interceptor chain configuration: " + chain); | ||
| 666 | - } | ||
| 667 | - for (int i = 0; i < chain.size() - 1; i++) { | ||
| 668 | - chain.get(i).setNext(chain.get(i + 1)); | ||
| 669 | - } | ||
| 670 | - return chain.get(0); | ||
| 671 | - } | ||
| 672 | - | ||
| 673 | - public abstract CommandInterceptor createTransactionInterceptor(); | ||
| 674 | - | ||
| 675 | - | ||
| 676 | - public void initBeans() { | ||
| 677 | - if (beans == null) { | ||
| 678 | - beans = new HashMap<>(); | ||
| 679 | - } | ||
| 680 | - } | ||
| 681 | - | ||
| 682 | - // id generator | ||
| 683 | - // ///////////////////////////////////////////////////////////// | ||
| 684 | - | ||
| 685 | - public void initIdGenerator() { | ||
| 686 | - if (idGenerator == null) { | ||
| 687 | - idGenerator = new StrongUuidGenerator(); | ||
| 688 | - } | ||
| 689 | - } | ||
| 690 | - | ||
| 691 | - public void initObjectMapper() { | ||
| 692 | - if (objectMapper == null) { | ||
| 693 | - objectMapper = new ObjectMapper(); | ||
| 694 | - objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); | ||
| 695 | - } | ||
| 696 | - } | ||
| 697 | - | ||
| 698 | - public void initClock() { | ||
| 699 | - if (clock == null) { | ||
| 700 | - clock = new DefaultClockImpl(); | ||
| 701 | - } | ||
| 702 | - } | ||
| 703 | - | ||
| 704 | - // Data managers /////////////////////////////////////////////////////////// | ||
| 705 | - | ||
| 706 | - public void initDataManagers() { | ||
| 707 | - if (propertyDataManager == null) { | ||
| 708 | - propertyDataManager = new MybatisPropertyDataManager(idGenerator); | ||
| 709 | - } | ||
| 710 | - | ||
| 711 | - if (byteArrayDataManager == null) { | ||
| 712 | - byteArrayDataManager = new MybatisByteArrayDataManager(idGenerator); | ||
| 713 | - } | ||
| 714 | - } | ||
| 715 | - | ||
| 716 | - // Entity managers ////////////////////////////////////////////////////////// | ||
| 717 | - | ||
| 718 | - public void initEntityManagers() { | ||
| 719 | - if (propertyEntityManager == null) { | ||
| 720 | - propertyEntityManager = new PropertyEntityManagerImpl(this, propertyDataManager); | ||
| 721 | - } | ||
| 722 | - | ||
| 723 | - if (byteArrayEntityManager == null) { | ||
| 724 | - byteArrayEntityManager = new ByteArrayEntityManagerImpl(byteArrayDataManager, getEngineCfgKey(), this::getEventDispatcher); | ||
| 725 | - } | ||
| 726 | - | ||
| 727 | - if (tableDataManager == null) { | ||
| 728 | - tableDataManager = new TableDataManagerImpl(this); | ||
| 729 | - } | ||
| 730 | - } | ||
| 731 | - | ||
| 732 | - // services | ||
| 733 | - // ///////////////////////////////////////////////////////////////// | ||
| 734 | - | ||
| 735 | - protected void initService(Object service) { | ||
| 736 | - if (service instanceof CommonEngineServiceImpl) { | ||
| 737 | - ((CommonEngineServiceImpl) service).setCommandExecutor(commandExecutor); | ||
| 738 | - } | ||
| 739 | - } | ||
| 740 | - | ||
| 741 | - // myBatis SqlSessionFactory | ||
| 742 | - // //////////////////////////////////////////////// | ||
| 743 | - | ||
| 744 | - public void initSessionFactories() { | ||
| 745 | - if (sessionFactories == null) { | ||
| 746 | - sessionFactories = new HashMap<>(); | ||
| 747 | - | ||
| 748 | - if (usingRelationalDatabase) { | ||
| 749 | - initDbSqlSessionFactory(); | ||
| 750 | - } | ||
| 751 | - | ||
| 752 | - addSessionFactory(new GenericManagerFactory(EntityCache.class, EntityCacheImpl.class)); | ||
| 753 | - | ||
| 754 | - if (isLoggingSessionEnabled()) { | ||
| 755 | - if (!sessionFactories.containsKey(LoggingSession.class)) { | ||
| 756 | - LoggingSessionFactory loggingSessionFactory = new LoggingSessionFactory(); | ||
| 757 | - loggingSessionFactory.setLoggingListener(loggingListener); | ||
| 758 | - loggingSessionFactory.setObjectMapper(objectMapper); | ||
| 759 | - sessionFactories.put(LoggingSession.class, loggingSessionFactory); | ||
| 760 | - } | ||
| 761 | - } | ||
| 762 | - | ||
| 763 | - commandContextFactory.setSessionFactories(sessionFactories); | ||
| 764 | - | ||
| 765 | - } else { | ||
| 766 | - if (usingRelationalDatabase) { | ||
| 767 | - initDbSqlSessionFactoryEntitySettings(); | ||
| 768 | - } | ||
| 769 | - } | ||
| 770 | - | ||
| 771 | - if (customSessionFactories != null) { | ||
| 772 | - for (SessionFactory sessionFactory : customSessionFactories) { | ||
| 773 | - addSessionFactory(sessionFactory); | ||
| 774 | - } | ||
| 775 | - } | ||
| 776 | - } | ||
| 777 | - | ||
| 778 | - public void initDbSqlSessionFactory() { | ||
| 779 | - if (dbSqlSessionFactory == null) { | ||
| 780 | - dbSqlSessionFactory = createDbSqlSessionFactory(); | ||
| 781 | - } | ||
| 782 | - dbSqlSessionFactory.setDatabaseType(databaseType); | ||
| 783 | - dbSqlSessionFactory.setSqlSessionFactory(sqlSessionFactory); | ||
| 784 | - dbSqlSessionFactory.setDbHistoryUsed(isDbHistoryUsed); | ||
| 785 | - dbSqlSessionFactory.setDatabaseTablePrefix(databaseTablePrefix); | ||
| 786 | - dbSqlSessionFactory.setTablePrefixIsSchema(tablePrefixIsSchema); | ||
| 787 | - dbSqlSessionFactory.setDatabaseCatalog(databaseCatalog); | ||
| 788 | - dbSqlSessionFactory.setDatabaseSchema(databaseSchema); | ||
| 789 | - dbSqlSessionFactory.setMaxNrOfStatementsInBulkInsert(maxNrOfStatementsInBulkInsert); | ||
| 790 | - | ||
| 791 | - initDbSqlSessionFactoryEntitySettings(); | ||
| 792 | - | ||
| 793 | - addSessionFactory(dbSqlSessionFactory); | ||
| 794 | - } | ||
| 795 | - | ||
| 796 | - public DbSqlSessionFactory createDbSqlSessionFactory() { | ||
| 797 | - return new DbSqlSessionFactory(usePrefixId); | ||
| 798 | - } | ||
| 799 | - | ||
| 800 | - protected abstract void initDbSqlSessionFactoryEntitySettings(); | ||
| 801 | - | ||
| 802 | - protected void defaultInitDbSqlSessionFactoryEntitySettings(List<Class<? extends Entity>> insertOrder, List<Class<? extends Entity>> deleteOrder) { | ||
| 803 | - if (insertOrder != null) { | ||
| 804 | - for (Class<? extends Entity> clazz : insertOrder) { | ||
| 805 | - dbSqlSessionFactory.getInsertionOrder().add(clazz); | ||
| 806 | - | ||
| 807 | - if (isBulkInsertEnabled) { | ||
| 808 | - dbSqlSessionFactory.getBulkInserteableEntityClasses().add(clazz); | ||
| 809 | - } | ||
| 810 | - } | ||
| 811 | - } | ||
| 812 | - | ||
| 813 | - if (deleteOrder != null) { | ||
| 814 | - for (Class<? extends Entity> clazz : deleteOrder) { | ||
| 815 | - dbSqlSessionFactory.getDeletionOrder().add(clazz); | ||
| 816 | - } | ||
| 817 | - } | ||
| 818 | - } | ||
| 819 | - | ||
| 820 | - public void initTransactionFactory() { | ||
| 821 | - if (transactionFactory == null) { | ||
| 822 | - if (transactionsExternallyManaged) { | ||
| 823 | - transactionFactory = new ManagedTransactionFactory(); | ||
| 824 | - Properties properties = new Properties(); | ||
| 825 | - properties.put("closeConnection", "false"); | ||
| 826 | - this.transactionFactory.setProperties(properties); | ||
| 827 | - } else { | ||
| 828 | - transactionFactory = new JdbcTransactionFactory(); | ||
| 829 | - } | ||
| 830 | - } | ||
| 831 | - } | ||
| 832 | - | ||
| 833 | - public void initSqlSessionFactory() { | ||
| 834 | - if (sqlSessionFactory == null) { | ||
| 835 | - InputStream inputStream = null; | ||
| 836 | - try { | ||
| 837 | - inputStream = getMyBatisXmlConfigurationStream(); | ||
| 838 | - | ||
| 839 | - Environment environment = new Environment("default", transactionFactory, dataSource); | ||
| 840 | - Reader reader = new InputStreamReader(inputStream); | ||
| 841 | - Properties properties = new Properties(); | ||
| 842 | - properties.put("prefix", databaseTablePrefix); | ||
| 843 | - | ||
| 844 | - String wildcardEscapeClause = ""; | ||
| 845 | - if ((databaseWildcardEscapeCharacter != null) && (databaseWildcardEscapeCharacter.length() != 0)) { | ||
| 846 | - wildcardEscapeClause = " escape '" + databaseWildcardEscapeCharacter + "'"; | ||
| 847 | - } | ||
| 848 | - properties.put("wildcardEscapeClause", wildcardEscapeClause); | ||
| 849 | - | ||
| 850 | - // set default properties | ||
| 851 | - properties.put("limitBefore", ""); | ||
| 852 | - properties.put("limitAfter", ""); | ||
| 853 | - properties.put("limitBetween", ""); | ||
| 854 | - properties.put("limitBeforeNativeQuery", ""); | ||
| 855 | - properties.put("limitAfterNativeQuery", ""); | ||
| 856 | - properties.put("blobType", "BLOB"); | ||
| 857 | - properties.put("boolValue", "TRUE"); | ||
| 858 | - | ||
| 859 | - if (databaseType != null) { | ||
| 860 | - properties.load(getResourceAsStream(pathToEngineDbProperties())); | ||
| 861 | - } | ||
| 862 | - | ||
| 863 | - Configuration configuration = initMybatisConfiguration(environment, reader, properties); | ||
| 864 | - sqlSessionFactory = new DefaultSqlSessionFactory(configuration); | ||
| 865 | - | ||
| 866 | - } catch (Exception e) { | ||
| 867 | - throw new FlowableException("Error while building ibatis SqlSessionFactory: " + e.getMessage(), e); | ||
| 868 | - } finally { | ||
| 869 | - IoUtil.closeSilently(inputStream); | ||
| 870 | - } | ||
| 871 | - } else { | ||
| 872 | - // This is needed when the SQL Session Factory is created by another engine. | ||
| 873 | - // When custom XML Mappers are registered with this engine they need to be loaded in the configuration as well | ||
| 874 | - applyCustomMybatisCustomizations(sqlSessionFactory.getConfiguration()); | ||
| 875 | - } | ||
| 876 | - } | ||
| 877 | - | ||
| 878 | - public String pathToEngineDbProperties() { | ||
| 879 | - return "org/flowable/common/db/properties/" + databaseType + ".properties"; | ||
| 880 | - } | ||
| 881 | - | ||
| 882 | - public Configuration initMybatisConfiguration(Environment environment, Reader reader, Properties properties) { | ||
| 883 | - XMLConfigBuilder parser = new XMLConfigBuilder(reader, "", properties); | ||
| 884 | - Configuration configuration = parser.getConfiguration(); | ||
| 885 | - | ||
| 886 | - if (databaseType != null) { | ||
| 887 | - configuration.setDatabaseId(databaseType); | ||
| 888 | - } | ||
| 889 | - | ||
| 890 | - configuration.setEnvironment(environment); | ||
| 891 | - | ||
| 892 | - initMybatisTypeHandlers(configuration); | ||
| 893 | - initCustomMybatisInterceptors(configuration); | ||
| 894 | - if (isEnableLogSqlExecutionTime()) { | ||
| 895 | - initMyBatisLogSqlExecutionTimePlugin(configuration); | ||
| 896 | - } | ||
| 897 | - | ||
| 898 | - configuration = parseMybatisConfiguration(parser); | ||
| 899 | - return configuration; | ||
| 900 | - } | ||
| 901 | - | ||
| 902 | - public void initCustomMybatisMappers(Configuration configuration) { | ||
| 903 | - if (getCustomMybatisMappers() != null) { | ||
| 904 | - for (Class<?> clazz : getCustomMybatisMappers()) { | ||
| 905 | - if (!configuration.hasMapper(clazz)) { | ||
| 906 | - configuration.addMapper(clazz); | ||
| 907 | - } | ||
| 908 | - } | ||
| 909 | - } | ||
| 910 | - } | ||
| 911 | - | ||
| 912 | - public void initMybatisTypeHandlers(Configuration configuration) { | ||
| 913 | - // When mapping into Map<String, Object> there is currently a problem with MyBatis. | ||
| 914 | - // It will return objects which are driver specific. | ||
| 915 | - // Therefore we are registering the mappings between Object.class and the specific jdbc type here. | ||
| 916 | - // see https://github.com/mybatis/mybatis-3/issues/2216 for more info | ||
| 917 | - TypeHandlerRegistry handlerRegistry = configuration.getTypeHandlerRegistry(); | ||
| 918 | - | ||
| 919 | - handlerRegistry.register(Object.class, JdbcType.BOOLEAN, new BooleanTypeHandler()); | ||
| 920 | - handlerRegistry.register(Object.class, JdbcType.BIT, new BooleanTypeHandler()); | ||
| 921 | - | ||
| 922 | - handlerRegistry.register(Object.class, JdbcType.TINYINT, new ByteTypeHandler()); | ||
| 923 | - | ||
| 924 | - handlerRegistry.register(Object.class, JdbcType.SMALLINT, new ShortTypeHandler()); | ||
| 925 | - | ||
| 926 | - handlerRegistry.register(Object.class, JdbcType.INTEGER, new IntegerTypeHandler()); | ||
| 927 | - | ||
| 928 | - handlerRegistry.register(Object.class, JdbcType.FLOAT, new FloatTypeHandler()); | ||
| 929 | - | ||
| 930 | - handlerRegistry.register(Object.class, JdbcType.DOUBLE, new DoubleTypeHandler()); | ||
| 931 | - | ||
| 932 | - handlerRegistry.register(Object.class, JdbcType.CHAR, new StringTypeHandler()); | ||
| 933 | - handlerRegistry.register(Object.class, JdbcType.CLOB, new ClobTypeHandler()); | ||
| 934 | - handlerRegistry.register(Object.class, JdbcType.VARCHAR, new StringTypeHandler()); | ||
| 935 | - handlerRegistry.register(Object.class, JdbcType.LONGVARCHAR, new StringTypeHandler()); | ||
| 936 | - handlerRegistry.register(Object.class, JdbcType.NVARCHAR, new NStringTypeHandler()); | ||
| 937 | - handlerRegistry.register(Object.class, JdbcType.NCHAR, new NStringTypeHandler()); | ||
| 938 | - handlerRegistry.register(Object.class, JdbcType.NCLOB, new NClobTypeHandler()); | ||
| 939 | - | ||
| 940 | - handlerRegistry.register(Object.class, JdbcType.ARRAY, new ArrayTypeHandler()); | ||
| 941 | - | ||
| 942 | - handlerRegistry.register(Object.class, JdbcType.BIGINT, new LongTypeHandler()); | ||
| 943 | - | ||
| 944 | - handlerRegistry.register(Object.class, JdbcType.REAL, new BigDecimalTypeHandler()); | ||
| 945 | - handlerRegistry.register(Object.class, JdbcType.DECIMAL, new BigDecimalTypeHandler()); | ||
| 946 | - handlerRegistry.register(Object.class, JdbcType.NUMERIC, new BigDecimalTypeHandler()); | ||
| 947 | - | ||
| 948 | - handlerRegistry.register(Object.class, JdbcType.BLOB, new BlobInputStreamTypeHandler()); | ||
| 949 | - handlerRegistry.register(Object.class, JdbcType.LONGVARBINARY, new BlobTypeHandler()); | ||
| 950 | - | ||
| 951 | - handlerRegistry.register(Object.class, JdbcType.DATE, new DateOnlyTypeHandler()); | ||
| 952 | - handlerRegistry.register(Object.class, JdbcType.TIME, new TimeOnlyTypeHandler()); | ||
| 953 | - handlerRegistry.register(Object.class, JdbcType.TIMESTAMP, new DateTypeHandler()); | ||
| 954 | - | ||
| 955 | - handlerRegistry.register(Object.class, JdbcType.SQLXML, new SqlxmlTypeHandler()); | ||
| 956 | - } | ||
| 957 | - | ||
| 958 | - public void initCustomMybatisInterceptors(Configuration configuration) { | ||
| 959 | - if (customMybatisInterceptors!=null){ | ||
| 960 | - for (Interceptor interceptor :customMybatisInterceptors){ | ||
| 961 | - configuration.addInterceptor(interceptor); | ||
| 962 | - } | ||
| 963 | - } | ||
| 964 | - } | ||
| 965 | - | ||
| 966 | - public void initMyBatisLogSqlExecutionTimePlugin(Configuration configuration) { | ||
| 967 | - configuration.addInterceptor(new LogSqlExecutionTimePlugin()); | ||
| 968 | - } | ||
| 969 | - | ||
| 970 | - public Configuration parseMybatisConfiguration(XMLConfigBuilder parser) { | ||
| 971 | - Configuration configuration = parser.parse(); | ||
| 972 | - | ||
| 973 | - applyCustomMybatisCustomizations(configuration); | ||
| 974 | - return configuration; | ||
| 975 | - } | ||
| 976 | - | ||
| 977 | - protected void applyCustomMybatisCustomizations(Configuration configuration) { | ||
| 978 | - initCustomMybatisMappers(configuration); | ||
| 979 | - | ||
| 980 | - if (dependentEngineMybatisTypeAliasConfigs != null) { | ||
| 981 | - for (MybatisTypeAliasConfigurator typeAliasConfig : dependentEngineMybatisTypeAliasConfigs) { | ||
| 982 | - typeAliasConfig.configure(configuration.getTypeAliasRegistry()); | ||
| 983 | - } | ||
| 984 | - } | ||
| 985 | - if (dependentEngineMybatisTypeHandlerConfigs != null) { | ||
| 986 | - for (MybatisTypeHandlerConfigurator typeHandlerConfig : dependentEngineMybatisTypeHandlerConfigs) { | ||
| 987 | - typeHandlerConfig.configure(configuration.getTypeHandlerRegistry()); | ||
| 988 | - } | ||
| 989 | - } | ||
| 990 | - | ||
| 991 | - parseDependentEngineMybatisXMLMappers(configuration); | ||
| 992 | - parseCustomMybatisXMLMappers(configuration); | ||
| 993 | - } | ||
| 994 | - | ||
| 995 | - public void parseCustomMybatisXMLMappers(Configuration configuration) { | ||
| 996 | - if (getCustomMybatisXMLMappers() != null) { | ||
| 997 | - for (String resource : getCustomMybatisXMLMappers()) { | ||
| 998 | - parseMybatisXmlMapping(configuration, resource); | ||
| 999 | - } | ||
| 1000 | - } | ||
| 1001 | - } | ||
| 1002 | - | ||
| 1003 | - public void parseDependentEngineMybatisXMLMappers(Configuration configuration) { | ||
| 1004 | - if (getDependentEngineMyBatisXmlMappers() != null) { | ||
| 1005 | - for (String resource : getDependentEngineMyBatisXmlMappers()) { | ||
| 1006 | - parseMybatisXmlMapping(configuration, resource); | ||
| 1007 | - } | ||
| 1008 | - } | ||
| 1009 | - } | ||
| 1010 | - | ||
| 1011 | - protected void parseMybatisXmlMapping(Configuration configuration, String resource) { | ||
| 1012 | - // see XMLConfigBuilder.mapperElement() | ||
| 1013 | - XMLMapperBuilder mapperParser = new XMLMapperBuilder(getResourceAsStream(resource), configuration, resource, configuration.getSqlFragments()); | ||
| 1014 | - mapperParser.parse(); | ||
| 1015 | - } | ||
| 1016 | - | ||
| 1017 | - protected InputStream getResourceAsStream(String resource) { | ||
| 1018 | - ClassLoader classLoader = getClassLoader(); | ||
| 1019 | - if (classLoader != null) { | ||
| 1020 | - return getClassLoader().getResourceAsStream(resource); | ||
| 1021 | - } else { | ||
| 1022 | - return this.getClass().getClassLoader().getResourceAsStream(resource); | ||
| 1023 | - } | ||
| 1024 | - } | ||
| 1025 | - | ||
| 1026 | - public void setMybatisMappingFile(String file) { | ||
| 1027 | - this.mybatisMappingFile = file; | ||
| 1028 | - } | ||
| 1029 | - | ||
| 1030 | - public String getMybatisMappingFile() { | ||
| 1031 | - return mybatisMappingFile; | ||
| 1032 | - } | ||
| 1033 | - | ||
| 1034 | - public abstract InputStream getMyBatisXmlConfigurationStream(); | ||
| 1035 | - | ||
| 1036 | - public void initConfigurators() { | ||
| 1037 | - | ||
| 1038 | - allConfigurators = new ArrayList<>(); | ||
| 1039 | - allConfigurators.addAll(getEngineSpecificEngineConfigurators()); | ||
| 1040 | - | ||
| 1041 | - // Configurators that are explicitly added to the config | ||
| 1042 | - if (configurators != null) { | ||
| 1043 | - allConfigurators.addAll(configurators); | ||
| 1044 | - } | ||
| 1045 | - | ||
| 1046 | - // Auto discovery through ServiceLoader | ||
| 1047 | - if (enableConfiguratorServiceLoader) { | ||
| 1048 | - ClassLoader classLoader = getClassLoader(); | ||
| 1049 | - if (classLoader == null) { | ||
| 1050 | - classLoader = ReflectUtil.getClassLoader(); | ||
| 1051 | - } | ||
| 1052 | - | ||
| 1053 | - ServiceLoader<EngineConfigurator> configuratorServiceLoader = ServiceLoader.load(EngineConfigurator.class, classLoader); | ||
| 1054 | - int nrOfServiceLoadedConfigurators = 0; | ||
| 1055 | - for (EngineConfigurator configurator : configuratorServiceLoader) { | ||
| 1056 | - allConfigurators.add(configurator); | ||
| 1057 | - nrOfServiceLoadedConfigurators++; | ||
| 1058 | - } | ||
| 1059 | - | ||
| 1060 | - if (nrOfServiceLoadedConfigurators > 0) { | ||
| 1061 | - logger.info("Found {} auto-discoverable Process Engine Configurator{}", nrOfServiceLoadedConfigurators, nrOfServiceLoadedConfigurators > 1 ? "s" : ""); | ||
| 1062 | - } | ||
| 1063 | - | ||
| 1064 | - if (!allConfigurators.isEmpty()) { | ||
| 1065 | - | ||
| 1066 | - // Order them according to the priorities (useful for dependent | ||
| 1067 | - // configurator) | ||
| 1068 | - allConfigurators.sort(new Comparator<EngineConfigurator>() { | ||
| 1069 | - | ||
| 1070 | - @Override | ||
| 1071 | - public int compare(EngineConfigurator configurator1, EngineConfigurator configurator2) { | ||
| 1072 | - int priority1 = configurator1.getPriority(); | ||
| 1073 | - int priority2 = configurator2.getPriority(); | ||
| 1074 | - | ||
| 1075 | - if (priority1 < priority2) { | ||
| 1076 | - return -1; | ||
| 1077 | - } else if (priority1 > priority2) { | ||
| 1078 | - return 1; | ||
| 1079 | - } | ||
| 1080 | - return 0; | ||
| 1081 | - } | ||
| 1082 | - }); | ||
| 1083 | - | ||
| 1084 | - // Execute the configurators | ||
| 1085 | - logger.info("Found {} Engine Configurators in total:", allConfigurators.size()); | ||
| 1086 | - for (EngineConfigurator configurator : allConfigurators) { | ||
| 1087 | - logger.info("{} (priority:{})", configurator.getClass(), configurator.getPriority()); | ||
| 1088 | - } | ||
| 1089 | - | ||
| 1090 | - } | ||
| 1091 | - | ||
| 1092 | - } | ||
| 1093 | - } | ||
| 1094 | - | ||
| 1095 | - public void close() { | ||
| 1096 | - if (forceCloseMybatisConnectionPool && dataSource instanceof PooledDataSource) { | ||
| 1097 | - /* | ||
| 1098 | - * When the datasource is created by a Flowable engine (i.e. it's an instance of PooledDataSource), | ||
| 1099 | - * the connection pool needs to be closed when closing the engine. | ||
| 1100 | - * Note that calling forceCloseAll() multiple times (as is the case when running with multiple engine) is ok. | ||
| 1101 | - */ | ||
| 1102 | - ((PooledDataSource) dataSource).forceCloseAll(); | ||
| 1103 | - } | ||
| 1104 | - } | ||
| 1105 | - | ||
| 1106 | - protected List<EngineConfigurator> getEngineSpecificEngineConfigurators() { | ||
| 1107 | - // meant to be overridden if needed | ||
| 1108 | - return Collections.emptyList(); | ||
| 1109 | - } | ||
| 1110 | - | ||
| 1111 | - public void configuratorsBeforeInit() { | ||
| 1112 | - for (EngineConfigurator configurator : allConfigurators) { | ||
| 1113 | - logger.info("Executing beforeInit() of {} (priority:{})", configurator.getClass(), configurator.getPriority()); | ||
| 1114 | - configurator.beforeInit(this); | ||
| 1115 | - } | ||
| 1116 | - } | ||
| 1117 | - | ||
| 1118 | - public void configuratorsAfterInit() { | ||
| 1119 | - for (EngineConfigurator configurator : allConfigurators) { | ||
| 1120 | - logger.info("Executing configure() of {} (priority:{})", configurator.getClass(), configurator.getPriority()); | ||
| 1121 | - configurator.configure(this); | ||
| 1122 | - } | ||
| 1123 | - } | ||
| 1124 | - | ||
| 1125 | - public LockManager getLockManager(String lockName) { | ||
| 1126 | - return new LockManagerImpl(commandExecutor, lockName, getLockPollRate(), getEngineCfgKey()); | ||
| 1127 | - } | ||
| 1128 | - | ||
| 1129 | - // getters and setters | ||
| 1130 | - // ////////////////////////////////////////////////////// | ||
| 1131 | - | ||
| 1132 | - public abstract String getEngineName(); | ||
| 1133 | - | ||
| 1134 | - public ClassLoader getClassLoader() { | ||
| 1135 | - return classLoader; | ||
| 1136 | - } | ||
| 1137 | - | ||
| 1138 | - public AbstractEngineConfiguration setClassLoader(ClassLoader classLoader) { | ||
| 1139 | - this.classLoader = classLoader; | ||
| 1140 | - return this; | ||
| 1141 | - } | ||
| 1142 | - | ||
| 1143 | - public boolean isUseClassForNameClassLoading() { | ||
| 1144 | - return useClassForNameClassLoading; | ||
| 1145 | - } | ||
| 1146 | - | ||
| 1147 | - public AbstractEngineConfiguration setUseClassForNameClassLoading(boolean useClassForNameClassLoading) { | ||
| 1148 | - this.useClassForNameClassLoading = useClassForNameClassLoading; | ||
| 1149 | - return this; | ||
| 1150 | - } | ||
| 1151 | - | ||
| 1152 | - public void addEngineLifecycleListener(EngineLifecycleListener engineLifecycleListener) { | ||
| 1153 | - if (this.engineLifecycleListeners == null) { | ||
| 1154 | - this.engineLifecycleListeners = new ArrayList<>(); | ||
| 1155 | - } | ||
| 1156 | - this.engineLifecycleListeners.add(engineLifecycleListener); | ||
| 1157 | - } | ||
| 1158 | - | ||
| 1159 | - public List<EngineLifecycleListener> getEngineLifecycleListeners() { | ||
| 1160 | - return engineLifecycleListeners; | ||
| 1161 | - } | ||
| 1162 | - | ||
| 1163 | - public AbstractEngineConfiguration setEngineLifecycleListeners(List<EngineLifecycleListener> engineLifecycleListeners) { | ||
| 1164 | - this.engineLifecycleListeners = engineLifecycleListeners; | ||
| 1165 | - return this; | ||
| 1166 | - } | ||
| 1167 | - | ||
| 1168 | - public String getDatabaseType() { | ||
| 1169 | - return databaseType; | ||
| 1170 | - } | ||
| 1171 | - | ||
| 1172 | - public AbstractEngineConfiguration setDatabaseType(String databaseType) { | ||
| 1173 | - this.databaseType = databaseType; | ||
| 1174 | - return this; | ||
| 1175 | - } | ||
| 1176 | - | ||
| 1177 | - public DataSource getDataSource() { | ||
| 1178 | - return dataSource; | ||
| 1179 | - } | ||
| 1180 | - | ||
| 1181 | - public AbstractEngineConfiguration setDataSource(DataSource dataSource) { | ||
| 1182 | - this.dataSource = dataSource; | ||
| 1183 | - return this; | ||
| 1184 | - } | ||
| 1185 | - | ||
| 1186 | - public SchemaManager getSchemaManager() { | ||
| 1187 | - return schemaManager; | ||
| 1188 | - } | ||
| 1189 | - | ||
| 1190 | - public AbstractEngineConfiguration setSchemaManager(SchemaManager schemaManager) { | ||
| 1191 | - this.schemaManager = schemaManager; | ||
| 1192 | - return this; | ||
| 1193 | - } | ||
| 1194 | - | ||
| 1195 | - public SchemaManager getCommonSchemaManager() { | ||
| 1196 | - return commonSchemaManager; | ||
| 1197 | - } | ||
| 1198 | - | ||
| 1199 | - public AbstractEngineConfiguration setCommonSchemaManager(SchemaManager commonSchemaManager) { | ||
| 1200 | - this.commonSchemaManager = commonSchemaManager; | ||
| 1201 | - return this; | ||
| 1202 | - } | ||
| 1203 | - | ||
| 1204 | - public Command<Void> getSchemaManagementCmd() { | ||
| 1205 | - return schemaManagementCmd; | ||
| 1206 | - } | ||
| 1207 | - | ||
| 1208 | - public AbstractEngineConfiguration setSchemaManagementCmd(Command<Void> schemaManagementCmd) { | ||
| 1209 | - this.schemaManagementCmd = schemaManagementCmd; | ||
| 1210 | - return this; | ||
| 1211 | - } | ||
| 1212 | - | ||
| 1213 | - public String getJdbcDriver() { | ||
| 1214 | - return jdbcDriver; | ||
| 1215 | - } | ||
| 1216 | - | ||
| 1217 | - public AbstractEngineConfiguration setJdbcDriver(String jdbcDriver) { | ||
| 1218 | - this.jdbcDriver = jdbcDriver; | ||
| 1219 | - return this; | ||
| 1220 | - } | ||
| 1221 | - | ||
| 1222 | - public String getJdbcUrl() { | ||
| 1223 | - return jdbcUrl; | ||
| 1224 | - } | ||
| 1225 | - | ||
| 1226 | - public AbstractEngineConfiguration setJdbcUrl(String jdbcUrl) { | ||
| 1227 | - this.jdbcUrl = jdbcUrl; | ||
| 1228 | - return this; | ||
| 1229 | - } | ||
| 1230 | - | ||
| 1231 | - public String getJdbcUsername() { | ||
| 1232 | - return jdbcUsername; | ||
| 1233 | - } | ||
| 1234 | - | ||
| 1235 | - public AbstractEngineConfiguration setJdbcUsername(String jdbcUsername) { | ||
| 1236 | - this.jdbcUsername = jdbcUsername; | ||
| 1237 | - return this; | ||
| 1238 | - } | ||
| 1239 | - | ||
| 1240 | - public String getJdbcPassword() { | ||
| 1241 | - return jdbcPassword; | ||
| 1242 | - } | ||
| 1243 | - | ||
| 1244 | - public AbstractEngineConfiguration setJdbcPassword(String jdbcPassword) { | ||
| 1245 | - this.jdbcPassword = jdbcPassword; | ||
| 1246 | - return this; | ||
| 1247 | - } | ||
| 1248 | - | ||
| 1249 | - public int getJdbcMaxActiveConnections() { | ||
| 1250 | - return jdbcMaxActiveConnections; | ||
| 1251 | - } | ||
| 1252 | - | ||
| 1253 | - public AbstractEngineConfiguration setJdbcMaxActiveConnections(int jdbcMaxActiveConnections) { | ||
| 1254 | - this.jdbcMaxActiveConnections = jdbcMaxActiveConnections; | ||
| 1255 | - return this; | ||
| 1256 | - } | ||
| 1257 | - | ||
| 1258 | - public int getJdbcMaxIdleConnections() { | ||
| 1259 | - return jdbcMaxIdleConnections; | ||
| 1260 | - } | ||
| 1261 | - | ||
| 1262 | - public AbstractEngineConfiguration setJdbcMaxIdleConnections(int jdbcMaxIdleConnections) { | ||
| 1263 | - this.jdbcMaxIdleConnections = jdbcMaxIdleConnections; | ||
| 1264 | - return this; | ||
| 1265 | - } | ||
| 1266 | - | ||
| 1267 | - public int getJdbcMaxCheckoutTime() { | ||
| 1268 | - return jdbcMaxCheckoutTime; | ||
| 1269 | - } | ||
| 1270 | - | ||
| 1271 | - public AbstractEngineConfiguration setJdbcMaxCheckoutTime(int jdbcMaxCheckoutTime) { | ||
| 1272 | - this.jdbcMaxCheckoutTime = jdbcMaxCheckoutTime; | ||
| 1273 | - return this; | ||
| 1274 | - } | ||
| 1275 | - | ||
| 1276 | - public int getJdbcMaxWaitTime() { | ||
| 1277 | - return jdbcMaxWaitTime; | ||
| 1278 | - } | ||
| 1279 | - | ||
| 1280 | - public AbstractEngineConfiguration setJdbcMaxWaitTime(int jdbcMaxWaitTime) { | ||
| 1281 | - this.jdbcMaxWaitTime = jdbcMaxWaitTime; | ||
| 1282 | - return this; | ||
| 1283 | - } | ||
| 1284 | - | ||
| 1285 | - public boolean isJdbcPingEnabled() { | ||
| 1286 | - return jdbcPingEnabled; | ||
| 1287 | - } | ||
| 1288 | - | ||
| 1289 | - public AbstractEngineConfiguration setJdbcPingEnabled(boolean jdbcPingEnabled) { | ||
| 1290 | - this.jdbcPingEnabled = jdbcPingEnabled; | ||
| 1291 | - return this; | ||
| 1292 | - } | ||
| 1293 | - | ||
| 1294 | - public int getJdbcPingConnectionNotUsedFor() { | ||
| 1295 | - return jdbcPingConnectionNotUsedFor; | ||
| 1296 | - } | ||
| 1297 | - | ||
| 1298 | - public AbstractEngineConfiguration setJdbcPingConnectionNotUsedFor(int jdbcPingConnectionNotUsedFor) { | ||
| 1299 | - this.jdbcPingConnectionNotUsedFor = jdbcPingConnectionNotUsedFor; | ||
| 1300 | - return this; | ||
| 1301 | - } | ||
| 1302 | - | ||
| 1303 | - public int getJdbcDefaultTransactionIsolationLevel() { | ||
| 1304 | - return jdbcDefaultTransactionIsolationLevel; | ||
| 1305 | - } | ||
| 1306 | - | ||
| 1307 | - public AbstractEngineConfiguration setJdbcDefaultTransactionIsolationLevel(int jdbcDefaultTransactionIsolationLevel) { | ||
| 1308 | - this.jdbcDefaultTransactionIsolationLevel = jdbcDefaultTransactionIsolationLevel; | ||
| 1309 | - return this; | ||
| 1310 | - } | ||
| 1311 | - | ||
| 1312 | - public String getJdbcPingQuery() { | ||
| 1313 | - return jdbcPingQuery; | ||
| 1314 | - } | ||
| 1315 | - | ||
| 1316 | - public AbstractEngineConfiguration setJdbcPingQuery(String jdbcPingQuery) { | ||
| 1317 | - this.jdbcPingQuery = jdbcPingQuery; | ||
| 1318 | - return this; | ||
| 1319 | - } | ||
| 1320 | - | ||
| 1321 | - public String getDataSourceJndiName() { | ||
| 1322 | - return dataSourceJndiName; | ||
| 1323 | - } | ||
| 1324 | - | ||
| 1325 | - public AbstractEngineConfiguration setDataSourceJndiName(String dataSourceJndiName) { | ||
| 1326 | - this.dataSourceJndiName = dataSourceJndiName; | ||
| 1327 | - return this; | ||
| 1328 | - } | ||
| 1329 | - | ||
| 1330 | - public CommandConfig getSchemaCommandConfig() { | ||
| 1331 | - return schemaCommandConfig; | ||
| 1332 | - } | ||
| 1333 | - | ||
| 1334 | - public AbstractEngineConfiguration setSchemaCommandConfig(CommandConfig schemaCommandConfig) { | ||
| 1335 | - this.schemaCommandConfig = schemaCommandConfig; | ||
| 1336 | - return this; | ||
| 1337 | - } | ||
| 1338 | - | ||
| 1339 | - public boolean isTransactionsExternallyManaged() { | ||
| 1340 | - return transactionsExternallyManaged; | ||
| 1341 | - } | ||
| 1342 | - | ||
| 1343 | - public AbstractEngineConfiguration setTransactionsExternallyManaged(boolean transactionsExternallyManaged) { | ||
| 1344 | - this.transactionsExternallyManaged = transactionsExternallyManaged; | ||
| 1345 | - return this; | ||
| 1346 | - } | ||
| 1347 | - | ||
| 1348 | - public Map<Object, Object> getBeans() { | ||
| 1349 | - return beans; | ||
| 1350 | - } | ||
| 1351 | - | ||
| 1352 | - public AbstractEngineConfiguration setBeans(Map<Object, Object> beans) { | ||
| 1353 | - this.beans = beans; | ||
| 1354 | - return this; | ||
| 1355 | - } | ||
| 1356 | - | ||
| 1357 | - public IdGenerator getIdGenerator() { | ||
| 1358 | - return idGenerator; | ||
| 1359 | - } | ||
| 1360 | - | ||
| 1361 | - public AbstractEngineConfiguration setIdGenerator(IdGenerator idGenerator) { | ||
| 1362 | - this.idGenerator = idGenerator; | ||
| 1363 | - return this; | ||
| 1364 | - } | ||
| 1365 | - | ||
| 1366 | - public boolean isUsePrefixId() { | ||
| 1367 | - return usePrefixId; | ||
| 1368 | - } | ||
| 1369 | - | ||
| 1370 | - public AbstractEngineConfiguration setUsePrefixId(boolean usePrefixId) { | ||
| 1371 | - this.usePrefixId = usePrefixId; | ||
| 1372 | - return this; | ||
| 1373 | - } | ||
| 1374 | - | ||
| 1375 | - public String getXmlEncoding() { | ||
| 1376 | - return xmlEncoding; | ||
| 1377 | - } | ||
| 1378 | - | ||
| 1379 | - public AbstractEngineConfiguration setXmlEncoding(String xmlEncoding) { | ||
| 1380 | - this.xmlEncoding = xmlEncoding; | ||
| 1381 | - return this; | ||
| 1382 | - } | ||
| 1383 | - | ||
| 1384 | - public CommandConfig getDefaultCommandConfig() { | ||
| 1385 | - return defaultCommandConfig; | ||
| 1386 | - } | ||
| 1387 | - | ||
| 1388 | - public AbstractEngineConfiguration setDefaultCommandConfig(CommandConfig defaultCommandConfig) { | ||
| 1389 | - this.defaultCommandConfig = defaultCommandConfig; | ||
| 1390 | - return this; | ||
| 1391 | - } | ||
| 1392 | - | ||
| 1393 | - public CommandExecutor getCommandExecutor() { | ||
| 1394 | - return commandExecutor; | ||
| 1395 | - } | ||
| 1396 | - | ||
| 1397 | - public AbstractEngineConfiguration setCommandExecutor(CommandExecutor commandExecutor) { | ||
| 1398 | - this.commandExecutor = commandExecutor; | ||
| 1399 | - return this; | ||
| 1400 | - } | ||
| 1401 | - | ||
| 1402 | - public CommandContextFactory getCommandContextFactory() { | ||
| 1403 | - return commandContextFactory; | ||
| 1404 | - } | ||
| 1405 | - | ||
| 1406 | - public AbstractEngineConfiguration setCommandContextFactory(CommandContextFactory commandContextFactory) { | ||
| 1407 | - this.commandContextFactory = commandContextFactory; | ||
| 1408 | - return this; | ||
| 1409 | - } | ||
| 1410 | - | ||
| 1411 | - public CommandInterceptor getCommandInvoker() { | ||
| 1412 | - return commandInvoker; | ||
| 1413 | - } | ||
| 1414 | - | ||
| 1415 | - public AbstractEngineConfiguration setCommandInvoker(CommandInterceptor commandInvoker) { | ||
| 1416 | - this.commandInvoker = commandInvoker; | ||
| 1417 | - return this; | ||
| 1418 | - } | ||
| 1419 | - | ||
| 1420 | - public AgendaOperationRunner getAgendaOperationRunner() { | ||
| 1421 | - return agendaOperationRunner; | ||
| 1422 | - } | ||
| 1423 | - | ||
| 1424 | - public AbstractEngineConfiguration setAgendaOperationRunner(AgendaOperationRunner agendaOperationRunner) { | ||
| 1425 | - this.agendaOperationRunner = agendaOperationRunner; | ||
| 1426 | - return this; | ||
| 1427 | - } | ||
| 1428 | - | ||
| 1429 | - public List<CommandInterceptor> getCustomPreCommandInterceptors() { | ||
| 1430 | - return customPreCommandInterceptors; | ||
| 1431 | - } | ||
| 1432 | - | ||
| 1433 | - public AbstractEngineConfiguration setCustomPreCommandInterceptors(List<CommandInterceptor> customPreCommandInterceptors) { | ||
| 1434 | - this.customPreCommandInterceptors = customPreCommandInterceptors; | ||
| 1435 | - return this; | ||
| 1436 | - } | ||
| 1437 | - | ||
| 1438 | - public List<CommandInterceptor> getCustomPostCommandInterceptors() { | ||
| 1439 | - return customPostCommandInterceptors; | ||
| 1440 | - } | ||
| 1441 | - | ||
| 1442 | - public AbstractEngineConfiguration setCustomPostCommandInterceptors(List<CommandInterceptor> customPostCommandInterceptors) { | ||
| 1443 | - this.customPostCommandInterceptors = customPostCommandInterceptors; | ||
| 1444 | - return this; | ||
| 1445 | - } | ||
| 1446 | - | ||
| 1447 | - public List<CommandInterceptor> getCommandInterceptors() { | ||
| 1448 | - return commandInterceptors; | ||
| 1449 | - } | ||
| 1450 | - | ||
| 1451 | - public AbstractEngineConfiguration setCommandInterceptors(List<CommandInterceptor> commandInterceptors) { | ||
| 1452 | - this.commandInterceptors = commandInterceptors; | ||
| 1453 | - return this; | ||
| 1454 | - } | ||
| 1455 | - | ||
| 1456 | - public Map<String, AbstractEngineConfiguration> getEngineConfigurations() { | ||
| 1457 | - return engineConfigurations; | ||
| 1458 | - } | ||
| 1459 | - | ||
| 1460 | - public AbstractEngineConfiguration setEngineConfigurations(Map<String, AbstractEngineConfiguration> engineConfigurations) { | ||
| 1461 | - this.engineConfigurations = engineConfigurations; | ||
| 1462 | - return this; | ||
| 1463 | - } | ||
| 1464 | - | ||
| 1465 | - public void addEngineConfiguration(String key, String scopeType, AbstractEngineConfiguration engineConfiguration) { | ||
| 1466 | - if (engineConfigurations == null) { | ||
| 1467 | - engineConfigurations = new HashMap<>(); | ||
| 1468 | - } | ||
| 1469 | - engineConfigurations.put(key, engineConfiguration); | ||
| 1470 | - engineConfigurations.put(scopeType, engineConfiguration); | ||
| 1471 | - } | ||
| 1472 | - | ||
| 1473 | - public Map<String, AbstractServiceConfiguration> getServiceConfigurations() { | ||
| 1474 | - return serviceConfigurations; | ||
| 1475 | - } | ||
| 1476 | - | ||
| 1477 | - public AbstractEngineConfiguration setServiceConfigurations(Map<String, AbstractServiceConfiguration> serviceConfigurations) { | ||
| 1478 | - this.serviceConfigurations = serviceConfigurations; | ||
| 1479 | - return this; | ||
| 1480 | - } | ||
| 1481 | - | ||
| 1482 | - public void addServiceConfiguration(String key, AbstractServiceConfiguration serviceConfiguration) { | ||
| 1483 | - if (serviceConfigurations == null) { | ||
| 1484 | - serviceConfigurations = new HashMap<>(); | ||
| 1485 | - } | ||
| 1486 | - serviceConfigurations.put(key, serviceConfiguration); | ||
| 1487 | - } | ||
| 1488 | - | ||
| 1489 | - public Map<String, EventRegistryEventConsumer> getEventRegistryEventConsumers() { | ||
| 1490 | - return eventRegistryEventConsumers; | ||
| 1491 | - } | ||
| 1492 | - | ||
| 1493 | - public AbstractEngineConfiguration setEventRegistryEventConsumers(Map<String, EventRegistryEventConsumer> eventRegistryEventConsumers) { | ||
| 1494 | - this.eventRegistryEventConsumers = eventRegistryEventConsumers; | ||
| 1495 | - return this; | ||
| 1496 | - } | ||
| 1497 | - | ||
| 1498 | - public void addEventRegistryEventConsumer(String key, EventRegistryEventConsumer eventRegistryEventConsumer) { | ||
| 1499 | - if (eventRegistryEventConsumers == null) { | ||
| 1500 | - eventRegistryEventConsumers = new HashMap<>(); | ||
| 1501 | - } | ||
| 1502 | - eventRegistryEventConsumers.put(key, eventRegistryEventConsumer); | ||
| 1503 | - } | ||
| 1504 | - | ||
| 1505 | - public AbstractEngineConfiguration setDefaultCommandInterceptors(Collection<? extends CommandInterceptor> defaultCommandInterceptors) { | ||
| 1506 | - this.defaultCommandInterceptors = defaultCommandInterceptors; | ||
| 1507 | - return this; | ||
| 1508 | - } | ||
| 1509 | - | ||
| 1510 | - public SqlSessionFactory getSqlSessionFactory() { | ||
| 1511 | - return sqlSessionFactory; | ||
| 1512 | - } | ||
| 1513 | - | ||
| 1514 | - public AbstractEngineConfiguration setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { | ||
| 1515 | - this.sqlSessionFactory = sqlSessionFactory; | ||
| 1516 | - return this; | ||
| 1517 | - } | ||
| 1518 | - | ||
| 1519 | - public boolean isDbHistoryUsed() { | ||
| 1520 | - return isDbHistoryUsed; | ||
| 1521 | - } | ||
| 1522 | - | ||
| 1523 | - public AbstractEngineConfiguration setDbHistoryUsed(boolean isDbHistoryUsed) { | ||
| 1524 | - this.isDbHistoryUsed = isDbHistoryUsed; | ||
| 1525 | - return this; | ||
| 1526 | - } | ||
| 1527 | - | ||
| 1528 | - public DbSqlSessionFactory getDbSqlSessionFactory() { | ||
| 1529 | - return dbSqlSessionFactory; | ||
| 1530 | - } | ||
| 1531 | - | ||
| 1532 | - public AbstractEngineConfiguration setDbSqlSessionFactory(DbSqlSessionFactory dbSqlSessionFactory) { | ||
| 1533 | - this.dbSqlSessionFactory = dbSqlSessionFactory; | ||
| 1534 | - return this; | ||
| 1535 | - } | ||
| 1536 | - | ||
| 1537 | - public TransactionFactory getTransactionFactory() { | ||
| 1538 | - return transactionFactory; | ||
| 1539 | - } | ||
| 1540 | - | ||
| 1541 | - public AbstractEngineConfiguration setTransactionFactory(TransactionFactory transactionFactory) { | ||
| 1542 | - this.transactionFactory = transactionFactory; | ||
| 1543 | - return this; | ||
| 1544 | - } | ||
| 1545 | - | ||
| 1546 | - public TransactionContextFactory getTransactionContextFactory() { | ||
| 1547 | - return transactionContextFactory; | ||
| 1548 | - } | ||
| 1549 | - | ||
| 1550 | - public AbstractEngineConfiguration setTransactionContextFactory(TransactionContextFactory transactionContextFactory) { | ||
| 1551 | - this.transactionContextFactory = transactionContextFactory; | ||
| 1552 | - return this; | ||
| 1553 | - } | ||
| 1554 | - | ||
| 1555 | - public int getMaxNrOfStatementsInBulkInsert() { | ||
| 1556 | - return maxNrOfStatementsInBulkInsert; | ||
| 1557 | - } | ||
| 1558 | - | ||
| 1559 | - public AbstractEngineConfiguration setMaxNrOfStatementsInBulkInsert(int maxNrOfStatementsInBulkInsert) { | ||
| 1560 | - this.maxNrOfStatementsInBulkInsert = maxNrOfStatementsInBulkInsert; | ||
| 1561 | - return this; | ||
| 1562 | - } | ||
| 1563 | - | ||
| 1564 | - public boolean isBulkInsertEnabled() { | ||
| 1565 | - return isBulkInsertEnabled; | ||
| 1566 | - } | ||
| 1567 | - | ||
| 1568 | - public AbstractEngineConfiguration setBulkInsertEnabled(boolean isBulkInsertEnabled) { | ||
| 1569 | - this.isBulkInsertEnabled = isBulkInsertEnabled; | ||
| 1570 | - return this; | ||
| 1571 | - } | ||
| 1572 | - | ||
| 1573 | - public Set<Class<?>> getCustomMybatisMappers() { | ||
| 1574 | - return customMybatisMappers; | ||
| 1575 | - } | ||
| 1576 | - | ||
| 1577 | - public AbstractEngineConfiguration setCustomMybatisMappers(Set<Class<?>> customMybatisMappers) { | ||
| 1578 | - this.customMybatisMappers = customMybatisMappers; | ||
| 1579 | - return this; | ||
| 1580 | - } | ||
| 1581 | - | ||
| 1582 | - public Set<String> getCustomMybatisXMLMappers() { | ||
| 1583 | - return customMybatisXMLMappers; | ||
| 1584 | - } | ||
| 1585 | - | ||
| 1586 | - public AbstractEngineConfiguration setCustomMybatisXMLMappers(Set<String> customMybatisXMLMappers) { | ||
| 1587 | - this.customMybatisXMLMappers = customMybatisXMLMappers; | ||
| 1588 | - return this; | ||
| 1589 | - } | ||
| 1590 | - | ||
| 1591 | - public Set<String> getDependentEngineMyBatisXmlMappers() { | ||
| 1592 | - return dependentEngineMyBatisXmlMappers; | ||
| 1593 | - } | ||
| 1594 | - | ||
| 1595 | - public AbstractEngineConfiguration setCustomMybatisInterceptors(List<Interceptor> customMybatisInterceptors) { | ||
| 1596 | - this.customMybatisInterceptors = customMybatisInterceptors; | ||
| 1597 | - return this; | ||
| 1598 | - } | ||
| 1599 | - | ||
| 1600 | - public List<Interceptor> getCustomMybatisInterceptors() { | ||
| 1601 | - return customMybatisInterceptors; | ||
| 1602 | - } | ||
| 1603 | - | ||
| 1604 | - public AbstractEngineConfiguration setDependentEngineMyBatisXmlMappers(Set<String> dependentEngineMyBatisXmlMappers) { | ||
| 1605 | - this.dependentEngineMyBatisXmlMappers = dependentEngineMyBatisXmlMappers; | ||
| 1606 | - return this; | ||
| 1607 | - } | ||
| 1608 | - | ||
| 1609 | - public List<MybatisTypeAliasConfigurator> getDependentEngineMybatisTypeAliasConfigs() { | ||
| 1610 | - return dependentEngineMybatisTypeAliasConfigs; | ||
| 1611 | - } | ||
| 1612 | - | ||
| 1613 | - public AbstractEngineConfiguration setDependentEngineMybatisTypeAliasConfigs(List<MybatisTypeAliasConfigurator> dependentEngineMybatisTypeAliasConfigs) { | ||
| 1614 | - this.dependentEngineMybatisTypeAliasConfigs = dependentEngineMybatisTypeAliasConfigs; | ||
| 1615 | - return this; | ||
| 1616 | - } | ||
| 1617 | - | ||
| 1618 | - public List<MybatisTypeHandlerConfigurator> getDependentEngineMybatisTypeHandlerConfigs() { | ||
| 1619 | - return dependentEngineMybatisTypeHandlerConfigs; | ||
| 1620 | - } | ||
| 1621 | - | ||
| 1622 | - public AbstractEngineConfiguration setDependentEngineMybatisTypeHandlerConfigs(List<MybatisTypeHandlerConfigurator> dependentEngineMybatisTypeHandlerConfigs) { | ||
| 1623 | - this.dependentEngineMybatisTypeHandlerConfigs = dependentEngineMybatisTypeHandlerConfigs; | ||
| 1624 | - return this; | ||
| 1625 | - } | ||
| 1626 | - | ||
| 1627 | - public List<SessionFactory> getCustomSessionFactories() { | ||
| 1628 | - return customSessionFactories; | ||
| 1629 | - } | ||
| 1630 | - | ||
| 1631 | - public AbstractEngineConfiguration addCustomSessionFactory(SessionFactory sessionFactory) { | ||
| 1632 | - if (customSessionFactories == null) { | ||
| 1633 | - customSessionFactories = new ArrayList<>(); | ||
| 1634 | - } | ||
| 1635 | - customSessionFactories.add(sessionFactory); | ||
| 1636 | - return this; | ||
| 1637 | - } | ||
| 1638 | - | ||
| 1639 | - public AbstractEngineConfiguration setCustomSessionFactories(List<SessionFactory> customSessionFactories) { | ||
| 1640 | - this.customSessionFactories = customSessionFactories; | ||
| 1641 | - return this; | ||
| 1642 | - } | ||
| 1643 | - | ||
| 1644 | - public boolean isUsingRelationalDatabase() { | ||
| 1645 | - return usingRelationalDatabase; | ||
| 1646 | - } | ||
| 1647 | - | ||
| 1648 | - public AbstractEngineConfiguration setUsingRelationalDatabase(boolean usingRelationalDatabase) { | ||
| 1649 | - this.usingRelationalDatabase = usingRelationalDatabase; | ||
| 1650 | - return this; | ||
| 1651 | - } | ||
| 1652 | - | ||
| 1653 | - public boolean isUsingSchemaMgmt() { | ||
| 1654 | - return usingSchemaMgmt; | ||
| 1655 | - } | ||
| 1656 | - | ||
| 1657 | - public AbstractEngineConfiguration setUsingSchemaMgmt(boolean usingSchema) { | ||
| 1658 | - this.usingSchemaMgmt = usingSchema; | ||
| 1659 | - return this; | ||
| 1660 | - } | ||
| 1661 | - | ||
| 1662 | - public String getDatabaseTablePrefix() { | ||
| 1663 | - return databaseTablePrefix; | ||
| 1664 | - } | ||
| 1665 | - | ||
| 1666 | - public AbstractEngineConfiguration setDatabaseTablePrefix(String databaseTablePrefix) { | ||
| 1667 | - this.databaseTablePrefix = databaseTablePrefix; | ||
| 1668 | - return this; | ||
| 1669 | - } | ||
| 1670 | - | ||
| 1671 | - public String getDatabaseWildcardEscapeCharacter() { | ||
| 1672 | - return databaseWildcardEscapeCharacter; | ||
| 1673 | - } | ||
| 1674 | - | ||
| 1675 | - public AbstractEngineConfiguration setDatabaseWildcardEscapeCharacter(String databaseWildcardEscapeCharacter) { | ||
| 1676 | - this.databaseWildcardEscapeCharacter = databaseWildcardEscapeCharacter; | ||
| 1677 | - return this; | ||
| 1678 | - } | ||
| 1679 | - | ||
| 1680 | - public String getDatabaseCatalog() { | ||
| 1681 | - return databaseCatalog; | ||
| 1682 | - } | ||
| 1683 | - | ||
| 1684 | - public AbstractEngineConfiguration setDatabaseCatalog(String databaseCatalog) { | ||
| 1685 | - this.databaseCatalog = databaseCatalog; | ||
| 1686 | - return this; | ||
| 1687 | - } | ||
| 1688 | - | ||
| 1689 | - public String getDatabaseSchema() { | ||
| 1690 | - return databaseSchema; | ||
| 1691 | - } | ||
| 1692 | - | ||
| 1693 | - public AbstractEngineConfiguration setDatabaseSchema(String databaseSchema) { | ||
| 1694 | - this.databaseSchema = databaseSchema; | ||
| 1695 | - return this; | ||
| 1696 | - } | ||
| 1697 | - | ||
| 1698 | - public boolean isTablePrefixIsSchema() { | ||
| 1699 | - return tablePrefixIsSchema; | ||
| 1700 | - } | ||
| 1701 | - | ||
| 1702 | - public AbstractEngineConfiguration setTablePrefixIsSchema(boolean tablePrefixIsSchema) { | ||
| 1703 | - this.tablePrefixIsSchema = tablePrefixIsSchema; | ||
| 1704 | - return this; | ||
| 1705 | - } | ||
| 1706 | - | ||
| 1707 | - public boolean isAlwaysLookupLatestDefinitionVersion() { | ||
| 1708 | - return alwaysLookupLatestDefinitionVersion; | ||
| 1709 | - } | ||
| 1710 | - | ||
| 1711 | - public AbstractEngineConfiguration setAlwaysLookupLatestDefinitionVersion(boolean alwaysLookupLatestDefinitionVersion) { | ||
| 1712 | - this.alwaysLookupLatestDefinitionVersion = alwaysLookupLatestDefinitionVersion; | ||
| 1713 | - return this; | ||
| 1714 | - } | ||
| 1715 | - | ||
| 1716 | - public boolean isFallbackToDefaultTenant() { | ||
| 1717 | - return fallbackToDefaultTenant; | ||
| 1718 | - } | ||
| 1719 | - | ||
| 1720 | - public AbstractEngineConfiguration setFallbackToDefaultTenant(boolean fallbackToDefaultTenant) { | ||
| 1721 | - this.fallbackToDefaultTenant = fallbackToDefaultTenant; | ||
| 1722 | - return this; | ||
| 1723 | - } | ||
| 1724 | - | ||
| 1725 | - /** | ||
| 1726 | - * @return name of the default tenant | ||
| 1727 | - * @deprecated use {@link AbstractEngineConfiguration#getDefaultTenantProvider()} instead | ||
| 1728 | - */ | ||
| 1729 | - @Deprecated | ||
| 1730 | - public String getDefaultTenantValue() { | ||
| 1731 | - return getDefaultTenantProvider().getDefaultTenant(null, null, null); | ||
| 1732 | - } | ||
| 1733 | - | ||
| 1734 | - public AbstractEngineConfiguration setDefaultTenantValue(String defaultTenantValue) { | ||
| 1735 | - this.defaultTenantProvider = (tenantId, scope, scopeKey) -> defaultTenantValue; | ||
| 1736 | - return this; | ||
| 1737 | - } | ||
| 1738 | - | ||
| 1739 | - public DefaultTenantProvider getDefaultTenantProvider() { | ||
| 1740 | - return defaultTenantProvider; | ||
| 1741 | - } | ||
| 1742 | - | ||
| 1743 | - public AbstractEngineConfiguration setDefaultTenantProvider(DefaultTenantProvider defaultTenantProvider) { | ||
| 1744 | - this.defaultTenantProvider = defaultTenantProvider; | ||
| 1745 | - return this; | ||
| 1746 | - } | ||
| 1747 | - | ||
| 1748 | - public boolean isEnableLogSqlExecutionTime() { | ||
| 1749 | - return enableLogSqlExecutionTime; | ||
| 1750 | - } | ||
| 1751 | - | ||
| 1752 | - public void setEnableLogSqlExecutionTime(boolean enableLogSqlExecutionTime) { | ||
| 1753 | - this.enableLogSqlExecutionTime = enableLogSqlExecutionTime; | ||
| 1754 | - } | ||
| 1755 | - | ||
| 1756 | - public Map<Class<?>, SessionFactory> getSessionFactories() { | ||
| 1757 | - return sessionFactories; | ||
| 1758 | - } | ||
| 1759 | - | ||
| 1760 | - public AbstractEngineConfiguration setSessionFactories(Map<Class<?>, SessionFactory> sessionFactories) { | ||
| 1761 | - this.sessionFactories = sessionFactories; | ||
| 1762 | - return this; | ||
| 1763 | - } | ||
| 1764 | - | ||
| 1765 | - public String getDatabaseSchemaUpdate() { | ||
| 1766 | - return databaseSchemaUpdate; | ||
| 1767 | - } | ||
| 1768 | - | ||
| 1769 | - public AbstractEngineConfiguration setDatabaseSchemaUpdate(String databaseSchemaUpdate) { | ||
| 1770 | - this.databaseSchemaUpdate = databaseSchemaUpdate; | ||
| 1771 | - return this; | ||
| 1772 | - } | ||
| 1773 | - | ||
| 1774 | - public boolean isUseLockForDatabaseSchemaUpdate() { | ||
| 1775 | - return useLockForDatabaseSchemaUpdate; | ||
| 1776 | - } | ||
| 1777 | - | ||
| 1778 | - public AbstractEngineConfiguration setUseLockForDatabaseSchemaUpdate(boolean useLockForDatabaseSchemaUpdate) { | ||
| 1779 | - this.useLockForDatabaseSchemaUpdate = useLockForDatabaseSchemaUpdate; | ||
| 1780 | - return this; | ||
| 1781 | - } | ||
| 1782 | - | ||
| 1783 | - public boolean isEnableEventDispatcher() { | ||
| 1784 | - return enableEventDispatcher; | ||
| 1785 | - } | ||
| 1786 | - | ||
| 1787 | - public AbstractEngineConfiguration setEnableEventDispatcher(boolean enableEventDispatcher) { | ||
| 1788 | - this.enableEventDispatcher = enableEventDispatcher; | ||
| 1789 | - return this; | ||
| 1790 | - } | ||
| 1791 | - | ||
| 1792 | - public FlowableEventDispatcher getEventDispatcher() { | ||
| 1793 | - return eventDispatcher; | ||
| 1794 | - } | ||
| 1795 | - | ||
| 1796 | - public AbstractEngineConfiguration setEventDispatcher(FlowableEventDispatcher eventDispatcher) { | ||
| 1797 | - this.eventDispatcher = eventDispatcher; | ||
| 1798 | - return this; | ||
| 1799 | - } | ||
| 1800 | - | ||
| 1801 | - public List<FlowableEventListener> getEventListeners() { | ||
| 1802 | - return eventListeners; | ||
| 1803 | - } | ||
| 1804 | - | ||
| 1805 | - public AbstractEngineConfiguration setEventListeners(List<FlowableEventListener> eventListeners) { | ||
| 1806 | - this.eventListeners = eventListeners; | ||
| 1807 | - return this; | ||
| 1808 | - } | ||
| 1809 | - | ||
| 1810 | - public Map<String, List<FlowableEventListener>> getTypedEventListeners() { | ||
| 1811 | - return typedEventListeners; | ||
| 1812 | - } | ||
| 1813 | - | ||
| 1814 | - public AbstractEngineConfiguration setTypedEventListeners(Map<String, List<FlowableEventListener>> typedEventListeners) { | ||
| 1815 | - this.typedEventListeners = typedEventListeners; | ||
| 1816 | - return this; | ||
| 1817 | - } | ||
| 1818 | - | ||
| 1819 | - public List<EventDispatchAction> getAdditionalEventDispatchActions() { | ||
| 1820 | - return additionalEventDispatchActions; | ||
| 1821 | - } | ||
| 1822 | - | ||
| 1823 | - public AbstractEngineConfiguration setAdditionalEventDispatchActions(List<EventDispatchAction> additionalEventDispatchActions) { | ||
| 1824 | - this.additionalEventDispatchActions = additionalEventDispatchActions; | ||
| 1825 | - return this; | ||
| 1826 | - } | ||
| 1827 | - | ||
| 1828 | - public void initEventDispatcher() { | ||
| 1829 | - if (this.eventDispatcher == null) { | ||
| 1830 | - this.eventDispatcher = new FlowableEventDispatcherImpl(); | ||
| 1831 | - } | ||
| 1832 | - | ||
| 1833 | - initAdditionalEventDispatchActions(); | ||
| 1834 | - | ||
| 1835 | - this.eventDispatcher.setEnabled(enableEventDispatcher); | ||
| 1836 | - | ||
| 1837 | - initEventListeners(); | ||
| 1838 | - initTypedEventListeners(); | ||
| 1839 | - } | ||
| 1840 | - | ||
| 1841 | - protected void initEventListeners() { | ||
| 1842 | - if (eventListeners != null) { | ||
| 1843 | - for (FlowableEventListener listenerToAdd : eventListeners) { | ||
| 1844 | - this.eventDispatcher.addEventListener(listenerToAdd); | ||
| 1845 | - } | ||
| 1846 | - } | ||
| 1847 | - } | ||
| 1848 | - | ||
| 1849 | - protected void initAdditionalEventDispatchActions() { | ||
| 1850 | - if (this.additionalEventDispatchActions == null) { | ||
| 1851 | - this.additionalEventDispatchActions = new ArrayList<>(); | ||
| 1852 | - } | ||
| 1853 | - } | ||
| 1854 | - | ||
| 1855 | - protected void initTypedEventListeners() { | ||
| 1856 | - if (typedEventListeners != null) { | ||
| 1857 | - for (Map.Entry<String, List<FlowableEventListener>> listenersToAdd : typedEventListeners.entrySet()) { | ||
| 1858 | - // Extract types from the given string | ||
| 1859 | - FlowableEngineEventType[] types = FlowableEngineEventType.getTypesFromString(listenersToAdd.getKey()); | ||
| 1860 | - | ||
| 1861 | - for (FlowableEventListener listenerToAdd : listenersToAdd.getValue()) { | ||
| 1862 | - this.eventDispatcher.addEventListener(listenerToAdd, types); | ||
| 1863 | - } | ||
| 1864 | - } | ||
| 1865 | - } | ||
| 1866 | - } | ||
| 1867 | - | ||
| 1868 | - public boolean isLoggingSessionEnabled() { | ||
| 1869 | - return loggingListener != null; | ||
| 1870 | - } | ||
| 1871 | - | ||
| 1872 | - public LoggingListener getLoggingListener() { | ||
| 1873 | - return loggingListener; | ||
| 1874 | - } | ||
| 1875 | - | ||
| 1876 | - public void setLoggingListener(LoggingListener loggingListener) { | ||
| 1877 | - this.loggingListener = loggingListener; | ||
| 1878 | - } | ||
| 1879 | - | ||
| 1880 | - public Clock getClock() { | ||
| 1881 | - return clock; | ||
| 1882 | - } | ||
| 1883 | - | ||
| 1884 | - public AbstractEngineConfiguration setClock(Clock clock) { | ||
| 1885 | - this.clock = clock; | ||
| 1886 | - return this; | ||
| 1887 | - } | ||
| 1888 | - | ||
| 1889 | - public ObjectMapper getObjectMapper() { | ||
| 1890 | - return objectMapper; | ||
| 1891 | - } | ||
| 1892 | - | ||
| 1893 | - public AbstractEngineConfiguration setObjectMapper(ObjectMapper objectMapper) { | ||
| 1894 | - this.objectMapper = objectMapper; | ||
| 1895 | - return this; | ||
| 1896 | - } | ||
| 1897 | - | ||
| 1898 | - public int getMaxLengthString() { | ||
| 1899 | - if (maxLengthStringVariableType == -1) { | ||
| 1900 | - if ("oracle".equalsIgnoreCase(databaseType)) { | ||
| 1901 | - return DEFAULT_ORACLE_MAX_LENGTH_STRING; | ||
| 1902 | - } else { | ||
| 1903 | - return DEFAULT_GENERIC_MAX_LENGTH_STRING; | ||
| 1904 | - } | ||
| 1905 | - } else { | ||
| 1906 | - return maxLengthStringVariableType; | ||
| 1907 | - } | ||
| 1908 | - } | ||
| 1909 | - | ||
| 1910 | - public int getMaxLengthStringVariableType() { | ||
| 1911 | - return maxLengthStringVariableType; | ||
| 1912 | - } | ||
| 1913 | - | ||
| 1914 | - public AbstractEngineConfiguration setMaxLengthStringVariableType(int maxLengthStringVariableType) { | ||
| 1915 | - this.maxLengthStringVariableType = maxLengthStringVariableType; | ||
| 1916 | - return this; | ||
| 1917 | - } | ||
| 1918 | - | ||
| 1919 | - public PropertyDataManager getPropertyDataManager() { | ||
| 1920 | - return propertyDataManager; | ||
| 1921 | - } | ||
| 1922 | - | ||
| 1923 | - public Duration getLockPollRate() { | ||
| 1924 | - return lockPollRate; | ||
| 1925 | - } | ||
| 1926 | - | ||
| 1927 | - public AbstractEngineConfiguration setLockPollRate(Duration lockPollRate) { | ||
| 1928 | - this.lockPollRate = lockPollRate; | ||
| 1929 | - return this; | ||
| 1930 | - } | ||
| 1931 | - | ||
| 1932 | - public Duration getSchemaLockWaitTime() { | ||
| 1933 | - return schemaLockWaitTime; | ||
| 1934 | - } | ||
| 1935 | - | ||
| 1936 | - public void setSchemaLockWaitTime(Duration schemaLockWaitTime) { | ||
| 1937 | - this.schemaLockWaitTime = schemaLockWaitTime; | ||
| 1938 | - } | ||
| 1939 | - | ||
| 1940 | - public AbstractEngineConfiguration setPropertyDataManager(PropertyDataManager propertyDataManager) { | ||
| 1941 | - this.propertyDataManager = propertyDataManager; | ||
| 1942 | - return this; | ||
| 1943 | - } | ||
| 1944 | - | ||
| 1945 | - public PropertyEntityManager getPropertyEntityManager() { | ||
| 1946 | - return propertyEntityManager; | ||
| 1947 | - } | ||
| 1948 | - | ||
| 1949 | - public AbstractEngineConfiguration setPropertyEntityManager(PropertyEntityManager propertyEntityManager) { | ||
| 1950 | - this.propertyEntityManager = propertyEntityManager; | ||
| 1951 | - return this; | ||
| 1952 | - } | ||
| 1953 | - | ||
| 1954 | - public ByteArrayDataManager getByteArrayDataManager() { | ||
| 1955 | - return byteArrayDataManager; | ||
| 1956 | - } | ||
| 1957 | - | ||
| 1958 | - public AbstractEngineConfiguration setByteArrayDataManager(ByteArrayDataManager byteArrayDataManager) { | ||
| 1959 | - this.byteArrayDataManager = byteArrayDataManager; | ||
| 1960 | - return this; | ||
| 1961 | - } | ||
| 1962 | - | ||
| 1963 | - public ByteArrayEntityManager getByteArrayEntityManager() { | ||
| 1964 | - return byteArrayEntityManager; | ||
| 1965 | - } | ||
| 1966 | - | ||
| 1967 | - public AbstractEngineConfiguration setByteArrayEntityManager(ByteArrayEntityManager byteArrayEntityManager) { | ||
| 1968 | - this.byteArrayEntityManager = byteArrayEntityManager; | ||
| 1969 | - return this; | ||
| 1970 | - } | ||
| 1971 | - | ||
| 1972 | - public TableDataManager getTableDataManager() { | ||
| 1973 | - return tableDataManager; | ||
| 1974 | - } | ||
| 1975 | - | ||
| 1976 | - public AbstractEngineConfiguration setTableDataManager(TableDataManager tableDataManager) { | ||
| 1977 | - this.tableDataManager = tableDataManager; | ||
| 1978 | - return this; | ||
| 1979 | - } | ||
| 1980 | - | ||
| 1981 | - public List<EngineDeployer> getDeployers() { | ||
| 1982 | - return deployers; | ||
| 1983 | - } | ||
| 1984 | - | ||
| 1985 | - public AbstractEngineConfiguration setDeployers(List<EngineDeployer> deployers) { | ||
| 1986 | - this.deployers = deployers; | ||
| 1987 | - return this; | ||
| 1988 | - } | ||
| 1989 | - | ||
| 1990 | - public List<EngineDeployer> getCustomPreDeployers() { | ||
| 1991 | - return customPreDeployers; | ||
| 1992 | - } | ||
| 1993 | - | ||
| 1994 | - public AbstractEngineConfiguration setCustomPreDeployers(List<EngineDeployer> customPreDeployers) { | ||
| 1995 | - this.customPreDeployers = customPreDeployers; | ||
| 1996 | - return this; | ||
| 1997 | - } | ||
| 1998 | - | ||
| 1999 | - public List<EngineDeployer> getCustomPostDeployers() { | ||
| 2000 | - return customPostDeployers; | ||
| 2001 | - } | ||
| 2002 | - | ||
| 2003 | - public AbstractEngineConfiguration setCustomPostDeployers(List<EngineDeployer> customPostDeployers) { | ||
| 2004 | - this.customPostDeployers = customPostDeployers; | ||
| 2005 | - return this; | ||
| 2006 | - } | ||
| 2007 | - | ||
| 2008 | - public boolean isEnableConfiguratorServiceLoader() { | ||
| 2009 | - return enableConfiguratorServiceLoader; | ||
| 2010 | - } | ||
| 2011 | - | ||
| 2012 | - public AbstractEngineConfiguration setEnableConfiguratorServiceLoader(boolean enableConfiguratorServiceLoader) { | ||
| 2013 | - this.enableConfiguratorServiceLoader = enableConfiguratorServiceLoader; | ||
| 2014 | - return this; | ||
| 2015 | - } | ||
| 2016 | - | ||
| 2017 | - public List<EngineConfigurator> getConfigurators() { | ||
| 2018 | - return configurators; | ||
| 2019 | - } | ||
| 2020 | - | ||
| 2021 | - public AbstractEngineConfiguration addConfigurator(EngineConfigurator configurator) { | ||
| 2022 | - if (configurators == null) { | ||
| 2023 | - configurators = new ArrayList<>(); | ||
| 2024 | - } | ||
| 2025 | - configurators.add(configurator); | ||
| 2026 | - return this; | ||
| 2027 | - } | ||
| 2028 | - | ||
| 2029 | - /** | ||
| 2030 | - * @return All {@link EngineConfigurator} instances. Will only contain values after init of the engine. | ||
| 2031 | - * Use the {@link #getConfigurators()} or {@link #addConfigurator(EngineConfigurator)} methods otherwise. | ||
| 2032 | - */ | ||
| 2033 | - public List<EngineConfigurator> getAllConfigurators() { | ||
| 2034 | - return allConfigurators; | ||
| 2035 | - } | ||
| 2036 | - | ||
| 2037 | - public AbstractEngineConfiguration setConfigurators(List<EngineConfigurator> configurators) { | ||
| 2038 | - this.configurators = configurators; | ||
| 2039 | - return this; | ||
| 2040 | - } | ||
| 2041 | - | ||
| 2042 | - public EngineConfigurator getIdmEngineConfigurator() { | ||
| 2043 | - return idmEngineConfigurator; | ||
| 2044 | - } | ||
| 2045 | - | ||
| 2046 | - public AbstractEngineConfiguration setIdmEngineConfigurator(EngineConfigurator idmEngineConfigurator) { | ||
| 2047 | - this.idmEngineConfigurator = idmEngineConfigurator; | ||
| 2048 | - return this; | ||
| 2049 | - } | ||
| 2050 | - | ||
| 2051 | - public EngineConfigurator getEventRegistryConfigurator() { | ||
| 2052 | - return eventRegistryConfigurator; | ||
| 2053 | - } | ||
| 2054 | - | ||
| 2055 | - public AbstractEngineConfiguration setEventRegistryConfigurator(EngineConfigurator eventRegistryConfigurator) { | ||
| 2056 | - this.eventRegistryConfigurator = eventRegistryConfigurator; | ||
| 2057 | - return this; | ||
| 2058 | - } | ||
| 2059 | - | ||
| 2060 | - public AbstractEngineConfiguration setForceCloseMybatisConnectionPool(boolean forceCloseMybatisConnectionPool) { | ||
| 2061 | - this.forceCloseMybatisConnectionPool = forceCloseMybatisConnectionPool; | ||
| 2062 | - return this; | ||
| 2063 | - } | ||
| 2064 | - | ||
| 2065 | - public boolean isForceCloseMybatisConnectionPool() { | ||
| 2066 | - return forceCloseMybatisConnectionPool; | ||
| 2067 | - } | ||
| 2068 | -} |
sql/dm/flowable-patch/src/main/resources/META-INF/package-info.md deleted
sql/dm/flowable-patch/src/main/resources/META-INF/services/liquibase.database.Database deleted
| 1 | -liquibase.database.core.CockroachDatabase | ||
| 2 | -liquibase.database.core.DB2Database | ||
| 3 | -liquibase.database.core.Db2zDatabase | ||
| 4 | -liquibase.database.core.DerbyDatabase | ||
| 5 | -liquibase.database.core.Firebird3Database | ||
| 6 | -liquibase.database.core.FirebirdDatabase | ||
| 7 | -liquibase.database.core.H2Database | ||
| 8 | -liquibase.database.core.HsqlDatabase | ||
| 9 | -liquibase.database.core.InformixDatabase | ||
| 10 | -liquibase.database.core.Ingres9Database | ||
| 11 | -liquibase.database.core.MSSQLDatabase | ||
| 12 | -liquibase.database.core.MariaDBDatabase | ||
| 13 | -liquibase.database.core.MockDatabase | ||
| 14 | -liquibase.database.core.MySQLDatabase | ||
| 15 | -liquibase.database.core.OracleDatabase | ||
| 16 | -liquibase.database.core.PostgresDatabase | ||
| 17 | -liquibase.database.core.SQLiteDatabase | ||
| 18 | -liquibase.database.core.SybaseASADatabase | ||
| 19 | -liquibase.database.core.SybaseDatabase | ||
| 20 | -liquibase.database.core.DmDatabase | ||
| 21 | -liquibase.database.core.UnsupportedDatabase |