This is an automated email from the ASF dual-hosted git repository.

wuzhiguo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/bigtop-manager.git


The following commit(s) were added to refs/heads/main by this push:
     new 7e10c1b  BIGTOP-4223: Support PostgreSQL for mybatis (#66)
7e10c1b is described below

commit 7e10c1bfb7264d2c585ada454ab876f1edd50ed2
Author: fuxiaofengfu <[email protected]>
AuthorDate: Sat Sep 14 22:43:29 2024 +0800

    BIGTOP-4223: Support PostgreSQL for mybatis (#66)
---
 .../apache/bigtop/manager/dao/enums/DBType.java    |   3 +-
 .../apache/bigtop/manager/dao/sql/SQLBuilder.java  |  80 +++++
 .../mapper/postgresql/ChatMessageMapper.xml        |  36 ++
 .../mapper/postgresql/ChatThreadMapper.xml         |  58 +++
 .../resources/mapper/postgresql/ClusterMapper.xml  |  81 +++++
 .../mapper/postgresql/ComponentMapper.xml          | 109 ++++++
 .../mapper/postgresql/HostComponentMapper.xml      | 222 ++++++++++++
 .../resources/mapper/postgresql/HostMapper.xml     | 111 ++++++
 .../main/resources/mapper/postgresql/JobMapper.xml | 142 ++++++++
 .../mapper/postgresql/PlatformAuthorizedMapper.xml |  45 +++
 .../resources/mapper/postgresql/PlatformMapper.xml |  38 ++
 .../resources/mapper/postgresql/RepoMapper.xml     |  64 ++++
 .../mapper/postgresql/ServiceConfigMapper.xml      | 118 +++++++
 .../resources/mapper/postgresql/ServiceMapper.xml  | 133 +++++++
 .../resources/mapper/postgresql/StackMapper.xml    |  46 +++
 .../resources/mapper/postgresql/StageMapper.xml    |  39 ++
 .../resources/mapper/postgresql/TaskMapper.xml     |  39 ++
 .../resources/mapper/postgresql/UserMapper.xml     |  43 +++
 .../manager/server/command/job/AbstractJob.java    |   4 +
 .../server/command/stage/AbstractStage.java        |   5 +
 .../manager/server/command/task/AbstractTask.java  |   4 +
 .../manager/server/config/MyBatisConfig.java       |   6 +-
 .../main/resources/ddl/PostgreSQL-DDL-CREATE.sql   | 391 +++++++++++++++++++++
 23 files changed, 1814 insertions(+), 3 deletions(-)

diff --git 
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/enums/DBType.java
 
b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/enums/DBType.java
index b2e8bac..111fa66 100644
--- 
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/enums/DBType.java
+++ 
b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/enums/DBType.java
@@ -25,7 +25,8 @@ import java.util.stream.Stream;
 
 @Getter
 public enum DBType {
-    MYSQL("mysql", "MYSQL"),
+    MYSQL("mysql", "MySQL"),
+    POSTGRESQL("postgresql", "PostgreSQL"),
     DM("dm", "DaMeng");
 
     DBType(String code, String desc) {
diff --git 
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/SQLBuilder.java
 
b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/SQLBuilder.java
index ce729c7..8a6d7ba 100644
--- 
a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/SQLBuilder.java
+++ 
b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/SQLBuilder.java
@@ -71,6 +71,25 @@ public class SQLBuilder {
                 }
                 break;
             }
+            case POSTGRESQL: {
+                sql.INSERT_INTO("\"" + tableMetaData.getTableName() + "\"");
+                for (Map.Entry<String, String> entry : 
fieldColumnMap.entrySet()) {
+                    // Ignore primary key
+                    if (Objects.equals(entry.getKey(), 
tableMetaData.getPkProperty())) {
+                        continue;
+                    }
+                    PropertyDescriptor ps = 
BeanUtils.getPropertyDescriptor(entityClass, entry.getKey());
+                    if (ps == null || ps.getReadMethod() == null) {
+                        continue;
+                    }
+                    Object value = 
ReflectionUtils.invokeMethod(ps.getReadMethod(), entity);
+                    if (!ObjectUtils.isEmpty(value)) {
+                        sql.VALUES("\"" + entry.getValue() + "\"", 
getTokenParam(entry.getKey()));
+                    }
+                }
+                break;
+            }
+
             default: {
                 log.error("Unsupported data source");
             }
@@ -105,6 +124,25 @@ public class SQLBuilder {
                 sql.WHERE(getEquals(tableMetaData.getPkColumn(), 
tableMetaData.getPkProperty()));
                 break;
             }
+            case POSTGRESQL: {
+                sql.UPDATE("\"" + tableMetaData.getTableName() + "\"");
+                for (Map.Entry<String, String> entry : 
fieldColumnMap.entrySet()) {
+                    // Ignore primary key
+                    if (Objects.equals(entry.getKey(), 
tableMetaData.getPkProperty())) {
+                        continue;
+                    }
+                    PropertyDescriptor ps = 
BeanUtils.getPropertyDescriptor(entityClass, entry.getKey());
+                    if (ps == null || ps.getReadMethod() == null) {
+                        continue;
+                    }
+                    Object value = 
ReflectionUtils.invokeMethod(ps.getReadMethod(), entity);
+                    if (!ObjectUtils.isEmpty(value)) {
+                        sql.SET("\"" + getEquals(entry.getValue() + "\"", 
entry.getKey()));
+                    }
+                }
+                sql.WHERE(getEquals(tableMetaData.getPkColumn(), 
tableMetaData.getPkProperty()));
+                break;
+            }
             default: {
                 log.error("Unsupported data source");
             }
@@ -123,6 +161,16 @@ public class SQLBuilder {
                 sql.WHERE(tableMetaData.getPkColumn() + " = '" + id + "'");
                 break;
             }
+            case POSTGRESQL: {
+                String baseColumns = tableMetaData.getBaseColumns();
+                if (baseColumns.toLowerCase().contains("user.")) {
+                    baseColumns = baseColumns.replace("user.", "\"user\".");
+                }
+                sql.SELECT(baseColumns);
+                sql.FROM("\"" + tableMetaData.getTableName() + "\"");
+                sql.WHERE(tableMetaData.getPkColumn() + " = " + id);
+                break;
+            }
             default: {
                 log.error("Unsupported data source");
             }
@@ -143,6 +191,17 @@ public class SQLBuilder {
                 sql.WHERE(tableMetaData.getPkColumn() + " in ('" + idsStr + 
"')");
                 break;
             }
+            case POSTGRESQL: {
+                String idsStr = 
ids.stream().map(String::valueOf).collect(Collectors.joining(","));
+                String baseColumns = tableMetaData.getBaseColumns();
+                if (baseColumns.toLowerCase().contains("user.")) {
+                    baseColumns = baseColumns.replace("user.", "\"user\".");
+                }
+                sql.SELECT(baseColumns);
+                sql.FROM("\"" + tableMetaData.getTableName() + "\"");
+                sql.WHERE(tableMetaData.getPkColumn() + " in (" + idsStr + 
")");
+                break;
+            }
             default: {
                 log.error("Unsupported data source");
             }
@@ -155,6 +214,14 @@ public class SQLBuilder {
 
         SQL sql = new SQL();
         switch (DBType.toType(databaseId)) {
+            case POSTGRESQL:
+                String baseColumns = tableMetaData.getBaseColumns();
+                if (baseColumns.toLowerCase().contains("user.")) {
+                    baseColumns = baseColumns.replace("user.", "\"user\".");
+                }
+                sql.SELECT(baseColumns);
+                sql.FROM("\"" + tableMetaData.getTableName() + "\"");
+                break;
             case MYSQL: {
                 sql.SELECT(tableMetaData.getBaseColumns());
                 sql.FROM(tableMetaData.getTableName());
@@ -176,6 +243,11 @@ public class SQLBuilder {
                 sql.WHERE(tableMetaData.getPkColumn() + " = '" + id + "'");
                 break;
             }
+            case POSTGRESQL: {
+                sql.FROM("\"" + tableMetaData.getTableName() + "\"");
+                sql.WHERE(tableMetaData.getPkColumn() + " = " + id);
+                break;
+            }
             default: {
                 log.error("Unsupported data source");
             }
@@ -194,6 +266,12 @@ public class SQLBuilder {
                 sql.WHERE(tableMetaData.getPkColumn() + " in ('" + idsStr + 
"')");
                 break;
             }
+            case POSTGRESQL: {
+                String idsStr = 
ids.stream().map(String::valueOf).collect(Collectors.joining(", "));
+                sql.DELETE_FROM("\"" + tableMetaData.getTableName() + "\"");
+                sql.WHERE(tableMetaData.getPkColumn() + " in (" + idsStr + 
")");
+                break;
+            }
             default: {
                 log.error("Unsupported data source");
             }
@@ -208,6 +286,8 @@ public class SQLBuilder {
         log.info("databaseId: {}", databaseId);
         SQL sql = new SQL();
         switch (DBType.toType(databaseId)) {
+            case POSTGRESQL:
+                tableName = "\"" + tableName + "\"";
             case MYSQL: {
                 sql = mysqlCondition(condition, tableName);
                 break;
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/ChatMessageMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ChatMessageMapper.xml
new file mode 100644
index 0000000..108410b
--- /dev/null
+++ 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ChatMessageMapper.xml
@@ -0,0 +1,36 @@
+<?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.bigtop.manager.dao.repository.ChatMessageDao">
+
+    <select id="findAllByThreadId" 
resultType="org.apache.bigtop.manager.dao.po.ChatMessagePO">
+        SELECT *
+        FROM llm_chat_message
+        WHERE thread_id = #{threadId}
+    </select>
+
+    <delete id="deleteByThreadId">
+        DELETE FROM llm_chat_message
+        WHERE thread_id = #{threadId}
+    </delete>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/ChatThreadMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ChatThreadMapper.xml
new file mode 100644
index 0000000..5ecd9a2
--- /dev/null
+++ 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ChatThreadMapper.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.bigtop.manager.dao.repository.ChatThreadDao">
+    <sql id="baseColumns">
+        id, user_id, platform_id, model
+    </sql>
+
+    <resultMap id="ChatThreadResultMap" 
type="org.apache.bigtop.manager.dao.po.ChatThreadPO">
+        <result property="threadInfo" column="thread_info" 
typeHandler="org.apache.bigtop.manager.dao.handler.JsonTypeHandler"/>
+    </resultMap>
+
+    <select id="findAllByUserId" 
resultType="org.apache.bigtop.manager.dao.po.ChatThreadPO">
+        SELECT *
+        FROM llm_chat_thread
+        WHERE user_id = #{userId}
+    </select>
+
+    <select id="findAllByPlatformAuthorizedIdAndUserId" 
resultType="org.apache.bigtop.manager.dao.po.ChatThreadPO">
+        SELECT *
+        FROM llm_chat_thread
+        WHERE platform_id = #{platformId} AND user_id = #{userId}
+    </select>
+
+    <select id="findByThreadId" resultMap="ChatThreadResultMap">
+        SELECT * FROM llm_chat_thread WHERE id = #{id}
+    </select>
+
+    <insert id="saveWithThreadInfo" 
parameterType="org.apache.bigtop.manager.dao.po.ChatThreadPO" 
useGeneratedKeys="true" keyProperty="id">
+        INSERT INTO llm_chat_thread (platform_id, user_id, model, thread_info)
+        VALUES (#{platformId}, #{userId}, #{model}, #{threadInfo, 
typeHandler=org.apache.bigtop.manager.dao.handler.JsonTypeHandler})
+            ON DUPLICATE KEY UPDATE
+            platform_id = VALUES(platform_id),
+            user_id = VALUES(user_id),
+            model = VALUES(model),
+            thread_info = VALUES(thread_info)
+    </insert>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/ClusterMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ClusterMapper.xml
new file mode 100644
index 0000000..75caa42
--- /dev/null
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ClusterMapper.xml
@@ -0,0 +1,81 @@
+<?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.bigtop.manager.dao.repository.ClusterDao">
+
+    <sql id="baseColumns">
+        id, cluster_name, cluster_type, root, user_group, packages, 
repo_template, state, selected, stack_id
+    </sql>
+    <sql id="baseColumnsV2">
+        ${alias}.id, ${alias}.cluster_name, ${alias}.cluster_type, 
${alias}.root, ${alias}.user_group, ${alias}.packages, ${alias}.repo_template, 
${alias}.state, ${alias}.selected, ${alias}.stack_id
+    </sql>
+
+    <select id="findByClusterName" 
resultType="org.apache.bigtop.manager.dao.po.ClusterPO">
+        select
+        <include refid="baseColumns"/>
+        from
+        cluster
+        <where>
+            <if test="clusterName!=null">
+                cluster_name=#{clusterName}
+            </if>
+        </where>
+        limit 1
+    </select>
+
+    <select id="count" resultType="java.lang.Integer">
+        select count(*) from cluster
+    </select>
+
+    <select id="findByIdJoin"
+            resultType="org.apache.bigtop.manager.dao.po.ClusterPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="r"/>
+        </include>
+        , s.stack_name, s.stack_version
+        from
+        cluster r
+        inner join stack s
+        on r.stack_id = s.id
+        <where>
+            <if test="clusterId!=0">
+                r.id=#{clusterId}
+            </if>
+        </where>
+    </select>
+
+    <select id="findAllByJoin"
+            resultType="org.apache.bigtop.manager.dao.po.ClusterPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="r"/>
+        </include>
+        , s.stack_name, s.stack_version
+        from
+        cluster r
+        inner join stack s
+        on r.stack_id = s.id
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/ComponentMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ComponentMapper.xml
new file mode 100644
index 0000000..cc1c93d
--- /dev/null
+++ 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ComponentMapper.xml
@@ -0,0 +1,109 @@
+<?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.bigtop.manager.dao.repository.ComponentDao">
+
+    <sql id="baseColumns">
+        id, component_name, display_name, command_script, custom_commands, 
category, quick_link, cardinality, service_id, cluster_id
+    </sql>
+    <sql id="baseColumnsV2">
+        ${alias}.id, ${alias}.component_name, ${alias}.display_name, 
${alias}.command_script, ${alias}.custom_commands, ${alias}.category, 
${alias}.quick_link, ${alias}.cardinality, ${alias}.service_id, 
${alias}.cluster_id
+    </sql>
+
+    <select id="findByClusterIdAndComponentName"
+            resultType="org.apache.bigtop.manager.dao.po.ComponentPO">
+        select
+        <include refid="baseColumns"/>
+        from
+        component
+        <where>
+            <if test="componentName != null">
+                component_name = #{componentName}
+            </if>
+            <if test="clusterId != 0">
+                and cluster_id = #{clusterId}
+            </if>
+        </where>
+    </select>
+
+    <select id="findAllByClusterId"
+            resultType="org.apache.bigtop.manager.dao.po.ComponentPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="r"/>
+        </include>
+        ,c.cluster_name, s.service_name
+        from
+        component r
+        inner join cluster c
+        on r.cluster_id = c.id
+        inner join service s
+        on r.service_id = s.id
+        <where>
+            <if test="clusterId != 0">
+                r.cluster_id = #{clusterId}
+            </if>
+        </where>
+    </select>
+
+    <select id="findAllByClusterIdAndServiceServiceNameIn"
+            resultType="org.apache.bigtop.manager.dao.po.ComponentPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="r"/>
+        </include>
+        from
+        (select * from component
+        <where>
+            <if test="clusterId != 0">
+                cluster_id = #{clusterId}
+            </if>
+        </where>
+        ) r
+        inner join (select * from service
+        <where>
+            <if test="serviceNames != null">
+                service_name in
+                <foreach collection="serviceNames" item="serviceName" 
index="index" open="(" close=")" separator=",">
+                    #{serviceName}
+                </foreach>
+            </if>
+        </where>
+        ) s
+        on r.service_id = s.id and r.cluster_id = s.cluster_id
+    </select>
+
+    <select id="findAllJoinService"
+            resultType="org.apache.bigtop.manager.dao.po.ComponentPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="r"/>
+        </include>
+            , s.service_name
+        from
+        component r
+        inner join service s
+        on r.service_id = s.id and r.cluster_id = s.cluster_id
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/HostComponentMapper.xml
 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/HostComponentMapper.xml
new file mode 100644
index 0000000..214dbc9
--- /dev/null
+++ 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/HostComponentMapper.xml
@@ -0,0 +1,222 @@
+<?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.bigtop.manager.dao.repository.HostComponentDao">
+
+    <sql id="baseColumns">
+        id, state, host_id, component_id
+    </sql>
+    <sql id="baseColumnsV2">
+        ${alias}.id, ${alias}.state, ${alias}.host_id, ${alias}.component_id
+    </sql>
+
+    <select id="findAllByClusterIdAndComponentName"
+            resultType="org.apache.bigtop.manager.dao.po.HostComponentPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="hc"/>
+        </include>
+        from
+        host_component hc
+        inner join (select * from component
+        <where>
+            <if test="componentName != null">
+                component_name = #{componentName}
+            </if>
+            <if test="clusterId != 0">
+                and cluster_id = #{clusterId}
+            </if>
+        </where>
+        ) c
+        on hc.component_id = c.id
+    </select>
+
+    <select id="findAllByClusterIdAndServiceId"
+            resultType="org.apache.bigtop.manager.dao.po.HostComponentPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="hc"/>
+        </include>
+        , c.service_id, c.component_name, c.display_name, c.category, 
s.service_name, clus.cluster_name, ht.hostname
+        from
+        host_component hc
+        inner join (select * from component
+        <where>
+            <if test="clusterId != 0">
+                cluster_id = #{clusterId}
+            </if>
+            <if test="serviceId != 0">
+                and service_id = #{serviceId}
+            </if>
+        </where>
+        ) c
+        on hc.component_id = c.id
+        inner join service s
+        on c.service_id = s.id
+        inner join cluster clus
+        on c.cluster_id = clus.id
+        inner join host ht
+        on hc.host_id = ht.id
+    </select>
+
+    <select id="findByClusterIdAndComponentNameAndHostname"
+            resultType="org.apache.bigtop.manager.dao.po.HostComponentPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="hc"/>
+        </include>
+        from
+        host_component hc
+        inner join (select * from host
+        <where>
+            <if test="hostname != null">
+                hostname = #{hostname}
+            </if>
+            <if test="clusterId != 0">
+                and cluster_id = #{clusterId}
+            </if>
+        </where>
+        ) h
+        on hc.host_id = h.id
+        inner join (select * from component
+        <where>
+            <if test="componentName != null">
+                component_name = #{componentName}
+            </if>
+        </where>
+        ) c
+        on hc.component_id = c.id and h.cluster_id = c.cluster_id
+        limit 1
+    </select>
+
+    <select id="findAllByClusterIdAndComponentNameAndHostnameIn"
+            resultType="org.apache.bigtop.manager.dao.po.HostComponentPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="hc"/>
+        </include>
+        , c.component_name, h.hostname
+        from
+        host_component hc
+        inner join (select * from host
+        <where>
+            <if test="hostnames != null">
+                hostname in
+                <foreach collection="hostnames" item="hostname" index="index" 
open="(" close=")" separator=",">
+                    #{hostname}
+                </foreach>
+            </if>
+            <if test="clusterId != 0">
+                and cluster_id = #{clusterId}
+            </if>
+        </where>
+        ) h
+        on hc.host_id = h.id
+        inner join (select * from component
+        <where>
+            <if test="componentName != null">
+                component_name = #{componentName}
+            </if>
+        </where>
+        ) c
+        on hc.component_id = c.id and h.cluster_id = c.cluster_id
+    </select>
+
+    <select id="findAllByClusterIdAndHostId"
+            resultType="org.apache.bigtop.manager.dao.po.HostComponentPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="hc"/>
+        </include>
+        , c.service_id, c.component_name, c.display_name, c.category, 
s.service_name, clus.cluster_name, ht.hostname
+        from
+        host_component hc
+        inner join component c
+        on hc.component_id = c.id
+        inner join service s
+        on c.service_id = s.id
+        inner join cluster clus
+        on c.cluster_id = clus.id
+        inner join (select * from host
+        <where>
+            <if test="clusterId != 0">
+                cluster_id = #{clusterId}
+            </if>
+            <if test="hostId != 0">
+                and id = #{hostId}
+            </if>
+        </where>
+        ) ht
+        on hc.host_id = ht.id
+    </select>
+
+    <select id="findAllByClusterId"
+            resultType="org.apache.bigtop.manager.dao.po.HostComponentPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="hc"/>
+        </include>
+        , c.service_id, c.component_name, c.display_name, c.category, 
s.service_name, clus.cluster_name, ht.hostname
+        from
+        host_component hc
+        inner join (select * from component
+        <where>
+            <if test="clusterId != 0">
+                cluster_id = #{clusterId}
+            </if>
+        </where>
+        ) c
+        on hc.component_id = c.id
+        inner join service s
+        on c.service_id = s.id
+        inner join cluster clus
+        on c.cluster_id = clus.id
+        inner join host ht
+        on hc.host_id = ht.id
+    </select>
+
+    <select id="findAllJoin"
+            resultType="org.apache.bigtop.manager.dao.po.HostComponentPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="hc"/>
+        </include>
+        
,st.stack_name,st.stack_version,ser.service_name,ser.service_user,clu.root,c.component_name,c.command_script,hst.hostname
+        from
+        host_component hc
+        inner join host hst
+        on hc.host_id = hst.id
+        inner join
+        component c
+        on hc.component_id = c.id
+        inner join
+        cluster clu
+        on c.cluster_id = clu.id
+        inner join
+        service ser
+        on c.service_id=ser.id and c.cluster_id = ser.cluster_id
+        inner join stack st
+        on clu.stack_id = st.id
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/HostMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/HostMapper.xml
new file mode 100644
index 0000000..4c475a7
--- /dev/null
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/HostMapper.xml
@@ -0,0 +1,111 @@
+<?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.bigtop.manager.dao.repository.HostDao">
+
+    <sql id="baseColumns">
+        id, hostname, ipv4, ipv6, os, arch, available_processors, 
free_memory_size, total_memory_size, free_disk, total_disk, state, cluster_id
+    </sql>
+
+    <sql id="baseColumnsV2">
+        ${alias}.id,  ${alias}.hostname,  ${alias}.ipv4,  ${alias}.ipv6,  
${alias}.os,  ${alias}.arch,  ${alias}.available_processors,  
${alias}.free_memory_size,  ${alias}.total_memory_size,  ${alias}.free_disk,  
${alias}.total_disk,  ${alias}.state,  ${alias}.cluster_id
+    </sql>
+
+    <select id="findByHostname" 
resultType="org.apache.bigtop.manager.dao.po.HostPO">
+        select
+        <include refid="baseColumns"/>
+        from
+        host
+        <where>
+            <if test="hostname != null">
+                hostname = #{hostname}
+            </if>
+        </where>
+        limit 1
+    </select>
+
+    <select id="findByIdJoin" 
resultType="org.apache.bigtop.manager.dao.po.HostPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="h"/>
+        </include>
+        ,clus.cluster_name
+        from
+        (select * from host
+        <where>
+            <if test="id != 0">
+                id = #{id}
+            </if>
+        </where>
+        ) h
+        inner join
+        cluster clus
+        on h.cluster_id = clus.id
+        limit 1
+    </select>
+
+    <select id="findAllByClusterId" parameterType="java.lang.Long"
+            resultType="org.apache.bigtop.manager.dao.po.HostPO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="h"/>
+        </include>
+        ,clus.cluster_name
+        from
+        host h
+        inner join
+        (select * from cluster
+        <where>
+            <if test="clusterId != 0">
+                id = #{clusterId}
+            </if>
+        </where>
+        ) clus
+        on h.cluster_id = clus.id
+    </select>
+
+    <select id="findAllByHostnameIn"
+            resultType="org.apache.bigtop.manager.dao.po.HostPO">
+        select
+        <include refid="baseColumns"/>
+        from
+        host
+        <where>
+            <if test="hostnames != null and hostnames.size() > 0">
+                hostname in
+                <foreach collection="hostnames" item="hostname" index="index" 
open="(" close=")" separator=", ">
+                    #{hostname}
+                </foreach>
+            </if>
+        </where>
+    </select>
+
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id" 
keyColumn="id">
+        insert into host (hostname, ipv4, ipv6, os, arch, 
available_processors, free_memory_size, total_memory_size, free_disk, 
total_disk, state, cluster_id, create_by, update_by, create_time, update_time)
+        values
+        <foreach collection='hosts' item='host' separator=','>
+            (#{host.hostname}, #{host.ipv4}, #{host.ipv6}, #{host.os}, 
#{host.arch}, #{host.availableProcessors}, #{host.freeMemorySize}, 
#{host.totalMemorySize}, #{host.freeDisk}, #{host.totalDisk}, #{host.state}, 
#{host.clusterId} 
,#{host.createBy},#{host.updateBy},#{host.createTime},#{host.updateTime})
+        </foreach>
+    </insert>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/JobMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/JobMapper.xml
new file mode 100644
index 0000000..7805bba
--- /dev/null
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/JobMapper.xml
@@ -0,0 +1,142 @@
+<?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.bigtop.manager.dao.repository.JobDao">
+
+    <sql id="baseColumns">
+        id, state, name, context, cluster_id, create_time, update_time
+    </sql>
+
+    <sql id="baseColumnsV2">
+        ${alias}.id, ${alias}.state, ${alias}.name, ${alias}.context, 
${alias}.cluster_id, ${alias}.create_time, ${alias}.update_time
+    </sql>
+
+    <resultMap id="jobMap" type="org.apache.bigtop.manager.dao.po.JobPO">
+        <id column="id" property="id"/>
+        <result column="state" property="state"/>
+        <result column="name" property="name"/>
+        <result column="context" property="context"/>
+        <result column="cluster_id" property="clusterId"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_time" property="updateTime"/>
+        <collection property="stages" 
ofType="org.apache.bigtop.manager.dao.po.StagePO">
+            <id column="s_id" property="id"/>
+            <result column="s_state" property="state"/>
+            <result column="s_name" property="name"/>
+            <result column="order" property="order"/>
+            <result column="service_name" property="serviceName"/>
+            <result column="component_name" property="componentName"/>
+            <result column="cluster_id" property="clusterId"/>
+            <result column="job_id" property="jobId"/>
+            <result column="create_time" property="createTime"/>
+            <result column="update_time" property="updateTime"/>
+            <collection property="tasks" 
ofType="org.apache.bigtop.manager.dao.po.TaskPO">
+                <id column="t_id" property="id"/>
+                <result column="state" property="state"/>
+                <result column="t_name" property="name"/>
+                <result column="t_state" property="state"/>
+                <result column="service_name" property="serviceName"/>
+                <result column="component_name" property="componentName"/>
+                <result column="command" property="command"/>
+                <result column="custom_command" property="customCommand"/>
+                <result column="hostname" property="hostname"/>
+                <result column="stack_name" property="stackName"/>
+                <result column="stack_version" property="stackVersion"/>
+                <result column="service_user" property="serviceUser"/>
+                <result column="content" property="content"/>
+                <result column="stage_id" property="stageId"/>
+                <result column="job_id" property="jobId"/>
+                <result column="cluster_id" property="clusterId"/>
+                <result column="create_time" property="createTime"/>
+                <result column="update_time" property="updateTime"/>
+            </collection>
+        </collection>
+    </resultMap>
+
+    <select id="findAllByIdsJoin" parameterType="java.lang.Long" 
resultMap="jobMap">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="h"/>
+        </include>
+        , st.id as s_id, st.name as s_name, st.state as s_state, st.order
+        , tk.id as t_id, tk.name as t_name, tk.state as t_state, tk.hostname
+        from
+        (select * from job
+        <where>
+            <if test="ids != null">
+                id in
+                <foreach collection="ids" item="id" index="index" open="(" 
close=")" separator=",">
+                    #{id}
+                </foreach>
+            </if>
+        </where>
+        ) h
+        inner join stage st
+        on h.id = st.job_id
+        inner join task tk
+        on tk.job_id = h.id and st.id = tk.stage_id
+        order by h.id desc
+    </select>
+
+    <select id="findByIdJoin" parameterType="java.lang.Long" 
resultMap="jobMap">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="h"/>
+        </include>
+        , st.id as s_id, st.name as s_name, st.state as s_state, st.order
+        , tk.id as t_id, tk.name as t_name, tk.state as t_state, tk.hostname
+        from
+        (select * from job
+        <where>
+            <if test="id != 0">
+                id = #{id}
+            </if>
+        </where>
+        ) h
+        inner join stage st
+        on h.id = st.job_id
+        inner join task tk
+        on tk.job_id = h.id and st.id = tk.stage_id
+    </select>
+
+    <select id="findAllByClusterId" parameterType="java.lang.Long" 
resultType="org.apache.bigtop.manager.dao.po.JobPO">
+        select
+        <include refid="baseColumns"/>
+        from
+        job
+        <where>
+            <if test="clusterId != 0">
+                cluster_id = #{clusterId}
+            </if>
+        </where>
+    </select>
+
+    <select id="findAllByClusterIsNull"
+            resultType="org.apache.bigtop.manager.dao.po.JobPO">
+        select
+        <include refid="baseColumns"/>
+        from
+        job where cluster_id is null
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/PlatformAuthorizedMapper.xml
 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/PlatformAuthorizedMapper.xml
new file mode 100644
index 0000000..f065a4c
--- /dev/null
+++ 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/PlatformAuthorizedMapper.xml
@@ -0,0 +1,45 @@
+<?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.bigtop.manager.dao.repository.PlatformAuthorizedDao">
+
+    <sql id="baseColumns">
+        id, credentials, platfotrm_id
+    </sql>
+
+    <resultMap id="PlatformAuthorizedResultMap" 
type="org.apache.bigtop.manager.dao.po.PlatformAuthorizedPO">
+        <result property="credentials" column="credentials" 
typeHandler="org.apache.bigtop.manager.dao.handler.JsonTypeHandler"/>
+    </resultMap>
+
+    <select id="findByPlatformId" resultMap="PlatformAuthorizedResultMap">
+        SELECT * FROM llm_platform_authorized WHERE id = #{id}
+    </select>
+
+    <insert id="saveWithCredentials" 
parameterType="org.apache.bigtop.manager.dao.po.PlatformAuthorizedPO" 
useGeneratedKeys="true" keyProperty="id">
+        INSERT INTO llm_platform_authorized (platform_id, credentials)
+        VALUES (#{platformId}, #{credentials, 
typeHandler=org.apache.bigtop.manager.dao.handler.JsonTypeHandler})
+            ON DUPLICATE KEY UPDATE
+                                 platform_id = VALUES(platform_id),
+                                 credentials = VALUES(credentials)
+    </insert>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/PlatformMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/PlatformMapper.xml
new file mode 100644
index 0000000..885ae6d
--- /dev/null
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/PlatformMapper.xml
@@ -0,0 +1,38 @@
+<?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.bigtop.manager.dao.repository.PlatformDao">
+
+    <sql id="baseColumns">
+        "id", "name", "credential", "support_models"
+    </sql>
+
+    <!-- Define the resultMap with the custom typeHandler for the credential 
column -->
+    <resultMap id="PlatformResultMap" 
type="org.apache.bigtop.manager.dao.po.PlatformPO">
+        <result property="credential" column="credential" 
typeHandler="org.apache.bigtop.manager.dao.handler.JsonTypeHandler"/>
+    </resultMap>
+
+    <select id="findByPlatformId" resultMap="PlatformResultMap">
+        SELECT * FROM llm_platform WHERE id = #{id}
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/RepoMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/RepoMapper.xml
new file mode 100644
index 0000000..cee5e86
--- /dev/null
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/RepoMapper.xml
@@ -0,0 +1,64 @@
+<?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.bigtop.manager.dao.repository.RepoDao">
+
+    <sql id="baseColumns">
+        id, base_url, os, arch, repo_id, repo_name, repo_type, cluster_id
+    </sql>
+
+    <select id="findByRepoName" 
resultType="org.apache.bigtop.manager.dao.po.RepoPO">
+        select
+        <include refid="baseColumns"/>
+        from
+        repo
+        <where>
+            <if test="repoName!=null">
+                repo_name=#{repoName}
+            </if>
+        </where>
+        limit 1
+    </select>
+
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id" 
keyColumn="id">
+        insert into repo (base_url, os, arch, repo_id, repo_name, repo_type, 
cluster_id, create_by, update_by, create_time, update_time)
+        values
+        <foreach collection='clusters' item='cluster' separator=','>
+            
(#{cluster.baseUrl},#{cluster.os},#{cluster.arch},#{cluster.repoId},#{cluster.repoName},#{cluster.repoType},#{cluster.clusterId},#{cluster.createBy},#{cluster.updateBy},#{cluster.createTime},#{cluster.updateTime})
+        </foreach>
+    </insert>
+
+    <select id="findAllByClusterId" parameterType="java.lang.Long"
+            resultType="org.apache.bigtop.manager.dao.po.RepoPO">
+        select
+        <include refid="baseColumns"/>
+        from
+        repo
+        <where>
+            <if test="clusterId != 0">
+                cluster_id = #{clusterId}
+            </if>
+        </where>
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/ServiceConfigMapper.xml
 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ServiceConfigMapper.xml
new file mode 100644
index 0000000..e40c4f9
--- /dev/null
+++ 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ServiceConfigMapper.xml
@@ -0,0 +1,118 @@
+<?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.bigtop.manager.dao.repository.ServiceConfigDao">
+
+    <sql id="baseColumns">
+        id, config_desc, version, selected, service_id, cluster_id, 
create_time, update_time
+    </sql>
+
+    <sql id="baseColumnsV2">
+        ${alias}.id, ${alias}.config_desc, ${alias}.version, 
${alias}.selected, ${alias}.service_id, ${alias}.cluster_id, 
${alias}.create_time, ${alias}.update_time
+    </sql>
+
+    <resultMap id="serviceConfigMap" 
type="org.apache.bigtop.manager.dao.po.ServiceConfigPO">
+        <id column="id" property="id"/>
+        <result column="config_desc" property="configDesc"/>
+        <result column="version" property="version"/>
+        <result column="selected" property="selected"/>
+        <result column="service_id" property="serviceId"/>
+        <result column="cluster_id" property="clusterId"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="service_name" property="serviceName"/>
+        <collection property="configs" 
ofType="org.apache.bigtop.manager.dao.po.TypeConfigPO">
+            <id column="tc_id" property="id"/>
+            <result column="type_name" property="typeName"/>
+            <result column="properties_json" property="propertiesJson"/>
+        </collection>
+    </resultMap>
+
+    <select id="findAllByClusterId" parameterType="java.lang.Long" 
resultMap="serviceConfigMap">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="r"/>
+        </include>
+        , s.service_name, tc.type_name, tc.properties_json, tc.id as tc_id
+        from
+        (select * from service_config
+        <where>
+            <if test="clusterId != 0">
+                cluster_id = #{clusterId}
+            </if>
+        </where>
+        ) r
+        inner join service s
+        on r.service_id = s.id
+        inner join type_config tc
+        on r.id = tc.service_config_id
+        order by version desc
+    </select>
+
+    <select id="findByClusterIdAndServiceIdAndSelectedIsTrue" 
resultMap="serviceConfigMap">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="r"/>
+        </include>
+        , s.service_name, tc.type_name, tc.properties_json
+        from
+        (select * from service_config
+        <where>
+            selected is true
+            <if test="clusterId != 0">
+                and cluster_id = #{clusterId}
+            </if>
+            <if test="serviceId != 0">
+                and service_id = #{serviceId}
+            </if>
+        </where>
+        ) r
+        inner join service s
+        on r.service_id = s.id
+        inner join type_config tc
+        on r.id = tc.service_config_id
+        limit 1
+    </select>
+
+    <select id="findAllByClusterIdAndSelectedIsTrue" 
resultMap="serviceConfigMap">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="r"/>
+        </include>
+        , s.service_name, tc.type_name, tc.properties_json
+        from
+        (select * from service_config
+        <where>
+        selected is true
+            <if test="clusterId != 0">
+                and cluster_id = #{clusterId}
+            </if>
+        </where>
+        ) r
+        inner join service s
+        on r.service_id = s.id
+        inner join type_config tc
+        on r.id = tc.service_config_id
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/ServiceMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ServiceMapper.xml
new file mode 100644
index 0000000..5a40565
--- /dev/null
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/ServiceMapper.xml
@@ -0,0 +1,133 @@
+<?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.bigtop.manager.dao.repository.ServiceDao">
+
+    <sql id="baseColumns">
+        id, service_name, display_name, service_desc, service_version, 
package_specifics, service_user, required_services, cluster_id
+    </sql>
+
+    <sql id="baseColumnsV2">
+        ${alias}.id, ${alias}.service_name, ${alias}.display_name, 
${alias}.service_desc, ${alias}.service_version, ${alias}.package_specifics, 
${alias}.service_user, ${alias}.required_services, ${alias}.cluster_id
+    </sql>
+
+    <resultMap id="serviceMap" 
type="org.apache.bigtop.manager.dao.po.ServicePO">
+        <id column="id" property="id"/>
+        <result column="service_name" property="serviceName"/>
+        <result column="display_name" property="displayName"/>
+        <result column="service_desc" property="serviceDesc"/>
+        <result column="service_version" property="serviceVersion"/>
+        <result column="package_specifics" property="packageSpecifics"/>
+        <result column="service_user" property="serviceUser"/>
+        <result column="required_services" property="requiredServices"/>
+        <result column="cluster_id" property="clusterId"/>
+        <result column="cluster_name" property="clusterName"/>
+        <result column="user_group" property="userGroup"/>
+        <collection property="components" 
ofType="org.apache.bigtop.manager.dao.po.ComponentPO">
+            <id column="cid" property="id"/>
+            <result column="component_name" property="componentName"/>
+            <result column="category" property="category"/>
+            <result column="quick_link" property="quickLink"/>
+            <result column="service_id" property="serviceId"/>
+            <result column="cluster_id" property="clusterId"/>
+        </collection>
+    </resultMap>
+
+    <select id="findAllByClusterId" parameterType="java.lang.Long" 
resultMap="serviceMap">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="s"/>
+        </include>
+        , clus.cluster_name, clus.user_group, c.component_name, c.category, 
c.quick_link, c.id as cid
+        from
+        (select * from service
+        <where>
+            <if test="clusterId != 0">
+                cluster_id = #{clusterId}
+            </if>
+        </where>
+        ) s
+        inner join
+        cluster clus
+        on s.cluster_id = clus.id
+        inner join
+        component c
+        on c.service_id = s.id
+    </select>
+
+    <select id="findByIdJoin" parameterType="java.lang.Long"
+            resultType="org.apache.bigtop.manager.dao.po.ServicePO">
+        select
+        <include refid="baseColumnsV2">
+            <property name="alias" value="s"/>
+        </include>
+        , clus.cluster_name, clus.user_group
+        from
+        (select * from service
+        <where>
+            <if test="id != 0">
+                id = #{id}
+            </if>
+        </where>
+        ) s
+        inner join
+        cluster clus
+        on s.cluster_id = clus.id
+    </select>
+
+    <select id="findByClusterIdAndServiceName"
+            resultType="org.apache.bigtop.manager.dao.po.ServicePO">
+        select
+        <include refid="baseColumns"/>
+        from
+        service
+        <where>
+            <if test="clusterId != 0">
+                cluster_id = #{clusterId}
+            </if>
+            <if test="serviceName != null">
+                and service_name = #{serviceName}
+            </if>
+        </where>
+    </select>
+
+    <select id="findByClusterIdAndServiceNameIn"
+            resultType="org.apache.bigtop.manager.dao.po.ServicePO">
+        select
+        <include refid="baseColumns"/>
+        from
+        service
+        <where>
+            <if test="clusterId != 0">
+                cluster_id = #{clusterId}
+            </if>
+            <if test="serviceNames != null and serviceNames.size() > 0">
+                and service_name = in
+                <foreach collection="serviceNames" item="serviceName" 
index="index" open="(" close=")" separator=", ">
+                    #{serviceName}
+                </foreach>
+            </if>
+        </where>
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/StackMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/StackMapper.xml
new file mode 100644
index 0000000..d9da21b
--- /dev/null
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/StackMapper.xml
@@ -0,0 +1,46 @@
+<?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.bigtop.manager.dao.repository.StackDao">
+
+    <sql id="baseColumns">
+        "id", "stack_name", "stack_version"
+    </sql>
+
+    <select id="findByStackNameAndStackVersion" 
resultType="org.apache.bigtop.manager.dao.po.StackPO">
+        select
+        <include refid="baseColumns"/>
+        from
+        stack
+        <where>
+            <if test="stackName!=null">
+                stack_name=#{stackName}
+            </if>
+            <if test="stackVersion!=null">
+                and stack_version=#{stackVersion}
+            </if>
+        </where>
+        limit 1
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/StageMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/StageMapper.xml
new file mode 100644
index 0000000..35d6ac5
--- /dev/null
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/StageMapper.xml
@@ -0,0 +1,39 @@
+<?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.bigtop.manager.dao.repository.StageDao">
+
+    <update id="updateStateByIds" parameterType="java.util.List">
+        UPDATE "stage"
+        SET "state" = CASE
+        <foreach collection="stages" item="item" index="index">
+            WHEN id = #{item.id} THEN #{item.state}
+        </foreach>
+        END
+        WHERE "id" IN
+        <foreach collection="stages" index="index" item="item" open="(" 
separator="," close=")">
+            #{item.id}
+        </foreach>
+    </update>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/TaskMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/TaskMapper.xml
new file mode 100644
index 0000000..a746f0d
--- /dev/null
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/TaskMapper.xml
@@ -0,0 +1,39 @@
+<?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.bigtop.manager.dao.repository.TaskDao">
+
+    <update id="updateStateByIds" parameterType="java.util.List">
+        UPDATE task
+        SET "state" = CASE
+        <foreach collection="tasks" item="item" index="index">
+            WHEN id = #{item.id} THEN #{item.state}
+        </foreach>
+        END
+        WHERE id IN
+        <foreach collection="tasks" index="index" item="item" open="(" 
separator="," close=")">
+            #{item.id}
+        </foreach>
+    </update>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-dao/src/main/resources/mapper/postgresql/UserMapper.xml 
b/bigtop-manager-dao/src/main/resources/mapper/postgresql/UserMapper.xml
new file mode 100644
index 0000000..24a32e2
--- /dev/null
+++ b/bigtop-manager-dao/src/main/resources/mapper/postgresql/UserMapper.xml
@@ -0,0 +1,43 @@
+<?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.bigtop.manager.dao.repository.UserDao">
+
+    <sql id="baseColumns">
+        "id", "username", "password", "nickname", "status"
+    </sql>
+
+    <select id="findByUsername" 
resultType="org.apache.bigtop.manager.dao.po.UserPO">
+        select
+        <include refid="baseColumns"/>
+        from
+        "user"
+        <where>
+            <if test="username!=null">
+                username=#{username}
+            </if>
+        </where>
+        limit 1
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
index 902311b..42f1248 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
@@ -33,10 +33,13 @@ import org.apache.bigtop.manager.server.command.stage.Stage;
 import org.apache.bigtop.manager.server.command.task.Task;
 import org.apache.bigtop.manager.server.holder.SpringContextHolder;
 
+import lombok.extern.slf4j.Slf4j;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.LinkedBlockingQueue;
 
+@Slf4j
 public abstract class AbstractJob implements Job {
 
     protected StackDao stackDao;
@@ -106,6 +109,7 @@ public abstract class AbstractJob implements Job {
                 }
             }
         } catch (Exception e) {
+            log.error(e.getMessage(), e);
             success = false;
         }
 
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java
index 2081f7c..f0a7567 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java
@@ -25,10 +25,13 @@ import org.apache.bigtop.manager.dao.repository.StageDao;
 import org.apache.bigtop.manager.server.command.task.Task;
 import org.apache.bigtop.manager.server.holder.SpringContextHolder;
 
+import lombok.extern.slf4j.Slf4j;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 
+@Slf4j
 public abstract class AbstractStage implements Stage {
 
     protected StageDao stageDao;
@@ -93,6 +96,7 @@ public abstract class AbstractStage implements Stage {
                         try {
                             return future.get();
                         } catch (Exception e) {
+                            log.error("stage failed,", e);
                             return false;
                         }
                     })
@@ -100,6 +104,7 @@ public abstract class AbstractStage implements Stage {
 
             allTaskSuccess = 
taskResults.stream().allMatch(Boolean::booleanValue);
         } catch (Exception e) {
+            log.error("stage failed", e);
             allTaskSuccess = false;
         }
 
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/task/AbstractTask.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/task/AbstractTask.java
index fc0871a..41f840c 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/task/AbstractTask.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/task/AbstractTask.java
@@ -31,6 +31,9 @@ import org.apache.bigtop.manager.grpc.utils.ProtobufUtil;
 import org.apache.bigtop.manager.server.grpc.GrpcClient;
 import org.apache.bigtop.manager.server.holder.SpringContextHolder;
 
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
 public abstract class AbstractTask implements Task {
 
     protected TaskDao taskDao;
@@ -85,6 +88,7 @@ public abstract class AbstractTask implements Task {
 
             taskSuccess = reply != null && reply.getCode() == 
MessageConstants.SUCCESS_CODE;
         } catch (Exception e) {
+            log.error("task failed", e);
             taskSuccess = false;
         }
 
diff --git 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/config/MyBatisConfig.java
 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/config/MyBatisConfig.java
index 17a3bda..b9b58f3 100644
--- 
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/config/MyBatisConfig.java
+++ 
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/config/MyBatisConfig.java
@@ -43,8 +43,10 @@ public class MyBatisConfig {
     public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws 
Exception {
         SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
         sessionFactory.setDataSource(dataSource);
-        sessionFactory.setMapperLocations(
-                new 
PathMatchingResourcePatternResolver().getResources("classpath*:mapper/**/*Mapper.xml"));
+        sessionFactory.setMapperLocations(new 
PathMatchingResourcePatternResolver()
+                .getResources(String.format(
+                        "classpath*:mapper/%s/**/*Mapper.xml",
+                        new 
ProductNameDatabaseIdProvider().getDatabaseId(dataSource))));
 
         org.apache.ibatis.session.Configuration configuration = new 
org.apache.ibatis.session.Configuration();
         configuration.setMapUnderscoreToCamelCase(true);
diff --git 
a/bigtop-manager-server/src/main/resources/ddl/PostgreSQL-DDL-CREATE.sql 
b/bigtop-manager-server/src/main/resources/ddl/PostgreSQL-DDL-CREATE.sql
new file mode 100644
index 0000000..3a94b40
--- /dev/null
+++ b/bigtop-manager-server/src/main/resources/ddl/PostgreSQL-DDL-CREATE.sql
@@ -0,0 +1,391 @@
+/*
+ * 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
+ *
+ *    https://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.
+ */
+
+CREATE TABLE audit_log
+(
+    id                BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
+    args              TEXT,
+    create_by         BIGINT,
+    create_time       TIMESTAMP(0),
+    operation_desc    VARCHAR(255),
+    operation_summary VARCHAR(255),
+    tag_desc          VARCHAR(255),
+    tag_name          VARCHAR(255),
+    update_by         BIGINT,
+    update_time       TIMESTAMP(0),
+    uri               VARCHAR(255),
+    user_id           BIGINT,
+    PRIMARY KEY (id)
+);
+
+CREATE TABLE "user"
+(
+    id          BIGINT CHECK (id > 0) NOT NULL GENERATED ALWAYS AS IDENTITY,
+    username    VARCHAR(32)  DEFAULT NULL,
+    password    VARCHAR(32)  DEFAULT NULL,
+    nickname    VARCHAR(32)  DEFAULT NULL,
+    status      BOOLEAN          DEFAULT TRUE,
+    create_time TIMESTAMP(0) DEFAULT NULL,
+    update_time TIMESTAMP(0) DEFAULT NULL,
+    create_by   BIGINT,
+    update_by   BIGINT,
+    PRIMARY KEY (id),
+    CONSTRAINT uk_username UNIQUE (username)
+);
+
+COMMENT ON COLUMN "user".status IS '0-Disable, 1-Enable';
+
+CREATE TABLE cluster
+(
+    id            BIGINT CHECK (id > 0) NOT NULL GENERATED ALWAYS AS IDENTITY,
+    cluster_name  VARCHAR(255)                      DEFAULT NULL,
+    cluster_desc  VARCHAR(255)                      DEFAULT NULL,
+    cluster_type  SMALLINT CHECK (cluster_type > 0) DEFAULT 1,
+    selected      BOOLEAN                               DEFAULT TRUE,
+    create_time   TIMESTAMP(0)                      DEFAULT NULL,
+    update_time   TIMESTAMP(0)                      DEFAULT NULL,
+    create_by     BIGINT,
+    packages      VARCHAR(255),
+    repo_template VARCHAR(255),
+    root          VARCHAR(255),
+    state         VARCHAR(255),
+    update_by     BIGINT,
+    user_group    VARCHAR(255),
+    stack_id      BIGINT,
+    PRIMARY KEY (id),
+    CONSTRAINT uk_cluster_name UNIQUE (cluster_name)
+);
+
+COMMENT ON COLUMN cluster.cluster_name IS 'Cluster Name';
+COMMENT ON COLUMN cluster.cluster_desc IS 'Cluster Description';
+COMMENT ON COLUMN cluster.cluster_type IS '1-Physical Machine, 2-Kubernetes';
+COMMENT ON COLUMN cluster.selected IS '0-Disable, 1-Enable';
+
+DROP INDEX IF EXISTS idx_cluster_stack_id;
+CREATE INDEX idx_cluster_stack_id ON cluster (stack_id);
+
+CREATE TABLE component
+(
+    id              BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
+    category        VARCHAR(255),
+    command_script  VARCHAR(255),
+    component_name  VARCHAR(255),
+    create_by       BIGINT,
+    create_time     TIMESTAMP(0),
+    custom_commands TEXT,
+    display_name    VARCHAR(255),
+    quick_link      VARCHAR(255),
+    cardinality     VARCHAR(255),
+    update_by       BIGINT,
+    update_time     TIMESTAMP(0),
+    cluster_id      BIGINT,
+    service_id      BIGINT,
+    PRIMARY KEY (id),
+    CONSTRAINT uk_component_name UNIQUE (component_name, cluster_id)
+);
+
+DROP INDEX IF EXISTS idx_component_cluster_id;
+DROP INDEX IF EXISTS idx_component_service_id;
+CREATE INDEX idx_component_cluster_id ON component (cluster_id);
+CREATE INDEX idx_component_service_id ON component (service_id);
+
+CREATE TABLE host_component
+(
+    id           BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
+    create_by    BIGINT,
+    create_time  TIMESTAMP(0),
+    state        VARCHAR(255),
+    update_by    BIGINT,
+    update_time  TIMESTAMP(0),
+    component_id BIGINT,
+    host_id      BIGINT,
+    PRIMARY KEY (id)
+);
+
+DROP INDEX IF EXISTS idx_hc_component_id;
+DROP INDEX IF EXISTS idx_hc_host_id;
+CREATE INDEX idx_hc_component_id ON host_component (component_id);
+CREATE INDEX idx_hc_host_id ON host_component (host_id);
+
+CREATE TABLE host
+(
+    id                   BIGINT CHECK (id > 0)         NOT NULL GENERATED 
ALWAYS AS IDENTITY,
+    cluster_id           BIGINT CHECK (cluster_id > 0) NOT NULL,
+    hostname             VARCHAR(255) DEFAULT NULL,
+    ipv4                 VARCHAR(32)  DEFAULT NULL,
+    ipv6                 VARCHAR(32)  DEFAULT NULL,
+    arch                 VARCHAR(32)  DEFAULT NULL,
+    os                   VARCHAR(32)  DEFAULT NULL,
+    processor_count      INT          DEFAULT NULL,
+    physical_memory      BIGINT       DEFAULT NULL,
+    state                VARCHAR(32)  DEFAULT NULL,
+    create_time          TIMESTAMP(0) DEFAULT NULL,
+    update_time          TIMESTAMP(0) DEFAULT NULL,
+    available_processors INTEGER,
+    create_by            BIGINT,
+    free_disk            BIGINT,
+    free_memory_size     BIGINT,
+    total_disk           BIGINT,
+    total_memory_size    BIGINT,
+    update_by            BIGINT,
+    PRIMARY KEY (id),
+    CONSTRAINT uk_hostname UNIQUE (hostname, cluster_id)
+);
+
+COMMENT ON COLUMN host.physical_memory IS 'Total Physical Memory(Bytes)';
+
+DROP INDEX IF EXISTS idx_host_cluster_id;
+CREATE INDEX idx_host_cluster_id ON host (cluster_id);
+
+CREATE TABLE repo
+(
+    id          BIGINT CHECK (id > 0)         NOT NULL GENERATED ALWAYS AS 
IDENTITY,
+    cluster_id  BIGINT CHECK (cluster_id > 0) NOT NULL,
+    os          VARCHAR(32)  DEFAULT NULL,
+    arch        VARCHAR(32)  DEFAULT NULL,
+    base_url    VARCHAR(64)  DEFAULT NULL,
+    repo_id     VARCHAR(32)  DEFAULT NULL,
+    repo_name   VARCHAR(64)  DEFAULT NULL,
+    repo_type   VARCHAR(64)  DEFAULT NULL,
+    create_time TIMESTAMP(0) DEFAULT NULL,
+    update_time TIMESTAMP(0) DEFAULT NULL,
+    create_by   BIGINT,
+    update_by   BIGINT,
+    PRIMARY KEY (id),
+    CONSTRAINT uk_repo_id UNIQUE (repo_id, os, arch, cluster_id)
+);
+
+DROP INDEX IF EXISTS idx_cluster_id;
+CREATE INDEX idx_cluster_id ON repo (cluster_id);
+
+CREATE TABLE stack
+(
+    id            BIGINT CHECK (id > 0) NOT NULL GENERATED ALWAYS AS IDENTITY,
+    stack_name    VARCHAR(32)           NOT NULL,
+    stack_version VARCHAR(32)           NOT NULL,
+    create_time   TIMESTAMP(0) DEFAULT NULL,
+    update_time   TIMESTAMP(0) DEFAULT NULL,
+    create_by     BIGINT,
+    update_by     BIGINT,
+    PRIMARY KEY (id),
+    CONSTRAINT uk_stack UNIQUE (stack_name, stack_version)
+);
+
+CREATE TABLE task
+(
+    id             BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
+    command        VARCHAR(255),
+    component_name VARCHAR(255),
+    content        TEXT,
+    context        TEXT   NOT NULL,
+    create_by      BIGINT,
+    create_time    TIMESTAMP(0),
+    custom_command VARCHAR(255),
+    hostname       VARCHAR(255),
+    name           VARCHAR(255),
+    service_name   VARCHAR(255),
+    service_user   VARCHAR(255),
+    stack_name     VARCHAR(255),
+    stack_version  VARCHAR(255),
+    state          VARCHAR(255),
+    update_by      BIGINT,
+    update_time    TIMESTAMP(0),
+    cluster_id     BIGINT,
+    job_id         BIGINT,
+    stage_id       BIGINT,
+    PRIMARY KEY (id)
+);
+
+DROP INDEX IF EXISTS idx_task_cluster_id;
+DROP INDEX IF EXISTS idx_task_job_id;
+DROP INDEX IF EXISTS idx_task_stage_id;
+CREATE INDEX idx_task_cluster_id ON task (cluster_id);
+CREATE INDEX idx_task_job_id ON task (job_id);
+CREATE INDEX idx_task_stage_id ON task (stage_id);
+
+CREATE TABLE job
+(
+    id          BIGINT CHECK (id > 0) NOT NULL GENERATED ALWAYS AS IDENTITY,
+    cluster_id  BIGINT CHECK (cluster_id > 0) DEFAULT NULL,
+    state       VARCHAR(32)           NOT NULL,
+    context     TEXT                  NOT NULL,
+    create_time TIMESTAMP(0)                  DEFAULT NULL,
+    update_time TIMESTAMP(0)                  DEFAULT NULL,
+    create_by   BIGINT,
+    name        VARCHAR(255),
+    update_by   BIGINT,
+    PRIMARY KEY (id)
+);
+
+CREATE INDEX idx_job_cluster_id ON job (cluster_id);
+
+CREATE TABLE type_config
+(
+    id                BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
+    create_by         BIGINT,
+    create_time       TIMESTAMP(0),
+    properties_json   TEXT,
+    type_name         VARCHAR(255),
+    update_by         BIGINT,
+    update_time       TIMESTAMP(0),
+    service_config_id BIGINT,
+    PRIMARY KEY (id)
+);
+
+CREATE TABLE service
+(
+    id                BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
+    create_by         BIGINT,
+    create_time       TIMESTAMP(0),
+    display_name      VARCHAR(255),
+    package_specifics VARCHAR(1024),
+    required_services VARCHAR(255),
+    service_desc      VARCHAR(1024),
+    service_name      VARCHAR(255),
+    service_user      VARCHAR(255),
+    service_version   VARCHAR(255),
+    update_by         BIGINT,
+    update_time       TIMESTAMP(0),
+    cluster_id        BIGINT,
+    PRIMARY KEY (id),
+    CONSTRAINT uk_service_name UNIQUE (service_name, cluster_id)
+);
+
+CREATE INDEX idx_service_cluster_id ON service (cluster_id);
+
+CREATE TABLE service_config
+(
+    id          BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
+    config_desc VARCHAR(255),
+    create_by   BIGINT,
+    create_time TIMESTAMP(0),
+    selected    BOOLEAN default FALSE,
+    update_by   BIGINT,
+    update_time TIMESTAMP(0),
+    version     INTEGER,
+    cluster_id  BIGINT,
+    service_id  BIGINT,
+    PRIMARY KEY (id)
+);
+
+CREATE INDEX idx_sc_cluster_id ON service_config (cluster_id);
+CREATE INDEX idx_sc_service_id ON service_config (service_id);
+
+CREATE TABLE setting
+(
+    id          BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
+    config_data TEXT,
+    create_by   BIGINT,
+    create_time TIMESTAMP(0),
+    type_name   VARCHAR(255),
+    update_by   BIGINT,
+    update_time TIMESTAMP(0),
+    PRIMARY KEY (id)
+);
+
+CREATE TABLE stage
+(
+    id             BIGINT CHECK (id > 0)     NOT NULL GENERATED ALWAYS AS 
IDENTITY,
+    name           VARCHAR(32)               NOT NULL,
+    cluster_id     BIGINT CHECK (cluster_id > 0) DEFAULT NULL,
+    job_id         BIGINT CHECK (job_id > 0) NOT NULL,
+    state          VARCHAR(32)               NOT NULL,
+    create_time    TIMESTAMP(0)                  DEFAULT NULL,
+    update_time    TIMESTAMP(0)                  DEFAULT NULL,
+    component_name VARCHAR(255),
+    context        TEXT,
+    create_by      BIGINT,
+    "order"        INTEGER,
+    service_name   VARCHAR(255),
+    update_by      BIGINT,
+    PRIMARY KEY (id)
+);
+
+CREATE INDEX idx_stage_cluster_id ON stage (cluster_id);
+CREATE INDEX idx_job_id ON stage (job_id);
+
+CREATE TABLE llm_platform
+(
+    id             BIGINT CHECK (id > 0) NOT NULL GENERATED ALWAYS AS IDENTITY,
+    name           VARCHAR(255)          NOT NULL,
+    credential     JSON         DEFAULT NULL,
+    support_models VARCHAR(255) DEFAULT NULL,
+    create_time    TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP,
+    update_time    TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP /* ON UPDATE 
CURRENT_TIMESTAMP */,
+    create_by      BIGINT       DEFAULT NULL,
+    update_by      BIGINT       DEFAULT NULL,
+    PRIMARY KEY (id)
+);
+
+CREATE TABLE llm_platform_authorized
+(
+    id          BIGINT CHECK (id > 0)          NOT NULL GENERATED ALWAYS AS 
IDENTITY,
+    platform_id BIGINT CHECK (platform_id > 0) NOT NULL,
+    credentials JSON                           NOT NULL,
+    create_time TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP,
+    update_time TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP /* ON UPDATE 
CURRENT_TIMESTAMP */,
+    create_by   BIGINT       DEFAULT NULL,
+    update_by   BIGINT       DEFAULT NULL,
+    PRIMARY KEY (id)
+);
+
+CREATE INDEX idx_authorized_platform_id ON llm_platform_authorized 
(platform_id);
+
+CREATE TABLE llm_chat_thread
+(
+    id          BIGINT CHECK (id > 0)          NOT NULL GENERATED ALWAYS AS 
IDENTITY,
+    platform_id BIGINT CHECK (platform_id > 0) NOT NULL,
+    user_id     BIGINT CHECK (user_id > 0)     NOT NULL,
+    model       VARCHAR(255)                   NOT NULL,
+    thread_info JSON         DEFAULT NULL,
+    create_time TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP,
+    update_time TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP /* ON UPDATE 
CURRENT_TIMESTAMP */,
+    create_by   BIGINT       DEFAULT NULL,
+    update_by   BIGINT       DEFAULT NULL,
+    PRIMARY KEY (id)
+);
+
+CREATE INDEX idx_chatthread_platform_id ON llm_chat_thread (platform_id);
+CREATE INDEX idx_chatthread_user_id ON llm_chat_thread (user_id);
+
+CREATE TABLE llm_chat_message
+(
+    id          BIGINT CHECK (id > 0)        NOT NULL GENERATED ALWAYS AS 
IDENTITY,
+    thread_id   BIGINT CHECK (thread_id > 0) NOT NULL,
+    user_id     BIGINT CHECK (user_id > 0)   NOT NULL,
+    message     TEXT                         NOT NULL,
+    sender      VARCHAR(50)                  NOT NULL,
+    create_time TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP,
+    update_time TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP /* ON UPDATE 
CURRENT_TIMESTAMP */,
+    create_by   BIGINT       DEFAULT NULL,
+    update_by   BIGINT       DEFAULT NULL,
+    PRIMARY KEY (id)
+);
+
+CREATE INDEX idx_thread_id ON llm_chat_message (thread_id);
+CREATE INDEX idx_message_user_id ON llm_chat_message (user_id);
+
+INSERT INTO "user" (create_time, update_time, nickname, password, status, 
username)
+VALUES (now(), now(), 'Administrator', '21232f297a57a5a743894a0e4a801fc3', 
true, 'admin');
+
+INSERT INTO llm_platform (credential, NAME, support_models)
+VALUES
+('{"apiKey": "API 
Key"}','OpenAI','gpt-3.5-turbo,gpt-4,gpt-4o,gpt-3.5-turbo-16k,gpt-4-turbo-preview,gpt-4-32k,gpt-4o-mini'),
+('{"apiKey": "API Key"}','DashScope','qwen-max,qwen-plus,qwen-turbo'),
+('{"apiKey": "API Key", "secretKey": "Secret 
Key"}','QianFan','Yi-34B-Chat,ERNIE-4.0-8K,ERNIE-3.5-128K,ERNIE-Speed-8K,Llama-2-7B-Chat,Fuyu-8B');

Reply via email to