Skip to content

Commit 26c55c0

Browse files
committed
Implements Db2UpsertAssembler
1 parent 4d56fcf commit 26c55c0

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed

doma-core/src/main/java/org/seasar/doma/jdbc/dialect/Db2Dialect.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import org.seasar.doma.jdbc.criteria.option.ForUpdateOption;
2222
import org.seasar.doma.jdbc.criteria.query.AliasManager;
2323
import org.seasar.doma.jdbc.criteria.query.CriteriaBuilder;
24+
import org.seasar.doma.jdbc.query.UpsertAssembler;
25+
import org.seasar.doma.jdbc.query.UpsertAssemblerContext;
2426

2527
/** A dialect for Db2. */
2628
public class Db2Dialect extends StandardDialect {
@@ -195,4 +197,9 @@ private void appendSql() {
195197
});
196198
}
197199
}
200+
201+
@Override
202+
public UpsertAssembler getUpsertAssembler(UpsertAssemblerContext context) {
203+
return new Db2UpsertAssembler(context);
204+
}
198205
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package org.seasar.doma.jdbc.dialect;
2+
3+
import org.seasar.doma.internal.jdbc.sql.PreparedSqlBuilder;
4+
import org.seasar.doma.jdbc.InParameter;
5+
import org.seasar.doma.jdbc.criteria.tuple.Tuple2;
6+
import org.seasar.doma.jdbc.entity.EntityPropertyType;
7+
import org.seasar.doma.jdbc.entity.EntityType;
8+
import org.seasar.doma.jdbc.query.DuplicateKeyType;
9+
import org.seasar.doma.jdbc.query.UpsertAssembler;
10+
import org.seasar.doma.jdbc.query.UpsertAssemblerContext;
11+
import org.seasar.doma.jdbc.query.UpsertAssemblerSupport;
12+
import org.seasar.doma.jdbc.query.UpsertSetValue;
13+
14+
import java.util.List;
15+
16+
public class Db2UpsertAssembler implements UpsertAssembler {
17+
private final PreparedSqlBuilder buf;
18+
private final EntityType<?> entityType;
19+
private final DuplicateKeyType duplicateKeyType;
20+
private final UpsertAssemblerSupport upsertAssemblerSupport;
21+
private final List<EntityPropertyType<?, ?>> keys;
22+
private final List<Tuple2<EntityPropertyType<?, ?>, InParameter<?>>> insertValues;
23+
private final List<Tuple2<EntityPropertyType<?, ?>, UpsertSetValue>> setValues;
24+
private final UpsertSetValue.Visitor upsertSetValueVisitor = new UpsertSetValueVisitor();
25+
26+
public Db2UpsertAssembler(UpsertAssemblerContext context) {
27+
this.buf = context.buf;
28+
this.entityType = context.entityType;
29+
this.duplicateKeyType = context.duplicateKeyType;
30+
this.keys = context.keys;
31+
this.insertValues = context.insertValues;
32+
this.setValues = context.setValues;
33+
this.upsertAssemblerSupport = new UpsertAssemblerSupport(context.naming, context.dialect);
34+
}
35+
36+
@Override
37+
public void assemble() {
38+
buf.appendSql("merge into ");
39+
tableNameAndAlias(entityType);
40+
buf.appendSql(" using (");
41+
excludeQuery();
42+
buf.appendSql(") as ");
43+
excludeAlias();
44+
buf.appendSql(" on ");
45+
for (EntityPropertyType<?, ?> key : keys) {
46+
targetColumn(key);
47+
buf.appendSql(" = ");
48+
assignmentColumn(key);
49+
buf.appendSql(" and ");
50+
}
51+
buf.cutBackSql(5);
52+
buf.appendSql(" when not matched then insert (");
53+
for (Tuple2<EntityPropertyType<?, ?>, InParameter<?>> insertValue : insertValues) {
54+
column(insertValue.component1());
55+
buf.appendSql(", ");
56+
}
57+
buf.cutBackSql(2);
58+
buf.appendSql(") values (");
59+
for (Tuple2<EntityPropertyType<?, ?>, InParameter<?>> insertValue : insertValues) {
60+
assignmentColumn(insertValue.component1());
61+
buf.appendSql(", ");
62+
}
63+
buf.cutBackSql(2);
64+
buf.appendSql(")");
65+
if (duplicateKeyType == DuplicateKeyType.UPDATE) {
66+
buf.appendSql(" when matched then update set ");
67+
for (Tuple2<EntityPropertyType<?, ?>, UpsertSetValue> setValue : setValues) {
68+
targetColumn(setValue.component1());
69+
buf.appendSql(" = ");
70+
setValue.component2().accept(upsertSetValueVisitor);
71+
buf.appendSql(", ");
72+
}
73+
buf.cutBackSql(2);
74+
}
75+
}
76+
77+
private void excludeQuery() {
78+
buf.appendSql("select ");
79+
for (Tuple2<EntityPropertyType<?, ?>, InParameter<?>> insertValue : insertValues) {
80+
column(insertValue.component1());
81+
buf.appendSql(", ");
82+
}
83+
buf.cutBackSql(2);
84+
buf.appendSql(" from values (");
85+
for (Tuple2<EntityPropertyType<?, ?>, InParameter<?>> insertValue : insertValues) {
86+
buf.appendParameter(insertValue.component2());
87+
buf.appendSql(" as ");
88+
column(insertValue.component1());
89+
buf.appendSql(", ");
90+
}
91+
buf.cutBackSql(2);
92+
buf.appendSql(") as dual");
93+
}
94+
95+
private void tableNameAndAlias(EntityType<?> entityType) {
96+
String sql =
97+
this.upsertAssemblerSupport.targetTable(
98+
entityType, UpsertAssemblerSupport.TableNameType.NAME_AS_ALIAS);
99+
buf.appendSql(sql);
100+
}
101+
102+
private void excludeAlias() {
103+
String sql = this.upsertAssemblerSupport.excludeAlias();
104+
buf.appendSql(sql);
105+
}
106+
107+
private void targetColumn(EntityPropertyType<?, ?> propertyType) {
108+
String sql =
109+
this.upsertAssemblerSupport.targetProp(
110+
propertyType, UpsertAssemblerSupport.ColumnNameType.NAME_ALIAS);
111+
buf.appendSql(sql);
112+
}
113+
114+
private void assignmentColumn(EntityPropertyType<?, ?> propertyType) {
115+
String sql =
116+
this.upsertAssemblerSupport.excludeProp(
117+
propertyType, UpsertAssemblerSupport.ColumnNameType.NAME_ALIAS);
118+
buf.appendSql(sql);
119+
}
120+
121+
private void column(EntityPropertyType<?, ?> propertyType) {
122+
String sql =
123+
this.upsertAssemblerSupport.excludeProp(
124+
propertyType, UpsertAssemblerSupport.ColumnNameType.NAME);
125+
buf.appendSql(sql);
126+
}
127+
128+
class UpsertSetValueVisitor implements UpsertSetValue.Visitor {
129+
@Override
130+
public void visit(UpsertSetValue.Param param) {
131+
buf.appendParameter(param.inParameter);
132+
}
133+
134+
@Override
135+
public void visit(UpsertSetValue.Prop prop) {
136+
String sql =
137+
upsertAssemblerSupport.excludeProp(
138+
prop.propertyType, UpsertAssemblerSupport.ColumnNameType.NAME_ALIAS);
139+
buf.appendSql(sql);
140+
}
141+
}
142+
}

0 commit comments

Comments
 (0)