刘光辉
5 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package jnpf.dmsMapper;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.Configuration;
import org.junit.jupiter.api.Test;
import java.io.InputStream;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
class DmsApprovedDisableMapperXmlTest {
    @Test void nativeApplicationApplicantUsesEachFormsPersistedField() throws Exception {
        Configuration c=parse("DmsDisableApplicationMapper");
        for (String operation : List.of("yichexiao", "yishixiao")) {
            String query=sql(c,"DmsDisableApplicationMapper","application",Map.of("operation",operation));
            assertFalse(query.contains("f_creator_user_id"));
            assertTrue(query.contains((operation.equals("yichexiao") ? "tiyi_ren_id" : "shenqing_ren_id") + " creator_user_id"));
            assertTrue(c.getResultMap("jnpf.dmsMapper.DmsDisableApplicationMapper.Occupancy").getResultMappings().stream()
                    .anyMatch(r -> "creator_user_id".equals(r.getColumn()) && "creatorUserId".equals(r.getProperty())));
            String fixtureDir=System.getProperty("dms.occupancySqlDir");
            if (fixtureDir != null) {
                java.nio.file.Path dir=java.nio.file.Paths.get(fixtureDir);
                java.nio.file.Files.createDirectories(dir);
                java.nio.file.Files.writeString(dir.resolve("application-"+operation+".sql"),query);
            }
        }
    }
    @Test void discoveryUsesStableTenantTaskOperationAndApplicationCursor() throws Exception {
        Configuration c=parse("DmsApprovedDisableMapper");
        Map<String,Object> args=new HashMap<>();args.put("limit",100);args.put("after",null);
        String first=sql(c,"DmsApprovedDisableMapper","approvedApplications",args);
        assertFalse(first.contains("OFFSET"));assertFalse(first.contains(">"));
        assertTrue(first.contains("NOT EXISTS"));
        assertTrue(first.contains("ORDER BY COALESCE(a.tenant_id,''),COALESCE(a.task_id,''),a.operation,a.application_id LIMIT ?"));
        args.put("after",Map.of("tenantId","tenant","taskId","task","operation","yichexiao","applicationId","app"));
        org.apache.ibatis.mapping.BoundSql bound=c.getMappedStatement("jnpf.dmsMapper.DmsApprovedDisableMapper.approvedApplications").getBoundSql(args);
        assertTrue(bound.getSql().contains("> (COALESCE("));
        assertEquals(List.of("after.tenantId","after.taskId","after.operation","after.applicationId","limit"),
                bound.getParameterMappings().stream().map(org.apache.ibatis.mapping.ParameterMapping::getProperty).toList());
    }
    Configuration parse(String mapper) throws Exception {
        Configuration c=new Configuration();String resource="mapper/"+mapper+".xml";
        try(InputStream in=Resources.getResourceAsStream(resource)){new XMLMapperBuilder(in,c,resource,c.getSqlFragments()).parse();}return c;
    }
    String sql(Configuration c,String mapper,String method,Map<String,Object> args){
        return c.getMappedStatement("jnpf.dmsMapper."+mapper+"."+method).getBoundSql(args).getSql().replaceAll("\\s+"," ");
    }
    @Test void bothNativeBranchesAreBoundWithoutRawTableSubstitution() throws Exception {
        String name="DmsApprovedDisableMapper";Configuration c=parse(name);
        for(String op:List.of("yichexiao","yishixiao")){
            Map<String,Object> args=new HashMap<>();args.put("operation",op);
            String s=sql(c,name,"nativeRows",args);
            assertTrue(s.contains(op.equals("yichexiao")?"dms_wenjian_chexiao_tiyi":"dms_wenjian_shixiao_shenqing"));
            assertTrue(s.contains("m.f_flow_state=2"));assertTrue(s.contains("FOR UPDATE OF m,c"));
        }
        assertTrue(c.getResultMap("jnpf.dmsMapper.DmsApprovedDisableMapper.Request").getResultMappings().stream()
                .anyMatch(r->"business_version_id".equals(r.getColumn())&&"businessVersionId".equals(r.getProperty())));
        String target=sql(c,name,"validateTarget",new HashMap<>());
        assertTrue(target.contains("z.wenjian_leixing='zhuwenjian'"));assertTrue(target.contains("z.biz_status='effective'"));
        String candidate=sql(c,name,"candidateExists",new HashMap<>());
        assertTrue(candidate.contains("fresh.wenjian_leixing='zhuwenjian'"));assertTrue(candidate.contains("b.status='APPLIED'"));
        assertTrue(candidate.contains("b.activated_at<=CURRENT_TIMESTAMP"));
    }
    @Test void fixedOccupancyRetainsReturnedAndRequiresRealUnsuccessfulEnd() throws Exception {
        Configuration c=parse("DmsDisableApplicationMapper");
        String s=sql(c,"DmsDisableApplicationMapper","pendingForFile",new HashMap<>());
        assertTrue(s.contains("dms_file_operation_occupancies"));
        assertFalse(s.contains("dms_wenjian_chexiao_tiyi")); assertFalse(s.contains("UNION ALL"));
        assertTrue(s.contains("g.zhu_wenjian_id= o.file_id"));
        assertTrue(s.contains("g.guanlian_wenjian_id=z.f_id"));
        assertTrue(s.contains("g.guanxi_leixing='jilu'"));
        assertFalse(s.contains("wenjian_mulu_id"));
        assertTrue(s.contains("o.active=true"));
        assertFalse(s.contains("workflow_task"));
        for (String op:List.of("yichexiao","yishixiao")) {
            String rows=sql(c,"DmsDisableApplicationMapper","applicationFiles",Map.of("operation",op));
            assertTrue(rows.contains("z.wenjian_leixing='zhuwenjian'"));
        }
        for (String method:List.of("legacyApplicationsForFile","legacyApplicationsForDocument")) {
            String legacy=sql(c,"DmsDisableApplicationMapper",method,new HashMap<>());
            assertFalse(legacy.contains("workflow_task"));
            assertTrue(legacy.contains("g.zhu_wenjian_id= a.file_id"));
            assertFalse(legacy.contains("wenjian_mulu_id"));
        }
        String conflict=sql(c,"DmsDisableApplicationMapper","conflictingFiles",Map.of("fileIds",List.of("f1","f2")));
        assertTrue(conflict.contains("o.task_id<>?"));assertFalse(conflict.contains("o.operation="));
        String release=sql(c,"DmsDisableApplicationMapper","releaseFile",new HashMap<>());
        assertTrue(release.contains("task_id=? AND operation=? AND file_id=?"));
        String fixtureDir=System.getProperty("dms.occupancySqlDir");
        if (fixtureDir!=null) {
            Map<String,Object> args=new HashMap<>();args.put("tenantId","tenant");args.put("fileId","record");
            args.put("taskId","own");args.put("operation","yichexiao");args.put("fileIds",List.of("main"));
            args.put("applicationId","application");args.put("flowId","flow");args.put("folderId","folder");
            args.put("documentId",UUID.fromString("00000000-0000-0000-0000-000000000001"));
            java.nio.file.Path dir=java.nio.file.Paths.get(fixtureDir);java.nio.file.Files.createDirectories(dir);
            for(String method:List.of("pendingForFile","pendingForDocument","conflictingFiles","selectedFiles","releaseFile","releaseTask","occupy","application","applicationFiles","legacyApplicationsForFile")) {
                org.apache.ibatis.mapping.BoundSql bound=c.getMappedStatement("jnpf.dmsMapper.DmsDisableApplicationMapper."+method).getBoundSql(args);
                String rendered=bound.getSql();
                for(org.apache.ibatis.mapping.ParameterMapping mapping:bound.getParameterMappings()) {
                    String prop=mapping.getProperty();Object value=bound.hasAdditionalParameter(prop)?bound.getAdditionalParameter(prop):args.get(prop);
                    String literal=value==null?"NULL":"'"+value.toString().replace("'","''")+"'";
                    rendered=rendered.replaceFirst("\\?",java.util.regex.Matcher.quoteReplacement(literal));
                }
                java.nio.file.Files.writeString(dir.resolve(method+".sql"),rendered.replace("public.","pg_temp."));
            }
        }
    }
    @Test void unifiedProgressSqlUsesSharedItemsAndBatchLease() throws Exception {
        Configuration c=parse("DmsApprovedDisableMapper"),b=parse("DmsApprovedBatchMapper");
        String candidates=sql(b,"DmsApprovedBatchMapper","retryCandidates",Map.of("includeDisable",false));
        assertTrue(candidates.contains("audit_type IN ('xinzeng_shenhe','xiuding_shenhe')"));
        assertFalse(sql(b,"DmsApprovedBatchMapper","retryCandidates",Map.of("includeDisable",true)).contains("audit_type IN"));
        String dirName=System.getProperty("dms.unifiedSqlDir");
        Map<String,Object> args=new HashMap<>();
        args.put("id","10000000-0000-0000-0000-000000000002");args.put("batchId","10000000-0000-0000-0000-000000000001");
        args.put("tenantId","0");args.put("flowId","fixture-flow");args.put("taskId","fixture-task");
        args.put("auditId","fixture-application");args.put("auditType","chexiao_shenqing");
        args.put("operation","yichexiao");args.put("sourceRowId","fixture-row");args.put("fileId","fixture-file");
        args.put("businessVersionId","fixture-version");args.put("sourceFileId","new-file");args.put("sourceVersionId","new-version");
        args.put("documentId","10000000-0000-0000-0000-000000000003");args.put("fileVersionId","10000000-0000-0000-0000-000000000004");
        args.put("folderId","10000000-0000-0000-0000-000000000005");args.put("actorId","fixture-actor");
        args.put("scheduledAt","2020-01-01T00:00:00Z");args.put("approvedAt","2020-01-01T00:00:00Z");
        args.put("sourceDigest","a".repeat(64));args.put("status","WAITING");args.put("leaseToken","fixture-lease");
        args.put("token","fixture-lease");args.put("delay",60);args.put("includeDisable",false);
        for (String method:List.of("enqueue","lock","dueItems","refreshProgress")) {
            String query=sql(c,"DmsApprovedDisableMapper",method,args);
            assertFalse(query.contains("dms_approved_file_disables"));
            if(dirName!=null) {
                Map<String,Object> values=new HashMap<>(args);
                if(method.equals("refreshProgress"))values.put("id",args.get("batchId"));
                dump(c,"DmsApprovedDisableMapper",method,values,dirName,method);
            }
        }
        if(dirName!=null) {
            args.put("id",args.get("batchId"));
            for(String method:List.of("insertBatch","claim","finish","retryCandidates"))
                dump(b,"DmsApprovedBatchMapper",method,args,dirName,method);
            args.put("error","fixture-row-failed");dump(b,"DmsApprovedBatchMapper","finish",args,dirName,"finishError");
            args.put("includeDisable",true);dump(b,"DmsApprovedBatchMapper","retryCandidates",args,dirName,"allCandidates");
        }
    }
    void dump(Configuration c,String mapper,String method,Map<String,Object> args,String dir,String filename) throws Exception {
        org.apache.ibatis.mapping.BoundSql bound=c.getMappedStatement("jnpf.dmsMapper."+mapper+"."+method).getBoundSql(args);
        String rendered=bound.getSql();
        for(org.apache.ibatis.mapping.ParameterMapping mapping:bound.getParameterMappings()) {
            Object value=args.get(mapping.getProperty());
            String literal=value==null?"NULL":value instanceof Number?value.toString():"'"+value.toString().replace("'","''")+"'";
            rendered=rendered.replaceFirst("\\?",java.util.regex.Matcher.quoteReplacement(literal));
        }
        java.nio.file.Path path=java.nio.file.Paths.get(dir);java.nio.file.Files.createDirectories(path);
        java.nio.file.Files.writeString(path.resolve(filename+".sql"),rendered.replace("public.","pg_temp."));
    }
    @Test void disableAndOccupancyMappersNeverAccessFileCenterTables() throws Exception {
        for (String mapper:List.of("DmsApprovedDisableMapper","DmsDisableApplicationMapper")) {
            try(InputStream in=Resources.getResourceAsStream("mapper/"+mapper+".xml")) {
                String xml=new String(in.readAllBytes(), java.nio.charset.StandardCharsets.UTF_8);
                for (String center:List.of("dms_documents","dms_folders","dms_file_versions","dms_version_states"))
                    assertFalse(xml.contains(center), mapper+" must use DMS center services, not "+center);
            }
        }
    }
}