eventRegistryEventConsumers = new HashMap<>();
+
+ // MYBATIS SQL SESSION FACTORY /////////////////////////////////////
+
+ protected boolean isDbHistoryUsed = true;
+ protected DbSqlSessionFactory dbSqlSessionFactory;
+ protected SqlSessionFactory sqlSessionFactory;
+ protected TransactionFactory transactionFactory;
+ protected TransactionContextFactory transactionContextFactory;
+
+ /**
+ * If set to true, enables bulk insert (grouping sql inserts together). Default true.
+ * For some databases (eg DB2+z/OS) needs to be set to false.
+ */
+ protected boolean isBulkInsertEnabled = true;
+
+ /**
+ * 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
+ * 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.
+ *
+ * By default: 100 (55 for mssql server as it has a hard limit of 2000 parameters in a statement)
+ */
+ protected int maxNrOfStatementsInBulkInsert = 100;
+
+ public int DEFAULT_MAX_NR_OF_STATEMENTS_BULK_INSERT_SQL_SERVER = 55; // currently Execution has most params (35). 2000 / 35 = 57.
+
+ protected String mybatisMappingFile;
+ protected Set> customMybatisMappers;
+ protected Set customMybatisXMLMappers;
+ protected List customMybatisInterceptors;
+
+ protected Set dependentEngineMyBatisXmlMappers;
+ protected List dependentEngineMybatisTypeAliasConfigs;
+ protected List dependentEngineMybatisTypeHandlerConfigs;
+
+ // SESSION FACTORIES ///////////////////////////////////////////////
+ protected List customSessionFactories;
+ protected Map, SessionFactory> sessionFactories;
+
+ protected boolean enableEventDispatcher = true;
+ protected FlowableEventDispatcher eventDispatcher;
+ protected List eventListeners;
+ protected Map> typedEventListeners;
+ protected List additionalEventDispatchActions;
+
+ protected LoggingListener loggingListener;
+
+ protected boolean transactionsExternallyManaged;
+
+ /**
+ * 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.
+ *
+ * If true (default), the {@link AbstractEngineConfiguration#getDatabaseSchemaUpdate()} value will be used to determine what needs to happen wrt the database schema.
+ *
+ * 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
+ * correct. The {@link AbstractEngineConfiguration#getDatabaseSchemaUpdate()} value will not be used.
+ */
+ protected boolean usingRelationalDatabase = true;
+
+ /**
+ * 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.
+ * Setting {@link #usingRelationalDatabase} to true will automatically imply using a schema.
+ */
+ protected boolean usingSchemaMgmt = true;
+
+ /**
+ * 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
+ * in a table named 'PRE1.ACT_RU_EXECUTION_'.
+ *
+ *
+ * NOTE: the prefix is not respected by automatic database schema management. If you use {@link AbstractEngineConfiguration#DB_SCHEMA_UPDATE_CREATE_DROP} or
+ * {@link AbstractEngineConfiguration#DB_SCHEMA_UPDATE_TRUE}, Flowable will create the database tables using the default names, regardless of the prefix configured here.
+ */
+ protected String databaseTablePrefix = "";
+
+ /**
+ * Escape character for doing wildcard searches.
+ *
+ * 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 '\';
+ */
+ protected String databaseWildcardEscapeCharacter;
+
+ /**
+ * database catalog to use
+ */
+ protected String databaseCatalog = "";
+
+ /**
+ * 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,
+ * https://jira.codehaus.org/browse/ACT-1062
+ */
+ protected String databaseSchema;
+
+ /**
+ * 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
+ * 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.
+ */
+ protected boolean tablePrefixIsSchema;
+
+ /**
+ * Set to true if the latest version of a definition should be retrieved, ignoring a possible parent deployment id value
+ */
+ protected boolean alwaysLookupLatestDefinitionVersion;
+
+ /**
+ * Set to true if by default lookups should fallback to the default tenant (an empty string by default or a defined tenant value)
+ */
+ protected boolean fallbackToDefaultTenant;
+
+ /**
+ * Default tenant provider that is executed when looking up definitions, in case the global or local fallback to default tenant value is true
+ */
+ protected DefaultTenantProvider defaultTenantProvider = (tenantId, scope, scopeKey) -> NO_TENANT_ID;
+
+ /**
+ * Enables the MyBatis plugin that logs the execution time of sql statements.
+ */
+ protected boolean enableLogSqlExecutionTime;
+
+ protected Properties databaseTypeMappings = getDefaultDatabaseTypeMappings();
+
+ /**
+ * Duration between the checks when acquiring a lock.
+ */
+ protected Duration lockPollRate = Duration.ofSeconds(10);
+
+ /**
+ * Duration to wait for the DB Schema lock before giving up.
+ */
+ protected Duration schemaLockWaitTime = Duration.ofMinutes(5);
+
+ // DATA MANAGERS //////////////////////////////////////////////////////////////////
+
+ protected PropertyDataManager propertyDataManager;
+ protected ByteArrayDataManager byteArrayDataManager;
+ protected TableDataManager tableDataManager;
+
+ // ENTITY MANAGERS ////////////////////////////////////////////////////////////////
+
+ protected PropertyEntityManager propertyEntityManager;
+ protected ByteArrayEntityManager byteArrayEntityManager;
+
+ protected List customPreDeployers;
+ protected List customPostDeployers;
+ protected List deployers;
+
+ // CONFIGURATORS ////////////////////////////////////////////////////////////
+
+ protected boolean enableConfiguratorServiceLoader = true; // Enabled by default. In certain environments this should be set to false (eg osgi)
+ protected List configurators; // The injected configurators
+ protected List allConfigurators; // Including auto-discovered configurators
+ protected EngineConfigurator idmEngineConfigurator;
+ protected EngineConfigurator eventRegistryConfigurator;
+
+ public static final String PRODUCT_NAME_POSTGRES = "PostgreSQL";
+ public static final String PRODUCT_NAME_CRDB = "CockroachDB";
+
+ public static final String DATABASE_TYPE_H2 = "h2";
+ public static final String DATABASE_TYPE_HSQL = "hsql";
+ public static final String DATABASE_TYPE_MYSQL = "mysql";
+ public static final String DATABASE_TYPE_ORACLE = "oracle";
+ public static final String DATABASE_TYPE_POSTGRES = "postgres";
+ public static final String DATABASE_TYPE_MSSQL = "mssql";
+ public static final String DATABASE_TYPE_DB2 = "db2";
+ public static final String DATABASE_TYPE_COCKROACHDB = "cockroachdb";
+
+ public static Properties getDefaultDatabaseTypeMappings() {
+ Properties databaseTypeMappings = new Properties();
+ databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
+ databaseTypeMappings.setProperty("HSQL Database Engine", DATABASE_TYPE_HSQL);
+ databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
+ databaseTypeMappings.setProperty("MariaDB", DATABASE_TYPE_MYSQL);
+ databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
+ databaseTypeMappings.setProperty(PRODUCT_NAME_POSTGRES, DATABASE_TYPE_POSTGRES);
+ databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL);
+ databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/NT", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/NT64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2 UDP", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUX", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUX390", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUXX8664", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUXZ64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUXPPC64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUXPPC64LE", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/400 SQL", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/6000", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2 UDB iSeries", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/AIX64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/HPUX", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/HP64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/SUN", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/SUN64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/PTX", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/2", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty(PRODUCT_NAME_CRDB, DATABASE_TYPE_COCKROACHDB);
+ databaseTypeMappings.setProperty("DM DBMS", DATABASE_TYPE_ORACLE); // dhb52: DM support
+ return databaseTypeMappings;
+ }
+
+ protected Map beans;
+
+ protected IdGenerator idGenerator;
+ protected boolean usePrefixId;
+
+ protected Clock clock;
+ protected ObjectMapper objectMapper;
+
+ // Variables
+
+ public static final int DEFAULT_GENERIC_MAX_LENGTH_STRING = 4000;
+ public static final int DEFAULT_ORACLE_MAX_LENGTH_STRING = 2000;
+
+ /**
+ * Define a max length for storing String variable types in the database. Mainly used for the Oracle NVARCHAR2 limit of 2000 characters
+ */
+ protected int maxLengthStringVariableType = -1;
+
+ protected void initEngineConfigurations() {
+ addEngineConfiguration(getEngineCfgKey(), getEngineScopeType(), this);
+ }
+
+ // DataSource
+ // ///////////////////////////////////////////////////////////////
+
+ protected void initDataSource() {
+ if (dataSource == null) {
+ if (dataSourceJndiName != null) {
+ try {
+ dataSource = (DataSource) new InitialContext().lookup(dataSourceJndiName);
+ } catch (Exception e) {
+ throw new FlowableException("couldn't lookup datasource from " + dataSourceJndiName + ": " + e.getMessage(), e);
+ }
+
+ } else if (jdbcUrl != null) {
+ if ((jdbcDriver == null) || (jdbcUsername == null)) {
+ throw new FlowableException("DataSource or JDBC properties have to be specified in a process engine configuration");
+ }
+
+ logger.debug("initializing datasource to db: {}", jdbcUrl);
+
+ if (logger.isInfoEnabled()) {
+ logger.info("Configuring Datasource with following properties (omitted password for security)");
+ logger.info("datasource driver : {}", jdbcDriver);
+ logger.info("datasource url : {}", jdbcUrl);
+ logger.info("datasource user name : {}", jdbcUsername);
+ }
+
+ PooledDataSource pooledDataSource = new PooledDataSource(this.getClass().getClassLoader(), jdbcDriver, jdbcUrl, jdbcUsername, jdbcPassword);
+
+ if (jdbcMaxActiveConnections > 0) {
+ pooledDataSource.setPoolMaximumActiveConnections(jdbcMaxActiveConnections);
+ }
+ if (jdbcMaxIdleConnections > 0) {
+ pooledDataSource.setPoolMaximumIdleConnections(jdbcMaxIdleConnections);
+ }
+ if (jdbcMaxCheckoutTime > 0) {
+ pooledDataSource.setPoolMaximumCheckoutTime(jdbcMaxCheckoutTime);
+ }
+ if (jdbcMaxWaitTime > 0) {
+ pooledDataSource.setPoolTimeToWait(jdbcMaxWaitTime);
+ }
+ if (jdbcPingEnabled) {
+ pooledDataSource.setPoolPingEnabled(true);
+ if (jdbcPingQuery != null) {
+ pooledDataSource.setPoolPingQuery(jdbcPingQuery);
+ }
+ pooledDataSource.setPoolPingConnectionsNotUsedFor(jdbcPingConnectionNotUsedFor);
+ }
+ if (jdbcDefaultTransactionIsolationLevel > 0) {
+ pooledDataSource.setDefaultTransactionIsolationLevel(jdbcDefaultTransactionIsolationLevel);
+ }
+ dataSource = pooledDataSource;
+ }
+ }
+
+ if (databaseType == null) {
+ initDatabaseType();
+ }
+ }
+
+ public void initDatabaseType() {
+ Connection connection = null;
+ try {
+ connection = dataSource.getConnection();
+ DatabaseMetaData databaseMetaData = connection.getMetaData();
+ String databaseProductName = databaseMetaData.getDatabaseProductName();
+ logger.debug("database product name: '{}'", databaseProductName);
+
+ // CRDB does not expose the version through the jdbc driver, so we need to fetch it through version().
+ if (PRODUCT_NAME_POSTGRES.equalsIgnoreCase(databaseProductName)) {
+ try (PreparedStatement preparedStatement = connection.prepareStatement("select version() as version;");
+ ResultSet resultSet = preparedStatement.executeQuery()) {
+ String version = null;
+ if (resultSet.next()) {
+ version = resultSet.getString("version");
+ }
+
+ if (StringUtils.isNotEmpty(version) && version.toLowerCase().startsWith(PRODUCT_NAME_CRDB.toLowerCase())) {
+ databaseProductName = PRODUCT_NAME_CRDB;
+ logger.info("CockroachDB version '{}' detected", version);
+ }
+ }
+ }
+
+ databaseType = databaseTypeMappings.getProperty(databaseProductName);
+ if (databaseType == null) {
+ throw new FlowableException("couldn't deduct database type from database product name '" + databaseProductName + "'");
+ }
+ logger.debug("using database type: {}", databaseType);
+
+ } catch (SQLException e) {
+ throw new RuntimeException("Exception while initializing Database connection", e);
+ } finally {
+ try {
+ if (connection != null) {
+ connection.close();
+ }
+ } catch (SQLException e) {
+ logger.error("Exception while closing the Database connection", e);
+ }
+ }
+
+ // Special care for MSSQL, as it has a hard limit of 2000 params per statement (incl bulk statement).
+ // Especially with executions, with 100 as default, this limit is passed.
+ if (DATABASE_TYPE_MSSQL.equals(databaseType)) {
+ maxNrOfStatementsInBulkInsert = DEFAULT_MAX_NR_OF_STATEMENTS_BULK_INSERT_SQL_SERVER;
+ }
+ }
+
+ public void initSchemaManager() {
+ if (this.commonSchemaManager == null) {
+ this.commonSchemaManager = new CommonDbSchemaManager();
+ }
+ }
+
+ // session factories ////////////////////////////////////////////////////////
+
+ public void addSessionFactory(SessionFactory sessionFactory) {
+ sessionFactories.put(sessionFactory.getSessionType(), sessionFactory);
+ }
+
+ public void initCommandContextFactory() {
+ if (commandContextFactory == null) {
+ commandContextFactory = new CommandContextFactory();
+ }
+ }
+
+ public void initTransactionContextFactory() {
+ if (transactionContextFactory == null) {
+ transactionContextFactory = new StandaloneMybatisTransactionContextFactory();
+ }
+ }
+
+ public void initCommandExecutors() {
+ initDefaultCommandConfig();
+ initSchemaCommandConfig();
+ initCommandInvoker();
+ initCommandInterceptors();
+ initCommandExecutor();
+ }
+
+
+ public void initDefaultCommandConfig() {
+ if (defaultCommandConfig == null) {
+ defaultCommandConfig = new CommandConfig();
+ }
+ }
+
+ public void initSchemaCommandConfig() {
+ if (schemaCommandConfig == null) {
+ schemaCommandConfig = new CommandConfig();
+ }
+ }
+
+ public void initCommandInvoker() {
+ if (commandInvoker == null) {
+ commandInvoker = new DefaultCommandInvoker();
+ }
+ }
+
+ public void initCommandInterceptors() {
+ if (commandInterceptors == null) {
+ commandInterceptors = new ArrayList<>();
+ if (customPreCommandInterceptors != null) {
+ commandInterceptors.addAll(customPreCommandInterceptors);
+ }
+ commandInterceptors.addAll(getDefaultCommandInterceptors());
+ if (customPostCommandInterceptors != null) {
+ commandInterceptors.addAll(customPostCommandInterceptors);
+ }
+ commandInterceptors.add(commandInvoker);
+ }
+ }
+
+ public Collection extends CommandInterceptor> getDefaultCommandInterceptors() {
+ if (defaultCommandInterceptors == null) {
+ List interceptors = new ArrayList<>();
+ interceptors.add(new LogInterceptor());
+
+ if (DATABASE_TYPE_COCKROACHDB.equals(databaseType)) {
+ interceptors.add(new CrDbRetryInterceptor());
+ }
+
+ CommandInterceptor transactionInterceptor = createTransactionInterceptor();
+ if (transactionInterceptor != null) {
+ interceptors.add(transactionInterceptor);
+ }
+
+ if (commandContextFactory != null) {
+ String engineCfgKey = getEngineCfgKey();
+ CommandContextInterceptor commandContextInterceptor = new CommandContextInterceptor(commandContextFactory,
+ classLoader, useClassForNameClassLoading, clock, objectMapper);
+ engineConfigurations.put(engineCfgKey, this);
+ commandContextInterceptor.setEngineCfgKey(engineCfgKey);
+ commandContextInterceptor.setEngineConfigurations(engineConfigurations);
+ interceptors.add(commandContextInterceptor);
+ }
+
+ if (transactionContextFactory != null) {
+ interceptors.add(new TransactionContextInterceptor(transactionContextFactory));
+ }
+
+ List additionalCommandInterceptors = getAdditionalDefaultCommandInterceptors();
+ if (additionalCommandInterceptors != null) {
+ interceptors.addAll(additionalCommandInterceptors);
+ }
+
+ defaultCommandInterceptors = interceptors;
+ }
+ return defaultCommandInterceptors;
+ }
+
+ public abstract String getEngineCfgKey();
+
+ public abstract String getEngineScopeType();
+
+ public List getAdditionalDefaultCommandInterceptors() {
+ return null;
+ }
+
+ public void initCommandExecutor() {
+ if (commandExecutor == null) {
+ CommandInterceptor first = initInterceptorChain(commandInterceptors);
+ commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
+ }
+ }
+
+ public CommandInterceptor initInterceptorChain(List chain) {
+ if (chain == null || chain.isEmpty()) {
+ throw new FlowableException("invalid command interceptor chain configuration: " + chain);
+ }
+ for (int i = 0; i < chain.size() - 1; i++) {
+ chain.get(i).setNext(chain.get(i + 1));
+ }
+ return chain.get(0);
+ }
+
+ public abstract CommandInterceptor createTransactionInterceptor();
+
+
+ public void initBeans() {
+ if (beans == null) {
+ beans = new HashMap<>();
+ }
+ }
+
+ // id generator
+ // /////////////////////////////////////////////////////////////
+
+ public void initIdGenerator() {
+ if (idGenerator == null) {
+ idGenerator = new StrongUuidGenerator();
+ }
+ }
+
+ public void initObjectMapper() {
+ if (objectMapper == null) {
+ objectMapper = new ObjectMapper();
+ objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+ }
+ }
+
+ public void initClock() {
+ if (clock == null) {
+ clock = new DefaultClockImpl();
+ }
+ }
+
+ // Data managers ///////////////////////////////////////////////////////////
+
+ public void initDataManagers() {
+ if (propertyDataManager == null) {
+ propertyDataManager = new MybatisPropertyDataManager(idGenerator);
+ }
+
+ if (byteArrayDataManager == null) {
+ byteArrayDataManager = new MybatisByteArrayDataManager(idGenerator);
+ }
+ }
+
+ // Entity managers //////////////////////////////////////////////////////////
+
+ public void initEntityManagers() {
+ if (propertyEntityManager == null) {
+ propertyEntityManager = new PropertyEntityManagerImpl(this, propertyDataManager);
+ }
+
+ if (byteArrayEntityManager == null) {
+ byteArrayEntityManager = new ByteArrayEntityManagerImpl(byteArrayDataManager, getEngineCfgKey(), this::getEventDispatcher);
+ }
+
+ if (tableDataManager == null) {
+ tableDataManager = new TableDataManagerImpl(this);
+ }
+ }
+
+ // services
+ // /////////////////////////////////////////////////////////////////
+
+ protected void initService(Object service) {
+ if (service instanceof CommonEngineServiceImpl) {
+ ((CommonEngineServiceImpl) service).setCommandExecutor(commandExecutor);
+ }
+ }
+
+ // myBatis SqlSessionFactory
+ // ////////////////////////////////////////////////
+
+ public void initSessionFactories() {
+ if (sessionFactories == null) {
+ sessionFactories = new HashMap<>();
+
+ if (usingRelationalDatabase) {
+ initDbSqlSessionFactory();
+ }
+
+ addSessionFactory(new GenericManagerFactory(EntityCache.class, EntityCacheImpl.class));
+
+ if (isLoggingSessionEnabled()) {
+ if (!sessionFactories.containsKey(LoggingSession.class)) {
+ LoggingSessionFactory loggingSessionFactory = new LoggingSessionFactory();
+ loggingSessionFactory.setLoggingListener(loggingListener);
+ loggingSessionFactory.setObjectMapper(objectMapper);
+ sessionFactories.put(LoggingSession.class, loggingSessionFactory);
+ }
+ }
+
+ commandContextFactory.setSessionFactories(sessionFactories);
+
+ } else {
+ if (usingRelationalDatabase) {
+ initDbSqlSessionFactoryEntitySettings();
+ }
+ }
+
+ if (customSessionFactories != null) {
+ for (SessionFactory sessionFactory : customSessionFactories) {
+ addSessionFactory(sessionFactory);
+ }
+ }
+ }
+
+ public void initDbSqlSessionFactory() {
+ if (dbSqlSessionFactory == null) {
+ dbSqlSessionFactory = createDbSqlSessionFactory();
+ }
+ dbSqlSessionFactory.setDatabaseType(databaseType);
+ dbSqlSessionFactory.setSqlSessionFactory(sqlSessionFactory);
+ dbSqlSessionFactory.setDbHistoryUsed(isDbHistoryUsed);
+ dbSqlSessionFactory.setDatabaseTablePrefix(databaseTablePrefix);
+ dbSqlSessionFactory.setTablePrefixIsSchema(tablePrefixIsSchema);
+ dbSqlSessionFactory.setDatabaseCatalog(databaseCatalog);
+ dbSqlSessionFactory.setDatabaseSchema(databaseSchema);
+ dbSqlSessionFactory.setMaxNrOfStatementsInBulkInsert(maxNrOfStatementsInBulkInsert);
+
+ initDbSqlSessionFactoryEntitySettings();
+
+ addSessionFactory(dbSqlSessionFactory);
+ }
+
+ public DbSqlSessionFactory createDbSqlSessionFactory() {
+ return new DbSqlSessionFactory(usePrefixId);
+ }
+
+ protected abstract void initDbSqlSessionFactoryEntitySettings();
+
+ protected void defaultInitDbSqlSessionFactoryEntitySettings(List> insertOrder, List> deleteOrder) {
+ if (insertOrder != null) {
+ for (Class extends Entity> clazz : insertOrder) {
+ dbSqlSessionFactory.getInsertionOrder().add(clazz);
+
+ if (isBulkInsertEnabled) {
+ dbSqlSessionFactory.getBulkInserteableEntityClasses().add(clazz);
+ }
+ }
+ }
+
+ if (deleteOrder != null) {
+ for (Class extends Entity> clazz : deleteOrder) {
+ dbSqlSessionFactory.getDeletionOrder().add(clazz);
+ }
+ }
+ }
+
+ public void initTransactionFactory() {
+ if (transactionFactory == null) {
+ if (transactionsExternallyManaged) {
+ transactionFactory = new ManagedTransactionFactory();
+ Properties properties = new Properties();
+ properties.put("closeConnection", "false");
+ this.transactionFactory.setProperties(properties);
+ } else {
+ transactionFactory = new JdbcTransactionFactory();
+ }
+ }
+ }
+
+ public void initSqlSessionFactory() {
+ if (sqlSessionFactory == null) {
+ InputStream inputStream = null;
+ try {
+ inputStream = getMyBatisXmlConfigurationStream();
+
+ Environment environment = new Environment("default", transactionFactory, dataSource);
+ Reader reader = new InputStreamReader(inputStream);
+ Properties properties = new Properties();
+ properties.put("prefix", databaseTablePrefix);
+
+ String wildcardEscapeClause = "";
+ if ((databaseWildcardEscapeCharacter != null) && (databaseWildcardEscapeCharacter.length() != 0)) {
+ wildcardEscapeClause = " escape '" + databaseWildcardEscapeCharacter + "'";
+ }
+ properties.put("wildcardEscapeClause", wildcardEscapeClause);
+
+ // set default properties
+ properties.put("limitBefore", "");
+ properties.put("limitAfter", "");
+ properties.put("limitBetween", "");
+ properties.put("limitBeforeNativeQuery", "");
+ properties.put("limitAfterNativeQuery", "");
+ properties.put("blobType", "BLOB");
+ properties.put("boolValue", "TRUE");
+
+ if (databaseType != null) {
+ properties.load(getResourceAsStream(pathToEngineDbProperties()));
+ }
+
+ Configuration configuration = initMybatisConfiguration(environment, reader, properties);
+ sqlSessionFactory = new DefaultSqlSessionFactory(configuration);
+
+ } catch (Exception e) {
+ throw new FlowableException("Error while building ibatis SqlSessionFactory: " + e.getMessage(), e);
+ } finally {
+ IoUtil.closeSilently(inputStream);
+ }
+ } else {
+ // This is needed when the SQL Session Factory is created by another engine.
+ // When custom XML Mappers are registered with this engine they need to be loaded in the configuration as well
+ applyCustomMybatisCustomizations(sqlSessionFactory.getConfiguration());
+ }
+ }
+
+ public String pathToEngineDbProperties() {
+ return "org/flowable/common/db/properties/" + databaseType + ".properties";
+ }
+
+ public Configuration initMybatisConfiguration(Environment environment, Reader reader, Properties properties) {
+ XMLConfigBuilder parser = new XMLConfigBuilder(reader, "", properties);
+ Configuration configuration = parser.getConfiguration();
+
+ if (databaseType != null) {
+ configuration.setDatabaseId(databaseType);
+ }
+
+ configuration.setEnvironment(environment);
+
+ initMybatisTypeHandlers(configuration);
+ initCustomMybatisInterceptors(configuration);
+ if (isEnableLogSqlExecutionTime()) {
+ initMyBatisLogSqlExecutionTimePlugin(configuration);
+ }
+
+ configuration = parseMybatisConfiguration(parser);
+ return configuration;
+ }
+
+ public void initCustomMybatisMappers(Configuration configuration) {
+ if (getCustomMybatisMappers() != null) {
+ for (Class> clazz : getCustomMybatisMappers()) {
+ if (!configuration.hasMapper(clazz)) {
+ configuration.addMapper(clazz);
+ }
+ }
+ }
+ }
+
+ public void initMybatisTypeHandlers(Configuration configuration) {
+ // When mapping into Map there is currently a problem with MyBatis.
+ // It will return objects which are driver specific.
+ // Therefore we are registering the mappings between Object.class and the specific jdbc type here.
+ // see https://github.com/mybatis/mybatis-3/issues/2216 for more info
+ TypeHandlerRegistry handlerRegistry = configuration.getTypeHandlerRegistry();
+
+ handlerRegistry.register(Object.class, JdbcType.BOOLEAN, new BooleanTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.BIT, new BooleanTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.TINYINT, new ByteTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.SMALLINT, new ShortTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.INTEGER, new IntegerTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.FLOAT, new FloatTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.DOUBLE, new DoubleTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.CHAR, new StringTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.CLOB, new ClobTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.VARCHAR, new StringTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.LONGVARCHAR, new StringTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.NVARCHAR, new NStringTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.NCHAR, new NStringTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.NCLOB, new NClobTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.ARRAY, new ArrayTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.BIGINT, new LongTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.REAL, new BigDecimalTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.DECIMAL, new BigDecimalTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.NUMERIC, new BigDecimalTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.BLOB, new BlobInputStreamTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.LONGVARBINARY, new BlobTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.DATE, new DateOnlyTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.TIME, new TimeOnlyTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.TIMESTAMP, new DateTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.SQLXML, new SqlxmlTypeHandler());
+ }
+
+ public void initCustomMybatisInterceptors(Configuration configuration) {
+ if (customMybatisInterceptors!=null){
+ for (Interceptor interceptor :customMybatisInterceptors){
+ configuration.addInterceptor(interceptor);
+ }
+ }
+ }
+
+ public void initMyBatisLogSqlExecutionTimePlugin(Configuration configuration) {
+ configuration.addInterceptor(new LogSqlExecutionTimePlugin());
+ }
+
+ public Configuration parseMybatisConfiguration(XMLConfigBuilder parser) {
+ Configuration configuration = parser.parse();
+
+ applyCustomMybatisCustomizations(configuration);
+ return configuration;
+ }
+
+ protected void applyCustomMybatisCustomizations(Configuration configuration) {
+ initCustomMybatisMappers(configuration);
+
+ if (dependentEngineMybatisTypeAliasConfigs != null) {
+ for (MybatisTypeAliasConfigurator typeAliasConfig : dependentEngineMybatisTypeAliasConfigs) {
+ typeAliasConfig.configure(configuration.getTypeAliasRegistry());
+ }
+ }
+ if (dependentEngineMybatisTypeHandlerConfigs != null) {
+ for (MybatisTypeHandlerConfigurator typeHandlerConfig : dependentEngineMybatisTypeHandlerConfigs) {
+ typeHandlerConfig.configure(configuration.getTypeHandlerRegistry());
+ }
+ }
+
+ parseDependentEngineMybatisXMLMappers(configuration);
+ parseCustomMybatisXMLMappers(configuration);
+ }
+
+ public void parseCustomMybatisXMLMappers(Configuration configuration) {
+ if (getCustomMybatisXMLMappers() != null) {
+ for (String resource : getCustomMybatisXMLMappers()) {
+ parseMybatisXmlMapping(configuration, resource);
+ }
+ }
+ }
+
+ public void parseDependentEngineMybatisXMLMappers(Configuration configuration) {
+ if (getDependentEngineMyBatisXmlMappers() != null) {
+ for (String resource : getDependentEngineMyBatisXmlMappers()) {
+ parseMybatisXmlMapping(configuration, resource);
+ }
+ }
+ }
+
+ protected void parseMybatisXmlMapping(Configuration configuration, String resource) {
+ // see XMLConfigBuilder.mapperElement()
+ XMLMapperBuilder mapperParser = new XMLMapperBuilder(getResourceAsStream(resource), configuration, resource, configuration.getSqlFragments());
+ mapperParser.parse();
+ }
+
+ protected InputStream getResourceAsStream(String resource) {
+ ClassLoader classLoader = getClassLoader();
+ if (classLoader != null) {
+ return getClassLoader().getResourceAsStream(resource);
+ } else {
+ return this.getClass().getClassLoader().getResourceAsStream(resource);
+ }
+ }
+
+ public void setMybatisMappingFile(String file) {
+ this.mybatisMappingFile = file;
+ }
+
+ public String getMybatisMappingFile() {
+ return mybatisMappingFile;
+ }
+
+ public abstract InputStream getMyBatisXmlConfigurationStream();
+
+ public void initConfigurators() {
+
+ allConfigurators = new ArrayList<>();
+ allConfigurators.addAll(getEngineSpecificEngineConfigurators());
+
+ // Configurators that are explicitly added to the config
+ if (configurators != null) {
+ allConfigurators.addAll(configurators);
+ }
+
+ // Auto discovery through ServiceLoader
+ if (enableConfiguratorServiceLoader) {
+ ClassLoader classLoader = getClassLoader();
+ if (classLoader == null) {
+ classLoader = ReflectUtil.getClassLoader();
+ }
+
+ ServiceLoader configuratorServiceLoader = ServiceLoader.load(EngineConfigurator.class, classLoader);
+ int nrOfServiceLoadedConfigurators = 0;
+ for (EngineConfigurator configurator : configuratorServiceLoader) {
+ allConfigurators.add(configurator);
+ nrOfServiceLoadedConfigurators++;
+ }
+
+ if (nrOfServiceLoadedConfigurators > 0) {
+ logger.info("Found {} auto-discoverable Process Engine Configurator{}", nrOfServiceLoadedConfigurators, nrOfServiceLoadedConfigurators > 1 ? "s" : "");
+ }
+
+ if (!allConfigurators.isEmpty()) {
+
+ // Order them according to the priorities (useful for dependent
+ // configurator)
+ allConfigurators.sort(new Comparator() {
+
+ @Override
+ public int compare(EngineConfigurator configurator1, EngineConfigurator configurator2) {
+ int priority1 = configurator1.getPriority();
+ int priority2 = configurator2.getPriority();
+
+ if (priority1 < priority2) {
+ return -1;
+ } else if (priority1 > priority2) {
+ return 1;
+ }
+ return 0;
+ }
+ });
+
+ // Execute the configurators
+ logger.info("Found {} Engine Configurators in total:", allConfigurators.size());
+ for (EngineConfigurator configurator : allConfigurators) {
+ logger.info("{} (priority:{})", configurator.getClass(), configurator.getPriority());
+ }
+
+ }
+
+ }
+ }
+
+ public void close() {
+ if (forceCloseMybatisConnectionPool && dataSource instanceof PooledDataSource) {
+ /*
+ * When the datasource is created by a Flowable engine (i.e. it's an instance of PooledDataSource),
+ * the connection pool needs to be closed when closing the engine.
+ * Note that calling forceCloseAll() multiple times (as is the case when running with multiple engine) is ok.
+ */
+ ((PooledDataSource) dataSource).forceCloseAll();
+ }
+ }
+
+ protected List getEngineSpecificEngineConfigurators() {
+ // meant to be overridden if needed
+ return Collections.emptyList();
+ }
+
+ public void configuratorsBeforeInit() {
+ for (EngineConfigurator configurator : allConfigurators) {
+ logger.info("Executing beforeInit() of {} (priority:{})", configurator.getClass(), configurator.getPriority());
+ configurator.beforeInit(this);
+ }
+ }
+
+ public void configuratorsAfterInit() {
+ for (EngineConfigurator configurator : allConfigurators) {
+ logger.info("Executing configure() of {} (priority:{})", configurator.getClass(), configurator.getPriority());
+ configurator.configure(this);
+ }
+ }
+
+ public LockManager getLockManager(String lockName) {
+ return new LockManagerImpl(commandExecutor, lockName, getLockPollRate(), getEngineCfgKey());
+ }
+
+ // getters and setters
+ // //////////////////////////////////////////////////////
+
+ public abstract String getEngineName();
+
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ public AbstractEngineConfiguration setClassLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ return this;
+ }
+
+ public boolean isUseClassForNameClassLoading() {
+ return useClassForNameClassLoading;
+ }
+
+ public AbstractEngineConfiguration setUseClassForNameClassLoading(boolean useClassForNameClassLoading) {
+ this.useClassForNameClassLoading = useClassForNameClassLoading;
+ return this;
+ }
+
+ public void addEngineLifecycleListener(EngineLifecycleListener engineLifecycleListener) {
+ if (this.engineLifecycleListeners == null) {
+ this.engineLifecycleListeners = new ArrayList<>();
+ }
+ this.engineLifecycleListeners.add(engineLifecycleListener);
+ }
+
+ public List getEngineLifecycleListeners() {
+ return engineLifecycleListeners;
+ }
+
+ public AbstractEngineConfiguration setEngineLifecycleListeners(List engineLifecycleListeners) {
+ this.engineLifecycleListeners = engineLifecycleListeners;
+ return this;
+ }
+
+ public String getDatabaseType() {
+ return databaseType;
+ }
+
+ public AbstractEngineConfiguration setDatabaseType(String databaseType) {
+ this.databaseType = databaseType;
+ return this;
+ }
+
+ public DataSource getDataSource() {
+ return dataSource;
+ }
+
+ public AbstractEngineConfiguration setDataSource(DataSource dataSource) {
+ this.dataSource = dataSource;
+ return this;
+ }
+
+ public SchemaManager getSchemaManager() {
+ return schemaManager;
+ }
+
+ public AbstractEngineConfiguration setSchemaManager(SchemaManager schemaManager) {
+ this.schemaManager = schemaManager;
+ return this;
+ }
+
+ public SchemaManager getCommonSchemaManager() {
+ return commonSchemaManager;
+ }
+
+ public AbstractEngineConfiguration setCommonSchemaManager(SchemaManager commonSchemaManager) {
+ this.commonSchemaManager = commonSchemaManager;
+ return this;
+ }
+
+ public Command getSchemaManagementCmd() {
+ return schemaManagementCmd;
+ }
+
+ public AbstractEngineConfiguration setSchemaManagementCmd(Command schemaManagementCmd) {
+ this.schemaManagementCmd = schemaManagementCmd;
+ return this;
+ }
+
+ public String getJdbcDriver() {
+ return jdbcDriver;
+ }
+
+ public AbstractEngineConfiguration setJdbcDriver(String jdbcDriver) {
+ this.jdbcDriver = jdbcDriver;
+ return this;
+ }
+
+ public String getJdbcUrl() {
+ return jdbcUrl;
+ }
+
+ public AbstractEngineConfiguration setJdbcUrl(String jdbcUrl) {
+ this.jdbcUrl = jdbcUrl;
+ return this;
+ }
+
+ public String getJdbcUsername() {
+ return jdbcUsername;
+ }
+
+ public AbstractEngineConfiguration setJdbcUsername(String jdbcUsername) {
+ this.jdbcUsername = jdbcUsername;
+ return this;
+ }
+
+ public String getJdbcPassword() {
+ return jdbcPassword;
+ }
+
+ public AbstractEngineConfiguration setJdbcPassword(String jdbcPassword) {
+ this.jdbcPassword = jdbcPassword;
+ return this;
+ }
+
+ public int getJdbcMaxActiveConnections() {
+ return jdbcMaxActiveConnections;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxActiveConnections(int jdbcMaxActiveConnections) {
+ this.jdbcMaxActiveConnections = jdbcMaxActiveConnections;
+ return this;
+ }
+
+ public int getJdbcMaxIdleConnections() {
+ return jdbcMaxIdleConnections;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxIdleConnections(int jdbcMaxIdleConnections) {
+ this.jdbcMaxIdleConnections = jdbcMaxIdleConnections;
+ return this;
+ }
+
+ public int getJdbcMaxCheckoutTime() {
+ return jdbcMaxCheckoutTime;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxCheckoutTime(int jdbcMaxCheckoutTime) {
+ this.jdbcMaxCheckoutTime = jdbcMaxCheckoutTime;
+ return this;
+ }
+
+ public int getJdbcMaxWaitTime() {
+ return jdbcMaxWaitTime;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxWaitTime(int jdbcMaxWaitTime) {
+ this.jdbcMaxWaitTime = jdbcMaxWaitTime;
+ return this;
+ }
+
+ public boolean isJdbcPingEnabled() {
+ return jdbcPingEnabled;
+ }
+
+ public AbstractEngineConfiguration setJdbcPingEnabled(boolean jdbcPingEnabled) {
+ this.jdbcPingEnabled = jdbcPingEnabled;
+ return this;
+ }
+
+ public int getJdbcPingConnectionNotUsedFor() {
+ return jdbcPingConnectionNotUsedFor;
+ }
+
+ public AbstractEngineConfiguration setJdbcPingConnectionNotUsedFor(int jdbcPingConnectionNotUsedFor) {
+ this.jdbcPingConnectionNotUsedFor = jdbcPingConnectionNotUsedFor;
+ return this;
+ }
+
+ public int getJdbcDefaultTransactionIsolationLevel() {
+ return jdbcDefaultTransactionIsolationLevel;
+ }
+
+ public AbstractEngineConfiguration setJdbcDefaultTransactionIsolationLevel(int jdbcDefaultTransactionIsolationLevel) {
+ this.jdbcDefaultTransactionIsolationLevel = jdbcDefaultTransactionIsolationLevel;
+ return this;
+ }
+
+ public String getJdbcPingQuery() {
+ return jdbcPingQuery;
+ }
+
+ public AbstractEngineConfiguration setJdbcPingQuery(String jdbcPingQuery) {
+ this.jdbcPingQuery = jdbcPingQuery;
+ return this;
+ }
+
+ public String getDataSourceJndiName() {
+ return dataSourceJndiName;
+ }
+
+ public AbstractEngineConfiguration setDataSourceJndiName(String dataSourceJndiName) {
+ this.dataSourceJndiName = dataSourceJndiName;
+ return this;
+ }
+
+ public CommandConfig getSchemaCommandConfig() {
+ return schemaCommandConfig;
+ }
+
+ public AbstractEngineConfiguration setSchemaCommandConfig(CommandConfig schemaCommandConfig) {
+ this.schemaCommandConfig = schemaCommandConfig;
+ return this;
+ }
+
+ public boolean isTransactionsExternallyManaged() {
+ return transactionsExternallyManaged;
+ }
+
+ public AbstractEngineConfiguration setTransactionsExternallyManaged(boolean transactionsExternallyManaged) {
+ this.transactionsExternallyManaged = transactionsExternallyManaged;
+ return this;
+ }
+
+ public Map getBeans() {
+ return beans;
+ }
+
+ public AbstractEngineConfiguration setBeans(Map beans) {
+ this.beans = beans;
+ return this;
+ }
+
+ public IdGenerator getIdGenerator() {
+ return idGenerator;
+ }
+
+ public AbstractEngineConfiguration setIdGenerator(IdGenerator idGenerator) {
+ this.idGenerator = idGenerator;
+ return this;
+ }
+
+ public boolean isUsePrefixId() {
+ return usePrefixId;
+ }
+
+ public AbstractEngineConfiguration setUsePrefixId(boolean usePrefixId) {
+ this.usePrefixId = usePrefixId;
+ return this;
+ }
+
+ public String getXmlEncoding() {
+ return xmlEncoding;
+ }
+
+ public AbstractEngineConfiguration setXmlEncoding(String xmlEncoding) {
+ this.xmlEncoding = xmlEncoding;
+ return this;
+ }
+
+ public CommandConfig getDefaultCommandConfig() {
+ return defaultCommandConfig;
+ }
+
+ public AbstractEngineConfiguration setDefaultCommandConfig(CommandConfig defaultCommandConfig) {
+ this.defaultCommandConfig = defaultCommandConfig;
+ return this;
+ }
+
+ public CommandExecutor getCommandExecutor() {
+ return commandExecutor;
+ }
+
+ public AbstractEngineConfiguration setCommandExecutor(CommandExecutor commandExecutor) {
+ this.commandExecutor = commandExecutor;
+ return this;
+ }
+
+ public CommandContextFactory getCommandContextFactory() {
+ return commandContextFactory;
+ }
+
+ public AbstractEngineConfiguration setCommandContextFactory(CommandContextFactory commandContextFactory) {
+ this.commandContextFactory = commandContextFactory;
+ return this;
+ }
+
+ public CommandInterceptor getCommandInvoker() {
+ return commandInvoker;
+ }
+
+ public AbstractEngineConfiguration setCommandInvoker(CommandInterceptor commandInvoker) {
+ this.commandInvoker = commandInvoker;
+ return this;
+ }
+
+ public AgendaOperationRunner getAgendaOperationRunner() {
+ return agendaOperationRunner;
+ }
+
+ public AbstractEngineConfiguration setAgendaOperationRunner(AgendaOperationRunner agendaOperationRunner) {
+ this.agendaOperationRunner = agendaOperationRunner;
+ return this;
+ }
+
+ public List getCustomPreCommandInterceptors() {
+ return customPreCommandInterceptors;
+ }
+
+ public AbstractEngineConfiguration setCustomPreCommandInterceptors(List customPreCommandInterceptors) {
+ this.customPreCommandInterceptors = customPreCommandInterceptors;
+ return this;
+ }
+
+ public List getCustomPostCommandInterceptors() {
+ return customPostCommandInterceptors;
+ }
+
+ public AbstractEngineConfiguration setCustomPostCommandInterceptors(List customPostCommandInterceptors) {
+ this.customPostCommandInterceptors = customPostCommandInterceptors;
+ return this;
+ }
+
+ public List getCommandInterceptors() {
+ return commandInterceptors;
+ }
+
+ public AbstractEngineConfiguration setCommandInterceptors(List commandInterceptors) {
+ this.commandInterceptors = commandInterceptors;
+ return this;
+ }
+
+ public Map getEngineConfigurations() {
+ return engineConfigurations;
+ }
+
+ public AbstractEngineConfiguration setEngineConfigurations(Map engineConfigurations) {
+ this.engineConfigurations = engineConfigurations;
+ return this;
+ }
+
+ public void addEngineConfiguration(String key, String scopeType, AbstractEngineConfiguration engineConfiguration) {
+ if (engineConfigurations == null) {
+ engineConfigurations = new HashMap<>();
+ }
+ engineConfigurations.put(key, engineConfiguration);
+ engineConfigurations.put(scopeType, engineConfiguration);
+ }
+
+ public Map getServiceConfigurations() {
+ return serviceConfigurations;
+ }
+
+ public AbstractEngineConfiguration setServiceConfigurations(Map serviceConfigurations) {
+ this.serviceConfigurations = serviceConfigurations;
+ return this;
+ }
+
+ public void addServiceConfiguration(String key, AbstractServiceConfiguration serviceConfiguration) {
+ if (serviceConfigurations == null) {
+ serviceConfigurations = new HashMap<>();
+ }
+ serviceConfigurations.put(key, serviceConfiguration);
+ }
+
+ public Map getEventRegistryEventConsumers() {
+ return eventRegistryEventConsumers;
+ }
+
+ public AbstractEngineConfiguration setEventRegistryEventConsumers(Map eventRegistryEventConsumers) {
+ this.eventRegistryEventConsumers = eventRegistryEventConsumers;
+ return this;
+ }
+
+ public void addEventRegistryEventConsumer(String key, EventRegistryEventConsumer eventRegistryEventConsumer) {
+ if (eventRegistryEventConsumers == null) {
+ eventRegistryEventConsumers = new HashMap<>();
+ }
+ eventRegistryEventConsumers.put(key, eventRegistryEventConsumer);
+ }
+
+ public AbstractEngineConfiguration setDefaultCommandInterceptors(Collection extends CommandInterceptor> defaultCommandInterceptors) {
+ this.defaultCommandInterceptors = defaultCommandInterceptors;
+ return this;
+ }
+
+ public SqlSessionFactory getSqlSessionFactory() {
+ return sqlSessionFactory;
+ }
+
+ public AbstractEngineConfiguration setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
+ this.sqlSessionFactory = sqlSessionFactory;
+ return this;
+ }
+
+ public boolean isDbHistoryUsed() {
+ return isDbHistoryUsed;
+ }
+
+ public AbstractEngineConfiguration setDbHistoryUsed(boolean isDbHistoryUsed) {
+ this.isDbHistoryUsed = isDbHistoryUsed;
+ return this;
+ }
+
+ public DbSqlSessionFactory getDbSqlSessionFactory() {
+ return dbSqlSessionFactory;
+ }
+
+ public AbstractEngineConfiguration setDbSqlSessionFactory(DbSqlSessionFactory dbSqlSessionFactory) {
+ this.dbSqlSessionFactory = dbSqlSessionFactory;
+ return this;
+ }
+
+ public TransactionFactory getTransactionFactory() {
+ return transactionFactory;
+ }
+
+ public AbstractEngineConfiguration setTransactionFactory(TransactionFactory transactionFactory) {
+ this.transactionFactory = transactionFactory;
+ return this;
+ }
+
+ public TransactionContextFactory getTransactionContextFactory() {
+ return transactionContextFactory;
+ }
+
+ public AbstractEngineConfiguration setTransactionContextFactory(TransactionContextFactory transactionContextFactory) {
+ this.transactionContextFactory = transactionContextFactory;
+ return this;
+ }
+
+ public int getMaxNrOfStatementsInBulkInsert() {
+ return maxNrOfStatementsInBulkInsert;
+ }
+
+ public AbstractEngineConfiguration setMaxNrOfStatementsInBulkInsert(int maxNrOfStatementsInBulkInsert) {
+ this.maxNrOfStatementsInBulkInsert = maxNrOfStatementsInBulkInsert;
+ return this;
+ }
+
+ public boolean isBulkInsertEnabled() {
+ return isBulkInsertEnabled;
+ }
+
+ public AbstractEngineConfiguration setBulkInsertEnabled(boolean isBulkInsertEnabled) {
+ this.isBulkInsertEnabled = isBulkInsertEnabled;
+ return this;
+ }
+
+ public Set> getCustomMybatisMappers() {
+ return customMybatisMappers;
+ }
+
+ public AbstractEngineConfiguration setCustomMybatisMappers(Set> customMybatisMappers) {
+ this.customMybatisMappers = customMybatisMappers;
+ return this;
+ }
+
+ public Set getCustomMybatisXMLMappers() {
+ return customMybatisXMLMappers;
+ }
+
+ public AbstractEngineConfiguration setCustomMybatisXMLMappers(Set customMybatisXMLMappers) {
+ this.customMybatisXMLMappers = customMybatisXMLMappers;
+ return this;
+ }
+
+ public Set getDependentEngineMyBatisXmlMappers() {
+ return dependentEngineMyBatisXmlMappers;
+ }
+
+ public AbstractEngineConfiguration setCustomMybatisInterceptors(List customMybatisInterceptors) {
+ this.customMybatisInterceptors = customMybatisInterceptors;
+ return this;
+ }
+
+ public List getCustomMybatisInterceptors() {
+ return customMybatisInterceptors;
+ }
+
+ public AbstractEngineConfiguration setDependentEngineMyBatisXmlMappers(Set dependentEngineMyBatisXmlMappers) {
+ this.dependentEngineMyBatisXmlMappers = dependentEngineMyBatisXmlMappers;
+ return this;
+ }
+
+ public List getDependentEngineMybatisTypeAliasConfigs() {
+ return dependentEngineMybatisTypeAliasConfigs;
+ }
+
+ public AbstractEngineConfiguration setDependentEngineMybatisTypeAliasConfigs(List dependentEngineMybatisTypeAliasConfigs) {
+ this.dependentEngineMybatisTypeAliasConfigs = dependentEngineMybatisTypeAliasConfigs;
+ return this;
+ }
+
+ public List getDependentEngineMybatisTypeHandlerConfigs() {
+ return dependentEngineMybatisTypeHandlerConfigs;
+ }
+
+ public AbstractEngineConfiguration setDependentEngineMybatisTypeHandlerConfigs(List dependentEngineMybatisTypeHandlerConfigs) {
+ this.dependentEngineMybatisTypeHandlerConfigs = dependentEngineMybatisTypeHandlerConfigs;
+ return this;
+ }
+
+ public List getCustomSessionFactories() {
+ return customSessionFactories;
+ }
+
+ public AbstractEngineConfiguration addCustomSessionFactory(SessionFactory sessionFactory) {
+ if (customSessionFactories == null) {
+ customSessionFactories = new ArrayList<>();
+ }
+ customSessionFactories.add(sessionFactory);
+ return this;
+ }
+
+ public AbstractEngineConfiguration setCustomSessionFactories(List customSessionFactories) {
+ this.customSessionFactories = customSessionFactories;
+ return this;
+ }
+
+ public boolean isUsingRelationalDatabase() {
+ return usingRelationalDatabase;
+ }
+
+ public AbstractEngineConfiguration setUsingRelationalDatabase(boolean usingRelationalDatabase) {
+ this.usingRelationalDatabase = usingRelationalDatabase;
+ return this;
+ }
+
+ public boolean isUsingSchemaMgmt() {
+ return usingSchemaMgmt;
+ }
+
+ public AbstractEngineConfiguration setUsingSchemaMgmt(boolean usingSchema) {
+ this.usingSchemaMgmt = usingSchema;
+ return this;
+ }
+
+ public String getDatabaseTablePrefix() {
+ return databaseTablePrefix;
+ }
+
+ public AbstractEngineConfiguration setDatabaseTablePrefix(String databaseTablePrefix) {
+ this.databaseTablePrefix = databaseTablePrefix;
+ return this;
+ }
+
+ public String getDatabaseWildcardEscapeCharacter() {
+ return databaseWildcardEscapeCharacter;
+ }
+
+ public AbstractEngineConfiguration setDatabaseWildcardEscapeCharacter(String databaseWildcardEscapeCharacter) {
+ this.databaseWildcardEscapeCharacter = databaseWildcardEscapeCharacter;
+ return this;
+ }
+
+ public String getDatabaseCatalog() {
+ return databaseCatalog;
+ }
+
+ public AbstractEngineConfiguration setDatabaseCatalog(String databaseCatalog) {
+ this.databaseCatalog = databaseCatalog;
+ return this;
+ }
+
+ public String getDatabaseSchema() {
+ return databaseSchema;
+ }
+
+ public AbstractEngineConfiguration setDatabaseSchema(String databaseSchema) {
+ this.databaseSchema = databaseSchema;
+ return this;
+ }
+
+ public boolean isTablePrefixIsSchema() {
+ return tablePrefixIsSchema;
+ }
+
+ public AbstractEngineConfiguration setTablePrefixIsSchema(boolean tablePrefixIsSchema) {
+ this.tablePrefixIsSchema = tablePrefixIsSchema;
+ return this;
+ }
+
+ public boolean isAlwaysLookupLatestDefinitionVersion() {
+ return alwaysLookupLatestDefinitionVersion;
+ }
+
+ public AbstractEngineConfiguration setAlwaysLookupLatestDefinitionVersion(boolean alwaysLookupLatestDefinitionVersion) {
+ this.alwaysLookupLatestDefinitionVersion = alwaysLookupLatestDefinitionVersion;
+ return this;
+ }
+
+ public boolean isFallbackToDefaultTenant() {
+ return fallbackToDefaultTenant;
+ }
+
+ public AbstractEngineConfiguration setFallbackToDefaultTenant(boolean fallbackToDefaultTenant) {
+ this.fallbackToDefaultTenant = fallbackToDefaultTenant;
+ return this;
+ }
+
+ /**
+ * @return name of the default tenant
+ * @deprecated use {@link AbstractEngineConfiguration#getDefaultTenantProvider()} instead
+ */
+ @Deprecated
+ public String getDefaultTenantValue() {
+ return getDefaultTenantProvider().getDefaultTenant(null, null, null);
+ }
+
+ public AbstractEngineConfiguration setDefaultTenantValue(String defaultTenantValue) {
+ this.defaultTenantProvider = (tenantId, scope, scopeKey) -> defaultTenantValue;
+ return this;
+ }
+
+ public DefaultTenantProvider getDefaultTenantProvider() {
+ return defaultTenantProvider;
+ }
+
+ public AbstractEngineConfiguration setDefaultTenantProvider(DefaultTenantProvider defaultTenantProvider) {
+ this.defaultTenantProvider = defaultTenantProvider;
+ return this;
+ }
+
+ public boolean isEnableLogSqlExecutionTime() {
+ return enableLogSqlExecutionTime;
+ }
+
+ public void setEnableLogSqlExecutionTime(boolean enableLogSqlExecutionTime) {
+ this.enableLogSqlExecutionTime = enableLogSqlExecutionTime;
+ }
+
+ public Map, SessionFactory> getSessionFactories() {
+ return sessionFactories;
+ }
+
+ public AbstractEngineConfiguration setSessionFactories(Map, SessionFactory> sessionFactories) {
+ this.sessionFactories = sessionFactories;
+ return this;
+ }
+
+ public String getDatabaseSchemaUpdate() {
+ return databaseSchemaUpdate;
+ }
+
+ public AbstractEngineConfiguration setDatabaseSchemaUpdate(String databaseSchemaUpdate) {
+ this.databaseSchemaUpdate = databaseSchemaUpdate;
+ return this;
+ }
+
+ public boolean isUseLockForDatabaseSchemaUpdate() {
+ return useLockForDatabaseSchemaUpdate;
+ }
+
+ public AbstractEngineConfiguration setUseLockForDatabaseSchemaUpdate(boolean useLockForDatabaseSchemaUpdate) {
+ this.useLockForDatabaseSchemaUpdate = useLockForDatabaseSchemaUpdate;
+ return this;
+ }
+
+ public boolean isEnableEventDispatcher() {
+ return enableEventDispatcher;
+ }
+
+ public AbstractEngineConfiguration setEnableEventDispatcher(boolean enableEventDispatcher) {
+ this.enableEventDispatcher = enableEventDispatcher;
+ return this;
+ }
+
+ public FlowableEventDispatcher getEventDispatcher() {
+ return eventDispatcher;
+ }
+
+ public AbstractEngineConfiguration setEventDispatcher(FlowableEventDispatcher eventDispatcher) {
+ this.eventDispatcher = eventDispatcher;
+ return this;
+ }
+
+ public List getEventListeners() {
+ return eventListeners;
+ }
+
+ public AbstractEngineConfiguration setEventListeners(List eventListeners) {
+ this.eventListeners = eventListeners;
+ return this;
+ }
+
+ public Map> getTypedEventListeners() {
+ return typedEventListeners;
+ }
+
+ public AbstractEngineConfiguration setTypedEventListeners(Map> typedEventListeners) {
+ this.typedEventListeners = typedEventListeners;
+ return this;
+ }
+
+ public List getAdditionalEventDispatchActions() {
+ return additionalEventDispatchActions;
+ }
+
+ public AbstractEngineConfiguration setAdditionalEventDispatchActions(List additionalEventDispatchActions) {
+ this.additionalEventDispatchActions = additionalEventDispatchActions;
+ return this;
+ }
+
+ public void initEventDispatcher() {
+ if (this.eventDispatcher == null) {
+ this.eventDispatcher = new FlowableEventDispatcherImpl();
+ }
+
+ initAdditionalEventDispatchActions();
+
+ this.eventDispatcher.setEnabled(enableEventDispatcher);
+
+ initEventListeners();
+ initTypedEventListeners();
+ }
+
+ protected void initEventListeners() {
+ if (eventListeners != null) {
+ for (FlowableEventListener listenerToAdd : eventListeners) {
+ this.eventDispatcher.addEventListener(listenerToAdd);
+ }
+ }
+ }
+
+ protected void initAdditionalEventDispatchActions() {
+ if (this.additionalEventDispatchActions == null) {
+ this.additionalEventDispatchActions = new ArrayList<>();
+ }
+ }
+
+ protected void initTypedEventListeners() {
+ if (typedEventListeners != null) {
+ for (Map.Entry> listenersToAdd : typedEventListeners.entrySet()) {
+ // Extract types from the given string
+ FlowableEngineEventType[] types = FlowableEngineEventType.getTypesFromString(listenersToAdd.getKey());
+
+ for (FlowableEventListener listenerToAdd : listenersToAdd.getValue()) {
+ this.eventDispatcher.addEventListener(listenerToAdd, types);
+ }
+ }
+ }
+ }
+
+ public boolean isLoggingSessionEnabled() {
+ return loggingListener != null;
+ }
+
+ public LoggingListener getLoggingListener() {
+ return loggingListener;
+ }
+
+ public void setLoggingListener(LoggingListener loggingListener) {
+ this.loggingListener = loggingListener;
+ }
+
+ public Clock getClock() {
+ return clock;
+ }
+
+ public AbstractEngineConfiguration setClock(Clock clock) {
+ this.clock = clock;
+ return this;
+ }
+
+ public ObjectMapper getObjectMapper() {
+ return objectMapper;
+ }
+
+ public AbstractEngineConfiguration setObjectMapper(ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ return this;
+ }
+
+ public int getMaxLengthString() {
+ if (maxLengthStringVariableType == -1) {
+ if ("oracle".equalsIgnoreCase(databaseType)) {
+ return DEFAULT_ORACLE_MAX_LENGTH_STRING;
+ } else {
+ return DEFAULT_GENERIC_MAX_LENGTH_STRING;
+ }
+ } else {
+ return maxLengthStringVariableType;
+ }
+ }
+
+ public int getMaxLengthStringVariableType() {
+ return maxLengthStringVariableType;
+ }
+
+ public AbstractEngineConfiguration setMaxLengthStringVariableType(int maxLengthStringVariableType) {
+ this.maxLengthStringVariableType = maxLengthStringVariableType;
+ return this;
+ }
+
+ public PropertyDataManager getPropertyDataManager() {
+ return propertyDataManager;
+ }
+
+ public Duration getLockPollRate() {
+ return lockPollRate;
+ }
+
+ public AbstractEngineConfiguration setLockPollRate(Duration lockPollRate) {
+ this.lockPollRate = lockPollRate;
+ return this;
+ }
+
+ public Duration getSchemaLockWaitTime() {
+ return schemaLockWaitTime;
+ }
+
+ public void setSchemaLockWaitTime(Duration schemaLockWaitTime) {
+ this.schemaLockWaitTime = schemaLockWaitTime;
+ }
+
+ public AbstractEngineConfiguration setPropertyDataManager(PropertyDataManager propertyDataManager) {
+ this.propertyDataManager = propertyDataManager;
+ return this;
+ }
+
+ public PropertyEntityManager getPropertyEntityManager() {
+ return propertyEntityManager;
+ }
+
+ public AbstractEngineConfiguration setPropertyEntityManager(PropertyEntityManager propertyEntityManager) {
+ this.propertyEntityManager = propertyEntityManager;
+ return this;
+ }
+
+ public ByteArrayDataManager getByteArrayDataManager() {
+ return byteArrayDataManager;
+ }
+
+ public AbstractEngineConfiguration setByteArrayDataManager(ByteArrayDataManager byteArrayDataManager) {
+ this.byteArrayDataManager = byteArrayDataManager;
+ return this;
+ }
+
+ public ByteArrayEntityManager getByteArrayEntityManager() {
+ return byteArrayEntityManager;
+ }
+
+ public AbstractEngineConfiguration setByteArrayEntityManager(ByteArrayEntityManager byteArrayEntityManager) {
+ this.byteArrayEntityManager = byteArrayEntityManager;
+ return this;
+ }
+
+ public TableDataManager getTableDataManager() {
+ return tableDataManager;
+ }
+
+ public AbstractEngineConfiguration setTableDataManager(TableDataManager tableDataManager) {
+ this.tableDataManager = tableDataManager;
+ return this;
+ }
+
+ public List getDeployers() {
+ return deployers;
+ }
+
+ public AbstractEngineConfiguration setDeployers(List deployers) {
+ this.deployers = deployers;
+ return this;
+ }
+
+ public List getCustomPreDeployers() {
+ return customPreDeployers;
+ }
+
+ public AbstractEngineConfiguration setCustomPreDeployers(List customPreDeployers) {
+ this.customPreDeployers = customPreDeployers;
+ return this;
+ }
+
+ public List getCustomPostDeployers() {
+ return customPostDeployers;
+ }
+
+ public AbstractEngineConfiguration setCustomPostDeployers(List customPostDeployers) {
+ this.customPostDeployers = customPostDeployers;
+ return this;
+ }
+
+ public boolean isEnableConfiguratorServiceLoader() {
+ return enableConfiguratorServiceLoader;
+ }
+
+ public AbstractEngineConfiguration setEnableConfiguratorServiceLoader(boolean enableConfiguratorServiceLoader) {
+ this.enableConfiguratorServiceLoader = enableConfiguratorServiceLoader;
+ return this;
+ }
+
+ public List getConfigurators() {
+ return configurators;
+ }
+
+ public AbstractEngineConfiguration addConfigurator(EngineConfigurator configurator) {
+ if (configurators == null) {
+ configurators = new ArrayList<>();
+ }
+ configurators.add(configurator);
+ return this;
+ }
+
+ /**
+ * @return All {@link EngineConfigurator} instances. Will only contain values after init of the engine.
+ * Use the {@link #getConfigurators()} or {@link #addConfigurator(EngineConfigurator)} methods otherwise.
+ */
+ public List getAllConfigurators() {
+ return allConfigurators;
+ }
+
+ public AbstractEngineConfiguration setConfigurators(List configurators) {
+ this.configurators = configurators;
+ return this;
+ }
+
+ public EngineConfigurator getIdmEngineConfigurator() {
+ return idmEngineConfigurator;
+ }
+
+ public AbstractEngineConfiguration setIdmEngineConfigurator(EngineConfigurator idmEngineConfigurator) {
+ this.idmEngineConfigurator = idmEngineConfigurator;
+ return this;
+ }
+
+ public EngineConfigurator getEventRegistryConfigurator() {
+ return eventRegistryConfigurator;
+ }
+
+ public AbstractEngineConfiguration setEventRegistryConfigurator(EngineConfigurator eventRegistryConfigurator) {
+ this.eventRegistryConfigurator = eventRegistryConfigurator;
+ return this;
+ }
+
+ public AbstractEngineConfiguration setForceCloseMybatisConnectionPool(boolean forceCloseMybatisConnectionPool) {
+ this.forceCloseMybatisConnectionPool = forceCloseMybatisConnectionPool;
+ return this;
+ }
+
+ public boolean isForceCloseMybatisConnectionPool() {
+ return forceCloseMybatisConnectionPool;
+ }
+}
diff --git a/sql/db2/flowable-patch/src/main/resources/META-INF/package-info.md b/sql/db2/flowable-patch/src/main/resources/META-INF/package-info.md
new file mode 100644
index 000000000..1932c7a3f
--- /dev/null
+++ b/sql/db2/flowable-patch/src/main/resources/META-INF/package-info.md
@@ -0,0 +1 @@
+防止IDEA将`.`和`/`混为一谈
\ No newline at end of file
diff --git a/sql/db2/flowable-patch/src/main/resources/META-INF/services/liquibase.database.Database b/sql/db2/flowable-patch/src/main/resources/META-INF/services/liquibase.database.Database
new file mode 100644
index 000000000..efbcfcca2
--- /dev/null
+++ b/sql/db2/flowable-patch/src/main/resources/META-INF/services/liquibase.database.Database
@@ -0,0 +1,21 @@
+liquibase.database.core.CockroachDatabase
+liquibase.database.core.DB2Database
+liquibase.database.core.Db2zDatabase
+liquibase.database.core.DerbyDatabase
+liquibase.database.core.Firebird3Database
+liquibase.database.core.FirebirdDatabase
+liquibase.database.core.H2Database
+liquibase.database.core.HsqlDatabase
+liquibase.database.core.InformixDatabase
+liquibase.database.core.Ingres9Database
+liquibase.database.core.MSSQLDatabase
+liquibase.database.core.MariaDBDatabase
+liquibase.database.core.MockDatabase
+liquibase.database.core.MySQLDatabase
+liquibase.database.core.OracleDatabase
+liquibase.database.core.PostgresDatabase
+liquibase.database.core.SQLiteDatabase
+liquibase.database.core.SybaseASADatabase
+liquibase.database.core.SybaseDatabase
+liquibase.database.core.DmDatabase
+liquibase.database.core.UnsupportedDatabase
diff --git a/sql/dm/README.md b/sql/dm/README.md
deleted file mode 100644
index e8b39a86a..000000000
--- a/sql/dm/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-暂未适配国产 DM 数据库,如果你有需要,可以微信联系 wangwenbin-server 一起建设。
-
-你需要把表结构与数据导入到 DM 数据库,我来测试与适配代码。
diff --git a/sql/dm/flowable-patch/src/main/java/liquibase/database/core/DmDatabase.java b/sql/dm/flowable-patch/src/main/java/liquibase/database/core/DmDatabase.java
new file mode 100644
index 000000000..fbc4c6bc1
--- /dev/null
+++ b/sql/dm/flowable-patch/src/main/java/liquibase/database/core/DmDatabase.java
@@ -0,0 +1,598 @@
+package liquibase.database.core;
+
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import liquibase.CatalogAndSchema;
+import liquibase.Scope;
+import liquibase.database.AbstractJdbcDatabase;
+import liquibase.database.DatabaseConnection;
+import liquibase.database.OfflineConnection;
+import liquibase.database.jvm.JdbcConnection;
+import liquibase.exception.DatabaseException;
+import liquibase.exception.UnexpectedLiquibaseException;
+import liquibase.exception.ValidationErrors;
+import liquibase.executor.ExecutorService;
+import liquibase.statement.DatabaseFunction;
+import liquibase.statement.SequenceCurrentValueFunction;
+import liquibase.statement.SequenceNextValueFunction;
+import liquibase.statement.core.RawCallStatement;
+import liquibase.statement.core.RawSqlStatement;
+import liquibase.structure.DatabaseObject;
+import liquibase.structure.core.Catalog;
+import liquibase.structure.core.Index;
+import liquibase.structure.core.PrimaryKey;
+import liquibase.structure.core.Schema;
+import liquibase.util.JdbcUtils;
+import liquibase.util.StringUtil;
+
+public class DmDatabase extends AbstractJdbcDatabase {
+ private static final String PRODUCT_NAME = "DM DBMS";
+
+ @Override
+ protected String getDefaultDatabaseProductName() {
+ return PRODUCT_NAME;
+ }
+
+ /**
+ * Is this AbstractDatabase subclass the correct one to use for the given connection.
+ *
+ * @param conn
+ */
+ @Override
+ public boolean isCorrectDatabaseImplementation(DatabaseConnection conn) throws DatabaseException {
+ return PRODUCT_NAME.equalsIgnoreCase(conn.getDatabaseProductName());
+ }
+
+ /**
+ * If this database understands the given url, return the default driver class name. Otherwise return null.
+ *
+ * @param url
+ */
+ @Override
+ public String getDefaultDriver(String url) {
+ if(url.startsWith("jdbc:dm")) {
+ return "dm.jdbc.driver.DmDriver";
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns an all-lower-case short name of the product. Used for end-user selecting of database type
+ * such as the DBMS precondition.
+ */
+ @Override
+ public String getShortName() {
+ return "dm";
+ }
+
+ @Override
+ public Integer getDefaultPort() {
+ return 5236;
+ }
+
+ /**
+ * Returns whether this database support initially deferrable columns.
+ */
+ @Override
+ public boolean supportsInitiallyDeferrableColumns() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsTablespaces() {
+ return true;
+ }
+
+ @Override
+ public int getPriority() {
+ return PRIORITY_DEFAULT;
+ }
+
+ private static final Pattern PROXY_USER = Pattern.compile(".*(?:thin|oci)\\:(.+)/@.*");
+
+ protected final int SHORT_IDENTIFIERS_LENGTH = 30;
+ protected final int LONG_IDENTIFIERS_LEGNTH = 128;
+ public static final int ORACLE_12C_MAJOR_VERSION = 12;
+
+ private Set reservedWords = new HashSet<>();
+ private Set userDefinedTypes;
+ private Map savedSessionNlsSettings;
+
+ private Boolean canAccessDbaRecycleBin;
+ private Integer databaseMajorVersion;
+ private Integer databaseMinorVersion;
+
+ /**
+ * Default constructor for an object that represents the Oracle Database DBMS.
+ */
+ public DmDatabase() {
+ super.unquotedObjectsAreUppercased = true;
+ //noinspection HardCodedStringLiteral
+ super.setCurrentDateTimeFunction("SYSTIMESTAMP");
+ // Setting list of Oracle's native functions
+ //noinspection HardCodedStringLiteral
+ dateFunctions.add(new DatabaseFunction("SYSDATE"));
+ //noinspection HardCodedStringLiteral
+ dateFunctions.add(new DatabaseFunction("SYSTIMESTAMP"));
+ //noinspection HardCodedStringLiteral
+ dateFunctions.add(new DatabaseFunction("CURRENT_TIMESTAMP"));
+ //noinspection HardCodedStringLiteral
+ super.sequenceNextValueFunction = "%s.nextval";
+ //noinspection HardCodedStringLiteral
+ super.sequenceCurrentValueFunction = "%s.currval";
+ }
+
+ private void tryProxySession(final String url, final Connection con) {
+ Matcher m = PROXY_USER.matcher(url);
+ if (m.matches()) {
+ Properties props = new Properties();
+ props.put("PROXY_USER_NAME", m.group(1));
+ try {
+ Method method = con.getClass().getMethod("openProxySession", int.class, Properties.class);
+ method.setAccessible(true);
+ method.invoke(con, 1, props);
+ } catch (Exception e) {
+ Scope.getCurrentScope().getLog(getClass()).info("Could not open proxy session on OracleDatabase: " + e.getCause().getMessage());
+ }
+ }
+ }
+
+ @Override
+ public int getDatabaseMajorVersion() throws DatabaseException {
+ if (databaseMajorVersion == null) {
+ return super.getDatabaseMajorVersion();
+ } else {
+ return databaseMajorVersion;
+ }
+ }
+
+ @Override
+ public int getDatabaseMinorVersion() throws DatabaseException {
+ if (databaseMinorVersion == null) {
+ return super.getDatabaseMinorVersion();
+ } else {
+ return databaseMinorVersion;
+ }
+ }
+
+ @Override
+ public String getJdbcCatalogName(CatalogAndSchema schema) {
+ return null;
+ }
+
+ @Override
+ public String getJdbcSchemaName(CatalogAndSchema schema) {
+ return correctObjectName((schema.getCatalogName() == null) ? schema.getSchemaName() : schema.getCatalogName(), Schema.class);
+ }
+
+ @Override
+ protected String getAutoIncrementClause(final String generationType, final Boolean defaultOnNull) {
+ if (StringUtil.isEmpty(generationType)) {
+ return super.getAutoIncrementClause();
+ }
+
+ String autoIncrementClause = "GENERATED %s AS IDENTITY"; // %s -- [ ALWAYS | BY DEFAULT [ ON NULL ] ]
+ String generationStrategy = generationType;
+ if (Boolean.TRUE.equals(defaultOnNull) && generationType.toUpperCase().equals("BY DEFAULT")) {
+ generationStrategy += " ON NULL";
+ }
+ return String.format(autoIncrementClause, generationStrategy);
+ }
+
+ @Override
+ public String generatePrimaryKeyName(String tableName) {
+ if (tableName.length() > 27) {
+ //noinspection HardCodedStringLiteral
+ return "PK_" + tableName.toUpperCase(Locale.US).substring(0, 27);
+ } else {
+ //noinspection HardCodedStringLiteral
+ return "PK_" + tableName.toUpperCase(Locale.US);
+ }
+ }
+
+ @Override
+ public boolean isReservedWord(String objectName) {
+ return reservedWords.contains(objectName.toUpperCase());
+ }
+
+ @Override
+ public boolean supportsSequences() {
+ return true;
+ }
+
+ /**
+ * Oracle supports catalogs in liquibase terms
+ *
+ * @return false
+ */
+ @Override
+ public boolean supportsSchemas() {
+ return false;
+ }
+
+ @Override
+ protected String getConnectionCatalogName() throws DatabaseException {
+ if (getConnection() instanceof OfflineConnection) {
+ return getConnection().getCatalog();
+ }
+ try {
+ //noinspection HardCodedStringLiteral
+ return Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", this).queryForObject(new RawCallStatement("select sys_context( 'userenv', 'current_schema' ) from dual"), String.class);
+ } catch (Exception e) {
+ //noinspection HardCodedStringLiteral
+ Scope.getCurrentScope().getLog(getClass()).info("Error getting default schema", e);
+ }
+ return null;
+ }
+
+ @Override
+ public String getDefaultCatalogName() {//NOPMD
+ return (super.getDefaultCatalogName() == null) ? null : super.getDefaultCatalogName().toUpperCase(Locale.US);
+ }
+
+ /**
+ * Returns an Oracle date literal with the same value as a string formatted using ISO 8601.
+ *
+ * Convert an ISO8601 date string to one of the following results:
+ * to_date('1995-05-23', 'YYYY-MM-DD')
+ * to_date('1995-05-23 09:23:59', 'YYYY-MM-DD HH24:MI:SS')
+ *
+ * Implementation restriction:
+ * Currently, only the following subsets of ISO8601 are supported:
+ *
+ * YYYY-MM-DD
+ * YYYY-MM-DDThh:mm:ss
+ *
+ */
+ @Override
+ public String getDateLiteral(String isoDate) {
+ String normalLiteral = super.getDateLiteral(isoDate);
+
+ if (isDateOnly(isoDate)) {
+ return "TO_DATE(" + normalLiteral + ", 'YYYY-MM-DD')";
+ } else if (isTimeOnly(isoDate)) {
+ return "TO_DATE(" + normalLiteral + ", 'HH24:MI:SS')";
+ } else if (isTimestamp(isoDate)) {
+ return "TO_TIMESTAMP(" + normalLiteral + ", 'YYYY-MM-DD HH24:MI:SS.FF')";
+ } else if (isDateTime(isoDate)) {
+ int seppos = normalLiteral.lastIndexOf('.');
+ if (seppos != -1) {
+ normalLiteral = normalLiteral.substring(0, seppos) + "'";
+ }
+ return "TO_DATE(" + normalLiteral + ", 'YYYY-MM-DD HH24:MI:SS')";
+ }
+ return "UNSUPPORTED:" + isoDate;
+ }
+
+ @Override
+ public boolean isSystemObject(DatabaseObject example) {
+ if (example == null) {
+ return false;
+ }
+
+ if (this.isLiquibaseObject(example)) {
+ return false;
+ }
+
+ if (example instanceof Schema) {
+ //noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral
+ if ("SYSTEM".equals(example.getName()) || "SYS".equals(example.getName()) || "CTXSYS".equals(example.getName()) || "XDB".equals(example.getName())) {
+ return true;
+ }
+ //noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral
+ if ("SYSTEM".equals(example.getSchema().getCatalogName()) || "SYS".equals(example.getSchema().getCatalogName()) || "CTXSYS".equals(example.getSchema().getCatalogName()) || "XDB".equals(example.getSchema().getCatalogName())) {
+ return true;
+ }
+ } else if (isSystemObject(example.getSchema())) {
+ return true;
+ }
+ if (example instanceof Catalog) {
+ //noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral
+ if (("SYSTEM".equals(example.getName()) || "SYS".equals(example.getName()) || "CTXSYS".equals(example.getName()) || "XDB".equals(example.getName()))) {
+ return true;
+ }
+ } else if (example.getName() != null) {
+ //noinspection HardCodedStringLiteral
+ if (example.getName().startsWith("BIN$")) { //oracle deleted table
+ boolean filteredInOriginalQuery = this.canAccessDbaRecycleBin();
+ if (!filteredInOriginalQuery) {
+ filteredInOriginalQuery = StringUtil.trimToEmpty(example.getSchema().getName()).equalsIgnoreCase(this.getConnection().getConnectionUserName());
+ }
+
+ if (filteredInOriginalQuery) {
+ return !((example instanceof PrimaryKey) || (example instanceof Index) || (example instanceof
+ liquibase.statement.UniqueConstraint));
+ } else {
+ return true;
+ }
+ } else //noinspection HardCodedStringLiteral
+ if (example.getName().startsWith("AQ$")) { //oracle AQ tables
+ return true;
+ } else //noinspection HardCodedStringLiteral
+ if (example.getName().startsWith("DR$")) { //oracle index tables
+ return true;
+ } else //noinspection HardCodedStringLiteral
+ if (example.getName().startsWith("SYS_IOT_OVER")) { //oracle system table
+ return true;
+ } else //noinspection HardCodedStringLiteral,HardCodedStringLiteral
+ if ((example.getName().startsWith("MDRT_") || example.getName().startsWith("MDRS_")) && example.getName().endsWith("$")) {
+ // CORE-1768 - Oracle creates these for spatial indices and will remove them when the index is removed.
+ return true;
+ } else //noinspection HardCodedStringLiteral
+ 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.
+ return true;
+ } else //noinspection HardCodedStringLiteral
+ if (example.getName().startsWith("RUPD$_")) { //Created by materialized view log tables using primary keys. Not available for DDL operations.
+ return true;
+ } else //noinspection HardCodedStringLiteral
+ if (example.getName().startsWith("WM$_")) { //Workspace Manager backup tables.
+ return true;
+ } else //noinspection HardCodedStringLiteral
+ 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.
+ return true;
+ } else //noinspection HardCodedStringLiteral
+ if ("JAVA$CLASS$MD5$TABLE".equals(example.getName())) { //This is a hash table that tracks the loading of Java objects into a schema.
+ return true;
+ } else //noinspection HardCodedStringLiteral
+ if (example.getName().startsWith("ISEQ$$_")) { //System-generated sequence
+ return true;
+ } else //noinspection HardCodedStringLiteral
+ if (example.getName().startsWith("USLOG$")) { //for update materialized view
+ return true;
+ } else if (example.getName().startsWith("SYS_FBA")) { //for Flashback tables
+ return true;
+ }
+ }
+
+ return super.isSystemObject(example);
+ }
+
+ @Override
+ public boolean supportsAutoIncrement() {
+ // Oracle supports Identity beginning with version 12c
+ boolean isAutoIncrementSupported = false;
+
+ try {
+ if (getDatabaseMajorVersion() >= 12) {
+ isAutoIncrementSupported = true;
+ }
+
+ // Returning true will generate create table command with 'IDENTITY' clause, example:
+ // 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));
+
+ // While returning false will continue to generate create table command without 'IDENTITY' clause, example:
+ // CREATE TABLE AutoIncTest (IDPrimaryKey NUMBER(19) NOT NULL, TypeID NUMBER(3) NOT NULL, Description NVARCHAR2(50), CONSTRAINT PK_AutoIncTest PRIMARY KEY (IDPrimaryKey));
+
+ } catch (DatabaseException ex) {
+ isAutoIncrementSupported = false;
+ }
+
+ return isAutoIncrementSupported;
+ }
+
+
+// public Set findUniqueConstraints(String schema) throws DatabaseException {
+// Set returnSet = new HashSet();
+//
+// List 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"));
+//
+// UniqueConstraint constraint = null;
+// for (Map map : maps) {
+// if (constraint == null || !constraint.getName().equals(constraint.getName())) {
+// returnSet.add(constraint);
+// Table table = new Table((String) map.get("TABLE_NAME"));
+// constraint = new UniqueConstraint(map.get("CONSTRAINT_NAME").toString(), table);
+// }
+// }
+// if (constraint != null) {
+// returnSet.add(constraint);
+// }
+//
+// return returnSet;
+// }
+
+ @Override
+ public boolean supportsRestrictForeignKeys() {
+ return false;
+ }
+
+ @Override
+ public int getDataTypeMaxParameters(String dataTypeName) {
+ //noinspection HardCodedStringLiteral
+ if ("BINARY_FLOAT".equals(dataTypeName.toUpperCase())) {
+ return 0;
+ }
+ //noinspection HardCodedStringLiteral
+ if ("BINARY_DOUBLE".equals(dataTypeName.toUpperCase())) {
+ return 0;
+ }
+ return super.getDataTypeMaxParameters(dataTypeName);
+ }
+
+ public String getSystemTableWhereClause(String tableNameColumn) {
+ List clauses = new ArrayList(Arrays.asList("BIN$",
+ "AQ$",
+ "DR$",
+ "SYS_IOT_OVER",
+ "MLOG$_",
+ "RUPD$_",
+ "WM$_",
+ "ISEQ$$_",
+ "USLOG$",
+ "SYS_FBA"));
+
+ for (int i = 0;i getUserDefinedTypes() {
+ if (userDefinedTypes == null) {
+ userDefinedTypes = new HashSet<>();
+ if ((getConnection() != null) && !(getConnection() instanceof OfflineConnection)) {
+ try {
+ try {
+ //noinspection HardCodedStringLiteral
+ userDefinedTypes.addAll(Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", this).queryForList(new RawSqlStatement("SELECT DISTINCT TYPE_NAME FROM ALL_TYPES"), String.class));
+ } catch (DatabaseException e) { //fall back to USER_TYPES if the user cannot see ALL_TYPES
+ //noinspection HardCodedStringLiteral
+ userDefinedTypes.addAll(Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", this).queryForList(new RawSqlStatement("SELECT TYPE_NAME FROM USER_TYPES"), String.class));
+ }
+ } catch (DatabaseException e) {
+ //ignore error
+ }
+ }
+ }
+
+ return userDefinedTypes;
+ }
+
+ @Override
+ public String generateDatabaseFunctionValue(DatabaseFunction databaseFunction) {
+ //noinspection HardCodedStringLiteral
+ if ((databaseFunction != null) && "current_timestamp".equalsIgnoreCase(databaseFunction.toString())) {
+ return databaseFunction.toString();
+ }
+ if ((databaseFunction instanceof SequenceNextValueFunction) || (databaseFunction instanceof
+ SequenceCurrentValueFunction)) {
+ String quotedSeq = super.generateDatabaseFunctionValue(databaseFunction);
+ // replace "myschema.my_seq".nextval with "myschema"."my_seq".nextval
+ return quotedSeq.replaceFirst("\"([^\\.\"]+)\\.([^\\.\"]+)\"", "\"$1\".\"$2\"");
+
+ }
+
+ return super.generateDatabaseFunctionValue(databaseFunction);
+ }
+
+ @Override
+ public ValidationErrors validate() {
+ ValidationErrors errors = super.validate();
+ DatabaseConnection connection = getConnection();
+ if ((connection == null) || (connection instanceof OfflineConnection)) {
+ //noinspection HardCodedStringLiteral
+ Scope.getCurrentScope().getLog(getClass()).info("Cannot validate offline database");
+ return errors;
+ }
+
+ if (!canAccessDbaRecycleBin()) {
+ errors.addWarning(getDbaRecycleBinWarning());
+ }
+
+ return errors;
+
+ }
+
+ public String getDbaRecycleBinWarning() {
+ //noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,
+ // HardCodedStringLiteral
+ //noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral
+ return "Liquibase needs to access the DBA_RECYCLEBIN table so we can automatically handle the case where " +
+ "constraints are deleted and restored. Since Oracle doesn't properly restore the original table names " +
+ "referenced in the constraint, we use the information from the DBA_RECYCLEBIN to automatically correct this" +
+ " issue.\n" +
+ "\n" +
+ "The user you used to connect to the database (" + getConnection().getConnectionUserName() +
+ ") needs to have \"SELECT ON SYS.DBA_RECYCLEBIN\" permissions set before we can perform this operation. " +
+ "Please run the following SQL to set the appropriate permissions, and try running the command again.\n" +
+ "\n" +
+ " GRANT SELECT ON SYS.DBA_RECYCLEBIN TO " + getConnection().getConnectionUserName() + ";";
+ }
+
+ public boolean canAccessDbaRecycleBin() {
+ if (canAccessDbaRecycleBin == null) {
+ DatabaseConnection connection = getConnection();
+ if ((connection == null) || (connection instanceof OfflineConnection)) {
+ return false;
+ }
+
+ Statement statement = null;
+ try {
+ statement = ((JdbcConnection) connection).createStatement();
+ @SuppressWarnings("HardCodedStringLiteral") ResultSet resultSet = statement.executeQuery("select 1 from dba_recyclebin where 0=1");
+ resultSet.close(); //don't need to do anything with the result set, just make sure statement ran.
+ this.canAccessDbaRecycleBin = true;
+ } catch (Exception e) {
+ //noinspection HardCodedStringLiteral
+ if ((e instanceof SQLException) && e.getMessage().startsWith("ORA-00942")) { //ORA-00942: table or view does not exist
+ this.canAccessDbaRecycleBin = false;
+ } else {
+ //noinspection HardCodedStringLiteral
+ Scope.getCurrentScope().getLog(getClass()).warning("Cannot check dba_recyclebin access", e);
+ this.canAccessDbaRecycleBin = false;
+ }
+ } finally {
+ JdbcUtils.close(null, statement);
+ }
+ }
+
+ return canAccessDbaRecycleBin;
+ }
+
+ @Override
+ public boolean supportsNotNullConstraintNames() {
+ return true;
+ }
+
+ /**
+ * Tests if the given String would be a valid identifier in Oracle DBMS. In Oracle, a valid identifier has
+ * the following form (case-insensitive comparison):
+ * 1st character: A-Z
+ * 2..n characters: A-Z0-9$_#
+ * The maximum length of an identifier differs by Oracle version and object type.
+ */
+ public boolean isValidOracleIdentifier(String identifier, Class extends DatabaseObject> type) {
+ if ((identifier == null) || (identifier.length() < 1))
+ return false;
+
+ if (!identifier.matches("^(i?)[A-Z][A-Z0-9\\$\\_\\#]*$"))
+ return false;
+
+ /*
+ * @todo It seems we currently do not have a class for tablespace identifiers, and all other classes
+ * we do know seem to be supported as 12cR2 long identifiers, so:
+ */
+ return (identifier.length() <= LONG_IDENTIFIERS_LEGNTH);
+ }
+
+ /**
+ * Returns the maximum number of bytes (NOT: characters) for an identifier. For Oracle <=12c Release 20, this
+ * is 30 bytes, and starting from 12cR2, up to 128 (except for tablespaces, PDB names and some other rather rare
+ * object types).
+ *
+ * @return the maximum length of an object identifier, in bytes
+ */
+ public int getIdentifierMaximumLength() {
+ try {
+ if (getDatabaseMajorVersion() < ORACLE_12C_MAJOR_VERSION) {
+ return SHORT_IDENTIFIERS_LENGTH;
+ } else if ((getDatabaseMajorVersion() == ORACLE_12C_MAJOR_VERSION) && (getDatabaseMinorVersion() <= 1)) {
+ return SHORT_IDENTIFIERS_LENGTH;
+ } else {
+ return LONG_IDENTIFIERS_LEGNTH;
+ }
+ } catch (DatabaseException ex) {
+ throw new UnexpectedLiquibaseException("Cannot determine the Oracle database version number", ex);
+ }
+
+ }
+}
diff --git a/sql/dm/flowable-patch/src/main/java/liquibase/datatype/core/BooleanType.java b/sql/dm/flowable-patch/src/main/java/liquibase/datatype/core/BooleanType.java
new file mode 100644
index 000000000..cda2492e2
--- /dev/null
+++ b/sql/dm/flowable-patch/src/main/java/liquibase/datatype/core/BooleanType.java
@@ -0,0 +1,165 @@
+package liquibase.datatype.core;
+
+import liquibase.change.core.LoadDataChange;
+import liquibase.database.Database;
+import liquibase.database.core.*;
+import liquibase.datatype.DataTypeInfo;
+import liquibase.datatype.DatabaseDataType;
+import liquibase.datatype.LiquibaseDataType;
+import liquibase.exception.UnexpectedLiquibaseException;
+import liquibase.statement.DatabaseFunction;
+import liquibase.util.StringUtil;
+
+import java.util.Locale;
+import java.util.regex.Pattern;
+
+@DataTypeInfo(name = "boolean", aliases = {"java.sql.Types.BOOLEAN", "java.lang.Boolean", "bit", "bool"}, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT)
+public class BooleanType extends LiquibaseDataType {
+
+ @Override
+ public DatabaseDataType toDatabaseDataType(Database database) {
+ String originalDefinition = StringUtil.trimToEmpty(getRawDefinition());
+ if ((database instanceof Firebird3Database)) {
+ return new DatabaseDataType("BOOLEAN");
+ }
+
+ if ((database instanceof Db2zDatabase) || (database instanceof FirebirdDatabase)) {
+ return new DatabaseDataType("SMALLINT");
+ } else if (database instanceof MSSQLDatabase) {
+ return new DatabaseDataType(database.escapeDataTypeName("bit"));
+ } else if (database instanceof MySQLDatabase) {
+ if (originalDefinition.toLowerCase(Locale.US).startsWith("bit")) {
+ return new DatabaseDataType("BIT", getParameters());
+ }
+ return new DatabaseDataType("BIT", 1);
+ } else if (database instanceof OracleDatabase) {
+ return new DatabaseDataType("NUMBER", 1);
+ } else if ((database instanceof SybaseASADatabase) || (database instanceof SybaseDatabase)) {
+ return new DatabaseDataType("BIT");
+ } else if (database instanceof DerbyDatabase) {
+ if (((DerbyDatabase) database).supportsBooleanDataType()) {
+ return new DatabaseDataType("BOOLEAN");
+ } else {
+ return new DatabaseDataType("SMALLINT");
+ }
+ } else if (database instanceof DB2Database) {
+ if (((DB2Database) database).supportsBooleanDataType())
+ return new DatabaseDataType("BOOLEAN");
+ else
+ return new DatabaseDataType("SMALLINT");
+ } else if (database instanceof HsqlDatabase) {
+ return new DatabaseDataType("BOOLEAN");
+ } else if (database instanceof PostgresDatabase) {
+ if (originalDefinition.toLowerCase(Locale.US).startsWith("bit")) {
+ return new DatabaseDataType("BIT", getParameters());
+ }
+ } else if (database instanceof DmDatabase) { // dhb52: DM Support
+ return new DatabaseDataType("bit");
+ }
+
+ return super.toDatabaseDataType(database);
+ }
+
+ @Override
+ public String objectToSql(Object value, Database database) {
+ if ((value == null) || "null".equals(value.toString().toLowerCase(Locale.US))) {
+ return null;
+ }
+
+ String returnValue;
+ if (value instanceof String) {
+ value = ((String) value).replaceAll("'", "");
+ 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))) {
+ returnValue = this.getTrueBooleanValue(database);
+ } else if ("false".equals(((String) value).toLowerCase(Locale.US)) || "0".equals(value) || "b'0'".equals(
+ ((String) value).toLowerCase(Locale.US)) || "f".equals(((String) value).toLowerCase(Locale.US)) || ((String) value).toLowerCase(Locale.US).equals(this.getFalseBooleanValue(database).toLowerCase(Locale.US))) {
+ returnValue = this.getFalseBooleanValue(database);
+ } else if (database instanceof PostgresDatabase && Pattern.matches("b?([01])\\1*(::bit|::\"bit\")?", (String) value)) {
+ returnValue = "b'"
+ + value.toString()
+ .replace("b", "")
+ .replace("\"", "")
+ .replace("::it", "")
+ + "'::\"bit\"";
+ } else {
+ throw new UnexpectedLiquibaseException("Unknown boolean value: " + value);
+ }
+ } else if (value instanceof Long) {
+ if (Long.valueOf(1).equals(value)) {
+ returnValue = this.getTrueBooleanValue(database);
+ } else {
+ returnValue = this.getFalseBooleanValue(database);
+ }
+ } else if (value instanceof Number) {
+ if (value.equals(1) || "1".equals(value.toString()) || "1.0".equals(value.toString())) {
+ returnValue = this.getTrueBooleanValue(database);
+ } else {
+ returnValue = this.getFalseBooleanValue(database);
+ }
+ } else if (value instanceof DatabaseFunction) {
+ return value.toString();
+ } else if (value instanceof Boolean) {
+ if (((Boolean) value)) {
+ returnValue = this.getTrueBooleanValue(database);
+ } else {
+ returnValue = this.getFalseBooleanValue(database);
+ }
+ } else {
+ throw new UnexpectedLiquibaseException("Cannot convert type " + value.getClass() + " to a boolean value");
+ }
+
+ return returnValue;
+ }
+
+ protected boolean isNumericBoolean(Database database) {
+ if (database instanceof Firebird3Database) {
+ return false;
+ }
+ if (database instanceof DerbyDatabase) {
+ return !((DerbyDatabase) database).supportsBooleanDataType();
+ } else if (database instanceof DB2Database) {
+ return !((DB2Database) database).supportsBooleanDataType();
+ }
+ return (database instanceof Db2zDatabase)
+ || (database instanceof FirebirdDatabase)
+ || (database instanceof MSSQLDatabase)
+ || (database instanceof MySQLDatabase)
+ || (database instanceof OracleDatabase)
+ || (database instanceof SQLiteDatabase)
+ || (database instanceof SybaseASADatabase)
+ || (database instanceof SybaseDatabase)
+ || (database instanceof DmDatabase); // dhb52: DM Support
+ }
+
+ /**
+ * The database-specific value to use for "false" "boolean" columns.
+ */
+ public String getFalseBooleanValue(Database database) {
+ if (isNumericBoolean(database)) {
+ return "0";
+ }
+ if (database instanceof InformixDatabase) {
+ return "'f'";
+ }
+ return "FALSE";
+ }
+
+ /**
+ * The database-specific value to use for "true" "boolean" columns.
+ */
+ public String getTrueBooleanValue(Database database) {
+ if (isNumericBoolean(database)) {
+ return "1";
+ }
+ if (database instanceof InformixDatabase) {
+ return "'t'";
+ }
+ return "TRUE";
+ }
+
+ @Override
+ public LoadDataChange.LOAD_DATA_TYPE getLoadTypeName() {
+ return LoadDataChange.LOAD_DATA_TYPE.BOOLEAN;
+ }
+
+}
diff --git a/sql/dm/flowable-patch/src/main/java/org/flowable/common/engine/impl/AbstractEngineConfiguration.java b/sql/dm/flowable-patch/src/main/java/org/flowable/common/engine/impl/AbstractEngineConfiguration.java
new file mode 100644
index 000000000..33c52d551
--- /dev/null
+++ b/sql/dm/flowable-patch/src/main/java/org/flowable/common/engine/impl/AbstractEngineConfiguration.java
@@ -0,0 +1,2068 @@
+/* Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.flowable.common.engine.impl;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ibatis.builder.xml.XMLConfigBuilder;
+import org.apache.ibatis.builder.xml.XMLMapperBuilder;
+import org.apache.ibatis.datasource.pooled.PooledDataSource;
+import org.apache.ibatis.mapping.Environment;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;
+import org.apache.ibatis.transaction.TransactionFactory;
+import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
+import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;
+import org.apache.ibatis.type.ArrayTypeHandler;
+import org.apache.ibatis.type.BigDecimalTypeHandler;
+import org.apache.ibatis.type.BlobInputStreamTypeHandler;
+import org.apache.ibatis.type.BlobTypeHandler;
+import org.apache.ibatis.type.BooleanTypeHandler;
+import org.apache.ibatis.type.ByteTypeHandler;
+import org.apache.ibatis.type.ClobTypeHandler;
+import org.apache.ibatis.type.DateOnlyTypeHandler;
+import org.apache.ibatis.type.DateTypeHandler;
+import org.apache.ibatis.type.DoubleTypeHandler;
+import org.apache.ibatis.type.FloatTypeHandler;
+import org.apache.ibatis.type.IntegerTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.LongTypeHandler;
+import org.apache.ibatis.type.NClobTypeHandler;
+import org.apache.ibatis.type.NStringTypeHandler;
+import org.apache.ibatis.type.ShortTypeHandler;
+import org.apache.ibatis.type.SqlxmlTypeHandler;
+import org.apache.ibatis.type.StringTypeHandler;
+import org.apache.ibatis.type.TimeOnlyTypeHandler;
+import org.apache.ibatis.type.TypeHandlerRegistry;
+import org.flowable.common.engine.api.FlowableException;
+import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
+import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
+import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
+import org.flowable.common.engine.api.engine.EngineLifecycleListener;
+import org.flowable.common.engine.impl.agenda.AgendaOperationRunner;
+import org.flowable.common.engine.impl.cfg.CommandExecutorImpl;
+import org.flowable.common.engine.impl.cfg.IdGenerator;
+import org.flowable.common.engine.impl.cfg.TransactionContextFactory;
+import org.flowable.common.engine.impl.cfg.standalone.StandaloneMybatisTransactionContextFactory;
+import org.flowable.common.engine.impl.db.CommonDbSchemaManager;
+import org.flowable.common.engine.impl.db.DbSqlSessionFactory;
+import org.flowable.common.engine.impl.db.LogSqlExecutionTimePlugin;
+import org.flowable.common.engine.impl.db.MybatisTypeAliasConfigurator;
+import org.flowable.common.engine.impl.db.MybatisTypeHandlerConfigurator;
+import org.flowable.common.engine.impl.db.SchemaManager;
+import org.flowable.common.engine.impl.event.EventDispatchAction;
+import org.flowable.common.engine.impl.event.FlowableEventDispatcherImpl;
+import org.flowable.common.engine.impl.interceptor.Command;
+import org.flowable.common.engine.impl.interceptor.CommandConfig;
+import org.flowable.common.engine.impl.interceptor.CommandContextFactory;
+import org.flowable.common.engine.impl.interceptor.CommandContextInterceptor;
+import org.flowable.common.engine.impl.interceptor.CommandExecutor;
+import org.flowable.common.engine.impl.interceptor.CommandInterceptor;
+import org.flowable.common.engine.impl.interceptor.CrDbRetryInterceptor;
+import org.flowable.common.engine.impl.interceptor.DefaultCommandInvoker;
+import org.flowable.common.engine.impl.interceptor.LogInterceptor;
+import org.flowable.common.engine.impl.interceptor.SessionFactory;
+import org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor;
+import org.flowable.common.engine.impl.lock.LockManager;
+import org.flowable.common.engine.impl.lock.LockManagerImpl;
+import org.flowable.common.engine.impl.logging.LoggingListener;
+import org.flowable.common.engine.impl.logging.LoggingSession;
+import org.flowable.common.engine.impl.logging.LoggingSessionFactory;
+import org.flowable.common.engine.impl.persistence.GenericManagerFactory;
+import org.flowable.common.engine.impl.persistence.StrongUuidGenerator;
+import org.flowable.common.engine.impl.persistence.cache.EntityCache;
+import org.flowable.common.engine.impl.persistence.cache.EntityCacheImpl;
+import org.flowable.common.engine.impl.persistence.entity.ByteArrayEntityManager;
+import org.flowable.common.engine.impl.persistence.entity.ByteArrayEntityManagerImpl;
+import org.flowable.common.engine.impl.persistence.entity.Entity;
+import org.flowable.common.engine.impl.persistence.entity.PropertyEntityManager;
+import org.flowable.common.engine.impl.persistence.entity.PropertyEntityManagerImpl;
+import org.flowable.common.engine.impl.persistence.entity.TableDataManager;
+import org.flowable.common.engine.impl.persistence.entity.TableDataManagerImpl;
+import org.flowable.common.engine.impl.persistence.entity.data.ByteArrayDataManager;
+import org.flowable.common.engine.impl.persistence.entity.data.PropertyDataManager;
+import org.flowable.common.engine.impl.persistence.entity.data.impl.MybatisByteArrayDataManager;
+import org.flowable.common.engine.impl.persistence.entity.data.impl.MybatisPropertyDataManager;
+import org.flowable.common.engine.impl.runtime.Clock;
+import org.flowable.common.engine.impl.service.CommonEngineServiceImpl;
+import org.flowable.common.engine.impl.util.DefaultClockImpl;
+import org.flowable.common.engine.impl.util.IoUtil;
+import org.flowable.common.engine.impl.util.ReflectUtil;
+import org.flowable.eventregistry.api.EventRegistryEventConsumer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+
+public abstract class AbstractEngineConfiguration {
+
+ protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+ /** The tenant id indicating 'no tenant' */
+ public static final String NO_TENANT_ID = "";
+
+ /**
+ * 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.
+ */
+ public static final String DB_SCHEMA_UPDATE_FALSE = "false";
+ public static final String DB_SCHEMA_UPDATE_CREATE = "create";
+ public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop";
+
+ /**
+ * Creates the schema when the form engine is being created and drops the schema when the form engine is being closed.
+ */
+ public static final String DB_SCHEMA_UPDATE_DROP_CREATE = "drop-create";
+
+ /**
+ * Upon building of the process engine, a check is performed and an update of the schema is performed if it is necessary.
+ */
+ public static final String DB_SCHEMA_UPDATE_TRUE = "true";
+
+ protected boolean forceCloseMybatisConnectionPool = true;
+
+ protected String databaseType;
+ protected String jdbcDriver = "org.h2.Driver";
+ protected String jdbcUrl = "jdbc:h2:tcp://localhost/~/flowable";
+ protected String jdbcUsername = "sa";
+ protected String jdbcPassword = "";
+ protected String dataSourceJndiName;
+ protected int jdbcMaxActiveConnections = 16;
+ protected int jdbcMaxIdleConnections = 8;
+ protected int jdbcMaxCheckoutTime;
+ protected int jdbcMaxWaitTime;
+ protected boolean jdbcPingEnabled;
+ protected String jdbcPingQuery;
+ protected int jdbcPingConnectionNotUsedFor;
+ protected int jdbcDefaultTransactionIsolationLevel;
+ protected DataSource dataSource;
+ protected SchemaManager commonSchemaManager;
+ protected SchemaManager schemaManager;
+ protected Command schemaManagementCmd;
+
+ protected String databaseSchemaUpdate = DB_SCHEMA_UPDATE_FALSE;
+
+ /**
+ * Whether to use a lock when performing the database schema create or update operations.
+ */
+ protected boolean useLockForDatabaseSchemaUpdate = false;
+
+ protected String xmlEncoding = "UTF-8";
+
+ // COMMAND EXECUTORS ///////////////////////////////////////////////
+
+ protected CommandExecutor commandExecutor;
+ protected Collection extends CommandInterceptor> defaultCommandInterceptors;
+ protected CommandConfig defaultCommandConfig;
+ protected CommandConfig schemaCommandConfig;
+ protected CommandContextFactory commandContextFactory;
+ protected CommandInterceptor commandInvoker;
+
+ protected AgendaOperationRunner agendaOperationRunner = (commandContext, runnable) -> runnable.run();
+
+ protected List customPreCommandInterceptors;
+ protected List customPostCommandInterceptors;
+ protected List commandInterceptors;
+
+ protected Map engineConfigurations = new HashMap<>();
+ protected Map serviceConfigurations = new HashMap<>();
+
+ protected ClassLoader classLoader;
+ /**
+ * Either use Class.forName or ClassLoader.loadClass for class loading. See http://forums.activiti.org/content/reflectutilloadclass-and-custom- classloader
+ */
+ protected boolean useClassForNameClassLoading = true;
+
+ protected List engineLifecycleListeners;
+
+ // Event Registry //////////////////////////////////////////////////
+ protected Map eventRegistryEventConsumers = new HashMap<>();
+
+ // MYBATIS SQL SESSION FACTORY /////////////////////////////////////
+
+ protected boolean isDbHistoryUsed = true;
+ protected DbSqlSessionFactory dbSqlSessionFactory;
+ protected SqlSessionFactory sqlSessionFactory;
+ protected TransactionFactory transactionFactory;
+ protected TransactionContextFactory transactionContextFactory;
+
+ /**
+ * If set to true, enables bulk insert (grouping sql inserts together). Default true.
+ * For some databases (eg DB2+z/OS) needs to be set to false.
+ */
+ protected boolean isBulkInsertEnabled = true;
+
+ /**
+ * 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
+ * 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.
+ *
+ * By default: 100 (55 for mssql server as it has a hard limit of 2000 parameters in a statement)
+ */
+ protected int maxNrOfStatementsInBulkInsert = 100;
+
+ public int DEFAULT_MAX_NR_OF_STATEMENTS_BULK_INSERT_SQL_SERVER = 55; // currently Execution has most params (35). 2000 / 35 = 57.
+
+ protected String mybatisMappingFile;
+ protected Set> customMybatisMappers;
+ protected Set customMybatisXMLMappers;
+ protected List customMybatisInterceptors;
+
+ protected Set dependentEngineMyBatisXmlMappers;
+ protected List dependentEngineMybatisTypeAliasConfigs;
+ protected List dependentEngineMybatisTypeHandlerConfigs;
+
+ // SESSION FACTORIES ///////////////////////////////////////////////
+ protected List customSessionFactories;
+ protected Map, SessionFactory> sessionFactories;
+
+ protected boolean enableEventDispatcher = true;
+ protected FlowableEventDispatcher eventDispatcher;
+ protected List eventListeners;
+ protected Map> typedEventListeners;
+ protected List additionalEventDispatchActions;
+
+ protected LoggingListener loggingListener;
+
+ protected boolean transactionsExternallyManaged;
+
+ /**
+ * 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.
+ *
+ * If true (default), the {@link AbstractEngineConfiguration#getDatabaseSchemaUpdate()} value will be used to determine what needs to happen wrt the database schema.
+ *
+ * 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
+ * correct. The {@link AbstractEngineConfiguration#getDatabaseSchemaUpdate()} value will not be used.
+ */
+ protected boolean usingRelationalDatabase = true;
+
+ /**
+ * 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.
+ * Setting {@link #usingRelationalDatabase} to true will automatically imply using a schema.
+ */
+ protected boolean usingSchemaMgmt = true;
+
+ /**
+ * 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
+ * in a table named 'PRE1.ACT_RU_EXECUTION_'.
+ *
+ *
+ * NOTE: the prefix is not respected by automatic database schema management. If you use {@link AbstractEngineConfiguration#DB_SCHEMA_UPDATE_CREATE_DROP} or
+ * {@link AbstractEngineConfiguration#DB_SCHEMA_UPDATE_TRUE}, Flowable will create the database tables using the default names, regardless of the prefix configured here.
+ */
+ protected String databaseTablePrefix = "";
+
+ /**
+ * Escape character for doing wildcard searches.
+ *
+ * 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 '\';
+ */
+ protected String databaseWildcardEscapeCharacter;
+
+ /**
+ * database catalog to use
+ */
+ protected String databaseCatalog = "";
+
+ /**
+ * 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,
+ * https://jira.codehaus.org/browse/ACT-1062
+ */
+ protected String databaseSchema;
+
+ /**
+ * 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
+ * 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.
+ */
+ protected boolean tablePrefixIsSchema;
+
+ /**
+ * Set to true if the latest version of a definition should be retrieved, ignoring a possible parent deployment id value
+ */
+ protected boolean alwaysLookupLatestDefinitionVersion;
+
+ /**
+ * Set to true if by default lookups should fallback to the default tenant (an empty string by default or a defined tenant value)
+ */
+ protected boolean fallbackToDefaultTenant;
+
+ /**
+ * Default tenant provider that is executed when looking up definitions, in case the global or local fallback to default tenant value is true
+ */
+ protected DefaultTenantProvider defaultTenantProvider = (tenantId, scope, scopeKey) -> NO_TENANT_ID;
+
+ /**
+ * Enables the MyBatis plugin that logs the execution time of sql statements.
+ */
+ protected boolean enableLogSqlExecutionTime;
+
+ protected Properties databaseTypeMappings = getDefaultDatabaseTypeMappings();
+
+ /**
+ * Duration between the checks when acquiring a lock.
+ */
+ protected Duration lockPollRate = Duration.ofSeconds(10);
+
+ /**
+ * Duration to wait for the DB Schema lock before giving up.
+ */
+ protected Duration schemaLockWaitTime = Duration.ofMinutes(5);
+
+ // DATA MANAGERS //////////////////////////////////////////////////////////////////
+
+ protected PropertyDataManager propertyDataManager;
+ protected ByteArrayDataManager byteArrayDataManager;
+ protected TableDataManager tableDataManager;
+
+ // ENTITY MANAGERS ////////////////////////////////////////////////////////////////
+
+ protected PropertyEntityManager propertyEntityManager;
+ protected ByteArrayEntityManager byteArrayEntityManager;
+
+ protected List customPreDeployers;
+ protected List customPostDeployers;
+ protected List deployers;
+
+ // CONFIGURATORS ////////////////////////////////////////////////////////////
+
+ protected boolean enableConfiguratorServiceLoader = true; // Enabled by default. In certain environments this should be set to false (eg osgi)
+ protected List configurators; // The injected configurators
+ protected List allConfigurators; // Including auto-discovered configurators
+ protected EngineConfigurator idmEngineConfigurator;
+ protected EngineConfigurator eventRegistryConfigurator;
+
+ public static final String PRODUCT_NAME_POSTGRES = "PostgreSQL";
+ public static final String PRODUCT_NAME_CRDB = "CockroachDB";
+
+ public static final String DATABASE_TYPE_H2 = "h2";
+ public static final String DATABASE_TYPE_HSQL = "hsql";
+ public static final String DATABASE_TYPE_MYSQL = "mysql";
+ public static final String DATABASE_TYPE_ORACLE = "oracle";
+ public static final String DATABASE_TYPE_POSTGRES = "postgres";
+ public static final String DATABASE_TYPE_MSSQL = "mssql";
+ public static final String DATABASE_TYPE_DB2 = "db2";
+ public static final String DATABASE_TYPE_COCKROACHDB = "cockroachdb";
+
+ public static Properties getDefaultDatabaseTypeMappings() {
+ Properties databaseTypeMappings = new Properties();
+ databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
+ databaseTypeMappings.setProperty("HSQL Database Engine", DATABASE_TYPE_HSQL);
+ databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
+ databaseTypeMappings.setProperty("MariaDB", DATABASE_TYPE_MYSQL);
+ databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
+ databaseTypeMappings.setProperty(PRODUCT_NAME_POSTGRES, DATABASE_TYPE_POSTGRES);
+ databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL);
+ databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/NT", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/NT64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2 UDP", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUX", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUX390", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUXX8664", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUXZ64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUXPPC64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUXPPC64LE", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/400 SQL", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/6000", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2 UDB iSeries", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/AIX64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/HPUX", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/HP64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/SUN", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/SUN64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/PTX", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/2", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty(PRODUCT_NAME_CRDB, DATABASE_TYPE_COCKROACHDB);
+ databaseTypeMappings.setProperty("DM DBMS", DATABASE_TYPE_ORACLE); // dhb52: DM support
+ return databaseTypeMappings;
+ }
+
+ protected Map beans;
+
+ protected IdGenerator idGenerator;
+ protected boolean usePrefixId;
+
+ protected Clock clock;
+ protected ObjectMapper objectMapper;
+
+ // Variables
+
+ public static final int DEFAULT_GENERIC_MAX_LENGTH_STRING = 4000;
+ public static final int DEFAULT_ORACLE_MAX_LENGTH_STRING = 2000;
+
+ /**
+ * Define a max length for storing String variable types in the database. Mainly used for the Oracle NVARCHAR2 limit of 2000 characters
+ */
+ protected int maxLengthStringVariableType = -1;
+
+ protected void initEngineConfigurations() {
+ addEngineConfiguration(getEngineCfgKey(), getEngineScopeType(), this);
+ }
+
+ // DataSource
+ // ///////////////////////////////////////////////////////////////
+
+ protected void initDataSource() {
+ if (dataSource == null) {
+ if (dataSourceJndiName != null) {
+ try {
+ dataSource = (DataSource) new InitialContext().lookup(dataSourceJndiName);
+ } catch (Exception e) {
+ throw new FlowableException("couldn't lookup datasource from " + dataSourceJndiName + ": " + e.getMessage(), e);
+ }
+
+ } else if (jdbcUrl != null) {
+ if ((jdbcDriver == null) || (jdbcUsername == null)) {
+ throw new FlowableException("DataSource or JDBC properties have to be specified in a process engine configuration");
+ }
+
+ logger.debug("initializing datasource to db: {}", jdbcUrl);
+
+ if (logger.isInfoEnabled()) {
+ logger.info("Configuring Datasource with following properties (omitted password for security)");
+ logger.info("datasource driver : {}", jdbcDriver);
+ logger.info("datasource url : {}", jdbcUrl);
+ logger.info("datasource user name : {}", jdbcUsername);
+ }
+
+ PooledDataSource pooledDataSource = new PooledDataSource(this.getClass().getClassLoader(), jdbcDriver, jdbcUrl, jdbcUsername, jdbcPassword);
+
+ if (jdbcMaxActiveConnections > 0) {
+ pooledDataSource.setPoolMaximumActiveConnections(jdbcMaxActiveConnections);
+ }
+ if (jdbcMaxIdleConnections > 0) {
+ pooledDataSource.setPoolMaximumIdleConnections(jdbcMaxIdleConnections);
+ }
+ if (jdbcMaxCheckoutTime > 0) {
+ pooledDataSource.setPoolMaximumCheckoutTime(jdbcMaxCheckoutTime);
+ }
+ if (jdbcMaxWaitTime > 0) {
+ pooledDataSource.setPoolTimeToWait(jdbcMaxWaitTime);
+ }
+ if (jdbcPingEnabled) {
+ pooledDataSource.setPoolPingEnabled(true);
+ if (jdbcPingQuery != null) {
+ pooledDataSource.setPoolPingQuery(jdbcPingQuery);
+ }
+ pooledDataSource.setPoolPingConnectionsNotUsedFor(jdbcPingConnectionNotUsedFor);
+ }
+ if (jdbcDefaultTransactionIsolationLevel > 0) {
+ pooledDataSource.setDefaultTransactionIsolationLevel(jdbcDefaultTransactionIsolationLevel);
+ }
+ dataSource = pooledDataSource;
+ }
+ }
+
+ if (databaseType == null) {
+ initDatabaseType();
+ }
+ }
+
+ public void initDatabaseType() {
+ Connection connection = null;
+ try {
+ connection = dataSource.getConnection();
+ DatabaseMetaData databaseMetaData = connection.getMetaData();
+ String databaseProductName = databaseMetaData.getDatabaseProductName();
+ logger.debug("database product name: '{}'", databaseProductName);
+
+ // CRDB does not expose the version through the jdbc driver, so we need to fetch it through version().
+ if (PRODUCT_NAME_POSTGRES.equalsIgnoreCase(databaseProductName)) {
+ try (PreparedStatement preparedStatement = connection.prepareStatement("select version() as version;");
+ ResultSet resultSet = preparedStatement.executeQuery()) {
+ String version = null;
+ if (resultSet.next()) {
+ version = resultSet.getString("version");
+ }
+
+ if (StringUtils.isNotEmpty(version) && version.toLowerCase().startsWith(PRODUCT_NAME_CRDB.toLowerCase())) {
+ databaseProductName = PRODUCT_NAME_CRDB;
+ logger.info("CockroachDB version '{}' detected", version);
+ }
+ }
+ }
+
+ databaseType = databaseTypeMappings.getProperty(databaseProductName);
+ if (databaseType == null) {
+ throw new FlowableException("couldn't deduct database type from database product name '" + databaseProductName + "'");
+ }
+ logger.debug("using database type: {}", databaseType);
+
+ } catch (SQLException e) {
+ throw new RuntimeException("Exception while initializing Database connection", e);
+ } finally {
+ try {
+ if (connection != null) {
+ connection.close();
+ }
+ } catch (SQLException e) {
+ logger.error("Exception while closing the Database connection", e);
+ }
+ }
+
+ // Special care for MSSQL, as it has a hard limit of 2000 params per statement (incl bulk statement).
+ // Especially with executions, with 100 as default, this limit is passed.
+ if (DATABASE_TYPE_MSSQL.equals(databaseType)) {
+ maxNrOfStatementsInBulkInsert = DEFAULT_MAX_NR_OF_STATEMENTS_BULK_INSERT_SQL_SERVER;
+ }
+ }
+
+ public void initSchemaManager() {
+ if (this.commonSchemaManager == null) {
+ this.commonSchemaManager = new CommonDbSchemaManager();
+ }
+ }
+
+ // session factories ////////////////////////////////////////////////////////
+
+ public void addSessionFactory(SessionFactory sessionFactory) {
+ sessionFactories.put(sessionFactory.getSessionType(), sessionFactory);
+ }
+
+ public void initCommandContextFactory() {
+ if (commandContextFactory == null) {
+ commandContextFactory = new CommandContextFactory();
+ }
+ }
+
+ public void initTransactionContextFactory() {
+ if (transactionContextFactory == null) {
+ transactionContextFactory = new StandaloneMybatisTransactionContextFactory();
+ }
+ }
+
+ public void initCommandExecutors() {
+ initDefaultCommandConfig();
+ initSchemaCommandConfig();
+ initCommandInvoker();
+ initCommandInterceptors();
+ initCommandExecutor();
+ }
+
+
+ public void initDefaultCommandConfig() {
+ if (defaultCommandConfig == null) {
+ defaultCommandConfig = new CommandConfig();
+ }
+ }
+
+ public void initSchemaCommandConfig() {
+ if (schemaCommandConfig == null) {
+ schemaCommandConfig = new CommandConfig();
+ }
+ }
+
+ public void initCommandInvoker() {
+ if (commandInvoker == null) {
+ commandInvoker = new DefaultCommandInvoker();
+ }
+ }
+
+ public void initCommandInterceptors() {
+ if (commandInterceptors == null) {
+ commandInterceptors = new ArrayList<>();
+ if (customPreCommandInterceptors != null) {
+ commandInterceptors.addAll(customPreCommandInterceptors);
+ }
+ commandInterceptors.addAll(getDefaultCommandInterceptors());
+ if (customPostCommandInterceptors != null) {
+ commandInterceptors.addAll(customPostCommandInterceptors);
+ }
+ commandInterceptors.add(commandInvoker);
+ }
+ }
+
+ public Collection extends CommandInterceptor> getDefaultCommandInterceptors() {
+ if (defaultCommandInterceptors == null) {
+ List interceptors = new ArrayList<>();
+ interceptors.add(new LogInterceptor());
+
+ if (DATABASE_TYPE_COCKROACHDB.equals(databaseType)) {
+ interceptors.add(new CrDbRetryInterceptor());
+ }
+
+ CommandInterceptor transactionInterceptor = createTransactionInterceptor();
+ if (transactionInterceptor != null) {
+ interceptors.add(transactionInterceptor);
+ }
+
+ if (commandContextFactory != null) {
+ String engineCfgKey = getEngineCfgKey();
+ CommandContextInterceptor commandContextInterceptor = new CommandContextInterceptor(commandContextFactory,
+ classLoader, useClassForNameClassLoading, clock, objectMapper);
+ engineConfigurations.put(engineCfgKey, this);
+ commandContextInterceptor.setEngineCfgKey(engineCfgKey);
+ commandContextInterceptor.setEngineConfigurations(engineConfigurations);
+ interceptors.add(commandContextInterceptor);
+ }
+
+ if (transactionContextFactory != null) {
+ interceptors.add(new TransactionContextInterceptor(transactionContextFactory));
+ }
+
+ List additionalCommandInterceptors = getAdditionalDefaultCommandInterceptors();
+ if (additionalCommandInterceptors != null) {
+ interceptors.addAll(additionalCommandInterceptors);
+ }
+
+ defaultCommandInterceptors = interceptors;
+ }
+ return defaultCommandInterceptors;
+ }
+
+ public abstract String getEngineCfgKey();
+
+ public abstract String getEngineScopeType();
+
+ public List getAdditionalDefaultCommandInterceptors() {
+ return null;
+ }
+
+ public void initCommandExecutor() {
+ if (commandExecutor == null) {
+ CommandInterceptor first = initInterceptorChain(commandInterceptors);
+ commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
+ }
+ }
+
+ public CommandInterceptor initInterceptorChain(List chain) {
+ if (chain == null || chain.isEmpty()) {
+ throw new FlowableException("invalid command interceptor chain configuration: " + chain);
+ }
+ for (int i = 0; i < chain.size() - 1; i++) {
+ chain.get(i).setNext(chain.get(i + 1));
+ }
+ return chain.get(0);
+ }
+
+ public abstract CommandInterceptor createTransactionInterceptor();
+
+
+ public void initBeans() {
+ if (beans == null) {
+ beans = new HashMap<>();
+ }
+ }
+
+ // id generator
+ // /////////////////////////////////////////////////////////////
+
+ public void initIdGenerator() {
+ if (idGenerator == null) {
+ idGenerator = new StrongUuidGenerator();
+ }
+ }
+
+ public void initObjectMapper() {
+ if (objectMapper == null) {
+ objectMapper = new ObjectMapper();
+ objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+ }
+ }
+
+ public void initClock() {
+ if (clock == null) {
+ clock = new DefaultClockImpl();
+ }
+ }
+
+ // Data managers ///////////////////////////////////////////////////////////
+
+ public void initDataManagers() {
+ if (propertyDataManager == null) {
+ propertyDataManager = new MybatisPropertyDataManager(idGenerator);
+ }
+
+ if (byteArrayDataManager == null) {
+ byteArrayDataManager = new MybatisByteArrayDataManager(idGenerator);
+ }
+ }
+
+ // Entity managers //////////////////////////////////////////////////////////
+
+ public void initEntityManagers() {
+ if (propertyEntityManager == null) {
+ propertyEntityManager = new PropertyEntityManagerImpl(this, propertyDataManager);
+ }
+
+ if (byteArrayEntityManager == null) {
+ byteArrayEntityManager = new ByteArrayEntityManagerImpl(byteArrayDataManager, getEngineCfgKey(), this::getEventDispatcher);
+ }
+
+ if (tableDataManager == null) {
+ tableDataManager = new TableDataManagerImpl(this);
+ }
+ }
+
+ // services
+ // /////////////////////////////////////////////////////////////////
+
+ protected void initService(Object service) {
+ if (service instanceof CommonEngineServiceImpl) {
+ ((CommonEngineServiceImpl) service).setCommandExecutor(commandExecutor);
+ }
+ }
+
+ // myBatis SqlSessionFactory
+ // ////////////////////////////////////////////////
+
+ public void initSessionFactories() {
+ if (sessionFactories == null) {
+ sessionFactories = new HashMap<>();
+
+ if (usingRelationalDatabase) {
+ initDbSqlSessionFactory();
+ }
+
+ addSessionFactory(new GenericManagerFactory(EntityCache.class, EntityCacheImpl.class));
+
+ if (isLoggingSessionEnabled()) {
+ if (!sessionFactories.containsKey(LoggingSession.class)) {
+ LoggingSessionFactory loggingSessionFactory = new LoggingSessionFactory();
+ loggingSessionFactory.setLoggingListener(loggingListener);
+ loggingSessionFactory.setObjectMapper(objectMapper);
+ sessionFactories.put(LoggingSession.class, loggingSessionFactory);
+ }
+ }
+
+ commandContextFactory.setSessionFactories(sessionFactories);
+
+ } else {
+ if (usingRelationalDatabase) {
+ initDbSqlSessionFactoryEntitySettings();
+ }
+ }
+
+ if (customSessionFactories != null) {
+ for (SessionFactory sessionFactory : customSessionFactories) {
+ addSessionFactory(sessionFactory);
+ }
+ }
+ }
+
+ public void initDbSqlSessionFactory() {
+ if (dbSqlSessionFactory == null) {
+ dbSqlSessionFactory = createDbSqlSessionFactory();
+ }
+ dbSqlSessionFactory.setDatabaseType(databaseType);
+ dbSqlSessionFactory.setSqlSessionFactory(sqlSessionFactory);
+ dbSqlSessionFactory.setDbHistoryUsed(isDbHistoryUsed);
+ dbSqlSessionFactory.setDatabaseTablePrefix(databaseTablePrefix);
+ dbSqlSessionFactory.setTablePrefixIsSchema(tablePrefixIsSchema);
+ dbSqlSessionFactory.setDatabaseCatalog(databaseCatalog);
+ dbSqlSessionFactory.setDatabaseSchema(databaseSchema);
+ dbSqlSessionFactory.setMaxNrOfStatementsInBulkInsert(maxNrOfStatementsInBulkInsert);
+
+ initDbSqlSessionFactoryEntitySettings();
+
+ addSessionFactory(dbSqlSessionFactory);
+ }
+
+ public DbSqlSessionFactory createDbSqlSessionFactory() {
+ return new DbSqlSessionFactory(usePrefixId);
+ }
+
+ protected abstract void initDbSqlSessionFactoryEntitySettings();
+
+ protected void defaultInitDbSqlSessionFactoryEntitySettings(List> insertOrder, List> deleteOrder) {
+ if (insertOrder != null) {
+ for (Class extends Entity> clazz : insertOrder) {
+ dbSqlSessionFactory.getInsertionOrder().add(clazz);
+
+ if (isBulkInsertEnabled) {
+ dbSqlSessionFactory.getBulkInserteableEntityClasses().add(clazz);
+ }
+ }
+ }
+
+ if (deleteOrder != null) {
+ for (Class extends Entity> clazz : deleteOrder) {
+ dbSqlSessionFactory.getDeletionOrder().add(clazz);
+ }
+ }
+ }
+
+ public void initTransactionFactory() {
+ if (transactionFactory == null) {
+ if (transactionsExternallyManaged) {
+ transactionFactory = new ManagedTransactionFactory();
+ Properties properties = new Properties();
+ properties.put("closeConnection", "false");
+ this.transactionFactory.setProperties(properties);
+ } else {
+ transactionFactory = new JdbcTransactionFactory();
+ }
+ }
+ }
+
+ public void initSqlSessionFactory() {
+ if (sqlSessionFactory == null) {
+ InputStream inputStream = null;
+ try {
+ inputStream = getMyBatisXmlConfigurationStream();
+
+ Environment environment = new Environment("default", transactionFactory, dataSource);
+ Reader reader = new InputStreamReader(inputStream);
+ Properties properties = new Properties();
+ properties.put("prefix", databaseTablePrefix);
+
+ String wildcardEscapeClause = "";
+ if ((databaseWildcardEscapeCharacter != null) && (databaseWildcardEscapeCharacter.length() != 0)) {
+ wildcardEscapeClause = " escape '" + databaseWildcardEscapeCharacter + "'";
+ }
+ properties.put("wildcardEscapeClause", wildcardEscapeClause);
+
+ // set default properties
+ properties.put("limitBefore", "");
+ properties.put("limitAfter", "");
+ properties.put("limitBetween", "");
+ properties.put("limitBeforeNativeQuery", "");
+ properties.put("limitAfterNativeQuery", "");
+ properties.put("blobType", "BLOB");
+ properties.put("boolValue", "TRUE");
+
+ if (databaseType != null) {
+ properties.load(getResourceAsStream(pathToEngineDbProperties()));
+ }
+
+ Configuration configuration = initMybatisConfiguration(environment, reader, properties);
+ sqlSessionFactory = new DefaultSqlSessionFactory(configuration);
+
+ } catch (Exception e) {
+ throw new FlowableException("Error while building ibatis SqlSessionFactory: " + e.getMessage(), e);
+ } finally {
+ IoUtil.closeSilently(inputStream);
+ }
+ } else {
+ // This is needed when the SQL Session Factory is created by another engine.
+ // When custom XML Mappers are registered with this engine they need to be loaded in the configuration as well
+ applyCustomMybatisCustomizations(sqlSessionFactory.getConfiguration());
+ }
+ }
+
+ public String pathToEngineDbProperties() {
+ return "org/flowable/common/db/properties/" + databaseType + ".properties";
+ }
+
+ public Configuration initMybatisConfiguration(Environment environment, Reader reader, Properties properties) {
+ XMLConfigBuilder parser = new XMLConfigBuilder(reader, "", properties);
+ Configuration configuration = parser.getConfiguration();
+
+ if (databaseType != null) {
+ configuration.setDatabaseId(databaseType);
+ }
+
+ configuration.setEnvironment(environment);
+
+ initMybatisTypeHandlers(configuration);
+ initCustomMybatisInterceptors(configuration);
+ if (isEnableLogSqlExecutionTime()) {
+ initMyBatisLogSqlExecutionTimePlugin(configuration);
+ }
+
+ configuration = parseMybatisConfiguration(parser);
+ return configuration;
+ }
+
+ public void initCustomMybatisMappers(Configuration configuration) {
+ if (getCustomMybatisMappers() != null) {
+ for (Class> clazz : getCustomMybatisMappers()) {
+ if (!configuration.hasMapper(clazz)) {
+ configuration.addMapper(clazz);
+ }
+ }
+ }
+ }
+
+ public void initMybatisTypeHandlers(Configuration configuration) {
+ // When mapping into Map there is currently a problem with MyBatis.
+ // It will return objects which are driver specific.
+ // Therefore we are registering the mappings between Object.class and the specific jdbc type here.
+ // see https://github.com/mybatis/mybatis-3/issues/2216 for more info
+ TypeHandlerRegistry handlerRegistry = configuration.getTypeHandlerRegistry();
+
+ handlerRegistry.register(Object.class, JdbcType.BOOLEAN, new BooleanTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.BIT, new BooleanTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.TINYINT, new ByteTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.SMALLINT, new ShortTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.INTEGER, new IntegerTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.FLOAT, new FloatTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.DOUBLE, new DoubleTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.CHAR, new StringTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.CLOB, new ClobTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.VARCHAR, new StringTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.LONGVARCHAR, new StringTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.NVARCHAR, new NStringTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.NCHAR, new NStringTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.NCLOB, new NClobTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.ARRAY, new ArrayTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.BIGINT, new LongTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.REAL, new BigDecimalTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.DECIMAL, new BigDecimalTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.NUMERIC, new BigDecimalTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.BLOB, new BlobInputStreamTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.LONGVARBINARY, new BlobTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.DATE, new DateOnlyTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.TIME, new TimeOnlyTypeHandler());
+ handlerRegistry.register(Object.class, JdbcType.TIMESTAMP, new DateTypeHandler());
+
+ handlerRegistry.register(Object.class, JdbcType.SQLXML, new SqlxmlTypeHandler());
+ }
+
+ public void initCustomMybatisInterceptors(Configuration configuration) {
+ if (customMybatisInterceptors!=null){
+ for (Interceptor interceptor :customMybatisInterceptors){
+ configuration.addInterceptor(interceptor);
+ }
+ }
+ }
+
+ public void initMyBatisLogSqlExecutionTimePlugin(Configuration configuration) {
+ configuration.addInterceptor(new LogSqlExecutionTimePlugin());
+ }
+
+ public Configuration parseMybatisConfiguration(XMLConfigBuilder parser) {
+ Configuration configuration = parser.parse();
+
+ applyCustomMybatisCustomizations(configuration);
+ return configuration;
+ }
+
+ protected void applyCustomMybatisCustomizations(Configuration configuration) {
+ initCustomMybatisMappers(configuration);
+
+ if (dependentEngineMybatisTypeAliasConfigs != null) {
+ for (MybatisTypeAliasConfigurator typeAliasConfig : dependentEngineMybatisTypeAliasConfigs) {
+ typeAliasConfig.configure(configuration.getTypeAliasRegistry());
+ }
+ }
+ if (dependentEngineMybatisTypeHandlerConfigs != null) {
+ for (MybatisTypeHandlerConfigurator typeHandlerConfig : dependentEngineMybatisTypeHandlerConfigs) {
+ typeHandlerConfig.configure(configuration.getTypeHandlerRegistry());
+ }
+ }
+
+ parseDependentEngineMybatisXMLMappers(configuration);
+ parseCustomMybatisXMLMappers(configuration);
+ }
+
+ public void parseCustomMybatisXMLMappers(Configuration configuration) {
+ if (getCustomMybatisXMLMappers() != null) {
+ for (String resource : getCustomMybatisXMLMappers()) {
+ parseMybatisXmlMapping(configuration, resource);
+ }
+ }
+ }
+
+ public void parseDependentEngineMybatisXMLMappers(Configuration configuration) {
+ if (getDependentEngineMyBatisXmlMappers() != null) {
+ for (String resource : getDependentEngineMyBatisXmlMappers()) {
+ parseMybatisXmlMapping(configuration, resource);
+ }
+ }
+ }
+
+ protected void parseMybatisXmlMapping(Configuration configuration, String resource) {
+ // see XMLConfigBuilder.mapperElement()
+ XMLMapperBuilder mapperParser = new XMLMapperBuilder(getResourceAsStream(resource), configuration, resource, configuration.getSqlFragments());
+ mapperParser.parse();
+ }
+
+ protected InputStream getResourceAsStream(String resource) {
+ ClassLoader classLoader = getClassLoader();
+ if (classLoader != null) {
+ return getClassLoader().getResourceAsStream(resource);
+ } else {
+ return this.getClass().getClassLoader().getResourceAsStream(resource);
+ }
+ }
+
+ public void setMybatisMappingFile(String file) {
+ this.mybatisMappingFile = file;
+ }
+
+ public String getMybatisMappingFile() {
+ return mybatisMappingFile;
+ }
+
+ public abstract InputStream getMyBatisXmlConfigurationStream();
+
+ public void initConfigurators() {
+
+ allConfigurators = new ArrayList<>();
+ allConfigurators.addAll(getEngineSpecificEngineConfigurators());
+
+ // Configurators that are explicitly added to the config
+ if (configurators != null) {
+ allConfigurators.addAll(configurators);
+ }
+
+ // Auto discovery through ServiceLoader
+ if (enableConfiguratorServiceLoader) {
+ ClassLoader classLoader = getClassLoader();
+ if (classLoader == null) {
+ classLoader = ReflectUtil.getClassLoader();
+ }
+
+ ServiceLoader configuratorServiceLoader = ServiceLoader.load(EngineConfigurator.class, classLoader);
+ int nrOfServiceLoadedConfigurators = 0;
+ for (EngineConfigurator configurator : configuratorServiceLoader) {
+ allConfigurators.add(configurator);
+ nrOfServiceLoadedConfigurators++;
+ }
+
+ if (nrOfServiceLoadedConfigurators > 0) {
+ logger.info("Found {} auto-discoverable Process Engine Configurator{}", nrOfServiceLoadedConfigurators, nrOfServiceLoadedConfigurators > 1 ? "s" : "");
+ }
+
+ if (!allConfigurators.isEmpty()) {
+
+ // Order them according to the priorities (useful for dependent
+ // configurator)
+ allConfigurators.sort(new Comparator() {
+
+ @Override
+ public int compare(EngineConfigurator configurator1, EngineConfigurator configurator2) {
+ int priority1 = configurator1.getPriority();
+ int priority2 = configurator2.getPriority();
+
+ if (priority1 < priority2) {
+ return -1;
+ } else if (priority1 > priority2) {
+ return 1;
+ }
+ return 0;
+ }
+ });
+
+ // Execute the configurators
+ logger.info("Found {} Engine Configurators in total:", allConfigurators.size());
+ for (EngineConfigurator configurator : allConfigurators) {
+ logger.info("{} (priority:{})", configurator.getClass(), configurator.getPriority());
+ }
+
+ }
+
+ }
+ }
+
+ public void close() {
+ if (forceCloseMybatisConnectionPool && dataSource instanceof PooledDataSource) {
+ /*
+ * When the datasource is created by a Flowable engine (i.e. it's an instance of PooledDataSource),
+ * the connection pool needs to be closed when closing the engine.
+ * Note that calling forceCloseAll() multiple times (as is the case when running with multiple engine) is ok.
+ */
+ ((PooledDataSource) dataSource).forceCloseAll();
+ }
+ }
+
+ protected List getEngineSpecificEngineConfigurators() {
+ // meant to be overridden if needed
+ return Collections.emptyList();
+ }
+
+ public void configuratorsBeforeInit() {
+ for (EngineConfigurator configurator : allConfigurators) {
+ logger.info("Executing beforeInit() of {} (priority:{})", configurator.getClass(), configurator.getPriority());
+ configurator.beforeInit(this);
+ }
+ }
+
+ public void configuratorsAfterInit() {
+ for (EngineConfigurator configurator : allConfigurators) {
+ logger.info("Executing configure() of {} (priority:{})", configurator.getClass(), configurator.getPriority());
+ configurator.configure(this);
+ }
+ }
+
+ public LockManager getLockManager(String lockName) {
+ return new LockManagerImpl(commandExecutor, lockName, getLockPollRate(), getEngineCfgKey());
+ }
+
+ // getters and setters
+ // //////////////////////////////////////////////////////
+
+ public abstract String getEngineName();
+
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ public AbstractEngineConfiguration setClassLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ return this;
+ }
+
+ public boolean isUseClassForNameClassLoading() {
+ return useClassForNameClassLoading;
+ }
+
+ public AbstractEngineConfiguration setUseClassForNameClassLoading(boolean useClassForNameClassLoading) {
+ this.useClassForNameClassLoading = useClassForNameClassLoading;
+ return this;
+ }
+
+ public void addEngineLifecycleListener(EngineLifecycleListener engineLifecycleListener) {
+ if (this.engineLifecycleListeners == null) {
+ this.engineLifecycleListeners = new ArrayList<>();
+ }
+ this.engineLifecycleListeners.add(engineLifecycleListener);
+ }
+
+ public List getEngineLifecycleListeners() {
+ return engineLifecycleListeners;
+ }
+
+ public AbstractEngineConfiguration setEngineLifecycleListeners(List engineLifecycleListeners) {
+ this.engineLifecycleListeners = engineLifecycleListeners;
+ return this;
+ }
+
+ public String getDatabaseType() {
+ return databaseType;
+ }
+
+ public AbstractEngineConfiguration setDatabaseType(String databaseType) {
+ this.databaseType = databaseType;
+ return this;
+ }
+
+ public DataSource getDataSource() {
+ return dataSource;
+ }
+
+ public AbstractEngineConfiguration setDataSource(DataSource dataSource) {
+ this.dataSource = dataSource;
+ return this;
+ }
+
+ public SchemaManager getSchemaManager() {
+ return schemaManager;
+ }
+
+ public AbstractEngineConfiguration setSchemaManager(SchemaManager schemaManager) {
+ this.schemaManager = schemaManager;
+ return this;
+ }
+
+ public SchemaManager getCommonSchemaManager() {
+ return commonSchemaManager;
+ }
+
+ public AbstractEngineConfiguration setCommonSchemaManager(SchemaManager commonSchemaManager) {
+ this.commonSchemaManager = commonSchemaManager;
+ return this;
+ }
+
+ public Command getSchemaManagementCmd() {
+ return schemaManagementCmd;
+ }
+
+ public AbstractEngineConfiguration setSchemaManagementCmd(Command schemaManagementCmd) {
+ this.schemaManagementCmd = schemaManagementCmd;
+ return this;
+ }
+
+ public String getJdbcDriver() {
+ return jdbcDriver;
+ }
+
+ public AbstractEngineConfiguration setJdbcDriver(String jdbcDriver) {
+ this.jdbcDriver = jdbcDriver;
+ return this;
+ }
+
+ public String getJdbcUrl() {
+ return jdbcUrl;
+ }
+
+ public AbstractEngineConfiguration setJdbcUrl(String jdbcUrl) {
+ this.jdbcUrl = jdbcUrl;
+ return this;
+ }
+
+ public String getJdbcUsername() {
+ return jdbcUsername;
+ }
+
+ public AbstractEngineConfiguration setJdbcUsername(String jdbcUsername) {
+ this.jdbcUsername = jdbcUsername;
+ return this;
+ }
+
+ public String getJdbcPassword() {
+ return jdbcPassword;
+ }
+
+ public AbstractEngineConfiguration setJdbcPassword(String jdbcPassword) {
+ this.jdbcPassword = jdbcPassword;
+ return this;
+ }
+
+ public int getJdbcMaxActiveConnections() {
+ return jdbcMaxActiveConnections;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxActiveConnections(int jdbcMaxActiveConnections) {
+ this.jdbcMaxActiveConnections = jdbcMaxActiveConnections;
+ return this;
+ }
+
+ public int getJdbcMaxIdleConnections() {
+ return jdbcMaxIdleConnections;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxIdleConnections(int jdbcMaxIdleConnections) {
+ this.jdbcMaxIdleConnections = jdbcMaxIdleConnections;
+ return this;
+ }
+
+ public int getJdbcMaxCheckoutTime() {
+ return jdbcMaxCheckoutTime;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxCheckoutTime(int jdbcMaxCheckoutTime) {
+ this.jdbcMaxCheckoutTime = jdbcMaxCheckoutTime;
+ return this;
+ }
+
+ public int getJdbcMaxWaitTime() {
+ return jdbcMaxWaitTime;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxWaitTime(int jdbcMaxWaitTime) {
+ this.jdbcMaxWaitTime = jdbcMaxWaitTime;
+ return this;
+ }
+
+ public boolean isJdbcPingEnabled() {
+ return jdbcPingEnabled;
+ }
+
+ public AbstractEngineConfiguration setJdbcPingEnabled(boolean jdbcPingEnabled) {
+ this.jdbcPingEnabled = jdbcPingEnabled;
+ return this;
+ }
+
+ public int getJdbcPingConnectionNotUsedFor() {
+ return jdbcPingConnectionNotUsedFor;
+ }
+
+ public AbstractEngineConfiguration setJdbcPingConnectionNotUsedFor(int jdbcPingConnectionNotUsedFor) {
+ this.jdbcPingConnectionNotUsedFor = jdbcPingConnectionNotUsedFor;
+ return this;
+ }
+
+ public int getJdbcDefaultTransactionIsolationLevel() {
+ return jdbcDefaultTransactionIsolationLevel;
+ }
+
+ public AbstractEngineConfiguration setJdbcDefaultTransactionIsolationLevel(int jdbcDefaultTransactionIsolationLevel) {
+ this.jdbcDefaultTransactionIsolationLevel = jdbcDefaultTransactionIsolationLevel;
+ return this;
+ }
+
+ public String getJdbcPingQuery() {
+ return jdbcPingQuery;
+ }
+
+ public AbstractEngineConfiguration setJdbcPingQuery(String jdbcPingQuery) {
+ this.jdbcPingQuery = jdbcPingQuery;
+ return this;
+ }
+
+ public String getDataSourceJndiName() {
+ return dataSourceJndiName;
+ }
+
+ public AbstractEngineConfiguration setDataSourceJndiName(String dataSourceJndiName) {
+ this.dataSourceJndiName = dataSourceJndiName;
+ return this;
+ }
+
+ public CommandConfig getSchemaCommandConfig() {
+ return schemaCommandConfig;
+ }
+
+ public AbstractEngineConfiguration setSchemaCommandConfig(CommandConfig schemaCommandConfig) {
+ this.schemaCommandConfig = schemaCommandConfig;
+ return this;
+ }
+
+ public boolean isTransactionsExternallyManaged() {
+ return transactionsExternallyManaged;
+ }
+
+ public AbstractEngineConfiguration setTransactionsExternallyManaged(boolean transactionsExternallyManaged) {
+ this.transactionsExternallyManaged = transactionsExternallyManaged;
+ return this;
+ }
+
+ public Map getBeans() {
+ return beans;
+ }
+
+ public AbstractEngineConfiguration setBeans(Map beans) {
+ this.beans = beans;
+ return this;
+ }
+
+ public IdGenerator getIdGenerator() {
+ return idGenerator;
+ }
+
+ public AbstractEngineConfiguration setIdGenerator(IdGenerator idGenerator) {
+ this.idGenerator = idGenerator;
+ return this;
+ }
+
+ public boolean isUsePrefixId() {
+ return usePrefixId;
+ }
+
+ public AbstractEngineConfiguration setUsePrefixId(boolean usePrefixId) {
+ this.usePrefixId = usePrefixId;
+ return this;
+ }
+
+ public String getXmlEncoding() {
+ return xmlEncoding;
+ }
+
+ public AbstractEngineConfiguration setXmlEncoding(String xmlEncoding) {
+ this.xmlEncoding = xmlEncoding;
+ return this;
+ }
+
+ public CommandConfig getDefaultCommandConfig() {
+ return defaultCommandConfig;
+ }
+
+ public AbstractEngineConfiguration setDefaultCommandConfig(CommandConfig defaultCommandConfig) {
+ this.defaultCommandConfig = defaultCommandConfig;
+ return this;
+ }
+
+ public CommandExecutor getCommandExecutor() {
+ return commandExecutor;
+ }
+
+ public AbstractEngineConfiguration setCommandExecutor(CommandExecutor commandExecutor) {
+ this.commandExecutor = commandExecutor;
+ return this;
+ }
+
+ public CommandContextFactory getCommandContextFactory() {
+ return commandContextFactory;
+ }
+
+ public AbstractEngineConfiguration setCommandContextFactory(CommandContextFactory commandContextFactory) {
+ this.commandContextFactory = commandContextFactory;
+ return this;
+ }
+
+ public CommandInterceptor getCommandInvoker() {
+ return commandInvoker;
+ }
+
+ public AbstractEngineConfiguration setCommandInvoker(CommandInterceptor commandInvoker) {
+ this.commandInvoker = commandInvoker;
+ return this;
+ }
+
+ public AgendaOperationRunner getAgendaOperationRunner() {
+ return agendaOperationRunner;
+ }
+
+ public AbstractEngineConfiguration setAgendaOperationRunner(AgendaOperationRunner agendaOperationRunner) {
+ this.agendaOperationRunner = agendaOperationRunner;
+ return this;
+ }
+
+ public List getCustomPreCommandInterceptors() {
+ return customPreCommandInterceptors;
+ }
+
+ public AbstractEngineConfiguration setCustomPreCommandInterceptors(List customPreCommandInterceptors) {
+ this.customPreCommandInterceptors = customPreCommandInterceptors;
+ return this;
+ }
+
+ public List getCustomPostCommandInterceptors() {
+ return customPostCommandInterceptors;
+ }
+
+ public AbstractEngineConfiguration setCustomPostCommandInterceptors(List customPostCommandInterceptors) {
+ this.customPostCommandInterceptors = customPostCommandInterceptors;
+ return this;
+ }
+
+ public List getCommandInterceptors() {
+ return commandInterceptors;
+ }
+
+ public AbstractEngineConfiguration setCommandInterceptors(List commandInterceptors) {
+ this.commandInterceptors = commandInterceptors;
+ return this;
+ }
+
+ public Map getEngineConfigurations() {
+ return engineConfigurations;
+ }
+
+ public AbstractEngineConfiguration setEngineConfigurations(Map engineConfigurations) {
+ this.engineConfigurations = engineConfigurations;
+ return this;
+ }
+
+ public void addEngineConfiguration(String key, String scopeType, AbstractEngineConfiguration engineConfiguration) {
+ if (engineConfigurations == null) {
+ engineConfigurations = new HashMap<>();
+ }
+ engineConfigurations.put(key, engineConfiguration);
+ engineConfigurations.put(scopeType, engineConfiguration);
+ }
+
+ public Map getServiceConfigurations() {
+ return serviceConfigurations;
+ }
+
+ public AbstractEngineConfiguration setServiceConfigurations(Map serviceConfigurations) {
+ this.serviceConfigurations = serviceConfigurations;
+ return this;
+ }
+
+ public void addServiceConfiguration(String key, AbstractServiceConfiguration serviceConfiguration) {
+ if (serviceConfigurations == null) {
+ serviceConfigurations = new HashMap<>();
+ }
+ serviceConfigurations.put(key, serviceConfiguration);
+ }
+
+ public Map getEventRegistryEventConsumers() {
+ return eventRegistryEventConsumers;
+ }
+
+ public AbstractEngineConfiguration setEventRegistryEventConsumers(Map eventRegistryEventConsumers) {
+ this.eventRegistryEventConsumers = eventRegistryEventConsumers;
+ return this;
+ }
+
+ public void addEventRegistryEventConsumer(String key, EventRegistryEventConsumer eventRegistryEventConsumer) {
+ if (eventRegistryEventConsumers == null) {
+ eventRegistryEventConsumers = new HashMap<>();
+ }
+ eventRegistryEventConsumers.put(key, eventRegistryEventConsumer);
+ }
+
+ public AbstractEngineConfiguration setDefaultCommandInterceptors(Collection extends CommandInterceptor> defaultCommandInterceptors) {
+ this.defaultCommandInterceptors = defaultCommandInterceptors;
+ return this;
+ }
+
+ public SqlSessionFactory getSqlSessionFactory() {
+ return sqlSessionFactory;
+ }
+
+ public AbstractEngineConfiguration setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
+ this.sqlSessionFactory = sqlSessionFactory;
+ return this;
+ }
+
+ public boolean isDbHistoryUsed() {
+ return isDbHistoryUsed;
+ }
+
+ public AbstractEngineConfiguration setDbHistoryUsed(boolean isDbHistoryUsed) {
+ this.isDbHistoryUsed = isDbHistoryUsed;
+ return this;
+ }
+
+ public DbSqlSessionFactory getDbSqlSessionFactory() {
+ return dbSqlSessionFactory;
+ }
+
+ public AbstractEngineConfiguration setDbSqlSessionFactory(DbSqlSessionFactory dbSqlSessionFactory) {
+ this.dbSqlSessionFactory = dbSqlSessionFactory;
+ return this;
+ }
+
+ public TransactionFactory getTransactionFactory() {
+ return transactionFactory;
+ }
+
+ public AbstractEngineConfiguration setTransactionFactory(TransactionFactory transactionFactory) {
+ this.transactionFactory = transactionFactory;
+ return this;
+ }
+
+ public TransactionContextFactory getTransactionContextFactory() {
+ return transactionContextFactory;
+ }
+
+ public AbstractEngineConfiguration setTransactionContextFactory(TransactionContextFactory transactionContextFactory) {
+ this.transactionContextFactory = transactionContextFactory;
+ return this;
+ }
+
+ public int getMaxNrOfStatementsInBulkInsert() {
+ return maxNrOfStatementsInBulkInsert;
+ }
+
+ public AbstractEngineConfiguration setMaxNrOfStatementsInBulkInsert(int maxNrOfStatementsInBulkInsert) {
+ this.maxNrOfStatementsInBulkInsert = maxNrOfStatementsInBulkInsert;
+ return this;
+ }
+
+ public boolean isBulkInsertEnabled() {
+ return isBulkInsertEnabled;
+ }
+
+ public AbstractEngineConfiguration setBulkInsertEnabled(boolean isBulkInsertEnabled) {
+ this.isBulkInsertEnabled = isBulkInsertEnabled;
+ return this;
+ }
+
+ public Set> getCustomMybatisMappers() {
+ return customMybatisMappers;
+ }
+
+ public AbstractEngineConfiguration setCustomMybatisMappers(Set> customMybatisMappers) {
+ this.customMybatisMappers = customMybatisMappers;
+ return this;
+ }
+
+ public Set getCustomMybatisXMLMappers() {
+ return customMybatisXMLMappers;
+ }
+
+ public AbstractEngineConfiguration setCustomMybatisXMLMappers(Set customMybatisXMLMappers) {
+ this.customMybatisXMLMappers = customMybatisXMLMappers;
+ return this;
+ }
+
+ public Set getDependentEngineMyBatisXmlMappers() {
+ return dependentEngineMyBatisXmlMappers;
+ }
+
+ public AbstractEngineConfiguration setCustomMybatisInterceptors(List customMybatisInterceptors) {
+ this.customMybatisInterceptors = customMybatisInterceptors;
+ return this;
+ }
+
+ public List getCustomMybatisInterceptors() {
+ return customMybatisInterceptors;
+ }
+
+ public AbstractEngineConfiguration setDependentEngineMyBatisXmlMappers(Set dependentEngineMyBatisXmlMappers) {
+ this.dependentEngineMyBatisXmlMappers = dependentEngineMyBatisXmlMappers;
+ return this;
+ }
+
+ public List getDependentEngineMybatisTypeAliasConfigs() {
+ return dependentEngineMybatisTypeAliasConfigs;
+ }
+
+ public AbstractEngineConfiguration setDependentEngineMybatisTypeAliasConfigs(List dependentEngineMybatisTypeAliasConfigs) {
+ this.dependentEngineMybatisTypeAliasConfigs = dependentEngineMybatisTypeAliasConfigs;
+ return this;
+ }
+
+ public List getDependentEngineMybatisTypeHandlerConfigs() {
+ return dependentEngineMybatisTypeHandlerConfigs;
+ }
+
+ public AbstractEngineConfiguration setDependentEngineMybatisTypeHandlerConfigs(List dependentEngineMybatisTypeHandlerConfigs) {
+ this.dependentEngineMybatisTypeHandlerConfigs = dependentEngineMybatisTypeHandlerConfigs;
+ return this;
+ }
+
+ public List getCustomSessionFactories() {
+ return customSessionFactories;
+ }
+
+ public AbstractEngineConfiguration addCustomSessionFactory(SessionFactory sessionFactory) {
+ if (customSessionFactories == null) {
+ customSessionFactories = new ArrayList<>();
+ }
+ customSessionFactories.add(sessionFactory);
+ return this;
+ }
+
+ public AbstractEngineConfiguration setCustomSessionFactories(List customSessionFactories) {
+ this.customSessionFactories = customSessionFactories;
+ return this;
+ }
+
+ public boolean isUsingRelationalDatabase() {
+ return usingRelationalDatabase;
+ }
+
+ public AbstractEngineConfiguration setUsingRelationalDatabase(boolean usingRelationalDatabase) {
+ this.usingRelationalDatabase = usingRelationalDatabase;
+ return this;
+ }
+
+ public boolean isUsingSchemaMgmt() {
+ return usingSchemaMgmt;
+ }
+
+ public AbstractEngineConfiguration setUsingSchemaMgmt(boolean usingSchema) {
+ this.usingSchemaMgmt = usingSchema;
+ return this;
+ }
+
+ public String getDatabaseTablePrefix() {
+ return databaseTablePrefix;
+ }
+
+ public AbstractEngineConfiguration setDatabaseTablePrefix(String databaseTablePrefix) {
+ this.databaseTablePrefix = databaseTablePrefix;
+ return this;
+ }
+
+ public String getDatabaseWildcardEscapeCharacter() {
+ return databaseWildcardEscapeCharacter;
+ }
+
+ public AbstractEngineConfiguration setDatabaseWildcardEscapeCharacter(String databaseWildcardEscapeCharacter) {
+ this.databaseWildcardEscapeCharacter = databaseWildcardEscapeCharacter;
+ return this;
+ }
+
+ public String getDatabaseCatalog() {
+ return databaseCatalog;
+ }
+
+ public AbstractEngineConfiguration setDatabaseCatalog(String databaseCatalog) {
+ this.databaseCatalog = databaseCatalog;
+ return this;
+ }
+
+ public String getDatabaseSchema() {
+ return databaseSchema;
+ }
+
+ public AbstractEngineConfiguration setDatabaseSchema(String databaseSchema) {
+ this.databaseSchema = databaseSchema;
+ return this;
+ }
+
+ public boolean isTablePrefixIsSchema() {
+ return tablePrefixIsSchema;
+ }
+
+ public AbstractEngineConfiguration setTablePrefixIsSchema(boolean tablePrefixIsSchema) {
+ this.tablePrefixIsSchema = tablePrefixIsSchema;
+ return this;
+ }
+
+ public boolean isAlwaysLookupLatestDefinitionVersion() {
+ return alwaysLookupLatestDefinitionVersion;
+ }
+
+ public AbstractEngineConfiguration setAlwaysLookupLatestDefinitionVersion(boolean alwaysLookupLatestDefinitionVersion) {
+ this.alwaysLookupLatestDefinitionVersion = alwaysLookupLatestDefinitionVersion;
+ return this;
+ }
+
+ public boolean isFallbackToDefaultTenant() {
+ return fallbackToDefaultTenant;
+ }
+
+ public AbstractEngineConfiguration setFallbackToDefaultTenant(boolean fallbackToDefaultTenant) {
+ this.fallbackToDefaultTenant = fallbackToDefaultTenant;
+ return this;
+ }
+
+ /**
+ * @return name of the default tenant
+ * @deprecated use {@link AbstractEngineConfiguration#getDefaultTenantProvider()} instead
+ */
+ @Deprecated
+ public String getDefaultTenantValue() {
+ return getDefaultTenantProvider().getDefaultTenant(null, null, null);
+ }
+
+ public AbstractEngineConfiguration setDefaultTenantValue(String defaultTenantValue) {
+ this.defaultTenantProvider = (tenantId, scope, scopeKey) -> defaultTenantValue;
+ return this;
+ }
+
+ public DefaultTenantProvider getDefaultTenantProvider() {
+ return defaultTenantProvider;
+ }
+
+ public AbstractEngineConfiguration setDefaultTenantProvider(DefaultTenantProvider defaultTenantProvider) {
+ this.defaultTenantProvider = defaultTenantProvider;
+ return this;
+ }
+
+ public boolean isEnableLogSqlExecutionTime() {
+ return enableLogSqlExecutionTime;
+ }
+
+ public void setEnableLogSqlExecutionTime(boolean enableLogSqlExecutionTime) {
+ this.enableLogSqlExecutionTime = enableLogSqlExecutionTime;
+ }
+
+ public Map, SessionFactory> getSessionFactories() {
+ return sessionFactories;
+ }
+
+ public AbstractEngineConfiguration setSessionFactories(Map, SessionFactory> sessionFactories) {
+ this.sessionFactories = sessionFactories;
+ return this;
+ }
+
+ public String getDatabaseSchemaUpdate() {
+ return databaseSchemaUpdate;
+ }
+
+ public AbstractEngineConfiguration setDatabaseSchemaUpdate(String databaseSchemaUpdate) {
+ this.databaseSchemaUpdate = databaseSchemaUpdate;
+ return this;
+ }
+
+ public boolean isUseLockForDatabaseSchemaUpdate() {
+ return useLockForDatabaseSchemaUpdate;
+ }
+
+ public AbstractEngineConfiguration setUseLockForDatabaseSchemaUpdate(boolean useLockForDatabaseSchemaUpdate) {
+ this.useLockForDatabaseSchemaUpdate = useLockForDatabaseSchemaUpdate;
+ return this;
+ }
+
+ public boolean isEnableEventDispatcher() {
+ return enableEventDispatcher;
+ }
+
+ public AbstractEngineConfiguration setEnableEventDispatcher(boolean enableEventDispatcher) {
+ this.enableEventDispatcher = enableEventDispatcher;
+ return this;
+ }
+
+ public FlowableEventDispatcher getEventDispatcher() {
+ return eventDispatcher;
+ }
+
+ public AbstractEngineConfiguration setEventDispatcher(FlowableEventDispatcher eventDispatcher) {
+ this.eventDispatcher = eventDispatcher;
+ return this;
+ }
+
+ public List getEventListeners() {
+ return eventListeners;
+ }
+
+ public AbstractEngineConfiguration setEventListeners(List eventListeners) {
+ this.eventListeners = eventListeners;
+ return this;
+ }
+
+ public Map> getTypedEventListeners() {
+ return typedEventListeners;
+ }
+
+ public AbstractEngineConfiguration setTypedEventListeners(Map> typedEventListeners) {
+ this.typedEventListeners = typedEventListeners;
+ return this;
+ }
+
+ public List getAdditionalEventDispatchActions() {
+ return additionalEventDispatchActions;
+ }
+
+ public AbstractEngineConfiguration setAdditionalEventDispatchActions(List additionalEventDispatchActions) {
+ this.additionalEventDispatchActions = additionalEventDispatchActions;
+ return this;
+ }
+
+ public void initEventDispatcher() {
+ if (this.eventDispatcher == null) {
+ this.eventDispatcher = new FlowableEventDispatcherImpl();
+ }
+
+ initAdditionalEventDispatchActions();
+
+ this.eventDispatcher.setEnabled(enableEventDispatcher);
+
+ initEventListeners();
+ initTypedEventListeners();
+ }
+
+ protected void initEventListeners() {
+ if (eventListeners != null) {
+ for (FlowableEventListener listenerToAdd : eventListeners) {
+ this.eventDispatcher.addEventListener(listenerToAdd);
+ }
+ }
+ }
+
+ protected void initAdditionalEventDispatchActions() {
+ if (this.additionalEventDispatchActions == null) {
+ this.additionalEventDispatchActions = new ArrayList<>();
+ }
+ }
+
+ protected void initTypedEventListeners() {
+ if (typedEventListeners != null) {
+ for (Map.Entry> listenersToAdd : typedEventListeners.entrySet()) {
+ // Extract types from the given string
+ FlowableEngineEventType[] types = FlowableEngineEventType.getTypesFromString(listenersToAdd.getKey());
+
+ for (FlowableEventListener listenerToAdd : listenersToAdd.getValue()) {
+ this.eventDispatcher.addEventListener(listenerToAdd, types);
+ }
+ }
+ }
+ }
+
+ public boolean isLoggingSessionEnabled() {
+ return loggingListener != null;
+ }
+
+ public LoggingListener getLoggingListener() {
+ return loggingListener;
+ }
+
+ public void setLoggingListener(LoggingListener loggingListener) {
+ this.loggingListener = loggingListener;
+ }
+
+ public Clock getClock() {
+ return clock;
+ }
+
+ public AbstractEngineConfiguration setClock(Clock clock) {
+ this.clock = clock;
+ return this;
+ }
+
+ public ObjectMapper getObjectMapper() {
+ return objectMapper;
+ }
+
+ public AbstractEngineConfiguration setObjectMapper(ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ return this;
+ }
+
+ public int getMaxLengthString() {
+ if (maxLengthStringVariableType == -1) {
+ if ("oracle".equalsIgnoreCase(databaseType)) {
+ return DEFAULT_ORACLE_MAX_LENGTH_STRING;
+ } else {
+ return DEFAULT_GENERIC_MAX_LENGTH_STRING;
+ }
+ } else {
+ return maxLengthStringVariableType;
+ }
+ }
+
+ public int getMaxLengthStringVariableType() {
+ return maxLengthStringVariableType;
+ }
+
+ public AbstractEngineConfiguration setMaxLengthStringVariableType(int maxLengthStringVariableType) {
+ this.maxLengthStringVariableType = maxLengthStringVariableType;
+ return this;
+ }
+
+ public PropertyDataManager getPropertyDataManager() {
+ return propertyDataManager;
+ }
+
+ public Duration getLockPollRate() {
+ return lockPollRate;
+ }
+
+ public AbstractEngineConfiguration setLockPollRate(Duration lockPollRate) {
+ this.lockPollRate = lockPollRate;
+ return this;
+ }
+
+ public Duration getSchemaLockWaitTime() {
+ return schemaLockWaitTime;
+ }
+
+ public void setSchemaLockWaitTime(Duration schemaLockWaitTime) {
+ this.schemaLockWaitTime = schemaLockWaitTime;
+ }
+
+ public AbstractEngineConfiguration setPropertyDataManager(PropertyDataManager propertyDataManager) {
+ this.propertyDataManager = propertyDataManager;
+ return this;
+ }
+
+ public PropertyEntityManager getPropertyEntityManager() {
+ return propertyEntityManager;
+ }
+
+ public AbstractEngineConfiguration setPropertyEntityManager(PropertyEntityManager propertyEntityManager) {
+ this.propertyEntityManager = propertyEntityManager;
+ return this;
+ }
+
+ public ByteArrayDataManager getByteArrayDataManager() {
+ return byteArrayDataManager;
+ }
+
+ public AbstractEngineConfiguration setByteArrayDataManager(ByteArrayDataManager byteArrayDataManager) {
+ this.byteArrayDataManager = byteArrayDataManager;
+ return this;
+ }
+
+ public ByteArrayEntityManager getByteArrayEntityManager() {
+ return byteArrayEntityManager;
+ }
+
+ public AbstractEngineConfiguration setByteArrayEntityManager(ByteArrayEntityManager byteArrayEntityManager) {
+ this.byteArrayEntityManager = byteArrayEntityManager;
+ return this;
+ }
+
+ public TableDataManager getTableDataManager() {
+ return tableDataManager;
+ }
+
+ public AbstractEngineConfiguration setTableDataManager(TableDataManager tableDataManager) {
+ this.tableDataManager = tableDataManager;
+ return this;
+ }
+
+ public List getDeployers() {
+ return deployers;
+ }
+
+ public AbstractEngineConfiguration setDeployers(List deployers) {
+ this.deployers = deployers;
+ return this;
+ }
+
+ public List getCustomPreDeployers() {
+ return customPreDeployers;
+ }
+
+ public AbstractEngineConfiguration setCustomPreDeployers(List customPreDeployers) {
+ this.customPreDeployers = customPreDeployers;
+ return this;
+ }
+
+ public List getCustomPostDeployers() {
+ return customPostDeployers;
+ }
+
+ public AbstractEngineConfiguration setCustomPostDeployers(List customPostDeployers) {
+ this.customPostDeployers = customPostDeployers;
+ return this;
+ }
+
+ public boolean isEnableConfiguratorServiceLoader() {
+ return enableConfiguratorServiceLoader;
+ }
+
+ public AbstractEngineConfiguration setEnableConfiguratorServiceLoader(boolean enableConfiguratorServiceLoader) {
+ this.enableConfiguratorServiceLoader = enableConfiguratorServiceLoader;
+ return this;
+ }
+
+ public List getConfigurators() {
+ return configurators;
+ }
+
+ public AbstractEngineConfiguration addConfigurator(EngineConfigurator configurator) {
+ if (configurators == null) {
+ configurators = new ArrayList<>();
+ }
+ configurators.add(configurator);
+ return this;
+ }
+
+ /**
+ * @return All {@link EngineConfigurator} instances. Will only contain values after init of the engine.
+ * Use the {@link #getConfigurators()} or {@link #addConfigurator(EngineConfigurator)} methods otherwise.
+ */
+ public List getAllConfigurators() {
+ return allConfigurators;
+ }
+
+ public AbstractEngineConfiguration setConfigurators(List configurators) {
+ this.configurators = configurators;
+ return this;
+ }
+
+ public EngineConfigurator getIdmEngineConfigurator() {
+ return idmEngineConfigurator;
+ }
+
+ public AbstractEngineConfiguration setIdmEngineConfigurator(EngineConfigurator idmEngineConfigurator) {
+ this.idmEngineConfigurator = idmEngineConfigurator;
+ return this;
+ }
+
+ public EngineConfigurator getEventRegistryConfigurator() {
+ return eventRegistryConfigurator;
+ }
+
+ public AbstractEngineConfiguration setEventRegistryConfigurator(EngineConfigurator eventRegistryConfigurator) {
+ this.eventRegistryConfigurator = eventRegistryConfigurator;
+ return this;
+ }
+
+ public AbstractEngineConfiguration setForceCloseMybatisConnectionPool(boolean forceCloseMybatisConnectionPool) {
+ this.forceCloseMybatisConnectionPool = forceCloseMybatisConnectionPool;
+ return this;
+ }
+
+ public boolean isForceCloseMybatisConnectionPool() {
+ return forceCloseMybatisConnectionPool;
+ }
+}
diff --git a/sql/dm/flowable-patch/src/main/resources/META-INF/package-info.md b/sql/dm/flowable-patch/src/main/resources/META-INF/package-info.md
new file mode 100644
index 000000000..1932c7a3f
--- /dev/null
+++ b/sql/dm/flowable-patch/src/main/resources/META-INF/package-info.md
@@ -0,0 +1 @@
+防止IDEA将`.`和`/`混为一谈
\ No newline at end of file
diff --git a/sql/dm/flowable-patch/src/main/resources/META-INF/services/liquibase.database.Database b/sql/dm/flowable-patch/src/main/resources/META-INF/services/liquibase.database.Database
new file mode 100644
index 000000000..efbcfcca2
--- /dev/null
+++ b/sql/dm/flowable-patch/src/main/resources/META-INF/services/liquibase.database.Database
@@ -0,0 +1,21 @@
+liquibase.database.core.CockroachDatabase
+liquibase.database.core.DB2Database
+liquibase.database.core.Db2zDatabase
+liquibase.database.core.DerbyDatabase
+liquibase.database.core.Firebird3Database
+liquibase.database.core.FirebirdDatabase
+liquibase.database.core.H2Database
+liquibase.database.core.HsqlDatabase
+liquibase.database.core.InformixDatabase
+liquibase.database.core.Ingres9Database
+liquibase.database.core.MSSQLDatabase
+liquibase.database.core.MariaDBDatabase
+liquibase.database.core.MockDatabase
+liquibase.database.core.MySQLDatabase
+liquibase.database.core.OracleDatabase
+liquibase.database.core.PostgresDatabase
+liquibase.database.core.SQLiteDatabase
+liquibase.database.core.SybaseASADatabase
+liquibase.database.core.SybaseDatabase
+liquibase.database.core.DmDatabase
+liquibase.database.core.UnsupportedDatabase
diff --git a/sql/dm/ruoyi-vue-pro-dm8.sql b/sql/dm/ruoyi-vue-pro-dm8.sql
index 8128c647e..e5369739e 100644
--- a/sql/dm/ruoyi-vue-pro-dm8.sql
+++ b/sql/dm/ruoyi-vue-pro-dm8.sql
@@ -3941,7 +3941,7 @@ CREATE TABLE "RUOYI_VUE_PRO"."SYSTEM_TENANT"
"CONTACT_MOBILE" VARCHAR(500) NULL,
"STATUS" TINYINT DEFAULT 0
NOT NULL,
- "DOMAIN" VARCHAR(256) DEFAULT ''
+ "WEBSITE" VARCHAR(256) DEFAULT ''
NULL,
"PACKAGE_ID" BIGINT NOT NULL,
"EXPIRE_TIME" TIMESTAMP(0) NOT NULL,
@@ -4943,9 +4943,9 @@ SET IDENTITY_INSERT "RUOYI_VUE_PRO"."SYSTEM_SOCIAL_USER" OFF;
SET IDENTITY_INSERT "RUOYI_VUE_PRO"."SYSTEM_SOCIAL_USER_BIND" ON;
SET IDENTITY_INSERT "RUOYI_VUE_PRO"."SYSTEM_SOCIAL_USER_BIND" OFF;
SET IDENTITY_INSERT "RUOYI_VUE_PRO"."SYSTEM_TENANT" ON;
-INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_TENANT"("ID","NAME","CONTACT_USER_ID","CONTACT_NAME","CONTACT_MOBILE","STATUS","DOMAIN","PACKAGE_ID","EXPIRE_TIME","ACCOUNT_COUNT","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(1,'芋道源码',null,'芋艿','17321315478',0,'https://www.iocoder.cn',0,'2099-02-19 17:14:16',9999,'1','2021-01-05 17:03:47','1','2022-02-23 12:15:11',0);
-INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_TENANT"("ID","NAME","CONTACT_USER_ID","CONTACT_NAME","CONTACT_MOBILE","STATUS","DOMAIN","PACKAGE_ID","EXPIRE_TIME","ACCOUNT_COUNT","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(121,'小租户',110,'小王2','15601691300',0,'http://www.iocoder.cn',111,'2024-03-11 00:00:00',20,'1','2022-02-22 00:56:14','1','2022-05-17 10:03:59',0);
-INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_TENANT"("ID","NAME","CONTACT_USER_ID","CONTACT_NAME","CONTACT_MOBILE","STATUS","DOMAIN","PACKAGE_ID","EXPIRE_TIME","ACCOUNT_COUNT","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(122,'测试租户',113,'芋道','15601691300',0,'https://www.iocoder.cn',111,'2022-04-30 00:00:00',50,'1','2022-03-07 21:37:58','1','2022-03-07 21:37:58',0);
+INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_TENANT"("ID","NAME","CONTACT_USER_ID","CONTACT_NAME","CONTACT_MOBILE","STATUS","WEBSITE","PACKAGE_ID","EXPIRE_TIME","ACCOUNT_COUNT","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(1,'芋道源码',null,'芋艿','17321315478',0,'https://www.iocoder.cn',0,'2099-02-19 17:14:16',9999,'1','2021-01-05 17:03:47','1','2022-02-23 12:15:11',0);
+INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_TENANT"("ID","NAME","CONTACT_USER_ID","CONTACT_NAME","CONTACT_MOBILE","STATUS","WEBSITE","PACKAGE_ID","EXPIRE_TIME","ACCOUNT_COUNT","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(121,'小租户',110,'小王2','15601691300',0,'http://www.iocoder.cn',111,'2024-03-11 00:00:00',20,'1','2022-02-22 00:56:14','1','2022-05-17 10:03:59',0);
+INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_TENANT"("ID","NAME","CONTACT_USER_ID","CONTACT_NAME","CONTACT_MOBILE","STATUS","WEBSITE","PACKAGE_ID","EXPIRE_TIME","ACCOUNT_COUNT","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(122,'测试租户',113,'芋道','15601691300',0,'https://www.iocoder.cn',111,'2022-04-30 00:00:00',50,'1','2022-03-07 21:37:58','1','2022-03-07 21:37:58',0);
SET IDENTITY_INSERT "RUOYI_VUE_PRO"."SYSTEM_TENANT" OFF;
SET IDENTITY_INSERT "RUOYI_VUE_PRO"."SYSTEM_TENANT_PACKAGE" ON;
@@ -5674,7 +5674,7 @@ COMMENT ON COLUMN "RUOYI_VUE_PRO"."SYSTEM_TENANT"."CONTACT_MOBILE" IS '联系手
COMMENT ON COLUMN "RUOYI_VUE_PRO"."SYSTEM_TENANT"."STATUS" IS '租户状态(0正常 1停用)';
-COMMENT ON COLUMN "RUOYI_VUE_PRO"."SYSTEM_TENANT"."DOMAIN" IS '绑定域名';
+COMMENT ON COLUMN "RUOYI_VUE_PRO"."SYSTEM_TENANT"."WEBSITE" IS '绑定域名';
COMMENT ON COLUMN "RUOYI_VUE_PRO"."SYSTEM_TENANT"."PACKAGE_ID" IS '租户套餐编号';
diff --git a/sql/mysql/optinal/crm.sql b/sql/mysql/optinal/crm.sql
new file mode 100644
index 000000000..135826585
--- /dev/null
+++ b/sql/mysql/optinal/crm.sql
@@ -0,0 +1,3 @@
+SET NAMES utf8mb4;
+-- `ruoyi-vue-pro`.crm_contact definition
+
diff --git a/sql/mysql/optinal/crm_data.sql b/sql/mysql/optinal/crm_data.sql
new file mode 100644
index 000000000..b5be1e691
--- /dev/null
+++ b/sql/mysql/optinal/crm_data.sql
@@ -0,0 +1,20 @@
+
+INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (184, '回款管理审批状态', 'crm_receivable_check_status', 0, '回款管理审批状态(0 未审核 1 审核通过 2 审核拒绝 3 审核中 4 已撤回)', '1', '2023-10-18 21:44:24', '1', '2023-10-18 21:44:24', b'0', '1970-01-01 00:00:00');
+
+INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (185, '回款管理-回款方式', 'crm_return_type', 0, '回款管理-回款方式', '1', '2023-10-18 21:54:10', '1', '2023-10-18 21:54:10', b'0', '1970-01-01 00:00:00');
+
+
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1389, 0, '未审核', '0', 'crm_receivable_check_status', 0, 'default', '', '0 未审核 ', '1', '2023-10-18 21:46:00', '1', '2023-10-18 21:47:16', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1390, 1, '审核通过', '1', 'crm_receivable_check_status', 0, 'default', '', '1 审核通过', '1', '2023-10-18 21:46:18', '1', '2023-10-18 21:47:08', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1391, 2, '审核拒绝', '2', 'crm_receivable_check_status', 0, 'default', '', ' 2 审核拒绝', '1', '2023-10-18 21:46:58', '1', '2023-10-18 21:47:21', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1392, 3, '审核中', '3', 'crm_receivable_check_status', 0, 'default', '', ' 3 审核中', '1', '2023-10-18 21:47:35', '1', '2023-10-18 21:47:35', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1393, 4, '已撤回', '4', 'crm_receivable_check_status', 0, 'default', '', ' 4 已撤回', '1', '2023-10-18 21:47:46', '1', '2023-10-18 21:47:46', b'0');
+
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1394, 1, '支票', '1', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:54:29', '1', '2023-10-18 21:54:29', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1395, 2, '现金', '2', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:54:41', '1', '2023-10-18 21:54:41', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1396, 3, '邮政汇款', '3', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:54:53', '1', '2023-10-18 21:54:53', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1397, 4, '电汇', '4', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:07', '1', '2023-10-18 21:55:07', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1398, 5, '网上转账', '5', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:24', '1', '2023-10-18 21:55:24', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1399, 6, '支付宝', '6', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:38', '1', '2023-10-18 21:55:38', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1400, 7, '微信支付', '7', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:53', '1', '2023-10-18 21:55:53', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1401, 8, '其他', '8', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:56:06', '1', '2023-10-18 21:56:06', b'0');
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/mapper/null/.gitkeep b/sql/mysql/optinal/crm_menu.sql
similarity index 100%
rename from yudao-module-infra/yudao-module-infra-biz/src/main/resources/mapper/null/.gitkeep
rename to sql/mysql/optinal/crm_menu.sql
diff --git a/sql/mysql/optinal/mall.sql b/sql/mysql/optinal/mall.sql
new file mode 100644
index 000000000..e69de29bb
diff --git a/sql/mysql/pay_wallet.sql b/sql/mysql/optinal/pay_wallet.sql
similarity index 56%
rename from sql/mysql/pay_wallet.sql
rename to sql/mysql/optinal/pay_wallet.sql
index e69b97b7b..1e9f1d255 100644
--- a/sql/mysql/pay_wallet.sql
+++ b/sql/mysql/optinal/pay_wallet.sql
@@ -5,18 +5,26 @@ DROP TABLE IF EXISTS `pay_transfer`;
CREATE TABLE `pay_transfer`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
- `type` int NOT NULL COMMENT '类型',
+ `no` varchar(64) NOT NULL COMMENT '转账单号',
`app_id` bigint NOT NULL COMMENT '应用编号',
- `merchant_order_id` varchar(64) NOT NULL COMMENT '商户订单编号',
- `price` int NOT NULL COMMENT '转账金额,单位:分',
- `subject` varchar(512) NOT NULL COMMENT '转账标题',
- `payee_info` varchar(512) NOT NULL COMMENT '收款人信息,不同类型和渠道不同',
+ `channel_id` bigint NOT NULL COMMENT '转账渠道编号',
+ `channel_code` varchar(32) NOT NULL COMMENT '转账渠道编码',
+ `merchant_transfer_id` varchar(64) NOT NULL COMMENT '商户转账单编号',
+ `type` int NOT NULL COMMENT '类型',
`status` tinyint NOT NULL COMMENT '转账状态',
`success_time` datetime NULL COMMENT '转账成功时间',
- `extension_id` bigint NULL COMMENT '转账渠道编号',
- `no` varchar(64) NULL COMMENT '转账单号',
- `channel_id` bigint NULL COMMENT '转账渠道编号',
- `channel_code` varchar(32) NULL COMMENT '转账渠道编码',
+ `price` int NOT NULL COMMENT '转账金额,单位:分',
+ `subject` varchar(512) NOT NULL COMMENT '转账标题',
+ `user_name` varchar(64) NULL COMMENT '收款人姓名',
+ `alipay_logon_id` varchar(64) NULL COMMENT '支付宝登录号',
+ `openid` varchar(64) NULL COMMENT '微信 openId',
+ `notify_url` varchar(1024) NOT NULL COMMENT '异步通知商户地址',
+ `user_ip` varchar(50) NOT NULL COMMENT '用户 IP',
+ `channel_extras` varchar(512) NULL DEFAULT NULL COMMENT '渠道的额外参数',
+ `channel_transfer_no` varchar(64) NULL DEFAULT NULL COMMENT '渠道转账单号',
+ `channel_error_code` varchar(128) NULL DEFAULT NULL COMMENT '调用渠道的错误码',
+ `channel_error_msg` varchar(256) NULL DEFAULT NULL COMMENT '调用渠道的错误提示',
+ `channel_notify_data` varchar(4096) NULL DEFAULT NULL COMMENT '渠道的同步/异步通知的内容',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
@@ -26,39 +34,18 @@ CREATE TABLE `pay_transfer`
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB COMMENT='转账单表';
--- ----------------------------
--- 转账扩展单
--- ----------------------------
-DROP TABLE IF EXISTS `pay_transfer_extension`;
-CREATE TABLE `pay_transfer_extension`
-(
- `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
- `no` varchar(64) NOT NULL COMMENT '转账单号',
- `transfer_id` bigint NOT NULL COMMENT '转账单编号',
- `channel_id` bigint NOT NULL COMMENT '转账渠道编号',
- `channel_code` varchar(32) NOT NULL COMMENT '转账渠道编码',
- `channel_extras` varchar(512) NULL DEFAULT NULL COMMENT '支付渠道的额外参数',
- `status` tinyint NOT NULL COMMENT '转账状态',
- `channel_notify_data` varchar(4096) NULL DEFAULT NULL COMMENT '支付渠道异步通知的内容',
- `creator` varchar(64) NULL DEFAULT '' COMMENT '创建者',
- `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `updater` varchar(64) NULL DEFAULT '' COMMENT '更新者',
- `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
- `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
- PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB COMMENT='转账拓展单表';
-
-- ----------------------------
-- Table structure for pay_demo_transfer
-- ----------------------------
DROP TABLE IF EXISTS `pay_demo_transfer`;
CREATE TABLE `pay_demo_transfer` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '订单编号',
- `user_id` bigint UNSIGNED NOT NULL COMMENT '用户编号',
- `price` int NOT NULL COMMENT '转账金额,单位:分',
+ `app_id` bigint NOT NULL COMMENT '应用编号',
`type` int NOT NULL COMMENT '转账类型',
- `payee_info` varchar(512) NOT NULL COMMENT '收款人信息,不同类型和渠道不同',
+ `price` int NOT NULL COMMENT '转账金额,单位:分',
+ `user_name` varchar(64) NULL COMMENT '收款人姓名',
+ `alipay_logon_id` varchar(64) NULL COMMENT '支付宝登录号',
+ `openid` varchar(64) NULL COMMENT '微信 openId',
`transfer_status` tinyint NOT NULL DEFAULT 0 COMMENT '转账状态',
`pay_transfer_id` bigint NULL DEFAULT NULL COMMENT '转账订单编号',
`pay_channel_code` varchar(16) NULL DEFAULT NULL COMMENT '转账支付成功渠道',
@@ -70,11 +57,11 @@ CREATE TABLE `pay_demo_transfer` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB COMMENT = '示例业务转账订单\n';
+) ENGINE = InnoDB COMMENT = '示例业务转账订单';
-ALTER TABLE `pay_channel`
- MODIFY COLUMN `config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '支付渠道配置' AFTER `app_id`;
+-- ALTER TABLE `pay_channel`
+-- MODIFY COLUMN `config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '支付渠道配置' AFTER `app_id`;
-- ----------------------------
-- 充值套餐表
@@ -203,3 +190,67 @@ VALUES (
'', '', '', 0
);
+-- 支付实战和转账实战数据库脚本
+
+update system_menu set deleted = 1 where id = 2161;
+
+INSERT INTO system_menu(
+ name, permission, type, sort, parent_id,
+ path, icon, component, status, component_name
+)
+VALUES (
+ '接入示例', '', 1, 99, 1117,
+ 'demo', 'ep:caret-right', '', 0, ''
+ );
+
+SELECT @parentId1 := LAST_INSERT_ID();
+
+INSERT INTO system_menu(
+ name, permission, type, sort, parent_id,
+ path, icon, component, status, component_name
+)
+VALUES (
+ '支付实战', '', 2, 1, @parentId1,
+ 'demo-order', 'fa:leaf', 'pay/demo/order/index', 0, NULL
+ );
+
+INSERT INTO system_menu(
+ name, permission, type, sort, parent_id,
+ path, icon, component, status, component_name
+)
+VALUES (
+ '转账实战', '', 2, 1, @parentId1,
+ 'demo-transfer', 'fa:leaf', 'pay/demo/transfer/index', 0, NULL
+ );
+
+-- 转账状态和转账类型数据字典
+INSERT INTO `system_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES ('支付转账类型', 'pay_transfer_type', 0, '', '1', '2023-10-28 16:27:18', '1', '2023-10-28 16:27:18', b'0', '1970-01-01 00:00:00');
+INSERT INTO `system_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES ('转账订单状态', 'pay_transfer_status', 0, '', '1', '2023-10-28 16:18:32', '1', '2023-10-28 16:18:32', b'0', '1970-01-01 00:00:00');
+
+INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '钱包余额', '4', 'pay_transfer_type', 0, 'info', '', '', '1', '2023-10-28 16:28:37', '1', '2023-10-28 16:28:37', b'0');
+INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3, '银行卡', '3', 'pay_transfer_type', 0, 'default', '', '', '1', '2023-10-28 16:28:21', '1', '2023-10-28 16:28:21', b'0');
+INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2, '微信余额', '2', 'pay_transfer_type', 0, 'info', '', '', '1', '2023-10-28 16:28:07', '1', '2023-10-28 16:28:07', b'0');
+INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '支付宝余额', '1', 'pay_transfer_type', 0, 'default', '', '', '1', '2023-10-28 16:27:44', '1', '2023-10-28 16:27:44', b'0');
+INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '转账失败', '30', 'pay_transfer_status', 0, 'warning', '', '', '1', '2023-10-28 16:24:16', '1', '2023-10-28 16:24:16', b'0');
+INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3, '转账成功', '20', 'pay_transfer_status', 0, 'success', '', '', '1', '2023-10-28 16:23:50', '1', '2023-10-28 16:23:50', b'0');
+INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2, '转账进行中', '10', 'pay_transfer_status', 0, 'info', '', '', '1', '2023-10-28 16:23:12', '1', '2023-10-28 16:23:12', b'0');
+INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '等待转账', '0', 'pay_transfer_status', 0, 'default', '', '', '1', '2023-10-28 16:21:43', '1', '2023-10-28 16:23:22', b'0');
+
+-- 转账订单菜单脚本
+
+INSERT INTO system_menu(
+ name, permission, type, sort, parent_id,
+ path, icon, component, status, component_name
+)
+VALUES (
+ '转账订单', '', 2, 3, 1117,
+ 'transfer', 'ep:credit-card', 'pay/transfer/index', 0, 'PayTransfer'
+ );
+
+-- 转账通知脚本
+
+ALTER TABLE `pay_app`
+ ADD COLUMN `transfer_notify_url` varchar(1024) NOT NULL COMMENT '转账结果的回调地址' AFTER `refund_notify_url`;
+ALTER TABLE `pay_notify_task`
+ MODIFY COLUMN `merchant_order_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '商户订单编号' AFTER `status`,
+ ADD COLUMN `merchant_transfer_id` varchar(64) COMMENT '商户转账单编号' AFTER `merchant_order_id`;
\ No newline at end of file
diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql
index f93b87120..50ae2fbd3 100644
--- a/sql/mysql/ruoyi-vue-pro.sql
+++ b/sql/mysql/ruoyi-vue-pro.sql
@@ -3,15 +3,15 @@
Source Server : 127.0.0.1 MySQL
Source Server Type : MySQL
- Source Server Version : 80034
- Source Host : localhost:3306
+ Source Server Version : 80200 (8.2.0)
+ Source Host : 127.0.0.1:3306
Source Schema : ruoyi-vue-pro
Target Server Type : MySQL
- Target Server Version : 80034
+ Target Server Version : 80200 (8.2.0)
File Encoding : 65001
- Date: 04/11/2023 20:42:49
+ Date: 30/11/2023 21:13:06
*/
SET NAMES utf8mb4;
@@ -385,7 +385,7 @@ CREATE TABLE `infra_api_error_log` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1781 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
+) ENGINE = InnoDB AUTO_INCREMENT = 2018 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
-- ----------------------------
-- Records of infra_api_error_log
@@ -423,7 +423,7 @@ CREATE TABLE `infra_codegen_column` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1804 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表字段定义';
+) ENGINE = InnoDB AUTO_INCREMENT = 2000 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表字段定义';
-- ----------------------------
-- Records of infra_codegen_column
@@ -450,13 +450,18 @@ CREATE TABLE `infra_codegen_table` (
`template_type` tinyint NOT NULL DEFAULT 1 COMMENT '模板类型',
`front_type` tinyint NOT NULL COMMENT '前端类型',
`parent_menu_id` bigint NULL DEFAULT NULL COMMENT '父菜单编号',
+ `master_table_id` bigint NULL DEFAULT NULL COMMENT '主表的编号',
+ `sub_join_column_id` bigint NULL DEFAULT NULL COMMENT '子表关联主表的字段编号',
+ `sub_join_many` bit(1) NULL DEFAULT NULL COMMENT '主表与子表是否一对多',
+ `tree_parent_column_id` bigint NULL DEFAULT NULL COMMENT '树表的父字段编号',
+ `tree_name_column_id` bigint NULL DEFAULT NULL COMMENT '树表的名字字段编号',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 136 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表定义';
+) ENGINE = InnoDB AUTO_INCREMENT = 155 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表定义';
-- ----------------------------
-- Records of infra_codegen_table
@@ -521,6 +526,151 @@ CREATE TABLE `infra_data_source_config` (
BEGIN;
COMMIT;
+-- ----------------------------
+-- Table structure for infra_demo01_contact
+-- ----------------------------
+DROP TABLE IF EXISTS `infra_demo01_contact`;
+CREATE TABLE `infra_demo01_contact` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
+ `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名字',
+ `sex` tinyint(1) NOT NULL COMMENT '性别',
+ `birthday` datetime NOT NULL COMMENT '出生年',
+ `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '简介',
+ `avatar` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '头像',
+ `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '示例联系人表';
+
+-- ----------------------------
+-- Records of infra_demo01_contact
+-- ----------------------------
+BEGIN;
+INSERT INTO `infra_demo01_contact` (`id`, `name`, `sex`, `birthday`, `description`, `avatar`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '土豆', 2, '2023-11-07 00:00:00', '天蚕土豆!呀
', 'http://127.0.0.1:48080/admin-api/infra/file/4/get/46f8fa1a37db3f3960d8910ff2fe3962ab3b2db87cf2f8ccb4dc8145b8bdf237.jpeg', '1', '2023-11-15 23:34:30', '1', '2023-11-15 23:47:39', b'0', 1);
+COMMIT;
+
+-- ----------------------------
+-- Table structure for infra_demo02_category
+-- ----------------------------
+DROP TABLE IF EXISTS `infra_demo02_category`;
+CREATE TABLE `infra_demo02_category` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
+ `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名字',
+ `parent_id` bigint NOT NULL COMMENT '父级编号',
+ `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '示例分类表';
+
+-- ----------------------------
+-- Records of infra_demo02_category
+-- ----------------------------
+BEGIN;
+INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '土豆', 0, '1', '2023-11-15 23:34:30', '1', '2023-11-16 20:24:23', b'0', 1);
+INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '番茄', 0, '1', '2023-11-16 20:24:00', '1', '2023-11-16 20:24:15', b'0', 1);
+INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, '怪怪', 0, '1', '2023-11-16 20:24:32', '1', '2023-11-16 20:24:32', b'0', 1);
+INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, '小番茄', 2, '1', '2023-11-16 20:24:39', '1', '2023-11-16 20:24:39', b'0', 1);
+INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, '大番茄', 2, '1', '2023-11-16 20:24:46', '1', '2023-11-16 20:24:46', b'0', 1);
+INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, '11', 3, '1', '2023-11-24 19:29:34', '1', '2023-11-24 19:29:34', b'0', 1);
+COMMIT;
+
+-- ----------------------------
+-- Table structure for infra_demo03_course
+-- ----------------------------
+DROP TABLE IF EXISTS `infra_demo03_course`;
+CREATE TABLE `infra_demo03_course` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
+ `student_id` bigint NOT NULL COMMENT '学生编号',
+ `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名字',
+ `score` tinyint NOT NULL COMMENT '分数',
+ `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '学生课程表';
+
+-- ----------------------------
+-- Records of infra_demo03_course
+-- ----------------------------
+BEGIN;
+INSERT INTO `infra_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 2, '语文', 66, '1', '2023-11-16 23:21:49', '1', '2023-11-16 23:21:49', b'0', 1);
+INSERT INTO `infra_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 2, '数学', 22, '1', '2023-11-16 23:21:49', '1', '2023-11-16 23:21:49', b'0', 1);
+INSERT INTO `infra_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, 5, '体育', 23, '1', '2023-11-16 23:22:46', '1', '2023-11-16 15:44:40', b'1', 1);
+INSERT INTO `infra_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 5, '计算机', 11, '1', '2023-11-16 23:22:46', '1', '2023-11-16 15:44:40', b'1', 1);
+INSERT INTO `infra_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (8, 5, '体育', 23, '1', '2023-11-16 23:22:46', '1', '2023-11-16 15:47:09', b'1', 1);
+INSERT INTO `infra_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, 5, '计算机', 11, '1', '2023-11-16 23:22:46', '1', '2023-11-16 15:47:09', b'1', 1);
+INSERT INTO `infra_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (10, 5, '体育', 23, '1', '2023-11-16 23:22:46', '1', '2023-11-16 23:47:10', b'0', 1);
+INSERT INTO `infra_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (11, 5, '计算机', 11, '1', '2023-11-16 23:22:46', '1', '2023-11-16 23:47:10', b'0', 1);
+INSERT INTO `infra_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (12, 2, '电脑', 33, '1', '2023-11-17 00:20:42', '1', '2023-11-16 16:20:45', b'1', 1);
+INSERT INTO `infra_demo03_course` (`id`, `student_id`, `name`, `score`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (13, 9, '滑雪', 12, '1', '2023-11-17 13:13:20', '1', '2023-11-17 13:13:20', b'0', 1);
+COMMIT;
+
+-- ----------------------------
+-- Table structure for infra_demo03_grade
+-- ----------------------------
+DROP TABLE IF EXISTS `infra_demo03_grade`;
+CREATE TABLE `infra_demo03_grade` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
+ `student_id` bigint NOT NULL COMMENT '学生编号',
+ `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名字',
+ `teacher` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '班主任',
+ `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '学生班级表';
+
+-- ----------------------------
+-- Records of infra_demo03_grade
+-- ----------------------------
+BEGIN;
+INSERT INTO `infra_demo03_grade` (`id`, `student_id`, `name`, `teacher`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 2, '三年 2 班', '周杰伦', '1', '2023-11-16 23:21:49', '1', '2023-11-16 23:21:49', b'0', 1);
+INSERT INTO `infra_demo03_grade` (`id`, `student_id`, `name`, `teacher`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (8, 5, '华为', '遥遥领先', '1', '2023-11-16 23:22:46', '1', '2023-11-16 23:47:10', b'0', 1);
+INSERT INTO `infra_demo03_grade` (`id`, `student_id`, `name`, `teacher`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, 9, '小图', '小娃111', '1', '2023-11-17 13:10:23', '1', '2023-11-17 13:10:23', b'0', 1);
+COMMIT;
+
+-- ----------------------------
+-- Table structure for infra_demo03_student
+-- ----------------------------
+DROP TABLE IF EXISTS `infra_demo03_student`;
+CREATE TABLE `infra_demo03_student` (
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
+ `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名字',
+ `sex` tinyint NOT NULL COMMENT '性别',
+ `birthday` datetime NOT NULL COMMENT '出生日期',
+ `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '简介',
+ `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '学生表';
+
+-- ----------------------------
+-- Records of infra_demo03_student
+-- ----------------------------
+BEGIN;
+INSERT INTO `infra_demo03_student` (`id`, `name`, `sex`, `birthday`, `description`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '小白', 1, '2023-11-16 00:00:00', '厉害
', '1', '2023-11-16 23:21:49', '1', '2023-11-17 16:49:06', b'0', 1);
+INSERT INTO `infra_demo03_student` (`id`, `name`, `sex`, `birthday`, `description`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, '大黑', 2, '2023-11-13 00:00:00', '你在教我做事?
', '1', '2023-11-16 23:22:46', '1', '2023-11-17 16:49:07', b'0', 1);
+INSERT INTO `infra_demo03_student` (`id`, `name`, `sex`, `birthday`, `description`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, '小花', 1, '2023-11-07 00:00:00', '哈哈哈
', '1', '2023-11-17 00:04:47', '1', '2023-11-17 16:49:08', b'0', 1);
+COMMIT;
+
-- ----------------------------
-- Table structure for infra_file
-- ----------------------------
@@ -539,7 +689,7 @@ CREATE TABLE `infra_file` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1108 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
+) ENGINE = InnoDB AUTO_INCREMENT = 1128 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
-- ----------------------------
-- Records of infra_file
@@ -588,7 +738,7 @@ CREATE TABLE `infra_file_content` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 202 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
+) ENGINE = InnoDB AUTO_INCREMENT = 221 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
-- ----------------------------
-- Records of infra_file_content
@@ -616,7 +766,7 @@ CREATE TABLE `infra_job` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 27 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表';
+) ENGINE = InnoDB AUTO_INCREMENT = 28 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表';
-- ----------------------------
-- Records of infra_job
@@ -657,7 +807,7 @@ CREATE TABLE `infra_job_log` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 232 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表';
+) ENGINE = InnoDB AUTO_INCREMENT = 233 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表';
-- ----------------------------
-- Records of infra_job_log
@@ -665,31 +815,6 @@ CREATE TABLE `infra_job_log` (
BEGIN;
COMMIT;
--- ----------------------------
--- Table structure for infra_test_demo
--- ----------------------------
-DROP TABLE IF EXISTS `infra_test_demo`;
-CREATE TABLE `infra_test_demo` (
- `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
- `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名字',
- `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态',
- `type` tinyint NOT NULL COMMENT '类型',
- `category` tinyint NOT NULL COMMENT '分类',
- `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '备注',
- `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
- `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
- `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
- PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
-
--- ----------------------------
--- Records of infra_test_demo
--- ----------------------------
-BEGIN;
-COMMIT;
-
-- ----------------------------
-- Table structure for member_address
-- ----------------------------
@@ -710,7 +835,7 @@ CREATE TABLE `member_address` (
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_userId`(`user_id` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址';
+) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址';
-- ----------------------------
-- Records of member_address
@@ -769,7 +894,7 @@ CREATE TABLE `member_experience_record` (
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员经验记录-用户编号',
INDEX `idx_user_biz_type`(`user_id` ASC, `biz_type` ASC) USING BTREE COMMENT '会员经验记录-用户业务类型'
-) ENGINE = InnoDB AUTO_INCREMENT = 41 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员经验记录';
+) ENGINE = InnoDB AUTO_INCREMENT = 42 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员经验记录';
-- ----------------------------
-- Records of member_experience_record
@@ -827,7 +952,7 @@ CREATE TABLE `member_group` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户分组';
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户分组';
-- ----------------------------
-- Records of member_group
@@ -855,7 +980,7 @@ CREATE TABLE `member_level` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级';
+) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级';
-- ----------------------------
-- Records of member_level
@@ -885,7 +1010,7 @@ CREATE TABLE `member_level_record` (
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员等级记录-用户编号'
-) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级记录';
+) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级记录';
-- ----------------------------
-- Records of member_level_record
@@ -915,7 +1040,7 @@ CREATE TABLE `member_point_record` (
PRIMARY KEY (`id`) USING BTREE,
INDEX `index_userId`(`user_id` ASC) USING BTREE,
INDEX `index_title`(`title` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 60 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户积分记录';
+) ENGINE = InnoDB AUTO_INCREMENT = 61 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户积分记录';
-- ----------------------------
-- Records of member_point_record
@@ -1055,7 +1180,7 @@ CREATE TABLE `member_tag` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员标签';
+) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员标签';
-- ----------------------------
-- Records of member_tag
@@ -1097,7 +1222,7 @@ CREATE TABLE `member_user` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 249 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员用户';
+) ENGINE = InnoDB AUTO_INCREMENT = 250 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员用户';
-- ----------------------------
-- Records of member_user
@@ -1131,7 +1256,7 @@ CREATE TABLE `system_dept` (
-- Records of system_dept
-- ----------------------------
BEGIN;
-INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, '芋道源码', 0, 0, 1, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2022-06-19 00:29:10', b'0', 1);
+INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, '芋道源码', 0, 0, 1, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2023-11-14 23:30:36', b'0', 1);
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (101, '深圳总公司', 100, 1, 104, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2022-05-16 20:25:23', b'0', 1);
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (102, '长沙分公司', 100, 2, NULL, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-12-15 05:01:40', b'0', 1);
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, '研发部门', 101, 1, 104, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '103', '2022-01-14 01:04:14', b'0', 1);
@@ -1165,14 +1290,14 @@ CREATE TABLE `system_dict_data` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1435 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
+) ENGINE = InnoDB AUTO_INCREMENT = 1455 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
-- ----------------------------
-- Records of system_dict_data
-- ----------------------------
BEGIN;
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, 1, '男', '1', 'system_user_sex', 0, 'default', 'A', '性别男', 'admin', '2021-01-05 17:03:48', '1', '2022-03-29 00:14:39', b'0');
-INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2, 2, '女', '2', 'system_user_sex', 1, 'success', '', '性别女', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 01:30:51', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2, 2, '女', '2', 'system_user_sex', 0, 'success', '', '性别女', 'admin', '2021-01-05 17:03:48', '1', '2023-11-15 23:30:37', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (8, 1, '正常', '1', 'infra_job_status', 0, 'success', '', '正常状态', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 19:33:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (9, 2, '暂停', '2', 'infra_job_status', 0, 'danger', '', '停用状态', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 19:33:45', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (12, 1, '系统内置', '1', 'infra_config_type', 0, 'danger', '', '参数类型 - 系统内置', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 19:06:02', b'0');
@@ -1474,6 +1599,20 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1438, 31, '微信公众平台', '31', 'system_social_type', 0, '', '', '', '1', '2023-11-04 13:05:18', '1', '2023-11-04 13:05:18', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1439, 32, '微信开放平台', '32', 'system_social_type', 0, '', '', '', '1', '2023-11-04 13:05:30', '1', '2023-11-04 13:05:30', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1440, 34, '微信小程序', '34', 'system_social_type', 0, '', '', '', '1', '2023-11-04 13:05:38', '1', '2023-11-04 13:07:16', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1441, 1, '上架', '1', 'crm_product_status', 0, 'success', '', '', '1', '2023-10-30 21:49:34', '1', '2023-10-30 21:49:34', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1442, 0, '下架', '0', 'crm_product_status', 0, 'success', '', '', '1', '2023-10-30 21:49:13', '1', '2023-10-30 21:49:13', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1443, 15, '子表', '15', 'infra_codegen_template_type', 0, 'default', '', '', '1', '2023-11-13 23:06:16', '1', '2023-11-13 23:06:16', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1444, 10, '主表(标准模式)', '10', 'infra_codegen_template_type', 0, 'default', '', '', '1', '2023-11-14 12:32:49', '1', '2023-11-14 12:32:49', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1445, 11, '主表(ERP 模式)', '11', 'infra_codegen_template_type', 0, 'default', '', '', '1', '2023-11-14 12:33:05', '1', '2023-11-14 12:33:05', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1446, 12, '主表(内嵌模式)', '12', 'infra_codegen_template_type', 0, '', '', '', '1', '2023-11-14 12:33:31', '1', '2023-11-14 12:33:31', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1447, 1, '负责人', '1', 'crm_permission_level', 0, 'default', '', '', '1', '2023-11-30 09:53:12', '1', '2023-11-30 09:53:12', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1448, 2, '只读', '2', 'crm_permission_level', 0, '', '', '', '1', '2023-11-30 09:53:29', '1', '2023-11-30 09:53:29', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1449, 3, '读写', '3', 'crm_permission_level', 0, '', '', '', '1', '2023-11-30 09:53:36', '1', '2023-11-30 09:53:36', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1450, 0, '未提交', '0', 'crm_audit_status', 0, '', '', '', '1', '2023-11-30 18:56:59', '1', '2023-11-30 18:56:59', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1451, 10, '审批中', '10', 'crm_audit_status', 0, '', '', '', '1', '2023-11-30 18:57:10', '1', '2023-11-30 18:57:10', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1452, 20, '审核通过', '20', 'crm_audit_status', 0, '', '', '', '1', '2023-11-30 18:57:24', '1', '2023-11-30 18:57:24', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1453, 30, '审核不通过', '30', 'crm_audit_status', 0, '', '', '', '1', '2023-11-30 18:57:32', '1', '2023-11-30 18:57:32', b'0');
+INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1454, 40, '已取消', '40', 'crm_audit_status', 0, '', '', '', '1', '2023-11-30 18:57:42', '1', '2023-11-30 18:57:42', b'0');
COMMIT;
-- ----------------------------
@@ -1494,7 +1633,7 @@ CREATE TABLE `system_dict_type` (
`deleted_time` datetime NULL DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `dict_type`(`type` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 600 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
+) ENGINE = InnoDB AUTO_INCREMENT = 607 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
-- ----------------------------
-- Records of system_dict_type
@@ -1573,6 +1712,9 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (188, '客户来源', 'crm_customer_source', 0, 'CRM 客户来源', '1', '2023-10-28 23:00:34', '1', '2023-10-28 15:11:16', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (600, 'Banner 位置', 'promotion_banner_position', 0, '', '1', '2023-10-08 07:24:25', '1', '2023-11-04 13:04:02', b'0', '1970-01-01 00:00:00');
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (601, '社交类型', 'system_social_type', 0, '', '1', '2023-11-04 13:03:54', '1', '2023-11-04 13:03:54', b'0', '1970-01-01 00:00:00');
+INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (604, '产品状态', 'crm_product_status', 0, '', '1', '2023-10-30 21:47:59', '1', '2023-10-30 21:48:45', b'0', '1970-01-01 00:00:00');
+INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (605, 'CRM 数据权限的级别', 'crm_permission_level', 0, '', '1', '2023-11-30 09:51:59', '1', '2023-11-30 09:51:59', b'0', '1970-01-01 00:00:00');
+INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (606, 'CRM 审批状态', 'crm_audit_status', 0, '', '1', '2023-11-30 18:56:23', '1', '2023-11-30 18:56:23', b'0', '1970-01-01 00:00:00');
COMMIT;
-- ----------------------------
@@ -1592,7 +1734,7 @@ CREATE TABLE `system_error_code` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 5932 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表';
+) ENGINE = InnoDB AUTO_INCREMENT = 6039 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表';
-- ----------------------------
-- Records of system_error_code
@@ -1621,7 +1763,7 @@ CREATE TABLE `system_login_log` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 2631 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
+) ENGINE = InnoDB AUTO_INCREMENT = 2667 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
-- ----------------------------
-- Records of system_login_log
@@ -1686,7 +1828,7 @@ CREATE TABLE `system_mail_log` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 355 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '邮件日志表';
+) ENGINE = InnoDB AUTO_INCREMENT = 356 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '邮件日志表';
-- ----------------------------
-- Records of system_mail_log
@@ -1751,7 +1893,7 @@ CREATE TABLE `system_menu` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 2449 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
+) ENGINE = InnoDB AUTO_INCREMENT = 2526 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
-- ----------------------------
-- Records of system_menu
@@ -1839,11 +1981,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1065, '设置用户角色', 'system:permission:assign-user-role', 3, 8, 101, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-01-07 10:23:28', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1066, '获得 Redis 监控信息', 'infra:redis:get-monitor-info', 3, 1, 113, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-01-26 01:02:31', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1067, '获得 Redis Key 列表', 'infra:redis:get-key-list', 3, 2, 113, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-01-26 01:02:52', '', '2022-04-20 17:03:10', b'0');
-INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1070, '代码生成示例', 'infra:test-demo:query', 2, 1, 2, 'test-demo', 'validCode', 'infra/testDemo/index', NULL, 0, b'1', b'1', b'1', '', '2021-02-06 12:42:49', '1', '2022-04-20 17:03:10', b'0');
-INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1071, '测试示例表创建', 'infra:test-demo:create', 3, 1, 1070, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-02-06 12:42:49', '1', '2022-04-20 17:03:10', b'0');
-INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1072, '测试示例表更新', 'infra:test-demo:update', 3, 2, 1070, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-02-06 12:42:49', '1', '2022-04-20 17:03:10', b'0');
-INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1073, '测试示例表删除', 'infra:test-demo:delete', 3, 3, 1070, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-02-06 12:42:49', '1', '2022-04-20 17:03:10', b'0');
-INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1074, '测试示例表导出', 'infra:test-demo:export', 3, 4, 1070, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-02-06 12:42:49', '1', '2022-04-20 17:03:10', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1070, '代码生成案例', '', 1, 1, 2, 'demo', 'ep:aim', 'infra/testDemo/index', NULL, 0, b'1', b'1', b'1', '', '2021-02-06 12:42:49', '1', '2023-11-15 23:45:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1075, '任务触发', 'infra:job:trigger', 3, 8, 110, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-02-07 13:03:10', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1076, '数据库文档', '', 2, 4, 2, 'db-doc', 'table', 'infra/dbDoc/index', 'InfraDBDoc', 0, b'1', b'1', b'1', '', '2021-02-08 01:41:47', '1', '2023-04-08 09:13:38', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1077, '监控平台', '', 2, 13, 2, 'skywalking', 'eye-open', 'infra/skywalking/index', 'InfraSkyWalking', 0, b'1', b'1', b'1', '', '2021-02-08 20:41:31', '1', '2023-04-08 10:39:06', b'0');
@@ -2165,7 +2303,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2302, '支付通知查询', 'pay:notify:query', 3, 1, 2301, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-07-20 04:41:32', '', '2023-07-20 04:41:32', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2303, '拼团活动', '', 2, 3, 2030, 'combination', 'fa:group', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:19:54', '1', '2023-08-12 17:20:05', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2304, '拼团商品', '', 2, 1, 2303, 'acitivity', 'ep:apple', 'mall/promotion/combination/activity/index', 'PromotionCombinationActivity', 0, b'1', b'1', b'1', '1', '2023-08-12 17:22:03', '1', '2023-08-12 17:22:29', b'0');
-INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2305, '拼团活动查询', 'promotion:combination-activity:query ', 3, 1, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:54:32', '1', '2023-08-12 17:54:32', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2305, '拼团活动查询', 'promotion:combination-activity:query', 3, 1, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:54:32', '1', '2023-11-24 11:57:40', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2306, '拼团活动创建', 'promotion:combination-activity:create', 3, 2, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:54:49', '1', '2023-08-12 17:54:49', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2307, '拼团活动更新', 'promotion:combination-activity:update', 3, 3, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:55:04', '1', '2023-08-12 17:55:04', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2308, '拼团活动删除', 'promotion:combination-activity:delete', 3, 4, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:55:23', '1', '2023-08-12 17:55:23', b'0');
@@ -2310,6 +2448,36 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2451, '三方应用更新', 'system:social-client:update', 3, 3, 2448, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-11-04 12:44:27', '1', '2023-11-04 12:44:27', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2452, '三方应用删除', 'system:social-client:delete', 3, 4, 2448, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-11-04 12:44:43', '1', '2023-11-04 12:44:43', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2453, '三方用户', 'system:social-user:query', 2, 2, 2447, 'user', 'ep:avatar', 'system/social/user/index.vue', 'SocialUser', 0, b'1', b'1', b'1', '1', '2023-11-04 14:01:05', '1', '2023-11-04 14:01:05', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2472, '主子表(内嵌)', '', 2, 12, 1070, 'demo03-inner', 'fa:power-off', 'infra/demo/demo03/inner/index', 'Demo03StudentInner', 0, b'1', b'1', b'1', '', '2023-11-13 04:39:51', '1', '2023-11-16 23:53:46', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2478, '单表(增删改查)', '', 2, 1, 1070, 'demo01-contact', 'ep:bicycle', 'infra/demo/demo01/index', 'Demo01Contact', 0, b'1', b'1', b'1', '', '2023-11-15 14:42:30', '1', '2023-11-16 20:34:40', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2479, '示例联系人查询', 'infra:demo01-contact:query', 3, 1, 2478, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-15 14:42:30', '', '2023-11-15 14:42:30', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2480, '示例联系人创建', 'infra:demo01-contact:create', 3, 2, 2478, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-15 14:42:30', '', '2023-11-15 14:42:30', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2481, '示例联系人更新', 'infra:demo01-contact:update', 3, 3, 2478, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-15 14:42:30', '', '2023-11-15 14:42:30', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2482, '示例联系人删除', 'infra:demo01-contact:delete', 3, 4, 2478, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-15 14:42:30', '', '2023-11-15 14:42:30', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2483, '示例联系人导出', 'infra:demo01-contact:export', 3, 5, 2478, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-15 14:42:30', '', '2023-11-15 14:42:30', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2484, '树表(增删改查)', '', 2, 2, 1070, 'demo02-category', 'fa:tree', 'infra/demo/demo02/index', 'Demo02Category', 0, b'1', b'1', b'1', '', '2023-11-16 12:18:27', '1', '2023-11-16 20:35:01', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2485, '示例分类查询', 'infra:demo02-category:query', 3, 1, 2484, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:18:27', '', '2023-11-16 12:18:27', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2486, '示例分类创建', 'infra:demo02-category:create', 3, 2, 2484, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:18:27', '', '2023-11-16 12:18:27', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2487, '示例分类更新', 'infra:demo02-category:update', 3, 3, 2484, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:18:27', '', '2023-11-16 12:18:27', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2488, '示例分类删除', 'infra:demo02-category:delete', 3, 4, 2484, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:18:27', '', '2023-11-16 12:18:27', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2489, '示例分类导出', 'infra:demo02-category:export', 3, 5, 2484, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:18:27', '', '2023-11-16 12:18:27', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2490, '主子表(标准)', '', 2, 10, 1070, 'demo03-normal', 'fa:battery-3', 'infra/demo/demo03/normal/index', 'Demo03StudentNormal', 0, b'1', b'1', b'1', '', '2023-11-16 12:53:37', '1', '2023-11-16 23:10:03', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2491, '学生查询', 'infra:demo03-student:query', 3, 1, 2490, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:53:37', '', '2023-11-16 12:53:37', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2492, '学生创建', 'infra:demo03-student:create', 3, 2, 2490, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:53:37', '', '2023-11-16 12:53:37', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2493, '学生更新', 'infra:demo03-student:update', 3, 3, 2490, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:53:37', '', '2023-11-16 12:53:37', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2494, '学生删除', 'infra:demo03-student:delete', 3, 4, 2490, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:53:37', '', '2023-11-16 12:53:37', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2495, '学生导出', 'infra:demo03-student:export', 3, 5, 2490, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:53:37', '', '2023-11-16 12:53:37', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2497, '主子表(ERP)', '', 2, 11, 1070, 'demo03-erp', 'ep:calendar', 'infra/demo/demo03/erp/index', 'Demo03StudentERP', 0, b'1', b'1', b'1', '', '2023-11-16 15:50:59', '1', '2023-11-17 13:19:56', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2516, '客户公海配置', '', 2, 0, 2524, 'customer-pool-config', 'ep:data-analysis', 'crm/config/customerPoolConfig/index', 'CrmCustomerPoolConfig', 0, b'1', b'1', b'1', '', '2023-11-18 13:33:31', '1', '2023-11-26 20:08:14', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2517, '客户公海配置保存', 'crm:customer-pool-config:update', 3, 1, 2516, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:31', '', '2023-11-18 13:33:31', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2518, '客户限制配置', '', 2, 0, 2524, 'customer-limit-config', 'ep:avatar', 'crm/config/customerLimitConfig/index', 'CrmCustomerLimitConfig', 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '1', '2023-11-26 20:07:04', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2519, '客户限制配置查询', 'crm:customer-limit-config:query', 3, 1, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2520, '客户限制配置创建', 'crm:customer-limit-config:create', 3, 2, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2521, '客户限制配置更新', 'crm:customer-limit-config:update', 3, 3, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2522, '客户限制配置删除', 'crm:customer-limit-config:delete', 3, 4, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2523, '客户限制配置导出', 'crm:customer-limit-config:export', 3, 5, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2524, '系统配置', '', 1, 99, 2397, 'config', 'ep:connection', '', '', 0, b'1', b'1', b'1', '1', '2023-11-18 21:58:00', '1', '2023-11-18 21:58:00', b'0');
+INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2525, 'WebSocket 测试', '', 2, 7, 2, 'websocket', 'ep:connection', 'infra/webSocket/index', 'InfraWebSocket', 0, b'1', b'1', b'1', '1', '2023-11-23 19:41:55', '1', '2023-11-24 19:22:30', b'0');
COMMIT;
-- ----------------------------
@@ -2336,7 +2504,7 @@ CREATE TABLE `system_notice` (
-- ----------------------------
BEGIN;
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '芋道的公众', '新版本内容133
', 1, 0, 'admin', '2021-01-05 17:03:48', '1', '2022-05-04 21:00:20', b'0', 1);
-INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '维护通知:2018-07-01 若依系统凌晨维护', ' 维护内容
', 2, 1, 'admin', '2021-01-05 17:03:48', '1', '2022-05-11 12:34:24', b'0', 1);
+INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '维护通知:2018-07-01 系统凌晨维护', ' 1111
', 2, 1, 'admin', '2021-01-05 17:03:48', '1', '2023-11-23 23:37:41', b'0', 1);
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, '我是测试标题', '哈哈哈哈123
', 1, 0, '110', '2022-02-22 01:01:25', '110', '2022-02-22 01:01:46', b'0', 121);
COMMIT;
@@ -2400,7 +2568,7 @@ CREATE TABLE `system_notify_template` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '站内信模板表';
+) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '站内信模板表';
-- ----------------------------
-- Records of system_notify_template
@@ -2430,7 +2598,7 @@ CREATE TABLE `system_oauth2_access_token` (
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_access_token`(`access_token` ASC) USING BTREE,
INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 3152 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
+) ENGINE = InnoDB AUTO_INCREMENT = 3587 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
-- ----------------------------
-- Records of system_oauth2_access_token
@@ -2552,7 +2720,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1099 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
+) ENGINE = InnoDB AUTO_INCREMENT = 1132 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
-- ----------------------------
-- Records of system_oauth2_refresh_token
@@ -2592,7 +2760,7 @@ CREATE TABLE `system_operate_log` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 8845 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
+) ENGINE = InnoDB AUTO_INCREMENT = 9175 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
-- ----------------------------
-- Records of system_operate_log
@@ -2625,8 +2793,8 @@ CREATE TABLE `system_post` (
-- ----------------------------
BEGIN;
INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'ceo', '董事长', 1, 0, '', 'admin', '2021-01-06 17:03:48', '1', '2023-02-11 15:19:04', b'0', 1);
-INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 'se', '项目经理', 2, 0, '', 'admin', '2021-01-05 17:03:48', '1', '2021-12-12 10:47:47', b'0', 1);
-INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 'user', '普通员工', 4, 0, '111', 'admin', '2021-01-05 17:03:48', '1', '2023-02-11 15:19:00', b'0', 1);
+INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 'se', '项目经理', 2, 0, '', 'admin', '2021-01-05 17:03:48', '1', '2023-11-15 09:18:20', b'0', 1);
+INSERT INTO `system_post` (`id`, `code`, `name`, `sort`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 'user', '普通员工', 4, 0, '111', 'admin', '2021-01-05 17:03:48', '1', '2023-11-15 09:18:18', b'0', 1);
COMMIT;
-- ----------------------------
@@ -2819,10 +2987,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1657, 101, 1066, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1658, 101, 1067, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1659, 101, 1070, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
-INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1660, 101, 1071, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
-INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1661, 101, 1072, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
-INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1662, 101, 1073, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
-INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1663, 101, 1074, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1664, 101, 1075, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1665, 101, 1076, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1666, 101, 1077, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
@@ -3140,10 +3304,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2027, 2, 1066, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2028, 2, 1067, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2029, 2, 1070, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
-INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2030, 2, 1071, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
-INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2031, 2, 1072, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
-INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2032, 2, 1073, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
-INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2033, 2, 1074, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2034, 2, 1075, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2035, 2, 1076, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2036, 2, 1082, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
@@ -3600,7 +3760,7 @@ CREATE TABLE `system_sms_code` (
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
-) ENGINE = InnoDB AUTO_INCREMENT = 535 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
+) ENGINE = InnoDB AUTO_INCREMENT = 536 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
-- ----------------------------
-- Records of system_sms_code
@@ -3627,8 +3787,6 @@ CREATE TABLE `system_sms_log` (
`user_type` tinyint NULL DEFAULT NULL COMMENT '用户类型',
`send_status` tinyint NOT NULL DEFAULT 0 COMMENT '发送状态',
`send_time` datetime NULL DEFAULT NULL COMMENT '发送时间',
- `send_code` int NULL DEFAULT NULL COMMENT '发送结果的编码',
- `send_msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '发送结果的提示',
`api_send_code` varchar(63) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '短信 API 发送结果的编码',
`api_send_msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '短信 API 发送失败的提示',
`api_request_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '短信 API 发送返回的唯一请求 ID',
@@ -3743,7 +3901,7 @@ CREATE TABLE `system_social_user` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
+) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
-- ----------------------------
-- Records of system_social_user
@@ -3768,7 +3926,7 @@ CREATE TABLE `system_social_user_bind` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 80 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
+) ENGINE = InnoDB AUTO_INCREMENT = 81 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
-- ----------------------------
-- Records of system_social_user_bind
@@ -3787,7 +3945,7 @@ CREATE TABLE `system_tenant` (
`contact_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '联系人',
`contact_mobile` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '联系手机',
`status` tinyint NOT NULL DEFAULT 0 COMMENT '租户状态(0正常 1停用)',
- `domain` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '绑定域名',
+ `website` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '绑定域名',
`package_id` bigint NOT NULL COMMENT '租户套餐编号',
`expire_time` datetime NOT NULL COMMENT '过期时间',
`account_count` int NOT NULL COMMENT '账号数量',
@@ -3803,9 +3961,9 @@ CREATE TABLE `system_tenant` (
-- Records of system_tenant
-- ----------------------------
BEGIN;
-INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `domain`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '芋道源码', NULL, '芋艿', '17321315478', 0, 'https://www.iocoder.cn', 0, '2099-02-19 17:14:16', 9999, '1', '2021-01-05 17:03:47', '1', '2022-02-23 12:15:11', b'0');
-INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `domain`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, '小租户', 110, '小王2', '15601691300', 0, 'http://www.iocoder.cn', 111, '2024-03-11 00:00:00', 20, '1', '2022-02-22 00:56:14', '1', '2023-09-16 16:59:42', b'0');
-INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `domain`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, '测试租户', 113, '芋道', '15601691300', 0, 'https://www.iocoder.cn', 111, '2022-04-30 00:00:00', 50, '1', '2022-03-07 21:37:58', '1', '2023-09-16 16:59:27', b'0');
+INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '芋道源码', NULL, '芋艿', '17321315478', 0, 'www.iocoder.cn', 0, '2099-02-19 17:14:16', 9999, '1', '2021-01-05 17:03:47', '1', '2023-11-06 11:41:41', b'0');
+INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, '小租户', 110, '小王2', '15601691300', 0, 'zsxq.iocoder.cn', 111, '2024-03-11 00:00:00', 20, '1', '2022-02-22 00:56:14', '1', '2023-11-06 11:41:47', b'0');
+INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, '测试租户', 113, '芋道', '15601691300', 0, 'test.iocoder.cn', 111, '2022-04-30 00:00:00', 50, '1', '2022-03-07 21:37:58', '1', '2023-11-06 11:41:53', b'0');
COMMIT;
-- ----------------------------
@@ -3938,13 +4096,13 @@ CREATE TABLE `system_users` (
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `idx_username`(`username` ASC, `update_time` ASC, `tenant_id` ASC) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 127 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
+) ENGINE = InnoDB AUTO_INCREMENT = 126 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
-- ----------------------------
-- Records of system_users
-- ----------------------------
BEGIN;
-INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://127.0.0.1:48080/admin-api/infra/file/4/get/37e56010ecbee472cdd821ac4b608e151e62a74d9633f15d085aee026eedeb60.png', 0, '0:0:0:0:0:0:0:1', '2023-11-04 10:33:16', 'admin', '2021-01-05 17:03:47', NULL, '2023-11-04 10:33:16', b'0', 1);
+INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://127.0.0.1:48080/admin-api/infra/file/4/get/37e56010ecbee472cdd821ac4b608e151e62a74d9633f15d085aee026eedeb60.png', 0, '127.0.0.1', '2023-11-30 09:16:00', 'admin', '2021-01-05 17:03:47', NULL, '2023-11-30 09:16:00', b'0', 1);
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '127.0.0.1', '2022-07-09 23:03:33', '', '2021-01-07 09:07:17', NULL, '2022-07-09 23:03:33', b'0', 1);
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$10$YMpimV4T6BtDhIaA8jSW.u8UTGBeGhc/qwXP4oxoMr4mOw9.qttt6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '127.0.0.1', '2022-07-08 01:26:27', '', '2021-01-13 23:50:35', NULL, '2022-07-08 01:26:27', b'0', 1);
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$10$GP8zvqHB//TekuzYZSBYAuBQJiNq1.fxQVDYJ.uBCOnWCtDVKE4H6', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, '', 0, '0:0:0:0:0:0:0:1', '2023-09-24 18:21:19', '', '2021-01-21 02:13:53', NULL, '2023-09-24 18:21:19', b'0', 1);
@@ -3959,7 +4117,7 @@ INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`,
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$10$/WCwGHu1eq0wOVDd/u8HweJ0gJCHyLS6T7ndCqI8UXZAQom1etk2e', '1', '11', 101, '[]', '', '', 1, '', 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2022-06-22 13:34:58', b'0', 1);
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (116, '15601691302', '$2a$10$L5C4S0U6adBWMvFv1Wwl4.DI/NwYS3WIfLj5Q.Naqr5II8CmqsDZ6', '小豆', NULL, NULL, NULL, '', '', 0, '', 0, '', NULL, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (117, 'admin123', '$2a$10$WI8Gg/lpZQIrOEZMHqka7OdFaD4Nx.B/qY8ZGTTUKrOJwaHFqibaC', '测试号', '1111', 100, '[2]', '', '15601691234', 1, '', 0, '', NULL, '1', '2022-07-09 17:40:26', '1', '2022-07-09 17:40:26', b'0', 1);
-INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (118, 'goudan', '$2a$10$Lrb71muL.s5/AFjQ2IHkzOFlAFwUToH.zQL7bnghvTDt/QptjGgF6', '狗蛋', NULL, 103, '[1]', '', '', 2, '', 0, '', NULL, '1', '2022-07-09 17:44:43', '1', '2022-12-31 17:29:13', b'0', 1);
+INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (118, 'goudan', '$2a$10$Lrb71muL.s5/AFjQ2IHkzOFlAFwUToH.zQL7bnghvTDt/QptjGgF6', '狗蛋', NULL, 103, '[1]', '', '', 2, '', 0, '', NULL, '1', '2022-07-09 17:44:43', '1', '2023-11-18 19:02:13', b'0', 1);
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
diff --git a/sql/oracle/ruoyi-vue-pro.sql b/sql/oracle/ruoyi-vue-pro.sql
index 46481ae2f..0eb0f6440 100644
--- a/sql/oracle/ruoyi-vue-pro.sql
+++ b/sql/oracle/ruoyi-vue-pro.sql
@@ -4178,7 +4178,7 @@ CREATE TABLE "SYSTEM_TENANT" (
"CONTACT_NAME" NVARCHAR2(30),
"CONTACT_MOBILE" NVARCHAR2(500),
"STATUS" NUMBER(4,0) NOT NULL,
- "DOMAIN" NVARCHAR2(256),
+ "WEBSITE" NVARCHAR2(256),
"PACKAGE_ID" NUMBER(20,0) NOT NULL,
"EXPIRE_TIME" DATE NOT NULL,
"ACCOUNT_COUNT" NUMBER(11,0) NOT NULL,
@@ -4211,7 +4211,7 @@ COMMENT ON COLUMN "SYSTEM_TENANT"."CONTACT_USER_ID" IS '联系人的用户编号
COMMENT ON COLUMN "SYSTEM_TENANT"."CONTACT_NAME" IS '联系人';
COMMENT ON COLUMN "SYSTEM_TENANT"."CONTACT_MOBILE" IS '联系手机';
COMMENT ON COLUMN "SYSTEM_TENANT"."STATUS" IS '租户状态(0正常 1停用)';
-COMMENT ON COLUMN "SYSTEM_TENANT"."DOMAIN" IS '绑定域名';
+COMMENT ON COLUMN "SYSTEM_TENANT"."WEBSITE" IS '绑定域名';
COMMENT ON COLUMN "SYSTEM_TENANT"."PACKAGE_ID" IS '租户套餐编号';
COMMENT ON COLUMN "SYSTEM_TENANT"."EXPIRE_TIME" IS '过期时间';
COMMENT ON COLUMN "SYSTEM_TENANT"."ACCOUNT_COUNT" IS '账号数量';
@@ -4225,9 +4225,9 @@ COMMENT ON TABLE "SYSTEM_TENANT" IS '租户表';
-- ----------------------------
-- Records of SYSTEM_TENANT
-- ----------------------------
-INSERT INTO "SYSTEM_TENANT" ("ID", "NAME", "CONTACT_USER_ID", "CONTACT_NAME", "CONTACT_MOBILE", "STATUS", "DOMAIN", "PACKAGE_ID", "EXPIRE_TIME", "ACCOUNT_COUNT", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('1', '芋道源码', NULL, '芋艿', '17321315478', '0', 'https://www.iocoder.cn', '0', TO_DATE('2099-02-19 17:14:16', 'SYYYY-MM-DD HH24:MI:SS'), '9999', '1', TO_DATE('2021-01-05 17:03:47', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-23 12:15:11', 'SYYYY-MM-DD HH24:MI:SS'), '0');
-INSERT INTO "SYSTEM_TENANT" ("ID", "NAME", "CONTACT_USER_ID", "CONTACT_NAME", "CONTACT_MOBILE", "STATUS", "DOMAIN", "PACKAGE_ID", "EXPIRE_TIME", "ACCOUNT_COUNT", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('121', '小租户', '110', '小王2', '15601691300', '0', 'http://www.iocoder.cn', '111', TO_DATE('2024-03-11 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '20', '1', TO_DATE('2022-02-22 00:56:14', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-03-19 18:37:20', 'SYYYY-MM-DD HH24:MI:SS'), '0');
-INSERT INTO "SYSTEM_TENANT" ("ID", "NAME", "CONTACT_USER_ID", "CONTACT_NAME", "CONTACT_MOBILE", "STATUS", "DOMAIN", "PACKAGE_ID", "EXPIRE_TIME", "ACCOUNT_COUNT", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('122', '测试租户', '113', '芋道', '15601691300', '0', 'https://www.iocoder.cn', '111', TO_DATE('2022-04-30 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '50', '1', TO_DATE('2022-03-07 21:37:58', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-03-07 21:37:58', 'SYYYY-MM-DD HH24:MI:SS'), '0');
+INSERT INTO "SYSTEM_TENANT" ("ID", "NAME", "CONTACT_USER_ID", "CONTACT_NAME", "CONTACT_MOBILE", "STATUS", "WEBSITE", "PACKAGE_ID", "EXPIRE_TIME", "ACCOUNT_COUNT", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('1', '芋道源码', NULL, '芋艿', '17321315478', '0', 'https://www.iocoder.cn', '0', TO_DATE('2099-02-19 17:14:16', 'SYYYY-MM-DD HH24:MI:SS'), '9999', '1', TO_DATE('2021-01-05 17:03:47', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-23 12:15:11', 'SYYYY-MM-DD HH24:MI:SS'), '0');
+INSERT INTO "SYSTEM_TENANT" ("ID", "NAME", "CONTACT_USER_ID", "CONTACT_NAME", "CONTACT_MOBILE", "STATUS", "WEBSITE", "PACKAGE_ID", "EXPIRE_TIME", "ACCOUNT_COUNT", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('121', '小租户', '110', '小王2', '15601691300', '0', 'http://www.iocoder.cn', '111', TO_DATE('2024-03-11 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '20', '1', TO_DATE('2022-02-22 00:56:14', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-03-19 18:37:20', 'SYYYY-MM-DD HH24:MI:SS'), '0');
+INSERT INTO "SYSTEM_TENANT" ("ID", "NAME", "CONTACT_USER_ID", "CONTACT_NAME", "CONTACT_MOBILE", "STATUS", "WEBSITE", "PACKAGE_ID", "EXPIRE_TIME", "ACCOUNT_COUNT", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('122', '测试租户', '113', '芋道', '15601691300', '0', 'https://www.iocoder.cn', '111', TO_DATE('2022-04-30 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '50', '1', TO_DATE('2022-03-07 21:37:58', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-03-07 21:37:58', 'SYYYY-MM-DD HH24:MI:SS'), '0');
COMMIT;
COMMIT;
diff --git a/sql/postgresql/ruoyi-vue-pro.sql b/sql/postgresql/ruoyi-vue-pro.sql
index cab2e38bc..206fdfce8 100644
--- a/sql/postgresql/ruoyi-vue-pro.sql
+++ b/sql/postgresql/ruoyi-vue-pro.sql
@@ -6779,7 +6779,7 @@ CREATE TABLE "system_tenant"
"contact_name" varchar(30) COLLATE "pg_catalog"."default" NOT NULL,
"contact_mobile" varchar(500) COLLATE "pg_catalog"."default",
"status" int2 NOT NULL,
- "domain" varchar(256) COLLATE "pg_catalog"."default",
+ "website" varchar(256) COLLATE "pg_catalog"."default",
"package_id" int8 NOT NULL,
"expire_time" timestamp(6) NOT NULL,
"account_count" int4 NOT NULL,
@@ -6803,7 +6803,7 @@ ON COLUMN "system_tenant"."contact_mobile" IS '联系手机';
COMMENT
ON COLUMN "system_tenant"."status" IS '租户状态(0正常 1停用)';
COMMENT
-ON COLUMN "system_tenant"."domain" IS '绑定域名';
+ON COLUMN "system_tenant"."website" IS '绑定域名';
COMMENT
ON COLUMN "system_tenant"."package_id" IS '租户套餐编号';
COMMENT
@@ -6827,17 +6827,17 @@ ON TABLE "system_tenant" IS '租户表';
-- Records of system_tenant
-- ----------------------------
BEGIN;
-INSERT INTO "system_tenant" ("id", "name", "contact_user_id", "contact_name", "contact_mobile", "status", "domain",
+INSERT INTO "system_tenant" ("id", "name", "contact_user_id", "contact_name", "contact_mobile", "status", "website",
"package_id", "expire_time", "account_count", "creator", "create_time", "updater",
"update_time", "deleted")
VALUES (1, '芋道源码', NULL, '芋艿', '17321315478', 0, 'https://www.iocoder.cn', 0, '2099-02-19 17:14:16', 9999, '1',
'2021-01-05 17:03:47', '1', '2022-02-23 12:15:11', 0);
-INSERT INTO "system_tenant" ("id", "name", "contact_user_id", "contact_name", "contact_mobile", "status", "domain",
+INSERT INTO "system_tenant" ("id", "name", "contact_user_id", "contact_name", "contact_mobile", "status", "website",
"package_id", "expire_time", "account_count", "creator", "create_time", "updater",
"update_time", "deleted")
VALUES (121, '小租户', 110, '小王2', '15601691300', 0, 'http://www.iocoder.cn', 111, '2024-03-11 00:00:00', 20, '1',
'2022-02-22 00:56:14', '1', '2022-03-19 18:37:20', 0);
-INSERT INTO "system_tenant" ("id", "name", "contact_user_id", "contact_name", "contact_mobile", "status", "domain",
+INSERT INTO "system_tenant" ("id", "name", "contact_user_id", "contact_name", "contact_mobile", "status", "website",
"package_id", "expire_time", "account_count", "creator", "create_time", "updater",
"update_time", "deleted")
VALUES (122, '测试租户', 113, '芋道', '15601691300', 0, 'https://www.iocoder.cn', 111, '2022-04-30 00:00:00', 50, '1',
diff --git a/sql/sqlserver/ruoyi-vue-pro.sql b/sql/sqlserver/ruoyi-vue-pro.sql
index 454d8d4bc..bfb10f6bd 100644
--- a/sql/sqlserver/ruoyi-vue-pro.sql
+++ b/sql/sqlserver/ruoyi-vue-pro.sql
@@ -10595,7 +10595,7 @@ CREATE TABLE [dbo].[system_tenant] (
[contact_name] nvarchar(30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[contact_mobile] nvarchar(500) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[status] tinyint NOT NULL,
- [domain] nvarchar(256) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
+ [website] nvarchar(256) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[package_id] bigint NOT NULL,
[expire_time] datetime2(7) NOT NULL,
[account_count] int NOT NULL,
@@ -10656,7 +10656,7 @@ EXEC sp_addextendedproperty
'MS_Description', N'绑定域名',
'SCHEMA', N'dbo',
'TABLE', N'system_tenant',
-'COLUMN', N'domain'
+'COLUMN', N'website'
GO
EXEC sp_addextendedproperty
@@ -10731,13 +10731,13 @@ GO
SET IDENTITY_INSERT [dbo].[system_tenant] ON
GO
-INSERT INTO [dbo].[system_tenant] ([id], [name], [contact_user_id], [contact_name], [contact_mobile], [status], [domain], [package_id], [expire_time], [account_count], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'1', N'芋道源码', NULL, N'芋艿', N'17321315478', N'0', N'https://www.iocoder.cn', N'0', N'2099-02-19 17:14:16.0000000', N'9999', N'1', N'2021-01-05 17:03:47.0000000', N'1', N'2022-02-23 12:15:11.0000000', N'0')
+INSERT INTO [dbo].[system_tenant] ([id], [name], [contact_user_id], [contact_name], [contact_mobile], [status], [website], [package_id], [expire_time], [account_count], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'1', N'芋道源码', NULL, N'芋艿', N'17321315478', N'0', N'https://www.iocoder.cn', N'0', N'2099-02-19 17:14:16.0000000', N'9999', N'1', N'2021-01-05 17:03:47.0000000', N'1', N'2022-02-23 12:15:11.0000000', N'0')
GO
-INSERT INTO [dbo].[system_tenant] ([id], [name], [contact_user_id], [contact_name], [contact_mobile], [status], [domain], [package_id], [expire_time], [account_count], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'121', N'小租户', N'110', N'小王2', N'15601691300', N'0', N'http://www.iocoder.cn', N'111', N'2024-03-11 00:00:00.0000000', N'20', N'1', N'2022-02-22 00:56:14.0000000', N'1', N'2022-03-19 18:37:20.0000000', N'0')
+INSERT INTO [dbo].[system_tenant] ([id], [name], [contact_user_id], [contact_name], [contact_mobile], [status], [website], [package_id], [expire_time], [account_count], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'121', N'小租户', N'110', N'小王2', N'15601691300', N'0', N'http://www.iocoder.cn', N'111', N'2024-03-11 00:00:00.0000000', N'20', N'1', N'2022-02-22 00:56:14.0000000', N'1', N'2022-03-19 18:37:20.0000000', N'0')
GO
-INSERT INTO [dbo].[system_tenant] ([id], [name], [contact_user_id], [contact_name], [contact_mobile], [status], [domain], [package_id], [expire_time], [account_count], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'122', N'测试租户', N'113', N'芋道', N'15601691300', N'0', N'https://www.iocoder.cn', N'111', N'2022-04-30 00:00:00.0000000', N'50', N'1', N'2022-03-07 21:37:58.0000000', N'1', N'2022-03-07 21:37:58.0000000', N'0')
+INSERT INTO [dbo].[system_tenant] ([id], [name], [contact_user_id], [contact_name], [contact_mobile], [status], [website], [package_id], [expire_time], [account_count], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'122', N'测试租户', N'113', N'芋道', N'15601691300', N'0', N'https://www.iocoder.cn', N'111', N'2022-04-30 00:00:00.0000000', N'50', N'1', N'2022-03-07 21:37:58.0000000', N'1', N'2022-03-07 21:37:58.0000000', N'0')
GO
SET IDENTITY_INSERT [dbo].[system_tenant] OFF
diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml
index 1b7ba6515..a82f9b08c 100644
--- a/yudao-dependencies/pom.xml
+++ b/yudao-dependencies/pom.xml
@@ -14,7 +14,7 @@
https://github.com/YunaiV/ruoyi-vue-pro
- 1.8.3-snapshot
+ 1.9.0-snapshot
1.5.0
2.7.17
@@ -78,10 +78,10 @@
4.6.4
2.2.1
3.1.853
- 1.0.5
+ 1.0.8
1.6.1
2.12.2
- 4.5.0
+ 4.5.7.B
@@ -135,11 +135,6 @@
yudao-spring-boot-starter-biz-pay
${revision}
-
- cn.iocoder.cloud
- yudao-spring-boot-starter-biz-weixin
- ${revision}
-
cn.iocoder.cloud
yudao-spring-boot-starter-biz-tenant
@@ -150,11 +145,6 @@
yudao-spring-boot-starter-biz-data-permission
${revision}
-
- cn.iocoder.cloud
- yudao-spring-boot-starter-biz-social
- ${revision}
-
cn.iocoder.cloud
yudao-spring-boot-starter-biz-error-code
@@ -203,6 +193,12 @@
${revision}
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-websocket
+ ${revision}
+
+
org.springdoc
springdoc-openapi-ui
@@ -627,11 +623,6 @@
weixin-java-pay
${weixin-java.version}
-
- com.github.binarywang
- weixin-java-mp
- ${weixin-java.version}
-
com.github.binarywang
wx-java-mp-spring-boot-starter
diff --git a/yudao-framework/pom.xml b/yudao-framework/pom.xml
index c2e7d6123..546f42723 100644
--- a/yudao-framework/pom.xml
+++ b/yudao-framework/pom.xml
@@ -34,8 +34,6 @@
yudao-spring-boot-starter-biz-sms
yudao-spring-boot-starter-biz-pay
- yudao-spring-boot-starter-biz-weixin
- yudao-spring-boot-starter-biz-social
yudao-spring-boot-starter-biz-tenant
yudao-spring-boot-starter-biz-data-permission
yudao-spring-boot-starter-biz-error-code
@@ -43,6 +41,7 @@
yudao-spring-boot-starter-flowable
yudao-spring-boot-starter-captcha
+ yudao-spring-boot-starter-websocket
yudao-spring-boot-starter-desensitize
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java
index 5738ded67..97819f993 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java
@@ -15,6 +15,13 @@ public class PageParam implements Serializable {
private static final Integer PAGE_NO = 1;
private static final Integer PAGE_SIZE = 10;
+ /**
+ * 每页条数 - 不分页
+ *
+ * 例如说,导出接口,可以设置 {@link #pageSize} 为 -1 不分页,查询所有数据。
+ */
+ public static final Integer PAGE_SIZE_NONE = -1;
+
@Schema(description = "页码,从 1 开始", requiredMode = Schema.RequiredMode.REQUIRED,example = "1")
@NotNull(message = "页码不能为空")
@Min(value = 1, message = "页码最小值为 1")
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
index 366e78e23..2d3232978 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
@@ -238,7 +238,7 @@ public class CollectionUtils {
if (CollUtil.isEmpty(from)) {
return null;
}
- assert from.size() > 0; // 断言,避免告警
+ assert !from.isEmpty(); // 断言,避免告警
T t = from.stream().max(Comparator.comparing(valueFunc)).get();
return valueFunc.apply(t);
}
@@ -280,6 +280,15 @@ public class CollectionUtils {
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
}
+ public static List convertListByFlatMap(Collection from,
+ Function super T, ? extends U> mapper,
+ Function> func) {
+ if (CollUtil.isEmpty(from)) {
+ return new ArrayList<>();
+ }
+ return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
+ }
+
public static Set convertSetByFlatMap(Collection from,
Function> func) {
if (CollUtil.isEmpty(from)) {
@@ -288,4 +297,13 @@ public class CollectionUtils {
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
}
+ public static Set convertSetByFlatMap(Collection from,
+ Function super T, ? extends U> mapper,
+ Function> func) {
+ if (CollUtil.isEmpty(from)) {
+ return new HashSet<>();
+ }
+ return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
+ }
+
}
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java
index 624a0d9a7..2c7288efa 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.common.util.json;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
@@ -30,6 +31,7 @@ public class JsonUtils {
static {
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略 null 值
objectMapper.registerModules(new JavaTimeModule()); // 解决 LocalDateTime 的序列化
}
@@ -71,6 +73,20 @@ public class JsonUtils {
}
}
+ public static T parseObject(String text, String path, Class clazz) {
+ if (StrUtil.isEmpty(text)) {
+ return null;
+ }
+ try {
+ JsonNode treeNode = objectMapper.readTree(text);
+ JsonNode pathNode = treeNode.path(path);
+ return objectMapper.readValue(pathNode.toString(), clazz);
+ } catch (IOException e) {
+ log.error("json parse err,json:{}", text, e);
+ throw new RuntimeException(e);
+ }
+ }
+
public static T parseObject(String text, Type type) {
if (StrUtil.isEmpty(text)) {
return null;
@@ -132,6 +148,20 @@ public class JsonUtils {
}
}
+ public static List parseArray(String text, String path, Class clazz) {
+ if (StrUtil.isEmpty(text)) {
+ return null;
+ }
+ try {
+ JsonNode treeNode = objectMapper.readTree(text);
+ JsonNode pathNode = treeNode.path(path);
+ return objectMapper.readValue(pathNode.toString(), objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
+ } catch (IOException e) {
+ log.error("json parse err,json:{}", text, e);
+ throw new RuntimeException(e);
+ }
+ }
+
public static JsonNode parseTree(String text) {
try {
return objectMapper.readTree(text);
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java
new file mode 100644
index 000000000..e14572a7f
--- /dev/null
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.framework.common.util.object;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * Bean 工具类
+ *
+ * 1. 默认使用 {@link cn.hutool.core.bean.BeanUtil} 作为实现类,虽然不同 bean 工具的性能有差别,但是对绝大多数同学的项目,不用在意这点性能
+ * 2. 针对复杂的对象转换,可以搜参考 AuthConvert 实现,通过 mapstruct + default 配合实现
+ *
+ * @author 芋道源码
+ */
+public class BeanUtils {
+
+ public static T toBean(Object source, Class targetClass) {
+ return BeanUtil.toBean(source, targetClass);
+ }
+
+ public static List toBean(List source, Class targetType) {
+ if (source == null) {
+ return null;
+ }
+ return CollectionUtils.convertList(source, s -> toBean(s, targetType));
+ }
+
+ public static PageResult toBean(PageResult source, Class targetType) {
+ if (source == null) {
+ return null;
+ }
+ return new PageResult<>(toBean(source.getList(), targetType), source.getTotal());
+ }
+
+}
\ No newline at end of file
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java
index cd5db713c..08cea833f 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java
@@ -50,4 +50,20 @@ public class StrUtils {
return Arrays.stream(integers).boxed().collect(Collectors.toList());
}
+ /**
+ * 移除字符串中,包含指定字符串的行
+ *
+ * @param content 字符串
+ * @param sequence 包含的字符串
+ * @return 移除后的字符串
+ */
+ public static String removeLineContains(String content, String sequence) {
+ if (StrUtil.isEmpty(content) || StrUtil.isEmpty(sequence)) {
+ return content;
+ }
+ return Arrays.stream(content.split("\n"))
+ .filter(line -> !line.contains(sequence))
+ .collect(Collectors.joining("\n"));
+ }
+
}
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/Telephone.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/Telephone.java
new file mode 100644
index 000000000..910601fd0
--- /dev/null
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/Telephone.java
@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.framework.common.validation;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.*;
+
+@Target({
+ ElementType.METHOD,
+ ElementType.FIELD,
+ ElementType.ANNOTATION_TYPE,
+ ElementType.CONSTRUCTOR,
+ ElementType.PARAMETER,
+ ElementType.TYPE_USE
+})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Constraint(
+ validatedBy = TelephoneValidator.class
+)
+public @interface Telephone {
+
+ String message() default "电话格式不正确";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+}
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/TelephoneValidator.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/TelephoneValidator.java
new file mode 100644
index 000000000..d214cfeef
--- /dev/null
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/TelephoneValidator.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.framework.common.validation;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.PhoneUtil;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+public class TelephoneValidator implements ConstraintValidator {
+
+ @Override
+ public void initialize(Telephone annotation) {
+ }
+
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext context) {
+ // 如果手机号为空,默认不校验,即校验通过
+ if (CharSequenceUtil.isEmpty(value)) {
+ return true;
+ }
+ // 校验手机
+ return PhoneUtil.isTel(value) || PhoneUtil.isPhone(value);
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java b/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java
index fd175367c..f2131e5b7 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java
@@ -49,8 +49,12 @@ public class ErrorCodeAutoGeneratorImpl implements ErrorCodeAutoGenerator {
log.info("[execute][解析到错误码数量为 ({}) 个]", autoGenerateDTOs.size());
// 第二步,写入到 system 服务
- errorCodeApi.autoGenerateErrorCodeList(autoGenerateDTOs).checkError();
- log.info("[execute][写入到 system 组件完成]");
+ try {
+ errorCodeApi.autoGenerateErrorCodeList(autoGenerateDTOs).checkError();
+ log.info("[execute][写入到 system 组件完成]");
+ } catch (Exception ex) {
+ log.error("[execute][写入到 system 组件失败({})]", ExceptionUtil.getRootCauseMessage(ex));
+ }
}
/**
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/loader/ErrorCodeLoader.java b/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/loader/ErrorCodeLoader.java
index 26fb060d2..0bf70211f 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/loader/ErrorCodeLoader.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/loader/ErrorCodeLoader.java
@@ -21,4 +21,14 @@ public interface ErrorCodeLoader {
ServiceExceptionUtil.put(code, msg);
}
+ /**
+ * 刷新错误码
+ */
+ void refreshErrorCodes();
+
+ /**
+ * 加载错误码
+ */
+ void loadErrorCodes();
+
}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/loader/ErrorCodeLoaderImpl.java b/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/loader/ErrorCodeLoaderImpl.java
index 870c74f11..64d08630d 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/loader/ErrorCodeLoaderImpl.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/loader/ErrorCodeLoaderImpl.java
@@ -1,6 +1,7 @@
package cn.iocoder.yudao.framework.errorcode.core.loader;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.exceptions.ExceptionUtil;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.module.system.api.errorcode.ErrorCodeApi;
import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeRespDTO;
@@ -8,6 +9,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import java.time.LocalDateTime;
@@ -43,31 +45,38 @@ public class ErrorCodeLoaderImpl implements ErrorCodeLoader {
*/
private LocalDateTime maxUpdateTime;
+ @Override
@EventListener(ApplicationReadyEvent.class)
+ @Async // 异步,保证项目的启动过程,毕竟非关键流程
public void loadErrorCodes() {
- this.loadErrorCodes0();
+ loadErrorCodes0();
}
+ @Override
@Scheduled(fixedDelay = REFRESH_ERROR_CODE_PERIOD, initialDelay = REFRESH_ERROR_CODE_PERIOD)
public void refreshErrorCodes() {
- this.loadErrorCodes0();
+ loadErrorCodes0();
}
private void loadErrorCodes0() {
- // 加载错误码
- List errorCodeRespDTOs = errorCodeApi.getErrorCodeList(applicationName, maxUpdateTime).getCheckedData();
- if (CollUtil.isEmpty(errorCodeRespDTOs)) {
- return;
- }
- log.info("[loadErrorCodes0][加载到 ({}) 个错误码]", errorCodeRespDTOs.size());
+ try {
+ // 加载错误码
+ List errorCodeRespDTOs = errorCodeApi.getErrorCodeList(applicationName, maxUpdateTime).getCheckedData();
+ if (CollUtil.isEmpty(errorCodeRespDTOs)) {
+ return;
+ }
+ log.info("[loadErrorCodes0][加载到 ({}) 个错误码]", errorCodeRespDTOs.size());
- // 刷新错误码的缓存
- errorCodeRespDTOs.forEach(errorCodeRespDTO -> {
- // 写入到错误码的缓存
- putErrorCode(errorCodeRespDTO.getCode(), errorCodeRespDTO.getMessage());
- // 记录下更新时间,方便增量更新
- maxUpdateTime = DateUtils.max(maxUpdateTime, errorCodeRespDTO.getUpdateTime());
- });
+ // 刷新错误码的缓存
+ errorCodeRespDTOs.forEach(errorCodeRespDTO -> {
+ // 写入到错误码的缓存
+ putErrorCode(errorCodeRespDTO.getCode(), errorCodeRespDTO.getMessage());
+ // 记录下更新时间,方便增量更新
+ maxUpdateTime = DateUtils.max(maxUpdateTime, errorCodeRespDTO.getUpdateTime());
+ });
+ } catch (Exception ex) {
+ log.error("[loadErrorCodes0][加载错误码失败({})]", ExceptionUtil.getRootCauseMessage(ex));
+ }
}
}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkServiceImpl.java b/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkServiceImpl.java
index 05353474c..e31ff2e33 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkServiceImpl.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/OperateLogFrameworkServiceImpl.java
@@ -21,7 +21,7 @@ public class OperateLogFrameworkServiceImpl implements OperateLogFrameworkServic
@Override
@Async
public void createOperateLog(OperateLog operateLog) {
- OperateLogCreateReqDTO reqDTO = BeanUtil.copyProperties(operateLog, OperateLogCreateReqDTO.class);
+ OperateLogCreateReqDTO reqDTO = BeanUtil.toBean(operateLog, OperateLogCreateReqDTO.class);
operateLogApi.createOperateLog(reqDTO);
}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java
index f4f326a65..bd361e9c0 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java
@@ -16,8 +16,8 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDT
import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
-import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result;
import com.github.binarywang.wxpay.bean.request.*;
@@ -175,8 +175,8 @@ public abstract class AbstractWxPayClient extends AbstractPayClient sendSms(Long logId, String mobile, String apiTemplateId,
- List> templateParams);
+ SmsSendRespDTO sendSms(Long logId, String mobile, String apiTemplateId,
+ List> templateParams) throws Throwable;
/**
* 解析接收短信的接收结果
@@ -49,6 +49,6 @@ public interface SmsClient {
* @param apiTemplateId 短信 API 的模板编号
* @return 短信模板
*/
- SmsCommonResult getSmsTemplate(String apiTemplateId);
+ SmsTemplateRespDTO getSmsTemplate(String apiTemplateId) throws Throwable;
}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/SmsCodeMapping.java b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/SmsCodeMapping.java
deleted file mode 100644
index 826306fde..000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/SmsCodeMapping.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package cn.iocoder.yudao.framework.sms.core.client;
-
-import cn.iocoder.yudao.framework.common.exception.ErrorCode;
-import cn.iocoder.yudao.framework.sms.core.enums.SmsFrameworkErrorCodeConstants;
-
-import java.util.function.Function;
-
-/**
- * 将 API 的错误码,转换为通用的错误码
- *
- * @see SmsCommonResult
- * @see SmsFrameworkErrorCodeConstants
- *
- * @author 芋道源码
- */
-public interface SmsCodeMapping extends Function {
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/SmsCommonResult.java b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/SmsCommonResult.java
deleted file mode 100644
index d314de2cd..000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/SmsCommonResult.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package cn.iocoder.yudao.framework.sms.core.client;
-
-import cn.hutool.core.exceptions.ExceptionUtil;
-import cn.hutool.core.lang.Assert;
-import cn.iocoder.yudao.framework.common.exception.ErrorCode;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.sms.core.enums.SmsFrameworkErrorCodeConstants;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-/**
- * 短信的 CommonResult 拓展类
- *
- * 考虑到不同的平台,返回的 code 和 msg 是不同的,所以统一额外返回 {@link #apiCode} 和 {@link #apiMsg} 字段
- *
- * 另外,一些短信平台(例如说阿里云、腾讯云)会返回一个请求编号,用于排查请求失败的问题,我们设置到 {@link #apiRequestId} 字段
- *
- * @author 芋道源码
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class SmsCommonResult extends CommonResult {
-
- /**
- * API 返回错误码
- *
- * 由于第三方的错误码可能是字符串,所以使用 String 类型
- */
- private String apiCode;
- /**
- * API 返回提示
- */
- private String apiMsg;
-
- /**
- * API 请求编号
- */
- private String apiRequestId;
-
- private SmsCommonResult() {
- }
-
- public static SmsCommonResult build(String apiCode, String apiMsg, String apiRequestId,
- T data, SmsCodeMapping codeMapping) {
- Assert.notNull(codeMapping, "参数 codeMapping 不能为空");
- SmsCommonResult result = new SmsCommonResult().setApiCode(apiCode).setApiMsg(apiMsg).setApiRequestId(apiRequestId);
- result.setData(data);
- // 翻译错误码
- if (codeMapping != null) {
- ErrorCode errorCode = codeMapping.apply(apiCode);
- if (errorCode == null) {
- errorCode = SmsFrameworkErrorCodeConstants.SMS_UNKNOWN;
- }
- result.setCode(errorCode.getCode()).setMsg(errorCode.getMsg());
- }
- return result;
- }
-
- public static SmsCommonResult error(Throwable ex) {
- SmsCommonResult result = new SmsCommonResult<>();
- result.setCode(SmsFrameworkErrorCodeConstants.EXCEPTION.getCode());
- result.setMsg(ExceptionUtil.getRootCauseMessage(ex));
- return result;
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/dto/SmsSendRespDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/dto/SmsSendRespDTO.java
index 9d320d57b..ec517508a 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/dto/SmsSendRespDTO.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/dto/SmsSendRespDTO.java
@@ -10,9 +10,34 @@ import lombok.Data;
@Data
public class SmsSendRespDTO {
+ /**
+ * 是否成功
+ */
+ private Boolean success;
+
+ /**
+ * API 请求编号
+ */
+ private String apiRequestId;
+
+ // ==================== 成功时字段 ====================
+
/**
* 短信 API 发送返回的序号
*/
private String serialNo;
+ // ==================== 失败时字段 ====================
+
+ /**
+ * API 返回错误码
+ *
+ * 由于第三方的错误码可能是字符串,所以使用 String 类型
+ */
+ private String apiCode;
+ /**
+ * API 返回提示
+ */
+ private String apiMsg;
+
}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/AbstractSmsClient.java b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/AbstractSmsClient.java
index f91083ddd..42f00f968 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/AbstractSmsClient.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/AbstractSmsClient.java
@@ -1,17 +1,9 @@
package cn.iocoder.yudao.framework.sms.core.client.impl;
-import cn.iocoder.yudao.framework.common.core.KeyValue;
import cn.iocoder.yudao.framework.sms.core.client.SmsClient;
-import cn.iocoder.yudao.framework.sms.core.client.SmsCodeMapping;
-import cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult;
-import cn.iocoder.yudao.framework.sms.core.client.dto.SmsReceiveRespDTO;
-import cn.iocoder.yudao.framework.sms.core.client.dto.SmsSendRespDTO;
-import cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateRespDTO;
import cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties;
import lombok.extern.slf4j.Slf4j;
-import java.util.List;
-
/**
* 短信客户端的抽象类,提供模板方法,减少子类的冗余代码
*
@@ -25,14 +17,9 @@ public abstract class AbstractSmsClient implements SmsClient {
* 短信渠道配置
*/
protected volatile SmsChannelProperties properties;
- /**
- * 错误码枚举类
- */
- protected final SmsCodeMapping codeMapping;
- public AbstractSmsClient(SmsChannelProperties properties, SmsCodeMapping codeMapping) {
- this.properties = prepareProperties(properties);
- this.codeMapping = codeMapping;
+ public AbstractSmsClient(SmsChannelProperties properties) {
+ this.properties = properties;
}
/**
@@ -54,74 +41,13 @@ public abstract class AbstractSmsClient implements SmsClient {
return;
}
log.info("[refresh][配置({})发生变化,重新初始化]", properties);
- this.properties = prepareProperties(properties);
// 初始化
this.init();
}
- /**
- * 在赋值给{@link this#properties}前,子类可根据需要预处理短信渠道配置
- *
- * @param properties 数据库中存储的短信渠道配置
- * @return 满足子类实现的短信渠道配置
- */
- protected SmsChannelProperties prepareProperties(SmsChannelProperties properties) {
- return properties;
- }
-
@Override
public Long getId() {
return properties.getId();
}
- @Override
- public final SmsCommonResult sendSms(Long logId, String mobile,
- String apiTemplateId, List> templateParams) {
- // 执行短信发送
- SmsCommonResult result;
- try {
- result = doSendSms(logId, mobile, apiTemplateId, templateParams);
- } catch (Throwable ex) {
- // 打印异常日志
- log.error("[sendSms][发送短信异常,sendLogId({}) mobile({}) apiTemplateId({}) templateParams({})]",
- logId, mobile, apiTemplateId, templateParams, ex);
- // 封装返回
- return SmsCommonResult.error(ex);
- }
- return result;
- }
-
- protected abstract SmsCommonResult doSendSms(Long sendLogId, String mobile,
- String apiTemplateId, List> templateParams)
- throws Throwable;
-
- @Override
- public List parseSmsReceiveStatus(String text) throws Throwable {
- try {
- return doParseSmsReceiveStatus(text);
- } catch (Throwable ex) {
- log.error("[parseSmsReceiveStatus][text({}) 解析发生异常]", text, ex);
- throw ex;
- }
- }
-
- protected abstract List doParseSmsReceiveStatus(String text) throws Throwable;
-
- @Override
- public SmsCommonResult getSmsTemplate(String apiTemplateId) {
- // 执行短信发送
- SmsCommonResult result;
- try {
- result = doGetSmsTemplate(apiTemplateId);
- } catch (Throwable ex) {
- // 打印异常日志
- log.error("[getSmsTemplate][获得短信模板({}) 发生异常]", apiTemplateId, ex);
- // 封装返回
- return SmsCommonResult.error(ex);
- }
- return result;
- }
-
- protected abstract SmsCommonResult doGetSmsTemplate(String apiTemplateId) throws Throwable;
-
}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsClient.java b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsClient.java
index 59723c4c9..d32a5bb11 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsClient.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsClient.java
@@ -1,25 +1,21 @@
package cn.iocoder.yudao.framework.sms.core.client.impl.aliyun;
import cn.hutool.core.lang.Assert;
-import cn.hutool.core.util.ReflectUtil;
-import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.core.KeyValue;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.yudao.framework.sms.core.client.dto.SmsReceiveRespDTO;
import cn.iocoder.yudao.framework.sms.core.client.dto.SmsSendRespDTO;
import cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateRespDTO;
import cn.iocoder.yudao.framework.sms.core.client.impl.AbstractSmsClient;
import cn.iocoder.yudao.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
import cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties;
-import com.aliyuncs.AcsRequest;
-import com.aliyuncs.AcsResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateRequest;
+import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
-import com.aliyuncs.exceptions.ClientException;
+import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -31,9 +27,8 @@ import lombok.extern.slf4j.Slf4j;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
-import java.util.function.Function;
-import java.util.stream.Collectors;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
@@ -46,6 +41,11 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DE
@Slf4j
public class AliyunSmsClient extends AbstractSmsClient {
+ /**
+ * 调用成功 code
+ */
+ public static final String API_CODE_SUCCESS = "OK";
+
/**
* REGION, 使用杭州
*/
@@ -57,7 +57,7 @@ public class AliyunSmsClient extends AbstractSmsClient {
private volatile IAcsClient client;
public AliyunSmsClient(SmsChannelProperties properties) {
- super(properties, new AliyunSmsCodeMapping());
+ super(properties);
Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空");
Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空");
}
@@ -69,9 +69,9 @@ public class AliyunSmsClient extends AbstractSmsClient {
}
@Override
- protected SmsCommonResult doSendSms(Long sendLogId, String mobile,
- String apiTemplateId, List> templateParams) {
- // 构建参数
+ public SmsSendRespDTO sendSms(Long sendLogId, String mobile, String apiTemplateId,
+ List