diff --git a/docs/zh_CN/ch3/DSS_User_Tests1_Scala.md b/docs/zh_CN/ch3/DSS_User_Tests1_Scala.md
new file mode 100644
index 0000000000..70c0b03317
--- /dev/null
+++ b/docs/zh_CN/ch3/DSS_User_Tests1_Scala.md
@@ -0,0 +1,82 @@
+# DSS用户测试样例1:Scala
+
+DSS用户测试样例的目的是为平台新用户提供一组测试样例,用于熟悉DSS的常见操作,并验证DSS平台的正确性
+
+![image-20200408211243941](../../../images/zh_CN/chapter3/tests/home.png)
+
+## 1.1 Spark Core(入口函数sc)
+
+在Scriptis中,已经默认为您注册了SparkContext,所以直接使用sc即可:
+
+### 1.1.1 单Value算子(Map算子为例)
+
+```scala
+val rddMap = sc.makeRDD(Array((1,"a"),(1,"d"),(2,"b"),(3,"c")),4)
+val res = rddMap.mapValues(data=>{data+"||||"})
+res.collect().foreach(data=>println(data._1+","+data._2))
+```
+
+### 1.1.2 双Value算子(union算子为例)
+
+```scala
+val rdd1 = sc.makeRDD(1 to 5)
+val rdd2 = sc.makeRDD(6 to 10)
+val rddCustom = rdd1.union(rdd2)
+rddCustom.collect().foreach(println)
+```
+
+### 1.1.3 K-V算子(reduceByKey算子为例子)
+
+```scala
+val rdd1 = sc.makeRDD(List(("female",1),("male",2),("female",3),("male",4)))
+val rdd2 = rdd1.reduceByKey((x,y)=>x+y)
+rdd2.collect().foreach(println)
+```
+
+### 1.1.4 执行算子(以上collect算子为例)
+
+### 1.1.5 从hdfs上读取文件并做简单执行
+
+```scala
+case class Person(name:String,age:String)
+val file = sc.textFile("/test.txt")
+val person = file.map(line=>{
+ val values=line.split(",")
+
+ Person(values(0),values(1))
+})
+val df = person.toDF()
+df.select($"name").show()
+```
+
+
+
+## 1.2 UDF函数测试
+
+### 1.2.1 函数定义
+
+
+
+```scala
+def ScalaUDF3(str: String): String = "hello, " + str + "this is a third attempt"
+```
+
+### 1.2.2 注册函数
+
+函数-》个人函数-》右击新增spark函数=》注册方式同常规spark开发
+
+ ![img](../../../images/zh_CN/chapter3/tests/udf1.png)
+
+## 1.3 UDAF函数测试
+
+### 1.3.1 Jar包上传
+
+ idea上开发一个求平均值的udaf函数,打成jar(wordcount)包,上传dss jar文件夹。
+
+ ![img](../../../images/zh_CN/chapter3/tests/udf2.png)
+
+### 1.3.2 注册函数
+
+函数-》个人函数-》右击新增普通函数=》注册方式同常规spark开发
+
+ ![img](../../../images/zh_CN/chapter3/tests/udf-3.png)
\ No newline at end of file
diff --git a/docs/zh_CN/ch3/DSS_User_Tests2_Hive.md b/docs/zh_CN/ch3/DSS_User_Tests2_Hive.md
new file mode 100644
index 0000000000..800277ca09
--- /dev/null
+++ b/docs/zh_CN/ch3/DSS_User_Tests2_Hive.md
@@ -0,0 +1,148 @@
+# DSS用户测试样例2:Hive
+
+DSS用户测试样例的目的是为平台新用户提供一组测试样例,用于熟悉DSS的常见操作,并验证DSS平台的正确性
+
+![image-20200408211243941](../../../images/zh_CN/chapter3/tests/home.png)
+
+## 2.1 数仓建表
+
+ 进入“数据库”页面,点击“+”,依次输入表信息、表结构和分区信息即可创建数据库表:
+
+
+
+ ![img](../../../images/zh_CN/chapter3/tests/hive2.png)
+
+ 通过以上流程,分别创建部门表dept、员工表emp和分区员工表emp_partition,建表语句如下:
+
+```sql
+create external table if not exists default.dept(
+ deptno int,
+ dname string,
+ loc int
+)
+row format delimited fields terminated by '\t';
+
+create external table if not exists default.emp(
+ empno int,
+ ename string,
+ job string,
+ mgr int,
+ hiredate string,
+ sal double,
+ comm double,
+ deptno int
+)
+row format delimited fields terminated by '\t';
+
+create table if not exists emp_partition(
+ empno int,
+ ename string,
+ job string,
+ mgr int,
+ hiredate string,
+ sal double,
+ comm double,
+ deptno int
+)
+partitioned by (month string)
+row format delimited fields terminated by '\t';
+```
+
+**导入数据**
+
+目前需要通过后台手动批量导入数据,可以通过insert方法从页面插入数据
+
+```sql
+load data local inpath 'dept.txt' into table default.dept;
+load data local inpath 'emp.txt' into table default.emp;
+load data local inpath 'emp1.txt' into table default.emp_partition;
+load data local inpath 'emp2.txt' into table default.emp_partition;
+load data local inpath 'emp2.txt' into table default.emp_partition;
+```
+
+其它数据按照上述语句导入,样例数据文件路径在:`examples\ch3`
+
+## 2.2 基本SQL语法测试
+
+### 2.2.1 简单查询
+
+```sql
+select * from dept;
+```
+
+### 2.2.2 Join连接
+
+```sql
+select * from emp
+left join dept
+on emp.deptno = dept.deptno;
+```
+
+### 2.2.3 聚合函数
+
+```sql
+select dept.dname, avg(sal) as avg_salary
+from emp left join dept
+on emp.deptno = dept.deptno
+group by dept.dname;
+```
+
+### 2.2.4 内置函数
+
+```sql
+select ename, job,sal,
+rank() over(partition by job order by sal desc) sal_rank
+from emp;
+```
+
+### 2.2.5 分区表简单查询
+
+```sql
+show partitions emp_partition;
+select * from emp_partition where month='202001';
+```
+
+### 2.2.6 分区表联合查询
+
+```sql
+select * from emp_partition where month='202001'
+union
+select * from emp_partition where month='202002'
+union
+select * from emp_partition where month='202003'
+```
+
+## 2.3 UDF函数测试
+
+### 2.3.1 Jar包上传
+
+进入Scriptis页面后,右键目录路径上传jar包:
+
+ ![img](../../../images/zh_CN/chapter3/tests/hive3.png)
+
+测试样例jar包在`examples\ch3\rename.jar`
+
+### 4.3.2 自定义函数
+
+进入“UDF函数”选项(如1),右击“个人函数”目录,选择“新增函数”:
+
+
+
+输入函数名称、选择jar包、并填写注册格式、输入输出格式即可创建函数:
+
+ ![img](../../../images/zh_CN/chapter3/tests/hive5.png)
+
+
+
+获得的函数如下:
+
+ ![img](../../../images/zh_CN/chapter3/tests/hive7.png)
+
+### 4.3.3 利用自定义函数进行SQL查询
+
+完成函数注册后,可进入工作空间页面创建.hql文件使用函数:
+
+```sql
+select deptno,ename, rename(ename) as new_name
+from emp;
+```
diff --git a/docs/zh_CN/ch3/DSS_User_Tests3_SparkSQL.md b/docs/zh_CN/ch3/DSS_User_Tests3_SparkSQL.md
new file mode 100644
index 0000000000..aaf2fb44d7
--- /dev/null
+++ b/docs/zh_CN/ch3/DSS_User_Tests3_SparkSQL.md
@@ -0,0 +1,61 @@
+# DSS用户测试样例3:SparkSQL
+
+DSS用户测试样例的目的是为平台新用户提供一组测试样例,用于熟悉DSS的常见操作,并验证DSS平台的正确性
+
+![image-20200408211243941](../../../images/zh_CN/chapter3/tests/home.png)
+
+## 3.1RDD与DataFrame转换
+
+### 3.1.1 RDD转为DataFrame
+
+```scala
+case class MyList(id:Int)
+
+val lis = List(1,2,3,4)
+
+val listRdd = sc.makeRDD(lis)
+import spark.implicits._
+val df = listRdd.map(value => MyList(value)).toDF()
+
+df.show()
+```
+
+### 3.1.2 DataFrame转为RDD
+
+```scala
+case class MyList(id:Int)
+
+val lis = List(1,2,3,4)
+val listRdd = sc.makeRDD(lis)
+import spark.implicits._
+val df = listRdd.map(value => MyList(value)).toDF()
+println("------------------")
+
+val dfToRdd = df.rdd
+
+dfToRdd.collect().foreach(print(_))
+```
+
+## 3.2 DSL语法风格实现
+
+```scala
+val df = df1.union(df2)
+val dfSelect = df.select($"department")
+dfSelect.show()
+```
+
+## 3.3 SQL语法风格实现(入口函数sqlContext)
+
+```scala
+val df = df1.union(df2)
+
+df.createOrReplaceTempView("dfTable")
+val innerSql = """
+ SELECT department
+ FROM dfTable
+ """
+val sqlDF = sqlContext.sql(innerSql)
+sqlDF.show()
+```
+
+
\ No newline at end of file
diff --git a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/dao/WorkspaceMapper.java b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/dao/WorkspaceMapper.java
index 819a221d35..387c597ff8 100644
--- a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/dao/WorkspaceMapper.java
+++ b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/dao/WorkspaceMapper.java
@@ -2,6 +2,11 @@
import com.webank.wedatasphere.dss.server.dto.response.*;
import com.webank.wedatasphere.dss.server.entity.*;
+import com.webank.wedatasphere.dss.server.dto.response.HomepageDemoInstanceVo;
+import com.webank.wedatasphere.dss.server.dto.response.HomepageDemoMenuVo;
+import com.webank.wedatasphere.dss.server.dto.response.HomepageVideoVo;
+import com.webank.wedatasphere.dss.server.dto.response.WorkspaceFavoriteVo;
+import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -36,4 +41,11 @@ public interface WorkspaceMapper {
List getMenuAppInstancesCn(Long id);
List getMenuAppInstanceEn(Long id);
+ List getWorkspaceFavoritesCn(@Param("username") String username, @Param("workspaceId") Long workspaceId);
+
+ List getWorkspaceFavoritesEn(@Param("username") String username, @Param("workspaceId") Long workspaceId);
+
+ void addFavorite(DWSFavorite dwsFavorite);
+
+ void deleteFavorite(Long favouritesId);
}
diff --git a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/dao/impl/workspaceMapper.xml b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/dao/impl/workspaceMapper.xml
index a211d50228..854904bd9b 100644
--- a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/dao/impl/workspaceMapper.xml
+++ b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/dao/impl/workspaceMapper.xml
@@ -35,6 +35,9 @@
m.`manual_button_url`,m.`icon`,m.`order`,app.`homepage_url` AS `access_button_url`,app.project_url, app.`name`
+
+ id,`username`,`workspace_id`,`menu_application_id`,`order`,`create_by`,`create_time`,`last_update_user`,`last_update_time`
+
+
+
+
+
+
+
+
+
+
+
+
+ INSERT INTO dss_onestop_user_favorites ()
+ VALUES
+ (#{id},#{username},#{workspaceId},#{menuApplicationId},#{order},#{createBy},#{createTime},#{lastUpdateUser},#{lastUpdateTime})
+
+
+
+ DELETE
+ FROM
+ dss_onestop_user_favorites
+ WHERE
+ id = #{favouritesId}
+
\ No newline at end of file
diff --git a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/dto/response/WorkspaceFavoriteVo.java b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/dto/response/WorkspaceFavoriteVo.java
new file mode 100644
index 0000000000..50d93bc8c9
--- /dev/null
+++ b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/dto/response/WorkspaceFavoriteVo.java
@@ -0,0 +1,65 @@
+package com.webank.wedatasphere.dss.server.dto.response;
+
+/**
+ * Created by Adamyuanyuan on 2020/6/25
+ */
+public class WorkspaceFavoriteVo {
+ private Long id;
+
+ private Long menuApplicationId;
+
+ private String name;
+
+ private String url;
+
+ private String icon;
+
+ private String title;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Long getMenuApplicationId() {
+ return menuApplicationId;
+ }
+
+ public void setMenuApplicationId(Long menuApplicationId) {
+ this.menuApplicationId = menuApplicationId;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getIcon() {
+ return icon;
+ }
+
+ public void setIcon(String icon) {
+ this.icon = icon;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
diff --git a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/entity/DWSFavorite.java b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/entity/DWSFavorite.java
new file mode 100644
index 0000000000..07a1b48828
--- /dev/null
+++ b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/entity/DWSFavorite.java
@@ -0,0 +1,57 @@
+package com.webank.wedatasphere.dss.server.entity;
+
+/**
+ * Created by Adamyuanyuan on 2020/6/25
+ */
+public class DWSFavorite extends BaseEntity{
+
+ private Long id;
+
+ private String username;
+
+ private Long workspaceId;
+
+ private Long menuApplicationId;
+
+ private Integer order;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public Long getWorkspaceId() {
+ return workspaceId;
+ }
+
+ public void setWorkspaceId(Long workspaceId) {
+ this.workspaceId = workspaceId;
+ }
+
+ public Long getMenuApplicationId() {
+ return menuApplicationId;
+ }
+
+ public void setMenuApplicationId(Long menuApplicationId) {
+ this.menuApplicationId = menuApplicationId;
+ }
+
+ public Integer getOrder() {
+ return order;
+ }
+
+ public void setOrder(Integer order) {
+ this.order = order;
+ }
+}
diff --git a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/restful/WorkspaceRestfulApi.java b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/restful/WorkspaceRestfulApi.java
index a55d1e0c1b..7fb0e12943 100644
--- a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/restful/WorkspaceRestfulApi.java
+++ b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/restful/WorkspaceRestfulApi.java
@@ -5,6 +5,8 @@
import com.webank.wedatasphere.dss.server.dto.response.OnestopMenuVo;
import com.webank.wedatasphere.dss.server.entity.DWSWorkspace;
import com.webank.wedatasphere.dss.server.dto.response.WorkspaceDepartmentVo;
+import com.webank.wedatasphere.dss.application.service.DSSUserService;
+import com.webank.wedatasphere.dss.server.dto.response.*;
import com.webank.wedatasphere.dss.server.service.DWSWorkspaceService;
import com.webank.wedatasphere.linkis.server.Message;
import com.webank.wedatasphere.linkis.server.security.SecurityFilter;
@@ -31,6 +33,8 @@ public class WorkspaceRestfulApi {
@Autowired
private DWSWorkspaceService dwsWorkspaceService;
+ @Autowired
+ private DSSUserService dssUserService;
@GET
@Path("/workspaces")
@@ -40,6 +44,13 @@ public Response getAllWorkspaces(@Context HttpServletRequest req) {
return Message.messageToResponse(Message.ok().data("workspaces", workspaces));
}
+ @GET
+ @Path("/workspaces/{id}")
+ public Response getWorkspacesById(@Context HttpServletRequest req, @PathParam("id") Long id) {
+ DWSWorkspace workspace = dwsWorkspaceService.getWorkspacesById(id);
+ return Message.messageToResponse(Message.ok().data("workspace", workspace));
+ }
+
@GET
@Path("/workspaces/departments")
public Response getAllWorkspaceDepartments(@Context HttpServletRequest req) {
@@ -89,7 +100,7 @@ public Response getAllVideos(@Context HttpServletRequest req) {
@GET
@Path("workspaces/{workspaceId}/managements")
- public Response getWorkspaceManagements(@Context HttpServletRequest req, @PathParam("workspaceId")Long workspaceId) {
+ public Response getWorkspaceManagements(@Context HttpServletRequest req, @PathParam("workspaceId") Long workspaceId) {
String header = req.getHeader("Content-language").trim();
boolean isChinese = "zh-CN".equals(header);
String username = SecurityFilter.getLoginUsername(req);
@@ -100,11 +111,45 @@ public Response getWorkspaceManagements(@Context HttpServletRequest req, @PathPa
@GET
@Path("workspaces/{workspaceId}/applications")
- public Response getWorkspaceApplications(@Context HttpServletRequest req, @PathParam("workspaceId")Long workspaceId) {
+ public Response getWorkspaceApplications(@Context HttpServletRequest req, @PathParam("workspaceId") Long workspaceId) {
String header = req.getHeader("Content-language").trim();
boolean isChinese = "zh-CN".equals(header);
String username = SecurityFilter.getLoginUsername(req);
List applications = dwsWorkspaceService.getWorkspaceApplications(workspaceId, username, isChinese);
return Message.messageToResponse(Message.ok().data("applications", applications));
}
+
+ @GET
+ @Path("/workspaces/{workspaceId}/favorites")
+ public Response getWorkspaceFavorites(@Context HttpServletRequest req, @PathParam("workspaceId") Long workspaceId) {
+ String header = req.getHeader("Content-language").trim();
+ boolean isChinese = "zh-CN".equals(header);
+ String username = SecurityFilter.getLoginUsername(req);
+ List favorites = dwsWorkspaceService.getWorkspaceFavorites(workspaceId, username, isChinese);
+ return Message.messageToResponse(Message.ok().data("favorites", favorites));
+ }
+
+ /**
+ * 应用加入收藏,返回收藏后id
+ *
+ * @param req
+ * @param json
+ * @return
+ */
+ @POST
+ @Path("/workspaces/{workspaceId}/favorites")
+ public Response addFavorite(@Context HttpServletRequest req, @PathParam("workspaceId") Long workspaceId, JsonNode json) {
+ String username = SecurityFilter.getLoginUsername(req);
+ Long menuApplicationId = json.get("menuApplicationId").getLongValue();
+ Long favoriteId = dwsWorkspaceService.addFavorite(username, workspaceId, menuApplicationId);
+ return Message.messageToResponse(Message.ok().data("favoriteId", favoriteId));
+ }
+
+ @DELETE
+ @Path("/workspaces/{workspaceId}/favorites/{favouritesId}")
+ public Response deleteFavorite(@Context HttpServletRequest req, @PathParam("workspaceId") Long workspaceId, @PathParam("favouritesId") Long favouritesId) {
+ String username = SecurityFilter.getLoginUsername(req);
+ Long favoriteId = dwsWorkspaceService.deleteFavorite(username, favouritesId);
+ return Message.messageToResponse(Message.ok().data("favoriteId", favoriteId));
+ }
}
diff --git a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/service/DWSWorkspaceService.java b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/service/DWSWorkspaceService.java
index e44a11e0da..c88779a4c3 100644
--- a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/service/DWSWorkspaceService.java
+++ b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/service/DWSWorkspaceService.java
@@ -5,6 +5,7 @@
import com.webank.wedatasphere.dss.server.dto.response.OnestopMenuVo;
import com.webank.wedatasphere.dss.server.entity.DWSWorkspace;
import com.webank.wedatasphere.dss.server.dto.response.WorkspaceDepartmentVo;
+import com.webank.wedatasphere.dss.server.dto.response.*;
import java.util.List;
@@ -27,4 +28,19 @@ public interface DWSWorkspaceService {
List getWorkspaceManagements(Long workspaceId, String username, boolean isChinese);
List getWorkspaceApplications(Long workspaceId, String username, boolean isChinese);
+
+ DWSWorkspace getWorkspacesById(Long id);
+
+ /**
+ * 查询用户收藏的应用,如果是新用户,就在数据库给它插入默认两个收藏:脚本开发与工作流 workflow scriptis
+ * @param workspaceId
+ * @param username
+ * @param isChinese
+ * @return
+ */
+ List getWorkspaceFavorites(Long workspaceId, String username, boolean isChinese);
+
+ Long addFavorite(String username, Long workspaceId, Long menuApplicationId);
+
+ Long deleteFavorite(String username, Long favouritesId);
}
diff --git a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/service/impl/DWSWorkspaceServiceImpl.java b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/service/impl/DWSWorkspaceServiceImpl.java
index 2c270b75d9..5718a01196 100644
--- a/dss-server/src/main/java/com/webank/wedatasphere/dss/server/service/impl/DWSWorkspaceServiceImpl.java
+++ b/dss-server/src/main/java/com/webank/wedatasphere/dss/server/service/impl/DWSWorkspaceServiceImpl.java
@@ -22,9 +22,16 @@ public class DWSWorkspaceServiceImpl implements DWSWorkspaceService {
@Override
public List getWorkspaces() {
+
return workspaceMapper.getWorkspaces();
}
+ @Override
+ public DWSWorkspace getWorkspacesById(Long id) {
+ return workspaceMapper.getWorkspaceById(id);
+ }
+
+
@Override
public Long addWorkspace(String userName, String name, String department, String label, String description) {
DWSWorkspace dwsWorkspace = new DWSWorkspace();
@@ -61,7 +68,7 @@ public List getWorkSpaceDepartments() {
@Override
public List getHomepageDemos(boolean isChinese) {
- List demoMenuVos = isChinese ? workspaceMapper.getHomepageDemoMenusCn():workspaceMapper.getHomepageDemoMenusEn();
+ List demoMenuVos = isChinese ? workspaceMapper.getHomepageDemoMenusCn() : workspaceMapper.getHomepageDemoMenusEn();
for (HomepageDemoMenuVo demoMenuVo : demoMenuVos) {
Long menuId = demoMenuVo.getId();
List demoInstanceVos = isChinese ? workspaceMapper.getHomepageInstancesByMenuIdCn(menuId) : workspaceMapper.getHomepageInstancesByMenuIdEn(menuId);
@@ -99,6 +106,31 @@ public List getWorkspaceApplications(Long workspaceId, String use
return getMenuAppInstances(applicationMenuVos, isChinese);
}
+ @Override
+ public List getWorkspaceFavorites(Long workspaceId, String username, boolean isChinese) {
+ return isChinese ? workspaceMapper.getWorkspaceFavoritesCn(username, workspaceId) : workspaceMapper.getWorkspaceFavoritesEn(username, workspaceId);
+ }
+
+ @Override
+ public Long addFavorite(String username, Long workspaceId, Long menuApplicationId) {
+ DWSFavorite dwsFavorite = new DWSFavorite();
+ dwsFavorite.setUsername(username);
+ dwsFavorite.setWorkspaceId(workspaceId);
+ dwsFavorite.setMenuApplicationId(menuApplicationId);
+ // todo: order will from the front end
+ dwsFavorite.setOrder(1);
+ dwsFavorite.setCreateBy(username);
+ dwsFavorite.setLastUpdateUser(username);
+ workspaceMapper.addFavorite(dwsFavorite);
+ return dwsFavorite.getId();
+ }
+
+ @Override
+ public Long deleteFavorite(String username, Long favouritesId) {
+ workspaceMapper.deleteFavorite(favouritesId);
+ return favouritesId;
+ }
+
private boolean isAdminUser(Long workspaceId, String username) {
DWSWorkspace workspace = workspaceMapper.getWorkspaceById(workspaceId);
return username != null && workspace != null && username.equals(workspace.getCreateBy());
diff --git a/examples/ch3/WordCount.jar b/examples/ch3/WordCount.jar
new file mode 100644
index 0000000000..cbcf5803c4
Binary files /dev/null and b/examples/ch3/WordCount.jar differ
diff --git a/examples/ch3/dept.txt b/examples/ch3/dept.txt
new file mode 100644
index 0000000000..fe587aa7dc
--- /dev/null
+++ b/examples/ch3/dept.txt
@@ -0,0 +1,4 @@
+10 ACCOUNTING 1700
+20 RESEARCH 1800
+30 SALES 1900
+40 OPERATIONS 1700
\ No newline at end of file
diff --git a/examples/ch3/emp.txt b/examples/ch3/emp.txt
new file mode 100644
index 0000000000..f8c77cd409
--- /dev/null
+++ b/examples/ch3/emp.txt
@@ -0,0 +1,14 @@
+7369 SMITH CLERK 7902 1980-12-17 800.00 20
+7499 ALLEN SALESMAN 7698 1981-2-20 1600.00 300.00 30
+7521 WARD SALESMAN 7698 1981-2-22 1250.00 500.00 30
+7566 JONES MANAGER 7839 1981-4-2 2975.00 20
+7654 MARTIN SALESMAN 7698 1981-9-28 1250.00 1400.00 30
+7698 BLAKE MANAGER 7839 1981-5-1 2850.00 30
+7782 CLARK MANAGER 7839 1981-6-9 2450.00 10
+7788 SCOTT ANALYST 7566 1987-4-19 3000.00 20
+7839 KING PRESIDENT 1981-11-17 5000.00 10
+7844 TURNER SALESMAN 7698 1981-9-8 1500.00 0.00 30
+7876 ADAMS CLERK 7788 1987-5-23 1100.00 20
+7900 JAMES CLERK 7698 1981-12-3 950.00 30
+7902 FORD ANALYST 7566 1981-12-3 3000.00 20
+7934 MILLER CLERK 7782 1982-1-23 1300.00 10
\ No newline at end of file
diff --git a/examples/ch3/emp1.txt b/examples/ch3/emp1.txt
new file mode 100644
index 0000000000..92d107a178
--- /dev/null
+++ b/examples/ch3/emp1.txt
@@ -0,0 +1,5 @@
+7369 SMITH CLERK 7902 2020-1-17 800.00 20
+7499 ALLEN SALESMAN 7698 2020-1-20 1600.00 300.00 30
+7521 WARD SALESMAN 7698 2020-1-22 1250.00 500.00 30
+7566 JONES MANAGER 7839 2020-1-2 2975.00 20
+7654 MARTIN SALESMAN 7698 2020-1-28 1250.00 1400.00 30
\ No newline at end of file
diff --git a/examples/ch3/emp2.txt b/examples/ch3/emp2.txt
new file mode 100644
index 0000000000..d00a23876b
--- /dev/null
+++ b/examples/ch3/emp2.txt
@@ -0,0 +1,5 @@
+7698 BLAKE MANAGER 7839 2020-2-1 2850.00 30
+7782 CLARK MANAGER 7839 2020-2-9 2450.00 10
+7788 SCOTT ANALYST 7566 2020-2-19 3000.00 20
+7839 KING PRESIDENT 2020-2-17 5000.00 10
+7844 TURNER SALESMAN 7698 2020-2-8 1500.00 0.00 30
\ No newline at end of file
diff --git a/examples/ch3/emp3.txt b/examples/ch3/emp3.txt
new file mode 100644
index 0000000000..8f62853f27
--- /dev/null
+++ b/examples/ch3/emp3.txt
@@ -0,0 +1,4 @@
+7876 ADAMS CLERK 7788 2020-3-23 1100.00 20
+7900 JAMES CLERK 7698 2020-3-3 950.00 30
+7902 FORD ANALYST 7566 2020-3-3 3000.00 20
+7934 MILLER CLERK 7782 2020-3-23 1300.00 10
\ No newline at end of file
diff --git a/examples/ch3/rename.jar b/examples/ch3/rename.jar
new file mode 100644
index 0000000000..738483a21b
Binary files /dev/null and b/examples/ch3/rename.jar differ
diff --git a/images/zh_CN/chapter3/tests/hive-6.png b/images/zh_CN/chapter3/tests/hive-6.png
new file mode 100644
index 0000000000..f1cb9d6615
Binary files /dev/null and b/images/zh_CN/chapter3/tests/hive-6.png differ
diff --git a/images/zh_CN/chapter3/tests/hive1.png b/images/zh_CN/chapter3/tests/hive1.png
new file mode 100644
index 0000000000..19322869c0
Binary files /dev/null and b/images/zh_CN/chapter3/tests/hive1.png differ
diff --git a/images/zh_CN/chapter3/tests/hive2.png b/images/zh_CN/chapter3/tests/hive2.png
new file mode 100644
index 0000000000..8232e3b46d
Binary files /dev/null and b/images/zh_CN/chapter3/tests/hive2.png differ
diff --git a/images/zh_CN/chapter3/tests/hive3.png b/images/zh_CN/chapter3/tests/hive3.png
new file mode 100644
index 0000000000..523f1e13cc
Binary files /dev/null and b/images/zh_CN/chapter3/tests/hive3.png differ
diff --git a/images/zh_CN/chapter3/tests/hive4.png b/images/zh_CN/chapter3/tests/hive4.png
new file mode 100644
index 0000000000..77e26589e8
Binary files /dev/null and b/images/zh_CN/chapter3/tests/hive4.png differ
diff --git a/images/zh_CN/chapter3/tests/hive5.png b/images/zh_CN/chapter3/tests/hive5.png
new file mode 100644
index 0000000000..f2ecae3019
Binary files /dev/null and b/images/zh_CN/chapter3/tests/hive5.png differ
diff --git a/images/zh_CN/chapter3/tests/hive7.png b/images/zh_CN/chapter3/tests/hive7.png
new file mode 100644
index 0000000000..efe7141071
Binary files /dev/null and b/images/zh_CN/chapter3/tests/hive7.png differ
diff --git a/images/zh_CN/chapter3/tests/home.png b/images/zh_CN/chapter3/tests/home.png
new file mode 100644
index 0000000000..1564c5150f
Binary files /dev/null and b/images/zh_CN/chapter3/tests/home.png differ
diff --git a/images/zh_CN/chapter3/tests/udf-3.png b/images/zh_CN/chapter3/tests/udf-3.png
new file mode 100644
index 0000000000..64bad9b7c4
Binary files /dev/null and b/images/zh_CN/chapter3/tests/udf-3.png differ
diff --git a/images/zh_CN/chapter3/tests/udf1.png b/images/zh_CN/chapter3/tests/udf1.png
new file mode 100644
index 0000000000..0866f38457
Binary files /dev/null and b/images/zh_CN/chapter3/tests/udf1.png differ
diff --git a/images/zh_CN/chapter3/tests/udf2.png b/images/zh_CN/chapter3/tests/udf2.png
new file mode 100644
index 0000000000..8bb046f7b3
Binary files /dev/null and b/images/zh_CN/chapter3/tests/udf2.png differ
diff --git a/web/package.json b/web/package.json
index 95693d3273..5ac9b99f5e 100644
--- a/web/package.json
+++ b/web/package.json
@@ -1,6 +1,6 @@
{
"name": "dataspherestudio",
- "version": "0.5.0",
+ "version": "0.9.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
diff --git a/web/src/js/module/workbench/script/result.vue b/web/src/js/module/workbench/script/result.vue
index b0b6842d10..94b30bdf98 100644
--- a/web/src/js/module/workbench/script/result.vue
+++ b/web/src/js/module/workbench/script/result.vue
@@ -17,9 +17,12 @@
:style="{'height': resultHeight}"
class="text-result-div">