<?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="Tigon">

    <!-- Search -->
    <sql id="search">
        <choose>
        <when test="s instanceof me.chyxion.tigon.mybatis.Search">
            <if test="s.hasCriterion()">
                where <include refid="Tigon.assemble" />
            </if>

            <if test="!_parameter.containsKey(&quot;__is_count__&quot;)">
                <include refid="Tigon.orderBy" />
                <include refid="Tigon.limit" />
            </if>
        </when>
        <when test="s != null">
            where <include refid="primaryKey" /> = #{s}
        </when>
        </choose>
    </sql>
    <!--/ Search -->

    <!-- Search Assemble -->
    <sql id="assemble">
        <foreach collection="s.assemble()" item="it">
            <choose>
                <when test="it instanceof me.chyxion.tigon.mybatis.SqlFragment">
                    ${it}
                </when>
                <otherwise>
                    #{it}
                </otherwise>
            </choose>
        </foreach>
    </sql>
    <!--/ Search Assemble -->

    <!-- Order By -->
    <sql id="orderBy">
        <if test="!s.orders().isEmpty()">
            order by
            <foreach collection="s.orders()" index="__col__"
                     item="__direction__" separator=", ">
                ${__col__} ${__direction__}
            </foreach>
        </if>
    </sql>
    <!--/ Order By -->

    <!-- Limit -->
    <sql id="limit">
        <choose>
            <when test="s.offset() != null and s.limit() != null">
                <bind name="__offset__" value="s.offset()" />
                <bind name="__limit__" value="s.limit()" />
                limit #{__offset__}, #{__limit__}
            </when>
            <when test="s.limit() != null">
                <bind name="__limit__" value="s.limit()" />
                limit #{__limit__}
            </when>
        </choose>
    </sql>
    <!--/ Limit -->

    <!-- Search For Count, Ignore Orders And Limit -->
    <sql id="searchForCount">
        <bind name="__is_count_dummy__" value="_parameter.put('__is_count__', true)" />
        <include refid="Tigon.search" />
    </sql>
    <!--/ Search For Count -->

    <!-- Insert -->
    <sql id="insert">
        insert into <include refid="table" />
        <choose>
            <!-- Model -->
            <when test="_parameter.containsKey(&quot;model&quot;)">
                <bind name="__before_insert_dummy__" value="model.beforeInsert()" />
                <foreach collection="model.cols()"
                    item="__col__" open="(" separator=", " close=")">
                    ${__col__}
                </foreach>
                values
                <foreach collection="model.values()" 
                    item="__val__" open="(" separator=", " close=")">
                    #{__val__}
                </foreach>
            </when>
            <!-- Models Array -->
            <when test="models.getClass().isArray()">
                <foreach collection="models[0].cols()"
                    item="__col__" open="(" separator=", " close=")">
                    ${__col__}
                </foreach>
                values
                <foreach item="model" collection="models" separator=", ">
                    <bind name="__before_insert_dummy__" value="model.beforeInsert()" />
                    <foreach collection="model.values()"
                             item="__val__" open="(" separator=", " close=")">
                        #{__val__}
                    </foreach>
                </foreach>
            </when>
            <!-- Models Collection -->
            <otherwise>
                <!-- Models -->
                <foreach collection="models.iterator().next().cols()" 
                    item="__col__" open="(" separator=", " close=")">
                    ${__col__}
                </foreach>
                values
                <foreach item="model" collection="models" separator=", ">
                    <foreach collection="model.values()" 
                        item="__val__" open="(" separator=", " close=")">
                        #{__val__}
                    </foreach>
                </foreach>
            </otherwise>
        </choose>
    </sql>
    <!--/ Insert -->

    <!-- Update -->
    <sql id="update">
        update <include refid="table" />
        <set>
        <choose>
            <when test="model instanceof java.util.Map">
                <foreach collection="model" index="__m_col__" item="__val__" separator=", ">
                    ${__m_col__} = #{__val__}
                </foreach>
            </when>
            <otherwise>
                <bind name="__before_update_dummy__" value="model.beforeUpdate()" />
                <foreach collection="model.updateMap()" index="__m_col__" item="__val__" separator=", ">
                    ${__m_col__} = #{__val__}
                </foreach>
            </otherwise>
        </choose>
        </set>

        <choose>
        <when test="_parameter.containsKey(&quot;s&quot;)">
            <include refid="Tigon.search" />
        </when>
        <otherwise>
            <bind name="__primary_key_value__" value="model.primaryKeyValue()" />
            where <include refid="primaryKey" /> = #{__primary_key_value__}
        </otherwise>
        </choose>
    </sql>
    <!--/ Update -->

    <!-- Set Cols null -->
    <sql id="setNull">
        update <include refid="table" />
        <set>
            <choose>
            <when test="_parameter.containsKey(&quot;cols&quot;)">
                <foreach item="col" collection="cols" separator=", ">
                    ${col} = null
                </foreach>
            </when>
            <otherwise>
                ${col} = null
            </otherwise>
            </choose>
        </set>
        <include refid="Tigon.search" />
    </sql>
    <!--/ Set Cols null -->

    <!-- Delete -->
    <sql id="delete">
        delete from
        <include refid="table" />
        <include refid="Tigon.search" />
    </sql>
    <!--/ Delete -->

    <!-- Find One -->
    <sql id="find">
        select
        <include refid="cols" />
        from
        <include refid="table" />
        <include refid="Tigon.search" />
    </sql>
    <!--/ Find One -->

    <!-- List -->
    <sql id="list">
        select
        <include refid="cols" />
        from
        <include refid="table" />
        <include refid="Tigon.search" />
    </sql>
    <!--/ List -->

    <!-- Count -->
    <sql id="count">
        select count(<include refid="primaryKey" />) from
        <include refid="table" />
        <include refid="Tigon.searchForCount" />
    </sql>
    <!--/ Count -->
</mapper>
