Skip to content

Commit b7a29bf

Browse files
committed
Implements HsqldbUpsertAssembler
1 parent 26c55c0 commit b7a29bf

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import org.seasar.doma.jdbc.SqlLogFormattingVisitor;
1313
import org.seasar.doma.jdbc.SqlLogType;
1414
import org.seasar.doma.jdbc.SqlNode;
15+
import org.seasar.doma.jdbc.query.UpsertAssembler;
16+
import org.seasar.doma.jdbc.query.UpsertAssemblerContext;
1517

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

0 commit comments

Comments
 (0)