<?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="jnpf.dmsMapper.DmsFileExpiryMapper">
|
<resultMap id="Item" type="jnpf.dmsEntity.storage.expiry.DmsFileExpiryItem">
|
<id column="file_version_id" property="fileVersionId" typeHandler="jnpf.dmsDatabase.DmsUuidTypeHandler"/>
|
<result column="document_id" property="documentId" typeHandler="jnpf.dmsDatabase.DmsUuidTypeHandler"/>
|
<result column="tenant_id" property="tenantId"/>
|
<result column="lifecycle_status" property="lifecycleStatus"/>
|
<result column="effective_from" property="effectiveFrom"/>
|
<result column="effective_to" property="effectiveTo"/>
|
<result column="expiry_cursor" property="expiryCursor"/>
|
<result column="search_task_id" property="searchTaskId"/>
|
</resultMap>
|
<!-- A cleanup receipt alone does not prove that older code updated the business version. -->
|
<sql id="NEEDS_PROJECTION">
|
NOT EXISTS (SELECT 1 FROM public.dms_file_expiry_cleanup c
|
WHERE c.tenant_id=s.tenant_id AND c.file_version_id=s.file_version_id)
|
OR EXISTS (SELECT 1 FROM public.dms_wenjian_ziyuan r
|
JOIN public.dms_wenjian_banben b ON b.f_tenant_id=r.f_tenant_id AND b.wenjian_id=r.f_id
|
AND b.f_id=r.dangqian_banben_id AND b.f_delete_mark IS NULL
|
WHERE r.f_tenant_id=s.tenant_id AND r.f_delete_mark IS NULL AND b.biz_status='effective'
|
AND b.wenjian_zhongxin_banben_id=CAST(s.file_version_id AS TEXT))
|
</sql>
|
<select id="candidates" resultMap="Item">
|
SELECT s.tenant_id, s.document_id, s.file_version_id, s.lifecycle_status, s.effective_from, s.effective_to,
|
s.effective_to AS expiry_cursor
|
FROM public.dms_version_states s
|
WHERE s.effective_to <= statement_timestamp()
|
AND (s.lifecycle_status = 'EFFECTIVE' OR (s.lifecycle_status = 'EXPIRED' AND (<include refid="NEEDS_PROJECTION"/>)))
|
<if test="after != null">
|
AND (s.effective_to, s.tenant_id, s.file_version_id) >
|
(#{after.expiryCursor}, #{after.tenantId}, #{after.fileVersionId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler})
|
</if>
|
ORDER BY s.effective_to, s.tenant_id, s.file_version_id LIMIT #{limit}
|
</select>
|
<!-- Lock the document first, matching activation and validity changes. Discovery never locks states. -->
|
<select id="tryLockDocument" resultType="java.util.UUID">
|
SELECT id FROM public.dms_documents WHERE tenant_id=#{tenantId}
|
AND id=#{documentId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler}
|
FOR UPDATE SKIP LOCKED
|
</select>
|
<select id="dueState" resultMap="Item">
|
SELECT tenant_id, document_id, file_version_id, lifecycle_status, effective_from, effective_to
|
FROM public.dms_version_states s WHERE tenant_id=#{tenantId}
|
AND file_version_id=#{fileVersionId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler}
|
AND lifecycle_status IN ('EFFECTIVE','EXPIRED') AND effective_to <= statement_timestamp()
|
AND (lifecycle_status <> 'EXPIRED' OR (<include refid="NEEDS_PROJECTION"/>))
|
</select>
|
<insert id="enqueueCleanup">
|
INSERT INTO public.dms_file_expiry_cleanup (tenant_id, file_version_id)
|
VALUES (#{tenantId}, #{fileVersionId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler})
|
ON CONFLICT (tenant_id, file_version_id) DO NOTHING
|
</insert>
|
<select id="cleanupCandidates" resultMap="Item">
|
SELECT tenant_id, file_version_id, search_task_id FROM public.dms_file_expiry_cleanup
|
WHERE completed_at IS NULL AND next_attempt_at <= statement_timestamp()
|
ORDER BY next_attempt_at, tenant_id, file_version_id LIMIT #{limit}
|
</select>
|
<select id="lockCleanup" resultMap="Item">
|
SELECT tenant_id, file_version_id, search_task_id FROM public.dms_file_expiry_cleanup
|
WHERE tenant_id=#{tenantId} AND file_version_id=#{fileVersionId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler}
|
AND completed_at IS NULL AND next_attempt_at <= statement_timestamp()
|
FOR UPDATE SKIP LOCKED
|
</select>
|
<update id="updateCleanup">
|
UPDATE public.dms_file_expiry_cleanup SET search_task_id=#{item.searchTaskId},
|
completed_at=CASE WHEN #{done} THEN statement_timestamp() ELSE NULL END,
|
attempts=attempts+1, last_error=#{error}, updated_at=statement_timestamp(),
|
next_attempt_at=statement_timestamp() + (#{delay} * INTERVAL '1 second')
|
WHERE tenant_id=#{item.tenantId}
|
AND file_version_id=#{item.fileVersionId,jdbcType=OTHER,typeHandler=jnpf.dmsDatabase.DmsUuidTypeHandler}
|
</update>
|
</mapper>
|