<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.persagy.dmp.rwd.digital.dao.ObjectRelationMapper">

    <resultMap id="BaseResultMap" type="com.persagy.dmp.digital.entity.ObjectRelation">
            <id property="id" column="id" jdbcType="VARCHAR"/>
            <result property="groupCode" column="group_code" jdbcType="VARCHAR"/>
            <result property="projectId" column="project_id" jdbcType="VARCHAR"/>
            <result property="graphId" column="graph_id" jdbcType="VARCHAR"/>
            <result property="graphCode" column="graph_code" jdbcType="VARCHAR"/>
            <result property="relCode" column="rel_code" jdbcType="VARCHAR"/>
            <result property="relValue" column="rel_value" jdbcType="VARCHAR"/>
            <result property="objFrom" column="obj_from" jdbcType="VARCHAR"/>
            <result property="objTo" column="obj_to" jdbcType="VARCHAR"/>
            <result property="createApp" column="create_app" jdbcType="VARCHAR"/>
            <result property="updateApp" column="update_app" jdbcType="VARCHAR"/>
            <result property="creator" column="creator" jdbcType="VARCHAR"/>
            <result property="creationTime" column="creation_time" jdbcType="CHAR"/>
            <result property="modifier" column="modifier" jdbcType="VARCHAR"/>
            <result property="modifiedTime" column="modified_time" jdbcType="CHAR"/>
            <result property="valid" column="valid" jdbcType="TINYINT"/>
            <result property="ts" column="ts" jdbcType="TIMESTAMP"/>
    </resultMap>

    <resultMap id="ObjectDigitalResultMap" type="com.persagy.dmp.digital.entity.ObjectDigital">
        <id property="id" column="id" jdbcType="VARCHAR"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="localId" column="local_id" jdbcType="VARCHAR"/>
        <result property="localName" column="local_name" jdbcType="VARCHAR"/>
        <result property="groupCode" column="group_code" jdbcType="VARCHAR"/>
        <result property="projectId" column="project_id" jdbcType="VARCHAR"/>
        <result property="objType" column="obj_type" jdbcType="VARCHAR"/>
        <result property="classCode" column="class_code" jdbcType="VARCHAR"/>
        <result property="grouping" column="grouping" jdbcType="INTEGER"/>
        <result property="infos" column="infos" jdbcType="VARCHAR" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
        <result property="virtualCodes" column="virtual_codes" jdbcType="VARCHAR" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
        <result property="createApp" column="create_app" jdbcType="VARCHAR"/>
        <result property="updateApp" column="update_app" jdbcType="VARCHAR"/>
        <result property="creator" column="creator" jdbcType="VARCHAR"/>
        <result property="creationTime" column="creation_time" jdbcType="CHAR"/>
        <result property="modifier" column="modifier" jdbcType="VARCHAR"/>
        <result property="modifiedTime" column="modified_time" jdbcType="CHAR"/>
        <result property="valid" column="valid" jdbcType="TINYINT"/>
        <result property="ts" column="ts" jdbcType="TIMESTAMP"/>
        <result property="objFromIds" column="objFromIds" jdbcType="VARCHAR" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
        <result property="objToIds" column="objToIds" jdbcType="VARCHAR" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
    </resultMap>

    <sql id="Base_Column_List">
        id,group_code,project_id,
        graph_id,graph_code,rel_code,
        rel_value,obj_from,obj_to,
        create_app,update_app,creator,
        creation_time,modifier,modified_time,
        valid,ts
    </sql>
    <sql id="insertObjectRelationCondition">


    </sql>
    <insert id="insertObjectRelationByRelChain">
        INSERT INTO dt_relation (
            id,
            group_code,
            project_id,
            graph_id,
            graph_code,
            rel_code,
            rel_value,
            obj_from,
            obj_to,
            create_app,
            update_app,
            creator,
            creation_time,
            modifier,
            modified_time,
            valid
        )
        SELECT
            (SELECT MD5(UUID()) FROM DUAL),
            dtr.group_code,
            dtr.project_id,
            CONCAT('Gt',#{param.graphCode},'001'),
            #{param.graphCode},
            #{param.relCode},
            NULL,
            dtr.obj_from,
            dtr.obj_to,
            #{param.appId},
            #{param.appId},
            #{param.accountId},
            DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),
            #{param.accountId},
            DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),
            1
        FROM
        (
        <if test="null!=param.chain and param.chain.size()>0">
            SELECT
            dtr0.obj_from AS obj_from,
            dtr${param.chain.size()-1}.obj_to AS obj_to,
            dtr0.group_code AS group_code,
            dtr0.project_id AS project_id
            FROM
            (
            <foreach collection="param.chain" item="rule" index="index">
             <choose>
                <when test="index==0">
                    ( SELECT obj_to, obj_from,group_code,project_id FROM dt_relation WHERE 1=1
                        <if test="null!=rule.graphCode and rule.graphCode.length>0">
                            AND graph_code = #{rule.graphCode}
                        </if>
                        <if test="null!=rule.relCode and rule.relCode.length>0">
                            AND rel_code = #{rule.relCode}
                        </if>
                        <if test="null!=rule.relValue and rule.relValue.length>0">
                            AND rel_value = #{rule.relValue}
                        </if>
                        <if test="null!=param.groupCode and param.groupCode.length>0">
                            AND group_code = #{param.groupCode}
                        </if>
                        <if test="null!=param.projectId and param.projectId.length>0">
                            AND project_id = #{param.projectId}
                        </if>
                        <if test="null!=param.fromIds and param.fromIds.size()>0">
                            <foreach collection="param.fromIds" item="fromId" separator="," open="AND obj_from IN(" close=")">
                                #{fromId}
                            </foreach>
                        </if>
                          AND valid = TRUE
                    ) AS dtr${index}
                </when>
                <when test="index==param.chain.size()-1">
                    INNER JOIN (SELECT if(#{rule.currentRelDirection},obj_to,obj_from) AS obj_to,if(#{rule.currentRelDirection},obj_from,obj_to) AS obj_from FROM dt_relation WHERE
                    (
                    1=1
                    <if test="null!=rule.graphCode and rule.graphCode.length>0">
                        AND graph_code = #{rule.graphCode}
                    </if>
                    <if test="null!=rule.relCode and rule.relCode.length>0">
                        AND rel_code = #{rule.relCode}
                    </if>
                    <if test="null!=rule.relValue and rule.relValue.length>0">
                        AND rel_value = #{rule.relValue}
                    </if>
                    <if test="null!=param.groupCode and param.groupCode.length>0">
                        AND group_code = #{param.groupCode}
                    </if>
                    <if test="null!=param.projectId and param.projectId.length>0">
                        AND project_id = #{param.projectId}
                    </if>
                    AND valid=TRUE
                    <if test="null!=param.toIds and param.toIds.size()>0">
                        if(#{rule.currentRelDirection},obj_to,obj_from) IN(
                        <foreach collection="param.toIds" item="toId" separator=",">
                            #{toId}
                        </foreach>
                        )
                    </if>
                        )) AS dtr${index} ON (if(#{rule.preRelDirection},dtr${index-1}.obj_to,dtr${index-1}.obj_from) = dtr${index}.obj_from)
                </when>
                <otherwise>
                    INNER JOIN dt_relation AS dtr${index} ON (
                        if(#{rule.preRelDirection},dtr${index-1}.obj_to,dtr${index-1}.obj_from) = if(#{rule.currentRelDirection},dtr${index}.obj_from,dtr${index}.obj_to)
                        <if test="null!=rule.graphCode and rule.graphCode.length>0">
                            AND dtr${index}.graph_code = #{rule.graphCode}
                        </if>
                        <if test="null!=rule.relCode and rule.relCode.length>0">
                            AND dtr${index}.rel_code = #{rule.relCode}
                        </if>
                        <if test="null!=rule.relValue and rule.relValue.length>0">
                            AND dtr${index}.rel_value = #{rule.relValue}
                        </if>
                        <if test="null!=param.groupCode and param.groupCode.length>0">
                            AND dtr${index}.group_code = #{param.groupCode}
                        </if>
                        <if test="null!=param.projectId and param.projectId.length>0">
                            AND dtr${index}.project_id = #{param.projectId}
                        </if>
                        AND dtr${index}.valid=TRUE)
                </otherwise>
             </choose>
            </foreach>
            )
        </if>
        ) AS dtr
    </insert>

    <select id="selectRelCodesByObjToIdsAndRelCode" resultMap="ObjectDigitalResultMap">
        SELECT
            dtr.obj_to AS id,IFNULL(JSON_ARRAYAGG(dtr.obj_from),JSON_ARRAY()) AS objFromIds
        FROM
            dt_relation dtr
        WHERE 1=1
        <if test="objIds!=null and objIds.size()>0">
            <foreach collection="objIds" item="objId" open="AND dtr.obj_to IN (" close=")" separator=",">
                #{objId}
            </foreach>
        </if>
        <if test="relCode!=null and relCode.length>0">
            AND dtr.rel_code = #{relCode}
        </if>
        AND dtr.valid=TRUE
        GROUP BY dtr.obj_to;
    </select>
    <select id="selectRelCodesByObjIdsAndRelCodes" resultMap="ObjectDigitalResultMap">
        SELECT
        rdtr.*
        FROM
        (
        (
        SELECT
        dtr.obj_to AS id,
        IFNULL( JSON_ARRAYAGG( dtr.obj_to ), JSON_ARRAY( ) ) AS objToIds,
        IFNULL( JSON_ARRAYAGG( dtr.obj_from ), JSON_ARRAY( ) ) AS objFromIds
        FROM
        dt_relation dtr
        WHERE
        1 = 1
        <if test="objIds!=null and objIds.size()>0">
            <foreach collection="objIds" item="objId" open="AND dtr.obj_to IN (" close=")" separator=",">
                #{objId}
            </foreach>
        </if>
        <if test="relCodes!=null and relCodes.size()>0">
            <foreach collection="relCodes" item="relCode" open="AND dtr.rel_code IN (" close=")" separator=",">
                #{relCode}
            </foreach>
        </if>
        AND dtr.valid=TRUE
        GROUP BY
        dtr.obj_to
        ) UNION
        (
        SELECT
        dtr.obj_from AS id,
        IFNULL( JSON_ARRAYAGG( dtr.obj_to ), JSON_ARRAY( ) ) AS objToIds,
        IFNULL( JSON_ARRAYAGG( dtr.obj_from ), JSON_ARRAY( ) ) AS objFromIds
        FROM
        dt_relation dtr
        WHERE
        1 = 1
        <if test="objIds!=null and objIds.size()>0">
            <foreach collection="objIds" item="objId" open="AND dtr.obj_from IN (" close=")" separator=",">
                #{objId}
            </foreach>
        </if>
        <if test="relCodes!=null and relCodes.size()>0">
            <foreach collection="relCodes" item="relCode" open="AND dtr.rel_code IN (" close=")" separator=",">
                #{relCode}
            </foreach>
        </if>
        AND dtr.valid=TRUE
        GROUP BY
        dtr.obj_from
        )
        ) AS rdtr;
    </select>
</mapper>
