This is an automated email from the ASF dual-hosted git repository.
nicholasjiang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/paimon-webui.git
The following commit(s) were added to refs/heads/main by this push:
new 378a6cd0 [Feature] Introduce history interface (#253)
378a6cd0 is described below
commit 378a6cd07908b73c59a32631d6708b6c2f0aec50
Author: s7monk <[email protected]>
AuthorDate: Mon May 27 16:01:29 2024 +0800
[Feature] Introduce history interface (#253)
---
.../web/server/controller/HistoryController.java | 67 +++++++++++
.../model/History.java} | 48 +++++---
.../HistoryMapper.java} | 27 +++--
.../paimon/web/server/service/HistoryService.java | 48 ++++++++
.../server/service/impl/HistoryServiceImpl.java | 48 ++++++++
.../web/server/service/impl/JobServiceImpl.java | 20 ++++
.../paimon/web/server/util/LocalDateTimeUtil.java | 5 +
.../src/main/resources/mapper/HistoryMapper.xml | 58 ++++++++++
.../server/controller/HistoryControllerTest.java | 128 +++++++++++++++++++++
scripts/sql/paimon-mysql.sql | 14 +++
10 files changed, 432 insertions(+), 31 deletions(-)
diff --git
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/HistoryController.java
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/HistoryController.java
new file mode 100644
index 00000000..14d69f28
--- /dev/null
+++
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/HistoryController.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.paimon.web.server.controller;
+
+import org.apache.paimon.web.server.data.model.History;
+import org.apache.paimon.web.server.data.result.PageR;
+import org.apache.paimon.web.server.data.result.R;
+import org.apache.paimon.web.server.service.HistoryService;
+import org.apache.paimon.web.server.util.PageSupport;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/** History api controller. */
+@RestController
+@RequestMapping("/api/history")
+public class HistoryController {
+
+ @Autowired private HistoryService historyService;
+
+ @SaCheckPermission("playground:history:query")
+ @GetMapping("/{id}")
+ public R<History> getStatement(@PathVariable("id") Integer id) {
+ return R.succeed(historyService.getById(id));
+ }
+
+ @SaCheckPermission("playground:history:list")
+ @GetMapping("/list")
+ public PageR<History> listSelectHistories(History selectHistory) {
+ IPage<History> page = PageSupport.startPage();
+ List<History> selectHistories = historyService.listHistories(page,
selectHistory);
+ return PageR.<History>builder()
+ .success(true)
+ .total(page.getTotal())
+ .data(selectHistories)
+ .build();
+ }
+
+ @SaCheckPermission("playground:history:query")
+ @GetMapping("/all")
+ public R<List<History>> all() {
+ return R.succeed(historyService.list());
+ }
+}
diff --git
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/util/LocalDateTimeUtil.java
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/History.java
similarity index 55%
copy from
paimon-web-server/src/main/java/org/apache/paimon/web/server/util/LocalDateTimeUtil.java
copy to
paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/History.java
index 7443f970..51416660 100644
---
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/util/LocalDateTimeUtil.java
+++
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/model/History.java
@@ -16,21 +16,35 @@
* limitations under the License.
*/
-package org.apache.paimon.web.server.util;
-
-import java.time.LocalDateTime;
-import java.time.OffsetDateTime;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-
-/** Local date time util. */
-public class LocalDateTimeUtil {
-
- public static LocalDateTime convertUtcStringToLocalDateTime(String
utcTimeStr) {
- OffsetDateTime utcTime =
- OffsetDateTime.parse(utcTimeStr + "Z",
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
- ZonedDateTime beijingTime =
utcTime.atZoneSameInstant(ZoneId.of("Asia/Shanghai"));
- return beijingTime.toLocalDateTime();
- }
+package org.apache.paimon.web.server.data.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/** History table model. */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@TableName("history")
+public class History extends BaseModel {
+
+ private String name;
+
+ private String taskType;
+
+ private Boolean isStreaming;
+
+ private Integer uid;
+
+ private Integer clusterId;
+
+ private String statements;
+
+ private static final long serialVersionUID = 1L;
}
diff --git
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/util/LocalDateTimeUtil.java
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/mapper/HistoryMapper.java
similarity index 56%
copy from
paimon-web-server/src/main/java/org/apache/paimon/web/server/util/LocalDateTimeUtil.java
copy to
paimon-web-server/src/main/java/org/apache/paimon/web/server/mapper/HistoryMapper.java
index 7443f970..3700808f 100644
---
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/util/LocalDateTimeUtil.java
+++
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/mapper/HistoryMapper.java
@@ -16,21 +16,20 @@
* limitations under the License.
*/
-package org.apache.paimon.web.server.util;
+package org.apache.paimon.web.server.mapper;
-import java.time.LocalDateTime;
-import java.time.OffsetDateTime;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
+import org.apache.paimon.web.server.data.model.History;
-/** Local date time util. */
-public class LocalDateTimeUtil {
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
- public static LocalDateTime convertUtcStringToLocalDateTime(String
utcTimeStr) {
- OffsetDateTime utcTime =
- OffsetDateTime.parse(utcTimeStr + "Z",
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
- ZonedDateTime beijingTime =
utcTime.atZoneSameInstant(ZoneId.of("Asia/Shanghai"));
- return beijingTime.toLocalDateTime();
- }
+import java.util.List;
+
+/** History mapper. */
+@Mapper
+public interface HistoryMapper extends BaseMapper<History> {
+
+ List<History> listHistories(IPage<History> page, @Param("history") History
history);
}
diff --git
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/HistoryService.java
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/HistoryService.java
new file mode 100644
index 00000000..4a856798
--- /dev/null
+++
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/HistoryService.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.paimon.web.server.service;
+
+import org.apache.paimon.web.server.data.model.History;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/** History Service. */
+public interface HistoryService extends IService<History> {
+
+ /**
+ * Saves a history record.
+ *
+ * @param history The selection history record to save
+ * @return true if the record was saved successfully, false otherwise
+ */
+ boolean saveHistory(History history);
+
+ /**
+ * Retrieves a paginated list of history records.
+ *
+ * @param page the pagination information
+ * @param history the filter criteria
+ * @return A list of History entities for the specified page
+ */
+ List<History> listHistories(IPage<History> page, @Param("history") History
history);
+}
diff --git
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/HistoryServiceImpl.java
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/HistoryServiceImpl.java
new file mode 100644
index 00000000..c31d1779
--- /dev/null
+++
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/HistoryServiceImpl.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.paimon.web.server.service.impl;
+
+import org.apache.paimon.web.server.data.model.History;
+import org.apache.paimon.web.server.mapper.HistoryMapper;
+import org.apache.paimon.web.server.service.HistoryService;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/** The implementation of {@link HistoryService}. */
+@Service
+public class HistoryServiceImpl extends ServiceImpl<HistoryMapper, History>
+ implements HistoryService {
+
+ @Autowired private HistoryMapper historyMapper;
+
+ @Override
+ public boolean saveHistory(History selectHistory) {
+ return this.save(selectHistory);
+ }
+
+ @Override
+ public List<History> listHistories(IPage<History> page, History history) {
+ return historyMapper.listHistories(page, history);
+ }
+}
diff --git
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/JobServiceImpl.java
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/JobServiceImpl.java
index 9c3ffdc0..40fb061c 100644
---
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/JobServiceImpl.java
+++
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/JobServiceImpl.java
@@ -32,12 +32,14 @@ import org.apache.paimon.web.server.data.dto.ResultFetchDTO;
import org.apache.paimon.web.server.data.dto.SessionDTO;
import org.apache.paimon.web.server.data.dto.StopJobDTO;
import org.apache.paimon.web.server.data.model.ClusterInfo;
+import org.apache.paimon.web.server.data.model.History;
import org.apache.paimon.web.server.data.model.JobInfo;
import org.apache.paimon.web.server.data.vo.JobStatisticsVO;
import org.apache.paimon.web.server.data.vo.JobVO;
import org.apache.paimon.web.server.data.vo.ResultDataVO;
import org.apache.paimon.web.server.mapper.JobMapper;
import org.apache.paimon.web.server.service.ClusterService;
+import org.apache.paimon.web.server.service.HistoryService;
import org.apache.paimon.web.server.service.JobExecutorService;
import org.apache.paimon.web.server.service.JobService;
import org.apache.paimon.web.server.service.SessionService;
@@ -85,6 +87,8 @@ public class JobServiceImpl extends ServiceImpl<JobMapper,
JobInfo> implements J
@Autowired private JobExecutorService jobExecutorService;
+ @Autowired private HistoryService historyService;
+
@Override
public JobVO submitJob(JobSubmitDTO jobSubmitDTO) {
String pipelineName = getPipelineName(jobSubmitDTO.getStatements());
@@ -108,6 +112,15 @@ public class JobServiceImpl extends ServiceImpl<JobMapper,
JobInfo> implements J
JobInfo jobInfo = buildJobInfo(executionResult, jobSubmitDTO);
this.save(jobInfo);
}
+ historyService.saveHistory(
+ History.builder()
+
.name(LocalDateTimeUtil.getFormattedDateTime(LocalDateTime.now()))
+ .taskType(jobSubmitDTO.getTaskType())
+ .isStreaming(jobSubmitDTO.isStreaming())
+ .uid(getCurrentUserId())
+
.clusterId(Integer.valueOf(jobSubmitDTO.getClusterId()))
+ .statements(jobSubmitDTO.getStatements())
+ .build());
return buildJobVO(executionResult, jobSubmitDTO);
} catch (Exception e) {
throw new RuntimeException("Error executing job: " +
e.getMessage(), e);
@@ -475,4 +488,11 @@ public class JobServiceImpl extends ServiceImpl<JobMapper,
JobInfo> implements J
}
return null;
}
+
+ private int getCurrentUserId() {
+ if (!StpUtil.isLogin()) {
+ throw new IllegalStateException("User must be logged in to access
this resource.");
+ }
+ return StpUtil.getLoginIdAsInt();
+ }
}
diff --git
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/util/LocalDateTimeUtil.java
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/util/LocalDateTimeUtil.java
index 7443f970..3759e77a 100644
---
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/util/LocalDateTimeUtil.java
+++
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/util/LocalDateTimeUtil.java
@@ -33,4 +33,9 @@ public class LocalDateTimeUtil {
ZonedDateTime beijingTime =
utcTime.atZoneSameInstant(ZoneId.of("Asia/Shanghai"));
return beijingTime.toLocalDateTime();
}
+
+ public static String getFormattedDateTime(LocalDateTime time) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd
HH:mm:ss");
+ return time.format(formatter);
+ }
}
diff --git a/paimon-web-server/src/main/resources/mapper/HistoryMapper.xml
b/paimon-web-server/src/main/resources/mapper/HistoryMapper.xml
new file mode 100644
index 00000000..5b7b9211
--- /dev/null
+++ b/paimon-web-server/src/main/resources/mapper/HistoryMapper.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+<!DOCTYPE mapper
+ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+ "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.apache.paimon.web.server.mapper.HistoryMapper">
+
+ <resultMap id="HistoryResult"
type="org.apache.paimon.web.server.data.model.History">
+ <id property="id" column="id" />
+ <result property="name" column="name" />
+ <result property="taskType" column="task_type" />
+ <result property="isStreaming" column="is_streaming" />
+ <result property="uid" column="uid" />
+ <result property="clusterId" column="cluster_id" />
+ <result property="statements" column="statements" />
+ <result property="createTime" column="create_time" />
+ <result property="updateTime" column="update_time" />
+ </resultMap>
+
+ <sql id="historyVo">
+ select id, name, task_type, is_streaming, uid, cluster_id, statements,
create_time, update_time from history order by create_time desc
+ </sql>
+
+ <select id="listHistories"
parameterType="org.apache.paimon.web.server.data.model.History"
resultMap="HistoryResult">
+ <include refid="historyVo"/>
+ <where>
+ <if test="history.name != null and history.name != ''">
+ AND name like concat('%', #{history.name}, '%')
+ </if>
+ <if test="history.statements != null and history.statements != ''">
+ AND statements like concat('%', #{history.statements}, '%')
+ </if>
+ <if test="history.params.beginTime != null and
history.params.beginTime != ''"><!-- Start time search -->
+ AND date_format(create_time,'%y%m%d') >=
date_format(#{history.params.beginTime},'%y%m%d')
+ </if>
+ <if test="history.params.endTime != null and
history.params.endTime != ''"><!-- End time search -->
+ AND date_format(create_time,'%y%m%d') <=
date_format(#{history.params.endTime},'%y%m%d')
+ </if>
+ </where>
+ </select>
+</mapper>
\ No newline at end of file
diff --git
a/paimon-web-server/src/test/java/org/apache/paimon/web/server/controller/HistoryControllerTest.java
b/paimon-web-server/src/test/java/org/apache/paimon/web/server/controller/HistoryControllerTest.java
new file mode 100644
index 00000000..c7ff8cd7
--- /dev/null
+++
b/paimon-web-server/src/test/java/org/apache/paimon/web/server/controller/HistoryControllerTest.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.paimon.web.server.controller;
+
+import org.apache.paimon.web.server.data.model.History;
+import org.apache.paimon.web.server.data.result.PageR;
+import org.apache.paimon.web.server.data.result.R;
+import org.apache.paimon.web.server.service.HistoryService;
+import org.apache.paimon.web.server.util.ObjectMapperUtils;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import
org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/** Test for {@link HistoryController}. */
+@SpringBootTest
+@AutoConfigureMockMvc
+public class HistoryControllerTest extends ControllerTestBase {
+
+ private static final String historyPath = "/api/history";
+
+ private static final int historyId = 1;
+ private static final String historyName = "test";
+
+ @Autowired private HistoryService historyService;
+
+ @BeforeEach
+ public void setup() {
+ History selectHistory = new History();
+ selectHistory.setId(historyId);
+ selectHistory.setName(historyName);
+ selectHistory.setTaskType("Flink");
+ selectHistory.setIsStreaming(false);
+ selectHistory.setUid(1);
+ selectHistory.setClusterId(1);
+ selectHistory.setStatements("select * from table");
+ historyService.saveHistory(selectHistory);
+ }
+
+ @AfterEach
+ public void after() {
+ historyService.removeById(historyId);
+ }
+
+ @Test
+ public void testSelectHistory() throws Exception {
+ String responseString =
+ mockMvc.perform(
+ MockMvcRequestBuilders.get(historyPath + "/" +
historyId)
+ .cookie(cookie)
+
.contentType(MediaType.APPLICATION_JSON_VALUE)
+
.accept(MediaType.APPLICATION_JSON_VALUE))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andDo(MockMvcResultHandlers.print())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ R<History> r =
+ ObjectMapperUtils.fromJSON(responseString, new
TypeReference<R<History>>() {});
+ assertEquals(200, r.getCode());
+ assertNotNull(r.getData());
+ assertEquals(historyName, r.getData().getName());
+ assertEquals(1, r.getData().getUid());
+ assertEquals(1, r.getData().getClusterId());
+ assertEquals("Flink", r.getData().getTaskType());
+ assertEquals(false, r.getData().getIsStreaming());
+ assertEquals("select * from table", r.getData().getStatements());
+ }
+
+ @Test
+ public void testListClusters() throws Exception {
+ String responseString =
+ mockMvc.perform(
+ MockMvcRequestBuilders.get(historyPath +
"/list")
+ .cookie(cookie)
+
.contentType(MediaType.APPLICATION_JSON_VALUE)
+
.accept(MediaType.APPLICATION_JSON_VALUE))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andDo(MockMvcResultHandlers.print())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ PageR<History> r =
+ ObjectMapperUtils.fromJSON(responseString, new
TypeReference<PageR<History>>() {});
+ assertTrue(
+ r.getData() != null
+ && ((r.getTotal() > 0 && r.getData().size() > 0)
+ || (r.getTotal() == 0 && r.getData().size() ==
0)));
+
+ History selectHistory = r.getData().get(0);
+ assertEquals(historyName, selectHistory.getName());
+ assertEquals(1, selectHistory.getUid());
+ assertEquals(1, selectHistory.getClusterId());
+ assertEquals("Flink", selectHistory.getTaskType());
+ assertEquals(false, selectHistory.getIsStreaming());
+ assertEquals("select * from table", selectHistory.getStatements());
+ }
+}
diff --git a/scripts/sql/paimon-mysql.sql b/scripts/sql/paimon-mysql.sql
index 2e065510..b83f9355 100644
--- a/scripts/sql/paimon-mysql.sql
+++ b/scripts/sql/paimon-mysql.sql
@@ -173,6 +173,20 @@ CREATE TABLE if not exists `job`
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'update
time'
) ENGINE = InnoDB DEFAULT CHARSET=utf8;
+DROP TABLE IF EXISTS `history`;
+CREATE TABLE if not exists `history`
+(
+ `id` int(11) not null auto_increment primary key comment 'id',
+ `name` varchar(100) not null comment 'name',
+ `task_type` varchar(100) not null comment 'task type',
+ `is_streaming` tinyint(1) comment 'is steaming',
+ `uid` int(11) comment 'user id',
+ `cluster_id` int(11) comment 'cluster id',
+ `statements` text COMMENT 'statements',
+ `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create
time',
+ `update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'update
time'
+ ) ENGINE = InnoDB DEFAULT CHARSET=utf8;
+
INSERT INTO `user` ( id, username, password, nickname, mobile
, email, enabled, is_delete)
VALUES ( 1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Admin', 0