mirror of
				https://github.com/vran-dev/databasir.git
				synced 2025-10-31 12:39:20 +08:00 
			
		
		
		
	feature:support auto sync project document by cron task (#3)
* feat: auto sync project document by cron task * feat:update README
This commit is contained in:
		
							
								
								
									
										22
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								README.md
									
									
									
									
									
								
							| @@ -4,10 +4,10 @@ | ||||
|  | ||||
| 以下功能尚在开发中 | ||||
|  | ||||
| - [ ] 定时文档同步 | ||||
| - [x] 定时文档同步 | ||||
| - [ ] 表字段协同注释 | ||||
| - [ ] 操作审计日志 | ||||
| - [x] 容器化部署 | ||||
| - [ ] 容器化部署 | ||||
|  | ||||
| ## 简介 | ||||
|  | ||||
| @@ -28,20 +28,38 @@ Databasir 采用了前后端分离的模式进行开发和部署,前端和后 | ||||
|  | ||||
| ## 展示 | ||||
|  | ||||
| - 首页 | ||||
|  | ||||
|  | ||||
|  | ||||
| - 项目中心 | ||||
|  | ||||
|  | ||||
|  | ||||
| - 项目创建 | ||||
|  | ||||
|  | ||||
|  | ||||
| - 项目文档 | ||||
|  | ||||
|  | ||||
|  | ||||
| - 分组成员 | ||||
|  | ||||
|  | ||||
|  | ||||
| - 添加成员 | ||||
|  | ||||
|  | ||||
|  | ||||
| - 用户中心 | ||||
|  | ||||
|  | ||||
|  | ||||
| - 个人中心 | ||||
|  | ||||
|  | ||||
|  | ||||
| - 系统邮件 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -25,6 +25,8 @@ dependencies { | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-aop' | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-security' | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-quartz' | ||||
|  | ||||
|     implementation 'org.flywaydb:flyway-core' | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -3,8 +3,10 @@ package com.databasir; | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; | ||||
| import org.springframework.scheduling.annotation.EnableScheduling; | ||||
|  | ||||
| @SpringBootApplication(exclude = {R2dbcAutoConfiguration.class}) | ||||
| @EnableScheduling | ||||
| public class DatabasirApplication { | ||||
|  | ||||
|     public static void main(String[] args) { | ||||
|   | ||||
| @@ -0,0 +1,25 @@ | ||||
| package com.databasir.job; | ||||
|  | ||||
| import com.databasir.core.domain.document.service.DocumentService; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.quartz.Job; | ||||
| import org.quartz.JobDataMap; | ||||
| import org.quartz.JobExecutionContext; | ||||
| import org.quartz.JobExecutionException; | ||||
|  | ||||
| @RequiredArgsConstructor | ||||
| @Slf4j | ||||
| public class ProjectDocumentAutoSyncJob implements Job { | ||||
|  | ||||
|     @Override | ||||
|     public void execute(JobExecutionContext context) throws JobExecutionException { | ||||
|         JobDataMap dataMap = context.getMergedJobDataMap(); | ||||
|         log.info("start sync project document: " + dataMap.toString()); | ||||
|         DocumentService documentService = (DocumentService) dataMap.get("documentService"); | ||||
|         Integer projectId = dataMap.getInt("projectId"); | ||||
|         documentService.syncByProjectId(projectId); | ||||
|         log.info("sync project document {} over....", projectId); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,166 @@ | ||||
| package com.databasir.job; | ||||
|  | ||||
| import com.databasir.core.domain.document.service.DocumentService; | ||||
| import com.databasir.dao.impl.ProjectSyncRuleDao; | ||||
| import com.databasir.dao.tables.pojos.ProjectSyncRulePojo; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.quartz.*; | ||||
| import org.quartz.impl.matchers.GroupMatcher; | ||||
| import org.springframework.data.util.Pair; | ||||
| import org.springframework.scheduling.annotation.Scheduled; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| import java.util.Optional; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| @Component | ||||
| @RequiredArgsConstructor | ||||
| @Slf4j | ||||
| public class ProjectDocumentAutoSyncTriggerJob { | ||||
|  | ||||
|     private static final String JOB_IDENTITY_PATTERN = "JOB_PROJECT[%s]"; | ||||
|  | ||||
|     private static final String TRIGGER_IDENTITY_PATTERN = "TRIGGER_PROJECT[%s]"; | ||||
|  | ||||
|     private final Scheduler scheduler; | ||||
|  | ||||
|     private final ProjectSyncRuleDao projectSyncRuleDao; | ||||
|  | ||||
|     private final DocumentService documentService; | ||||
|  | ||||
|     /** | ||||
|      * 启动 isAutoSync=true 的任务 | ||||
|      */ | ||||
|     @Scheduled(fixedRate = 1000) | ||||
|     public void scheduleProjectSync() { | ||||
|         List<Integer> currentlyTriggerProjectIds = getProjectJobDetails() | ||||
|                 .stream() | ||||
|                 .map(job -> job.getJobDataMap().getInt("projectId")) | ||||
|                 .collect(Collectors.toList()); | ||||
|         // 查询已开启自动同步但还未运行的任务 | ||||
|         projectSyncRuleDao.selectByIsAutoSyncAndNotInProjectIds(true, currentlyTriggerProjectIds) | ||||
|                 .stream() | ||||
|                 .map(this::jobAndTriggers) | ||||
|                 .forEach(jobAndTriggers -> { | ||||
|                     try { | ||||
|                         if (!scheduler.checkExists(jobAndTriggers.getSecond().getKey())) { | ||||
|                             scheduler.scheduleJob(jobAndTriggers.getFirst(), jobAndTriggers.getSecond()); | ||||
|                             log.info("schedule jobs: {}", jobAndTriggers.getFirst()); | ||||
|                         } | ||||
|                     } catch (SchedulerException e) { | ||||
|                         log.error("failed to unScheduleProjectSync.scheduleJob ", e); | ||||
|                     } | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 停止 Rule.cron 更新过的任务 | ||||
|      */ | ||||
|     @Scheduled(fixedRate = 1000) | ||||
|     public void reScheduleProjectSync() { | ||||
|         List<TriggerKey> triggerKeys = getProjectJobDetails() | ||||
|                 .stream() | ||||
|                 .filter(jobDetail -> { | ||||
|                     JobDataMap dataMap = jobDetail.getJobDataMap(); | ||||
|                     int projectId = dataMap.getInt("projectId"); | ||||
|                     String cron = dataMap.getString("cron"); | ||||
|                     return !projectSyncRuleDao.existsByProjectIdAndCron(projectId, cron); | ||||
|                 }) | ||||
|                 .map(jobDetail -> jobDetail.getJobDataMap().getInt("projectId")) | ||||
|                 .map(this::triggerKey) | ||||
|                 .collect(Collectors.toList()); | ||||
|         try { | ||||
|             if (!triggerKeys.isEmpty()) { | ||||
|                 scheduler.unscheduleJobs(triggerKeys); | ||||
|                 log.info("rescheduled jobs: {}", triggerKeys); | ||||
|             } | ||||
|         } catch (SchedulerException e) { | ||||
|             log.error("failed to reScheduleProjectSync ", e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 停止 isAutoSync=false 的项目 | ||||
|      */ | ||||
|     @Scheduled(fixedRate = 1000) | ||||
|     public void unScheduleProjectSync() { | ||||
|         List<Integer> projectIds = getProjectJobDetails() | ||||
|                 .stream() | ||||
|                 .map(job -> job.getJobDataMap().getInt("projectId")) | ||||
|                 .collect(Collectors.toList()); | ||||
|         // 查询已关闭自动同步但还在运行的任务 | ||||
|         List<TriggerKey> triggerKeys = projectSyncRuleDao.selectByIsAutoSyncAndProjectIds(false, projectIds) | ||||
|                 .stream() | ||||
|                 .map(p -> triggerKey(p.getProjectId())) | ||||
|                 .collect(Collectors.toList()); | ||||
|         try { | ||||
|             if (!triggerKeys.isEmpty()) { | ||||
|                 scheduler.unscheduleJobs(triggerKeys); | ||||
|                 log.info("unscheduled jobs: {}", triggerKeys); | ||||
|             } | ||||
|         } catch (SchedulerException e) { | ||||
|             log.error("failed to unScheduleProjectSync ", e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private List<JobDetail> getProjectJobDetails() { | ||||
|         try { | ||||
|             return scheduler.getJobKeys(GroupMatcher.anyGroup()) | ||||
|                     .stream() | ||||
|                     .map(jobKey -> { | ||||
|                         try { | ||||
|                             JobDetail job = scheduler.getJobDetail(jobKey); | ||||
|                             if (job.getJobDataMap().containsKey("projectId")) { | ||||
|                                 return Optional.of(job); | ||||
|                             } else { | ||||
|                                 return Optional.<JobDetail>empty(); | ||||
|                             } | ||||
|                         } catch (SchedulerException e) { | ||||
|                             log.error("getJobDetail error " + jobKey, e); | ||||
|                             return Optional.<JobDetail>empty(); | ||||
|                         } | ||||
|                     }) | ||||
|                     .filter(Optional::isPresent) | ||||
|                     .map(Optional::get) | ||||
|                     .collect(Collectors.toList()); | ||||
|         } catch (SchedulerException e) { | ||||
|             log.error("get jobKeys error", e); | ||||
|             return Collections.emptyList(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private Pair<JobDetail, Trigger> jobAndTriggers(ProjectSyncRulePojo rule) { | ||||
|         JobDataMap dataMap = new JobDataMap(); | ||||
|         Integer projectId = rule.getProjectId(); | ||||
|         Integer ruleId = rule.getId(); | ||||
|         dataMap.put("projectId", projectId); | ||||
|         dataMap.put("ruleId", ruleId); | ||||
|         dataMap.put("cron", rule.getAutoSyncCron()); | ||||
|         dataMap.put("documentService", documentService); | ||||
|         JobDetail job = JobBuilder.newJob() | ||||
|                 .ofType(ProjectDocumentAutoSyncJob.class) | ||||
|                 .withIdentity(jobKey(projectId)) | ||||
|                 .withDescription("auto sync project document") | ||||
|                 .usingJobData(dataMap) | ||||
|                 .build(); | ||||
|         CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(rule.getAutoSyncCron()); | ||||
|         Trigger trigger = TriggerBuilder.newTrigger() | ||||
|                 .withIdentity(triggerKey(projectId)) | ||||
|                 .forJob(job) | ||||
|                 .withSchedule(scheduleBuilder) | ||||
|                 .startNow() | ||||
|                 .build(); | ||||
|         return Pair.of(job, trigger); | ||||
|     } | ||||
|  | ||||
|     private TriggerKey triggerKey(Integer projectId) { | ||||
|         return TriggerKey.triggerKey(String.format(TRIGGER_IDENTITY_PATTERN, projectId)); | ||||
|     } | ||||
|  | ||||
|     private JobKey jobKey(Integer projectId) { | ||||
|         return JobKey.jobKey(String.format(JOB_IDENTITY_PATTERN, projectId)); | ||||
|     } | ||||
| } | ||||
| @@ -176,7 +176,7 @@ public class DocumentService { | ||||
|  | ||||
|     public Page<DatabaseDocumentVersionResponse> getVersionsBySchemaSourceId(Integer projectId, Pageable page) { | ||||
|         return databaseDocumentDao.selectOptionalByProjectId(projectId) | ||||
|                 .map(schemaMeta -> databaseDocumentHistoryDao.selectPageByDatabaseDocumentId(page, schemaMeta.getId()) | ||||
|                 .map(schemaMeta -> databaseDocumentHistoryDao.selectVersionPageByDatabaseDocumentId(page, schemaMeta.getId()) | ||||
|                         .map(history -> DatabaseDocumentVersionResponse.builder() | ||||
|                                 .version(history.getVersion()) | ||||
|                                 .createAt(history.getCreateAt()) | ||||
|   | ||||
| @@ -31,5 +31,7 @@ public interface ProjectResponseConverter { | ||||
|  | ||||
|     @Mapping(target = "id", source = "project.id") | ||||
|     @Mapping(target = "createAt", source = "project.createAt") | ||||
|     ProjectSimpleResponse toSimple(ProjectPojo project, DataSourcePojo dataSource); | ||||
|     ProjectSimpleResponse toSimple(ProjectPojo project, | ||||
|                                    DataSourcePojo dataSource, | ||||
|                                    ProjectSyncRulePojo syncRule); | ||||
| } | ||||
|   | ||||
| @@ -54,6 +54,10 @@ public class ProjectCreateRequest { | ||||
|  | ||||
|         private List<String> ignoreColumnNameRegexes = new ArrayList<>(); | ||||
|  | ||||
|         private Boolean isAutoSync = false; | ||||
|  | ||||
|         private String autoSyncCron; | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -15,6 +15,8 @@ public class ProjectDetailResponse { | ||||
|  | ||||
|     private String description; | ||||
|  | ||||
|     private Integer groupId; | ||||
|  | ||||
|     private DataSourceResponse dataSource; | ||||
|  | ||||
|     private ProjectSyncRuleResponse projectSyncRule; | ||||
| @@ -51,6 +53,10 @@ public class ProjectDetailResponse { | ||||
|  | ||||
|         private List<String> ignoreColumnNameRegexes = new ArrayList<>(); | ||||
|  | ||||
|         private Boolean isAutoSync; | ||||
|  | ||||
|         private String autoSyncCron; | ||||
|  | ||||
|         private LocalDateTime createAt; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -17,6 +17,10 @@ public class ProjectSimpleResponse { | ||||
|  | ||||
|     private String databaseType; | ||||
|  | ||||
|     private Boolean isAutoSync; | ||||
|  | ||||
|     private String autoSyncCron; | ||||
|  | ||||
|     private LocalDateTime createAt; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -52,5 +52,10 @@ public class ProjectUpdateRequest { | ||||
|  | ||||
|         private List<String> ignoreColumnNameRegexes = new ArrayList<>(); | ||||
|  | ||||
|         @NotNull | ||||
|         private Boolean isAutoSync; | ||||
|  | ||||
|         private String autoSyncCron; | ||||
|  | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -73,7 +73,6 @@ public class ProjectService { | ||||
|         List<DataSourcePropertyPojo> properties = dataSourcePojoConverter.of(propertyValues, dataSourceId); | ||||
|         dataSourcePropertyDao.batchInsert(properties); | ||||
|  | ||||
|         // TODO redesign it | ||||
|         ProjectSyncRulePojo syncRule = projectPojoConverter.of(request.getProjectSyncRule(), projectId); | ||||
|         projectSyncRuleDao.insertAndReturnId(syncRule); | ||||
|     } | ||||
| @@ -98,9 +97,10 @@ public class ProjectService { | ||||
|                 dataSourcePropertyDao.batchInsert(properties); | ||||
|             } | ||||
|  | ||||
|             // update project sync rule TODO redesign it | ||||
|             // update project sync rule | ||||
|             ProjectSyncRulePojo syncRule = projectPojoConverter.of(request.getProjectSyncRule(), projectId); | ||||
|             projectSyncRuleDao.updateByProjectId(syncRule); | ||||
|             projectSyncRuleDao.deleteByProjectId(projectId); | ||||
|             projectSyncRuleDao.insertAndReturnId(syncRule); | ||||
|  | ||||
|             // update project info | ||||
|             ProjectPojo project = projectPojoConverter.of(request); | ||||
| @@ -132,9 +132,13 @@ public class ProjectService { | ||||
|         Map<Integer, DataSourcePojo> dataSourceMapByProjectId = dataSourceDao.selectInProjectIds(projectIds) | ||||
|                 .stream() | ||||
|                 .collect(Collectors.toMap(DataSourcePojo::getProjectId, Function.identity())); | ||||
|         Map<Integer, ProjectSyncRulePojo> syncRuleMapByProjectId = projectSyncRuleDao.selectInProjectIds(projectIds) | ||||
|                 .stream() | ||||
|                 .collect(Collectors.toMap(ProjectSyncRulePojo::getProjectId, Function.identity())); | ||||
|         return pageData.map(project -> { | ||||
|             DataSourcePojo dataSource = dataSourceMapByProjectId.get(project.getId()); | ||||
|             return projectResponseConverter.toSimple(project, dataSource); | ||||
|             ProjectSyncRulePojo syncRule = syncRuleMapByProjectId.get(project.getId()); | ||||
|             return projectResponseConverter.toSimple(project, dataSource, syncRule); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -72,12 +72,12 @@ public class Login extends TableImpl<LoginRecord> { | ||||
|     /** | ||||
|      * The column <code>databasir.login.access_token_expire_at</code>. | ||||
|      */ | ||||
|     public final TableField<LoginRecord, LocalDateTime> ACCESS_TOKEN_EXPIRE_AT = createField(DSL.name("access_token_expire_at"), SQLDataType.LOCALDATETIME(0).nullable(false), this, ""); | ||||
|     public final TableField<LoginRecord, LocalDateTime> ACCESS_TOKEN_EXPIRE_AT = createField(DSL.name("access_token_expire_at"), SQLDataType.LOCALDATETIME(0).nullable(false).defaultValue(DSL.field("CURRENT_TIMESTAMP", SQLDataType.LOCALDATETIME)), this, ""); | ||||
|  | ||||
|     /** | ||||
|      * The column <code>databasir.login.refresh_token_expire_at</code>. | ||||
|      */ | ||||
|     public final TableField<LoginRecord, LocalDateTime> REFRESH_TOKEN_EXPIRE_AT = createField(DSL.name("refresh_token_expire_at"), SQLDataType.LOCALDATETIME(0).nullable(false), this, ""); | ||||
|     public final TableField<LoginRecord, LocalDateTime> REFRESH_TOKEN_EXPIRE_AT = createField(DSL.name("refresh_token_expire_at"), SQLDataType.LOCALDATETIME(0).nullable(false).defaultValue(DSL.field("CURRENT_TIMESTAMP", SQLDataType.LOCALDATETIME)), this, ""); | ||||
|  | ||||
|     /** | ||||
|      * The column <code>databasir.login.update_at</code>. | ||||
|   | ||||
| @@ -18,7 +18,7 @@ import org.jooq.Identity; | ||||
| import org.jooq.JSON; | ||||
| import org.jooq.Name; | ||||
| import org.jooq.Record; | ||||
| import org.jooq.Row6; | ||||
| import org.jooq.Row8; | ||||
| import org.jooq.Schema; | ||||
| import org.jooq.Table; | ||||
| import org.jooq.TableField; | ||||
| @@ -72,6 +72,16 @@ public class ProjectSyncRule extends TableImpl<ProjectSyncRuleRecord> { | ||||
|      */ | ||||
|     public final TableField<ProjectSyncRuleRecord, JSON> IGNORE_COLUMN_NAME_REGEX_ARRAY = createField(DSL.name("ignore_column_name_regex_array"), SQLDataType.JSON.nullable(false), this, ""); | ||||
|  | ||||
|     /** | ||||
|      * The column <code>databasir.project_sync_rule.is_auto_sync</code>. | ||||
|      */ | ||||
|     public final TableField<ProjectSyncRuleRecord, Boolean> IS_AUTO_SYNC = createField(DSL.name("is_auto_sync"), SQLDataType.BOOLEAN.nullable(false).defaultValue(DSL.inline("0", SQLDataType.BOOLEAN)), this, ""); | ||||
|  | ||||
|     /** | ||||
|      * The column <code>databasir.project_sync_rule.auto_sync_cron</code>. | ||||
|      */ | ||||
|     public final TableField<ProjectSyncRuleRecord, String> AUTO_SYNC_CRON = createField(DSL.name("auto_sync_cron"), SQLDataType.VARCHAR(128).nullable(false).defaultValue(DSL.inline("", SQLDataType.VARCHAR)), this, ""); | ||||
|  | ||||
|     /** | ||||
|      * The column <code>databasir.project_sync_rule.update_at</code>. | ||||
|      */ | ||||
| @@ -164,11 +174,11 @@ public class ProjectSyncRule extends TableImpl<ProjectSyncRuleRecord> { | ||||
|     } | ||||
|  | ||||
|     // ------------------------------------------------------------------------- | ||||
|     // Row6 type methods | ||||
|     // Row8 type methods | ||||
|     // ------------------------------------------------------------------------- | ||||
|  | ||||
|     @Override | ||||
|     public Row6<Integer, Integer, JSON, JSON, LocalDateTime, LocalDateTime> fieldsRow() { | ||||
|         return (Row6) super.fieldsRow(); | ||||
|     public Row8<Integer, Integer, JSON, JSON, Boolean, String, LocalDateTime, LocalDateTime> fieldsRow() { | ||||
|         return (Row8) super.fieldsRow(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -22,6 +22,8 @@ public class ProjectSyncRulePojo implements Serializable { | ||||
|     private Integer       projectId; | ||||
|     private JSON          ignoreTableNameRegexArray; | ||||
|     private JSON          ignoreColumnNameRegexArray; | ||||
|     private Boolean       isAutoSync; | ||||
|     private String        autoSyncCron; | ||||
|     private LocalDateTime updateAt; | ||||
|     private LocalDateTime createAt; | ||||
|  | ||||
| @@ -32,6 +34,8 @@ public class ProjectSyncRulePojo implements Serializable { | ||||
|         this.projectId = value.projectId; | ||||
|         this.ignoreTableNameRegexArray = value.ignoreTableNameRegexArray; | ||||
|         this.ignoreColumnNameRegexArray = value.ignoreColumnNameRegexArray; | ||||
|         this.isAutoSync = value.isAutoSync; | ||||
|         this.autoSyncCron = value.autoSyncCron; | ||||
|         this.updateAt = value.updateAt; | ||||
|         this.createAt = value.createAt; | ||||
|     } | ||||
| @@ -41,6 +45,8 @@ public class ProjectSyncRulePojo implements Serializable { | ||||
|         Integer       projectId, | ||||
|         JSON          ignoreTableNameRegexArray, | ||||
|         JSON          ignoreColumnNameRegexArray, | ||||
|         Boolean       isAutoSync, | ||||
|         String        autoSyncCron, | ||||
|         LocalDateTime updateAt, | ||||
|         LocalDateTime createAt | ||||
|     ) { | ||||
| @@ -48,6 +54,8 @@ public class ProjectSyncRulePojo implements Serializable { | ||||
|         this.projectId = projectId; | ||||
|         this.ignoreTableNameRegexArray = ignoreTableNameRegexArray; | ||||
|         this.ignoreColumnNameRegexArray = ignoreColumnNameRegexArray; | ||||
|         this.isAutoSync = isAutoSync; | ||||
|         this.autoSyncCron = autoSyncCron; | ||||
|         this.updateAt = updateAt; | ||||
|         this.createAt = createAt; | ||||
|     } | ||||
| @@ -112,6 +120,34 @@ public class ProjectSyncRulePojo implements Serializable { | ||||
|         this.ignoreColumnNameRegexArray = ignoreColumnNameRegexArray; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Getter for <code>databasir.project_sync_rule.is_auto_sync</code>. | ||||
|      */ | ||||
|     public Boolean getIsAutoSync() { | ||||
|         return this.isAutoSync; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Setter for <code>databasir.project_sync_rule.is_auto_sync</code>. | ||||
|      */ | ||||
|     public void setIsAutoSync(Boolean isAutoSync) { | ||||
|         this.isAutoSync = isAutoSync; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Getter for <code>databasir.project_sync_rule.auto_sync_cron</code>. | ||||
|      */ | ||||
|     public String getAutoSyncCron() { | ||||
|         return this.autoSyncCron; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Setter for <code>databasir.project_sync_rule.auto_sync_cron</code>. | ||||
|      */ | ||||
|     public void setAutoSyncCron(String autoSyncCron) { | ||||
|         this.autoSyncCron = autoSyncCron; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Getter for <code>databasir.project_sync_rule.update_at</code>. | ||||
|      */ | ||||
| @@ -148,6 +184,8 @@ public class ProjectSyncRulePojo implements Serializable { | ||||
|         sb.append(", ").append(projectId); | ||||
|         sb.append(", ").append(ignoreTableNameRegexArray); | ||||
|         sb.append(", ").append(ignoreColumnNameRegexArray); | ||||
|         sb.append(", ").append(isAutoSync); | ||||
|         sb.append(", ").append(autoSyncCron); | ||||
|         sb.append(", ").append(updateAt); | ||||
|         sb.append(", ").append(createAt); | ||||
|  | ||||
|   | ||||
| @@ -12,8 +12,8 @@ import java.time.LocalDateTime; | ||||
| import org.jooq.Field; | ||||
| import org.jooq.JSON; | ||||
| import org.jooq.Record1; | ||||
| import org.jooq.Record6; | ||||
| import org.jooq.Row6; | ||||
| import org.jooq.Record8; | ||||
| import org.jooq.Row8; | ||||
| import org.jooq.impl.UpdatableRecordImpl; | ||||
|  | ||||
|  | ||||
| @@ -21,7 +21,7 @@ import org.jooq.impl.UpdatableRecordImpl; | ||||
|  * This class is generated by jOOQ. | ||||
|  */ | ||||
| @SuppressWarnings({ "all", "unchecked", "rawtypes" }) | ||||
| public class ProjectSyncRuleRecord extends UpdatableRecordImpl<ProjectSyncRuleRecord> implements Record6<Integer, Integer, JSON, JSON, LocalDateTime, LocalDateTime> { | ||||
| public class ProjectSyncRuleRecord extends UpdatableRecordImpl<ProjectSyncRuleRecord> implements Record8<Integer, Integer, JSON, JSON, Boolean, String, LocalDateTime, LocalDateTime> { | ||||
|  | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
| @@ -85,32 +85,60 @@ public class ProjectSyncRuleRecord extends UpdatableRecordImpl<ProjectSyncRuleRe | ||||
|         return (JSON) get(3); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Setter for <code>databasir.project_sync_rule.is_auto_sync</code>. | ||||
|      */ | ||||
|     public void setIsAutoSync(Boolean value) { | ||||
|         set(4, value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Getter for <code>databasir.project_sync_rule.is_auto_sync</code>. | ||||
|      */ | ||||
|     public Boolean getIsAutoSync() { | ||||
|         return (Boolean) get(4); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Setter for <code>databasir.project_sync_rule.auto_sync_cron</code>. | ||||
|      */ | ||||
|     public void setAutoSyncCron(String value) { | ||||
|         set(5, value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Getter for <code>databasir.project_sync_rule.auto_sync_cron</code>. | ||||
|      */ | ||||
|     public String getAutoSyncCron() { | ||||
|         return (String) get(5); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Setter for <code>databasir.project_sync_rule.update_at</code>. | ||||
|      */ | ||||
|     public void setUpdateAt(LocalDateTime value) { | ||||
|         set(4, value); | ||||
|         set(6, value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Getter for <code>databasir.project_sync_rule.update_at</code>. | ||||
|      */ | ||||
|     public LocalDateTime getUpdateAt() { | ||||
|         return (LocalDateTime) get(4); | ||||
|         return (LocalDateTime) get(6); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Setter for <code>databasir.project_sync_rule.create_at</code>. | ||||
|      */ | ||||
|     public void setCreateAt(LocalDateTime value) { | ||||
|         set(5, value); | ||||
|         set(7, value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Getter for <code>databasir.project_sync_rule.create_at</code>. | ||||
|      */ | ||||
|     public LocalDateTime getCreateAt() { | ||||
|         return (LocalDateTime) get(5); | ||||
|         return (LocalDateTime) get(7); | ||||
|     } | ||||
|  | ||||
|     // ------------------------------------------------------------------------- | ||||
| @@ -123,17 +151,17 @@ public class ProjectSyncRuleRecord extends UpdatableRecordImpl<ProjectSyncRuleRe | ||||
|     } | ||||
|  | ||||
|     // ------------------------------------------------------------------------- | ||||
|     // Record6 type implementation | ||||
|     // Record8 type implementation | ||||
|     // ------------------------------------------------------------------------- | ||||
|  | ||||
|     @Override | ||||
|     public Row6<Integer, Integer, JSON, JSON, LocalDateTime, LocalDateTime> fieldsRow() { | ||||
|         return (Row6) super.fieldsRow(); | ||||
|     public Row8<Integer, Integer, JSON, JSON, Boolean, String, LocalDateTime, LocalDateTime> fieldsRow() { | ||||
|         return (Row8) super.fieldsRow(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Row6<Integer, Integer, JSON, JSON, LocalDateTime, LocalDateTime> valuesRow() { | ||||
|         return (Row6) super.valuesRow(); | ||||
|     public Row8<Integer, Integer, JSON, JSON, Boolean, String, LocalDateTime, LocalDateTime> valuesRow() { | ||||
|         return (Row8) super.valuesRow(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -157,12 +185,22 @@ public class ProjectSyncRuleRecord extends UpdatableRecordImpl<ProjectSyncRuleRe | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Field<LocalDateTime> field5() { | ||||
|     public Field<Boolean> field5() { | ||||
|         return ProjectSyncRule.PROJECT_SYNC_RULE.IS_AUTO_SYNC; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Field<String> field6() { | ||||
|         return ProjectSyncRule.PROJECT_SYNC_RULE.AUTO_SYNC_CRON; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Field<LocalDateTime> field7() { | ||||
|         return ProjectSyncRule.PROJECT_SYNC_RULE.UPDATE_AT; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Field<LocalDateTime> field6() { | ||||
|     public Field<LocalDateTime> field8() { | ||||
|         return ProjectSyncRule.PROJECT_SYNC_RULE.CREATE_AT; | ||||
|     } | ||||
|  | ||||
| @@ -187,12 +225,22 @@ public class ProjectSyncRuleRecord extends UpdatableRecordImpl<ProjectSyncRuleRe | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public LocalDateTime component5() { | ||||
|     public Boolean component5() { | ||||
|         return getIsAutoSync(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String component6() { | ||||
|         return getAutoSyncCron(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public LocalDateTime component7() { | ||||
|         return getUpdateAt(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public LocalDateTime component6() { | ||||
|     public LocalDateTime component8() { | ||||
|         return getCreateAt(); | ||||
|     } | ||||
|  | ||||
| @@ -217,12 +265,22 @@ public class ProjectSyncRuleRecord extends UpdatableRecordImpl<ProjectSyncRuleRe | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public LocalDateTime value5() { | ||||
|     public Boolean value5() { | ||||
|         return getIsAutoSync(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String value6() { | ||||
|         return getAutoSyncCron(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public LocalDateTime value7() { | ||||
|         return getUpdateAt(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public LocalDateTime value6() { | ||||
|     public LocalDateTime value8() { | ||||
|         return getCreateAt(); | ||||
|     } | ||||
|  | ||||
| @@ -251,25 +309,39 @@ public class ProjectSyncRuleRecord extends UpdatableRecordImpl<ProjectSyncRuleRe | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public ProjectSyncRuleRecord value5(LocalDateTime value) { | ||||
|     public ProjectSyncRuleRecord value5(Boolean value) { | ||||
|         setIsAutoSync(value); | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public ProjectSyncRuleRecord value6(String value) { | ||||
|         setAutoSyncCron(value); | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public ProjectSyncRuleRecord value7(LocalDateTime value) { | ||||
|         setUpdateAt(value); | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public ProjectSyncRuleRecord value6(LocalDateTime value) { | ||||
|     public ProjectSyncRuleRecord value8(LocalDateTime value) { | ||||
|         setCreateAt(value); | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public ProjectSyncRuleRecord values(Integer value1, Integer value2, JSON value3, JSON value4, LocalDateTime value5, LocalDateTime value6) { | ||||
|     public ProjectSyncRuleRecord values(Integer value1, Integer value2, JSON value3, JSON value4, Boolean value5, String value6, LocalDateTime value7, LocalDateTime value8) { | ||||
|         value1(value1); | ||||
|         value2(value2); | ||||
|         value3(value3); | ||||
|         value4(value4); | ||||
|         value5(value5); | ||||
|         value6(value6); | ||||
|         value7(value7); | ||||
|         value8(value8); | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
| @@ -287,13 +359,15 @@ public class ProjectSyncRuleRecord extends UpdatableRecordImpl<ProjectSyncRuleRe | ||||
|     /** | ||||
|      * Create a detached, initialised ProjectSyncRuleRecord | ||||
|      */ | ||||
|     public ProjectSyncRuleRecord(Integer id, Integer projectId, JSON ignoreTableNameRegexArray, JSON ignoreColumnNameRegexArray, LocalDateTime updateAt, LocalDateTime createAt) { | ||||
|     public ProjectSyncRuleRecord(Integer id, Integer projectId, JSON ignoreTableNameRegexArray, JSON ignoreColumnNameRegexArray, Boolean isAutoSync, String autoSyncCron, LocalDateTime updateAt, LocalDateTime createAt) { | ||||
|         super(ProjectSyncRule.PROJECT_SYNC_RULE); | ||||
|  | ||||
|         setId(id); | ||||
|         setProjectId(projectId); | ||||
|         setIgnoreTableNameRegexArray(ignoreTableNameRegexArray); | ||||
|         setIgnoreColumnNameRegexArray(ignoreColumnNameRegexArray); | ||||
|         setIsAutoSync(isAutoSync); | ||||
|         setAutoSyncCron(autoSyncCron); | ||||
|         setUpdateAt(updateAt); | ||||
|         setCreateAt(createAt); | ||||
|     } | ||||
| @@ -309,6 +383,8 @@ public class ProjectSyncRuleRecord extends UpdatableRecordImpl<ProjectSyncRuleRe | ||||
|             setProjectId(value.getProjectId()); | ||||
|             setIgnoreTableNameRegexArray(value.getIgnoreTableNameRegexArray()); | ||||
|             setIgnoreColumnNameRegexArray(value.getIgnoreColumnNameRegexArray()); | ||||
|             setIsAutoSync(value.getIsAutoSync()); | ||||
|             setAutoSyncCron(value.getAutoSyncCron()); | ||||
|             setUpdateAt(value.getUpdateAt()); | ||||
|             setCreateAt(value.getCreateAt()); | ||||
|         } | ||||
|   | ||||
| @@ -2,13 +2,17 @@ package com.databasir.dao.impl; | ||||
|  | ||||
| import com.databasir.dao.tables.pojos.DatabaseDocumentHistoryPojo; | ||||
| import com.databasir.dao.tables.records.DatabaseDocumentHistoryRecord; | ||||
| import com.databasir.dao.value.DatabaseDocumentVersionPojo; | ||||
| import lombok.Getter; | ||||
| import org.jooq.Condition; | ||||
| import org.jooq.DSLContext; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.data.domain.Page; | ||||
| import org.springframework.data.domain.PageImpl; | ||||
| import org.springframework.data.domain.Pageable; | ||||
| import org.springframework.stereotype.Repository; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Optional; | ||||
|  | ||||
| import static com.databasir.dao.Tables.DATABASE_DOCUMENT_HISTORY; | ||||
| @@ -31,8 +35,24 @@ public class DatabaseDocumentHistoryDao extends BaseDao<DatabaseDocumentHistoryR | ||||
|                 .fetchOptionalInto(DatabaseDocumentHistoryPojo.class); | ||||
|     } | ||||
|  | ||||
|     public Page<DatabaseDocumentHistoryPojo> selectPageByDatabaseDocumentId(Pageable request, Integer schemaDocumentId) { | ||||
|         return super.selectByPage(request, DATABASE_DOCUMENT_HISTORY.DATABASE_DOCUMENT_ID.eq(schemaDocumentId)); | ||||
|     public Page<DatabaseDocumentVersionPojo> selectVersionPageByDatabaseDocumentId(Pageable request, Integer schemaDocumentId) { | ||||
|         Condition condition = DATABASE_DOCUMENT_HISTORY.DATABASE_DOCUMENT_ID.eq(schemaDocumentId); | ||||
|         Integer count = getDslContext() | ||||
|                 .selectCount().from(DATABASE_DOCUMENT_HISTORY).where(condition) | ||||
|                 .fetchOne(0, int.class); | ||||
|         int total = count == null ? 0 : count; | ||||
|         List<DatabaseDocumentVersionPojo> data = getDslContext() | ||||
|                 .select( | ||||
|                         DATABASE_DOCUMENT_HISTORY.VERSION, | ||||
|                         DATABASE_DOCUMENT_HISTORY.DATABASE_DOCUMENT_ID, | ||||
|                         DATABASE_DOCUMENT_HISTORY.CREATE_AT | ||||
|                 ) | ||||
|                 .from(DATABASE_DOCUMENT_HISTORY) | ||||
|                 .where(condition) | ||||
|                 .orderBy(getSortFields(request.getSort())) | ||||
|                 .offset(request.getOffset()) | ||||
|                 .limit(request.getPageSize()) | ||||
|                 .fetchInto(DatabaseDocumentVersionPojo.class); | ||||
|         return new PageImpl<>(data, request, total); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -9,6 +9,8 @@ import org.jooq.DSLContext; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Repository; | ||||
|  | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| import java.util.Optional; | ||||
|  | ||||
| import static com.databasir.dao.Tables.PROJECT_SYNC_RULE; | ||||
| @@ -46,4 +48,51 @@ public class ProjectSyncRuleDao extends BaseDao<ProjectSyncRuleRecord, ProjectSy | ||||
|                 .update(table).set(record).where(table.PROJECT_ID.eq(rule.getProjectId())) | ||||
|                 .execute(); | ||||
|     } | ||||
|  | ||||
|     public void deleteByProjectId(Integer projectId) { | ||||
|         getDslContext() | ||||
|                 .deleteFrom(PROJECT_SYNC_RULE).where(PROJECT_SYNC_RULE.PROJECT_ID.eq(projectId)) | ||||
|                 .execute(); | ||||
|     } | ||||
|  | ||||
|     public List<ProjectSyncRulePojo> selectInProjectIds(List<Integer> projectIds) { | ||||
|         if (projectIds == null || projectIds.isEmpty()) { | ||||
|             return Collections.emptyList(); | ||||
|         } | ||||
|         return getDslContext() | ||||
|                 .selectFrom(PROJECT_SYNC_RULE).where(PROJECT_SYNC_RULE.PROJECT_ID.in(projectIds)) | ||||
|                 .fetchInto(ProjectSyncRulePojo.class); | ||||
|     } | ||||
|  | ||||
|     public List<ProjectSyncRulePojo> selectByIsAutoSyncAndProjectIds(boolean isAutoSync, List<Integer> projectIds) { | ||||
|         if (projectIds == null || projectIds.isEmpty()) { | ||||
|             return Collections.emptyList(); | ||||
|         } | ||||
|         return getDslContext() | ||||
|                 .selectFrom(PROJECT_SYNC_RULE).where( | ||||
|                         PROJECT_SYNC_RULE.IS_AUTO_SYNC.eq(isAutoSync) | ||||
|                                 .and(PROJECT_SYNC_RULE.PROJECT_ID.in(projectIds)) | ||||
|                 ) | ||||
|                 .fetchInto(ProjectSyncRulePojo.class); | ||||
|     } | ||||
|  | ||||
|     public List<ProjectSyncRulePojo> selectByIsAutoSyncAndNotInProjectIds(boolean isAutoSync, List<Integer> projectIds) { | ||||
|         if (projectIds == null || projectIds.isEmpty()) { | ||||
|             return getDslContext() | ||||
|                     .selectFrom(PROJECT_SYNC_RULE) | ||||
|                     .where(PROJECT_SYNC_RULE.IS_AUTO_SYNC.eq(isAutoSync) | ||||
|                             .and(PROJECT_SYNC_RULE.PROJECT_ID.notIn(projectIds))) | ||||
|                     .fetchInto(ProjectSyncRulePojo.class); | ||||
|         } else { | ||||
|             return getDslContext() | ||||
|                     .selectFrom(PROJECT_SYNC_RULE).where(PROJECT_SYNC_RULE.IS_AUTO_SYNC.eq(isAutoSync)) | ||||
|                     .fetchInto(ProjectSyncRulePojo.class); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public boolean existsByProjectIdAndCron(int projectId, String cron) { | ||||
|         return dslContext.fetchExists(PROJECT_SYNC_RULE, | ||||
|                 PROJECT_SYNC_RULE.PROJECT_ID.eq(projectId) | ||||
|                         .and(PROJECT_SYNC_RULE.AUTO_SYNC_CRON.eq(cron))); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,15 @@ | ||||
| package com.databasir.dao.value; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| @Data | ||||
| public class DatabaseDocumentVersionPojo { | ||||
|  | ||||
|     private Integer databaseDocumentId; | ||||
|  | ||||
|     private Long version; | ||||
|  | ||||
|     private LocalDateTime createAt; | ||||
| } | ||||
| @@ -78,11 +78,13 @@ CREATE TABLE `project` | ||||
| CREATE TABLE `project_sync_rule` | ||||
| ( | ||||
|     id                             INT PRIMARY KEY AUTO_INCREMENT, | ||||
|     project_id                     INT       NOT NULL, | ||||
|     ignore_table_name_regex_array  JSON      NOT NULL, | ||||
|     ignore_column_name_regex_array JSON      NOT NULL, | ||||
|     update_at                      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | ||||
|     create_at                      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||
|     project_id                     INT          NOT NULL, | ||||
|     ignore_table_name_regex_array  JSON         NOT NULL, | ||||
|     ignore_column_name_regex_array JSON         NOT NULL, | ||||
|     is_auto_sync                   BOOLEAN      NOT NULL DEFAULT FALSE, | ||||
|     auto_sync_cron                 VARCHAR(128) NOT NULL DEFAULT '', | ||||
|     update_at                      TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | ||||
|     create_at                      TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||
|     CONSTRAINT UNIQUE uk_project_id (project_id) | ||||
| ) CHARSET utf8mb4 | ||||
|   COLLATE utf8mb4_unicode_ci; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user