diff --git a/magic-boot-ui/src/views/quartz/index.vue b/magic-boot-ui/src/views/quartz/index.vue
new file mode 100644
index 0000000..a6cbff7
--- /dev/null
+++ b/magic-boot-ui/src/views/quartz/index.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+ 查看
+ 编辑
+
+
+
+
+
+
+
+
diff --git a/magic-boot/pom.xml b/magic-boot/pom.xml
index 5f1ded3..467f269 100644
--- a/magic-boot/pom.xml
+++ b/magic-boot/pom.xml
@@ -56,6 +56,15 @@
org.springframework.boot
spring-boot-starter-quartz
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+ org.projectlombok
+ lombok
+ true
+
diff --git a/magic-boot/src/main/java/org/ssssssss/magicboot/form/AddJobForm.java b/magic-boot/src/main/java/org/ssssssss/magicboot/form/AddJobForm.java
new file mode 100644
index 0000000..263d5f6
--- /dev/null
+++ b/magic-boot/src/main/java/org/ssssssss/magicboot/form/AddJobForm.java
@@ -0,0 +1,54 @@
+package org.ssssssss.magicboot.form;
+
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+/**
+ * 新增定时任务
+ */
+@Getter
+@Setter
+public class AddJobForm {
+
+ /**
+ * 任务名称
+ */
+ private String jName;
+ /**
+ * 任务组
+ */
+ private String jGroup;
+ /**
+ * 触发器名称
+ */
+ private String tName;
+ /**
+ * 触发器组
+ */
+ private String tGroup;
+ /**
+ * cron表达式
+ */
+ private String cron;
+ /**
+ * 执行MagicAPI中的接口,原始内容,不包含code以及message信息
+ * Params:
+ * method – 请求方法
+ */
+ private String method;
+ /**
+ * 执行MagicAPI中的接口,原始内容,不包含code以及message信息
+ * Params:
+ * path – 请求路径
+ */
+ private String path;
+ /**
+ * 执行MagicAPI中的接口,原始内容,不包含code以及message信息
+ * Params:
+ * context – 变量信息
+ */
+ private Map context;
+}
diff --git a/magic-boot/src/main/java/org/ssssssss/magicboot/quartz/MagicApiJob.java b/magic-boot/src/main/java/org/ssssssss/magicboot/quartz/MagicApiJob.java
new file mode 100644
index 0000000..504a4da
--- /dev/null
+++ b/magic-boot/src/main/java/org/ssssssss/magicboot/quartz/MagicApiJob.java
@@ -0,0 +1,62 @@
+package org.ssssssss.magicboot.quartz;
+
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.JobDataMap;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.quartz.SchedulerException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+import org.springframework.stereotype.Component;
+import org.ssssssss.magicapi.provider.MagicAPIService;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Optional;
+
+/**
+ * 基于magic-api接口的定时任务
+ */
+@Slf4j
+@Component
+public class MagicApiJob extends QuartzJobBean {
+
+ @Autowired
+ private MagicAPIService magicAPIService;
+
+ @Override
+ protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
+
+ /**
+ * 这是一个接口任务
+ * 需要执行magic-api接口的代码
+ * 首先你需要配置好magic-api接口,得到接口的请求方式、请求地址、请求参数
+ * 然后这个job会调用在java层调用magic-api的java代码去执行
+ * 这样一个完成的基于magic-api的定时任务接口就完成了
+ */
+
+ // 获取之前保存的参数
+ JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
+ // 取出请求方式与路径
+ String path = jobDataMap.getString("path");
+ String method = jobDataMap.getString("method");
+ Optional.ofNullable(path).orElseThrow(()->new RuntimeException("path 不能为空"));
+ Optional.ofNullable(method).orElseThrow(()->new RuntimeException("method 不能为空"));
+
+ // 移除请求方式与路径,剩下的都是参数
+ jobDataMap.remove("path");
+ jobDataMap.remove("method");
+
+ /**
+ *
+ * 执行MagicAPI中的接口,原始内容,不包含code以及message信息
+ * Params:
+ * method – 请求方法
+ * path – 请求路径
+ * context – 变量信息
+ */
+ log.info("开始执行magicApi定时任务");
+ magicAPIService.execute(method,path,jobDataMap);
+ log.info("结束执行magicApi定时任务");
+ }
+}
diff --git a/magic-boot/src/main/java/org/ssssssss/magicboot/quartz/ScheduledTasksController.java b/magic-boot/src/main/java/org/ssssssss/magicboot/quartz/ScheduledTasksController.java
new file mode 100644
index 0000000..5aaa33c
--- /dev/null
+++ b/magic-boot/src/main/java/org/ssssssss/magicboot/quartz/ScheduledTasksController.java
@@ -0,0 +1,78 @@
+package org.ssssssss.magicboot.quartz;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.ssssssss.magicboot.form.AddJobForm;
+import org.ssssssss.magicboot.vo.Result;
+
+/**
+ * 定时任务控制器
+ */
+@Slf4j
+@Controller
+@RequestMapping("/job")
+public class ScheduledTasksController {
+
+ @Autowired
+ private ScheduledTasksService scheduledTasksService;
+
+ /**
+ * 获取所有运行中的任务
+ * @return
+ */
+ @ResponseBody
+ @RequestMapping("/getAllJob")
+ public Result getAllJob() {
+ return scheduledTasksService.getAllJob();
+ }
+ /**
+ * 新增一个定时任务
+ * @param form
+ * @return
+ */
+ @ResponseBody
+ @RequestMapping("/addJob")
+ public Result addJob(AddJobForm form) {
+ scheduledTasksService.addJob(form);
+ return Result.isSuccess("添加定时任务 成功");
+ }
+
+ /**
+ * 暂停定时任务
+ * @param jName 任务名
+ * @param jGroup 任务组
+ */
+ @ResponseBody
+ @RequestMapping("/pauseJob")
+ public Result pauseJob(String jName, String jGroup) {
+ scheduledTasksService.pauseJob(jName, jGroup);
+ return Result.isSuccess("暂停定时任务 成功");
+ }
+
+ /**
+ * 继续定时任务
+ * @param jName 任务名
+ * @param jGroup 任务组
+ */
+ @ResponseBody
+ @RequestMapping("/resumeJob")
+ public Result resumeJob(String jName, String jGroup) {
+ scheduledTasksService.resumeJob(jName, jGroup);
+ return Result.isSuccess("继续定时任务 成功");
+ }
+
+ /**
+ * 删除定时任务
+ * @param jName 任务名
+ * @param jGroup 任务组
+ */
+ @ResponseBody
+ @RequestMapping("/resumeJob")
+ public Result deleteJob(String jName, String jGroup) {
+ scheduledTasksService.deleteJob(jName, jGroup);
+ return Result.isSuccess("删除定时任务 成功");
+ }
+}
diff --git a/magic-boot/src/main/java/org/ssssssss/magicboot/quartz/ScheduledTasksService.java b/magic-boot/src/main/java/org/ssssssss/magicboot/quartz/ScheduledTasksService.java
new file mode 100644
index 0000000..66431c7
--- /dev/null
+++ b/magic-boot/src/main/java/org/ssssssss/magicboot/quartz/ScheduledTasksService.java
@@ -0,0 +1,135 @@
+package org.ssssssss.magicboot.quartz;
+
+import org.quartz.*;
+import org.quartz.impl.matchers.GroupMatcher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.ssssssss.magicboot.form.AddJobForm;
+import org.ssssssss.magicboot.vo.Result;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+
+/**
+ * 定时任务业务控制层
+ */
+@Service
+public class ScheduledTasksService {
+
+ @Autowired
+ private Scheduler scheduler;
+
+ /**
+ * 获取所有运行中的任务
+ * @return
+ */
+ public Result getAllJob(){
+ try {
+ List formList = new ArrayList<>();
+ AddJobForm form = null;
+ for (TriggerKey triggerKey : scheduler.getTriggerKeys(GroupMatcher.anyGroup())) {
+ ///通过triggerKey在scheduler中获取trigger对象
+ CronTrigger trigger = (CronTrigger)scheduler.getTrigger(triggerKey);
+ JobDetail jobDetail = scheduler.getJobDetail(trigger.getJobKey());
+
+ form = new AddJobForm();
+
+ form.setMethod(jobDetail.getJobDataMap().getString("method"));
+ form.setPath(jobDetail.getJobDataMap().getString("path"));
+
+ jobDetail.getJobDataMap().remove("method");
+ jobDetail.getJobDataMap().remove("path");
+
+ form.setContext(jobDetail.getJobDataMap());
+ form.setJName(jobDetail.getKey().getName());
+ form.setJGroup(jobDetail.getKey().getGroup());
+
+ form.setTName(trigger.getJobKey().getName());
+ form.setTGroup(trigger.getJobKey().getGroup());
+
+ formList.add(form);
+ }
+ return Result.isSuccess(form);
+
+ } catch (SchedulerException e) {
+ e.printStackTrace();
+ return Result.isBad("获取所有任务失败:{}",e.getMessage());
+ }
+ }
+
+ /**
+ * 新增一个定时任务
+ */
+ public void addJob(AddJobForm form) {
+ Optional.ofNullable(form).orElseThrow(()->new RuntimeException("参数 不能为空"));
+ Optional.ofNullable(form.getPath()).orElseThrow(()->new RuntimeException("path 不能为空"));
+ Optional.ofNullable(form.getMethod()).orElseThrow(()->new RuntimeException("method 不能为空"));
+ Optional.ofNullable(form.getJName()).orElseThrow(()->new RuntimeException("任务名称 不能为空"));
+ Optional.ofNullable(form.getTName()).orElseThrow(()->new RuntimeException("触发器名称 不能为空"));
+ Optional.ofNullable(form.getCron()).orElseThrow(()->new RuntimeException("cron表达式 不能为空"));
+
+ try {
+ // 携带参数供执行job时调用
+ JobDataMap newJobDataMap = new JobDataMap();
+ newJobDataMap.put("method",form.getMethod());
+ newJobDataMap.put("path",form.getPath());
+ newJobDataMap.putAll(form.getContext());
+
+ JobDetail jobDetail = JobBuilder.newJob(MagicApiJob.class)
+ .withIdentity(form.getJName(), form.getJGroup())
+ .setJobData(newJobDataMap)
+ .build();
+ CronTrigger trigger = TriggerBuilder.newTrigger()
+ .withIdentity(form.getTName(), form.getTGroup())
+ .usingJobData(newJobDataMap)
+ .startNow()
+ .withSchedule(CronScheduleBuilder.cronSchedule(form.getCron()))
+ .build();
+ scheduler.start();
+ scheduler.scheduleJob(jobDetail, trigger);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 暂停定时任务
+ * @param jName 任务名
+ * @param jGroup 任务组
+ */
+ public void pauseJob(String jName, String jGroup) {
+ try {
+ scheduler.pauseJob(JobKey.jobKey(jName, jGroup));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 继续定时任务
+ * @param jName 任务名
+ * @param jGroup 任务组
+ */
+ public void resumeJob(String jName, String jGroup) {
+ try {
+ scheduler.resumeJob(JobKey.jobKey(jName, jGroup));
+ } catch (SchedulerException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 删除定时任务
+ * @param jName 任务名
+ * @param jGroup 任务组
+ */
+ public void deleteJob(String jName, String jGroup) {
+ try {
+ scheduler.deleteJob(JobKey.jobKey(jName, jGroup));
+ } catch (SchedulerException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/magic-boot/src/main/java/org/ssssssss/magicboot/vo/Result.java b/magic-boot/src/main/java/org/ssssssss/magicboot/vo/Result.java
new file mode 100644
index 0000000..76b9a67
--- /dev/null
+++ b/magic-boot/src/main/java/org/ssssssss/magicboot/vo/Result.java
@@ -0,0 +1,112 @@
+package org.ssssssss.magicboot.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class Result {
+ // 错误码
+ private String code;
+ // 提示信息
+ private String msg;
+ // 具体的内容
+ private T data;
+ // 是否成功
+ private boolean success;
+ // 总数
+ private Long total;
+
+ public Result() {
+ }
+
+ public Result(String code, String msg, T data, boolean success) {
+ this.code = code;
+ this.msg = msg;
+ this.data = data;
+ this.success = success;
+ }
+
+ public static Result isSuccess(T data) {
+ Result objectResult = new Result();
+ objectResult.setCode("200");
+ objectResult.setSuccess(true);
+ objectResult.setMsg("成功");
+ objectResult.setData(data);
+ return objectResult;
+ }
+
+ public static Result isSuccess(T data, Long count) {
+ Result objectResult = new Result();
+ objectResult.setCode("200");
+ objectResult.setSuccess(true);
+ objectResult.setMsg("成功");
+ objectResult.setData(data);
+ objectResult.setTotal(count);
+ return objectResult;
+ }
+
+ public static Result isBad(T data) {
+ Result objectResult = new Result();
+ objectResult.setCode("400");
+ objectResult.setSuccess(false);
+ objectResult.setMsg("失败");
+ objectResult.setData(data);
+ return objectResult;
+ }
+
+ public static Result isBad(String msg) {
+ Result objectResult = new Result<>();
+ objectResult.setCode("400");
+ objectResult.setSuccess(false);
+ objectResult.setMsg(msg);
+ return objectResult;
+ }
+
+ public static Result isBad(String msg, String code) {
+ Result objectResult = new Result();
+ objectResult.setCode(code);
+ objectResult.setSuccess(false);
+ objectResult.setMsg(msg);
+ return objectResult;
+ }
+
+ public static Result getResult(boolean isSuccess, T data) {
+ if (isSuccess) {
+ return Result.isSuccess(data);
+ }
+ return Result.isBad(data);
+ }
+
+ public static Result getResult(boolean isSuccess, T data, String msg) {
+ if (isSuccess) {
+ return Result.isSuccess(data);
+ }
+ return Result.isBad(msg);
+ }
+
+ public static Result getResult(boolean isSuccess, String msg) {
+ if (isSuccess) {
+ return Result.isSuccess(null);
+ }
+ return Result.isBad(msg);
+ }
+
+ public static Result getResult(boolean isSuccess, String msg, String code) {
+ if (isSuccess) {
+ return Result.isSuccess(null);
+ }
+ return Result.isBad(msg, code);
+ }
+
+
+ @Override
+ public String toString() {
+ return "Result{" +
+ "code='" + code + '\'' +
+ ", msg='" + msg + '\'' +
+ ", data=" + data +
+ ", success=" + success +
+ '}';
+ }
+}
diff --git a/magic-boot/src/main/resources/application-quartz.yml b/magic-boot/src/main/resources/application-quartz.yml
new file mode 100644
index 0000000..68c7f2f
--- /dev/null
+++ b/magic-boot/src/main/resources/application-quartz.yml
@@ -0,0 +1,6 @@
+spring:
+ quartz:
+ job-store-type: jdbc
+ jdbc:
+ initialize-schema: always
+ schema: classpath:schema/tables_mysql.sql
diff --git a/magic-boot/src/main/resources/application.yml b/magic-boot/src/main/resources/application.yml
index f069408..fd23c6d 100644
--- a/magic-boot/src/main/resources/application.yml
+++ b/magic-boot/src/main/resources/application.yml
@@ -7,6 +7,9 @@ server:
spring:
profiles:
active: dev
+ include:
+ - online
+ - quartz
servlet:
multipart:
max-file-size: 200MB
@@ -15,9 +18,9 @@ spring:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
datasource:
- url: jdbc:mysql://localhost:3307/magic-boot?useSSL=false&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF8&autoReconnect=true&serverTimezone=Asia/Shanghai
+ url: jdbc:mysql://localhost:3306/magic-boot?useSSL=false&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF8&autoReconnect=true&serverTimezone=Asia/Shanghai
username: root
- password: root
+ password: "********"
upload:
# oss,disk(磁盘)
@@ -68,4 +71,4 @@ sa-token:
# token风格
token-style: uuid
# 是否输出操作日志
- is-log: false
\ No newline at end of file
+ is-log: false
diff --git a/magic-boot/src/main/resources/schema/tables_mysql.sql b/magic-boot/src/main/resources/schema/tables_mysql.sql
new file mode 100644
index 0000000..fd986ab
--- /dev/null
+++ b/magic-boot/src/main/resources/schema/tables_mysql.sql
@@ -0,0 +1,159 @@
+DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
+DROP TABLE IF EXISTS QRTZ_LOCKS;
+DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
+DROP TABLE IF EXISTS QRTZ_CALENDARS;
+
+
+CREATE TABLE QRTZ_JOB_DETAILS
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ JOB_NAME VARCHAR(200) NOT NULL,
+ JOB_GROUP VARCHAR(200) NOT NULL,
+ DESCRIPTION VARCHAR(250) NULL,
+ JOB_CLASS_NAME VARCHAR(250) NOT NULL,
+ IS_DURABLE VARCHAR(1) NOT NULL,
+ IS_NONCONCURRENT VARCHAR(1) NOT NULL,
+ IS_UPDATE_DATA VARCHAR(1) NOT NULL,
+ REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
+ JOB_DATA BLOB NULL,
+ PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+
+CREATE TABLE QRTZ_TRIGGERS
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ JOB_NAME VARCHAR(200) NOT NULL,
+ JOB_GROUP VARCHAR(200) NOT NULL,
+ DESCRIPTION VARCHAR(250) NULL,
+ NEXT_FIRE_TIME BIGINT(13) NULL,
+ PREV_FIRE_TIME BIGINT(13) NULL,
+ PRIORITY INTEGER NULL,
+ TRIGGER_STATE VARCHAR(16) NOT NULL,
+ TRIGGER_TYPE VARCHAR(8) NOT NULL,
+ START_TIME BIGINT(13) NOT NULL,
+ END_TIME BIGINT(13) NULL,
+ CALENDAR_NAME VARCHAR(200) NULL,
+ MISFIRE_INSTR SMALLINT(2) NULL,
+ JOB_DATA BLOB NULL,
+ PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+ REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ REPEAT_COUNT BIGINT(7) NOT NULL,
+ REPEAT_INTERVAL BIGINT(12) NOT NULL,
+ TIMES_TRIGGERED BIGINT(10) NOT NULL,
+ PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE QRTZ_CRON_TRIGGERS
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ CRON_EXPRESSION VARCHAR(200) NOT NULL,
+ TIME_ZONE_ID VARCHAR(80),
+ PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE QRTZ_SIMPROP_TRIGGERS
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ STR_PROP_1 VARCHAR(512) NULL,
+ STR_PROP_2 VARCHAR(512) NULL,
+ STR_PROP_3 VARCHAR(512) NULL,
+ INT_PROP_1 INT NULL,
+ INT_PROP_2 INT NULL,
+ LONG_PROP_1 BIGINT NULL,
+ LONG_PROP_2 BIGINT NULL,
+ DEC_PROP_1 NUMERIC(13,4) NULL,
+ DEC_PROP_2 NUMERIC(13,4) NULL,
+ BOOL_PROP_1 VARCHAR(1) NULL,
+ BOOL_PROP_2 VARCHAR(1) NULL,
+ PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE QRTZ_BLOB_TRIGGERS
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ BLOB_DATA BLOB NULL,
+ PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE QRTZ_CALENDARS
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ CALENDAR_NAME VARCHAR(200) NOT NULL,
+ CALENDAR BLOB NOT NULL,
+ PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE QRTZ_FIRED_TRIGGERS
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ ENTRY_ID VARCHAR(95) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ INSTANCE_NAME VARCHAR(200) NOT NULL,
+ FIRED_TIME BIGINT(13) NOT NULL,
+ SCHED_TIME BIGINT(13) NOT NULL,
+ PRIORITY INTEGER NOT NULL,
+ STATE VARCHAR(16) NOT NULL,
+ JOB_NAME VARCHAR(200) NULL,
+ JOB_GROUP VARCHAR(200) NULL,
+ IS_NONCONCURRENT VARCHAR(1) NULL,
+ REQUESTS_RECOVERY VARCHAR(1) NULL,
+ PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+
+CREATE TABLE QRTZ_SCHEDULER_STATE
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ INSTANCE_NAME VARCHAR(200) NOT NULL,
+ LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
+ CHECKIN_INTERVAL BIGINT(13) NOT NULL,
+ PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+
+CREATE TABLE QRTZ_LOCKS
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ LOCK_NAME VARCHAR(40) NOT NULL,
+ PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+
+
+commit;