Skip to content

Commit 997dcd5

Browse files
committed
Add support for the @Returning annotation in Delete, Insert, and Update DAO operations
1 parent a98f711 commit 997dcd5

File tree

28 files changed

+1089
-27
lines changed

28 files changed

+1089
-27
lines changed

doma-core/src/main/java/org/seasar/doma/Delete.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,10 @@
100100
* @return the output format of SQL logs.
101101
*/
102102
SqlLogType sqlLog() default SqlLogType.FORMATTED;
103+
104+
/**
105+
* @return the {@link Returning} annotation configuration, which defines inclusions or exclusions
106+
* for returning values.
107+
*/
108+
Returning returning() default @Returning;
103109
}

doma-core/src/main/java/org/seasar/doma/Insert.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,10 @@
137137
* @return the keys that should be used to determine if a duplicate key exists.
138138
*/
139139
String[] duplicateKeys() default {};
140+
141+
/**
142+
* @return the {@link Returning} annotation configuration, which defines inclusions or exclusions
143+
* for returning values.
144+
*/
145+
Returning returning() default @Returning;
140146
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright Doma Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.seasar.doma;
17+
18+
/**
19+
* Indicates that specific properties of an entity should be included or excluded in the context of
20+
* a {@link Dao} operation.
21+
*
22+
* <ul>
23+
* <li>These attributes are optional and can be used together.
24+
* <li>When neither attribute is specified, all properties are included by default.
25+
* </ul>
26+
*/
27+
public @interface Returning {
28+
/**
29+
* Specifies the names of properties to be explicitly included. If specified, only the listed
30+
* properties will be included.
31+
*
32+
* @return an array of property names to include
33+
*/
34+
String[] include() default {};
35+
36+
/**
37+
* Specifies the names of properties to be explicitly excluded. If specified, all properties will
38+
* be included except for those listed.
39+
*
40+
* @return an array of property names to exclude
41+
*/
42+
String[] exclude() default {};
43+
}

doma-core/src/main/java/org/seasar/doma/Update.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,10 @@
138138
* @return the output format of SQL logs.
139139
*/
140140
SqlLogType sqlLog() default SqlLogType.FORMATTED;
141+
142+
/**
143+
* @return the {@link Returning} annotation configuration, which defines inclusions or exclusions
144+
* for returning values.
145+
*/
146+
Returning returning() default @Returning;
141147
}

doma-core/src/main/java/org/seasar/doma/message/Message.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,12 @@ public enum Message implements MessageResource {
10051005
DOMA4489("The property path \"{0}\" is duplicated in another @AssociationLinker."),
10061006
DOMA4490(
10071007
"Multiple @ExternalDomain definitions were found for type \"{0}\". \"{1}\" conflicts with \"{2}\"."),
1008+
DOMA4491("\"returning = @Returning\" cannot be specified when \"sqlFile = true\"."),
1009+
DOMA4492("\"returning = @Returning\" is not allowed in combination with @Sql."),
1010+
DOMA4493("The property \"{0}\" is not found in the entity class \"{1}\"."),
1011+
DOMA4494("The property \"{0}\" is not found in the entity class \"{1}\"."),
1012+
DOMA4495(
1013+
"When \"returning = @Returning\" is specified, the return type must be the same as the parameter type or an Optional whose element is the parameter type."),
10081014

10091015
// other
10101016
DOMA5001(

doma-processor/src/main/java/org/seasar/doma/internal/apt/annot/Annotations.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,14 @@ public DomainConvertersAnnot newDomainConvertersAnnot(TypeElement typeElement) {
188188

189189
public DeleteAnnot newDeleteAnnot(ExecutableElement method) {
190190
assertNotNull(method);
191-
return newInstance(method, Delete.class, DeleteAnnot::new);
191+
AnnotationMirror deleteMirror = ctx.getMoreElements().getAnnotationMirror(method, Delete.class);
192+
if (deleteMirror == null) {
193+
return null;
194+
}
195+
ReturningAnnot returningAnnot = newReturningAnnot(deleteMirror, ModifyAnnot.RETURNING);
196+
Map<String, AnnotationValue> valuesWithDefaults =
197+
ctx.getMoreElements().getValuesWithDefaults(deleteMirror);
198+
return new DeleteAnnot(deleteMirror, returningAnnot, valuesWithDefaults);
192199
}
193200

194201
public EmbeddableAnnot newEmbeddableAnnot(TypeElement typeElement) {
@@ -241,7 +248,14 @@ public FunctionAnnot newFunctionAnnot(final ExecutableElement method) {
241248

242249
public InsertAnnot newInsertAnnot(ExecutableElement method) {
243250
assertNotNull(method);
244-
return newInstance(method, Insert.class, InsertAnnot::new);
251+
AnnotationMirror insertMirror = ctx.getMoreElements().getAnnotationMirror(method, Insert.class);
252+
if (insertMirror == null) {
253+
return null;
254+
}
255+
ReturningAnnot returningAnnot = newReturningAnnot(insertMirror, ModifyAnnot.RETURNING);
256+
Map<String, AnnotationValue> valuesWithDefaults =
257+
ctx.getMoreElements().getValuesWithDefaults(insertMirror);
258+
return new InsertAnnot(insertMirror, returningAnnot, valuesWithDefaults);
245259
}
246260

247261
public MultiInsertAnnot newMultiInsertAnnot(ExecutableElement method) {
@@ -273,6 +287,27 @@ public ResultSetAnnot newResultSetAnnot(VariableElement param) {
273287
return newInstance(param, ResultSet.class, ResultSetAnnot::new);
274288
}
275289

290+
private ReturningAnnot newReturningAnnot(AnnotationMirror annotationMirror) {
291+
assertNotNull(annotationMirror);
292+
return newInstance(annotationMirror, ReturningAnnot::new);
293+
}
294+
295+
private ReturningAnnot newReturningAnnot(
296+
AnnotationMirror ownerAnnotationMirror, String returningElementName) {
297+
assertNotNull(ownerAnnotationMirror, returningElementName);
298+
Map<String, AnnotationValue> valuesWithoutDefaults =
299+
ctx.getMoreElements().getValuesWithoutDefaults(ownerAnnotationMirror);
300+
AnnotationValue returning = valuesWithoutDefaults.get(returningElementName);
301+
if (returning == null) {
302+
return null;
303+
}
304+
AnnotationMirror returningMirror = AnnotationValueUtil.toAnnotation(returning);
305+
if (returningMirror == null) {
306+
return null;
307+
}
308+
return newReturningAnnot(returningMirror);
309+
}
310+
276311
public ScriptAnnot newScriptAnnot(ExecutableElement method) {
277312
assertNotNull(method);
278313
return newInstance(method, Script.class, ScriptAnnot::new);
@@ -315,7 +350,14 @@ public TableAnnot newTableAnnot(TypeElement typeElement) {
315350

316351
public UpdateAnnot newUpdateAnnot(ExecutableElement method) {
317352
assertNotNull(method);
318-
return newInstance(method, Update.class, UpdateAnnot::new);
353+
AnnotationMirror updateMirror = ctx.getMoreElements().getAnnotationMirror(method, Update.class);
354+
if (updateMirror == null) {
355+
return null;
356+
}
357+
ReturningAnnot returningAnnot = newReturningAnnot(updateMirror, ModifyAnnot.RETURNING);
358+
Map<String, AnnotationValue> valuesWithDefaults =
359+
ctx.getMoreElements().getValuesWithDefaults(updateMirror);
360+
return new UpdateAnnot(updateMirror, returningAnnot, valuesWithDefaults);
319361
}
320362

321363
public ValueAnnot newValueAnnot(TypeElement typeElement) {

doma-processor/src/main/java/org/seasar/doma/internal/apt/annot/DeleteAnnot.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121

2222
public class DeleteAnnot extends ModifyAnnot {
2323

24-
DeleteAnnot(AnnotationMirror annotationMirror, Map<String, AnnotationValue> values) {
25-
super(annotationMirror, values);
24+
DeleteAnnot(
25+
AnnotationMirror annotationMirror,
26+
ReturningAnnot returningAnnot,
27+
Map<String, AnnotationValue> values) {
28+
super(annotationMirror, returningAnnot, values);
2629
}
2730
}

doma-processor/src/main/java/org/seasar/doma/internal/apt/annot/InsertAnnot.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121

2222
public class InsertAnnot extends ModifyAnnot {
2323

24-
InsertAnnot(AnnotationMirror annotationMirror, Map<String, AnnotationValue> values) {
25-
super(annotationMirror, values);
24+
InsertAnnot(
25+
AnnotationMirror annotationMirror,
26+
ReturningAnnot returningAnnot,
27+
Map<String, AnnotationValue> values) {
28+
super(annotationMirror, returningAnnot, values);
2629
}
2730
}

doma-processor/src/main/java/org/seasar/doma/internal/apt/annot/ModifyAnnot.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ public abstract class ModifyAnnot extends AbstractAnnot {
5252

5353
private static final String DUPLICATE_KEYS = "duplicateKeys";
5454

55+
static final String RETURNING = "returning";
56+
57+
private final ReturningAnnot returningAnnot;
58+
5559
private final AnnotationValue sqlFile;
5660

5761
private final AnnotationValue queryTimeout;
@@ -74,7 +78,10 @@ public abstract class ModifyAnnot extends AbstractAnnot {
7478

7579
private final AnnotationValue duplicateKeys;
7680

77-
ModifyAnnot(AnnotationMirror annotationMirror, Map<String, AnnotationValue> values) {
81+
ModifyAnnot(
82+
AnnotationMirror annotationMirror,
83+
ReturningAnnot returningAnnot,
84+
Map<String, AnnotationValue> values) {
7885
super(annotationMirror);
7986

8087
// non null values
@@ -83,6 +90,7 @@ public abstract class ModifyAnnot extends AbstractAnnot {
8390
this.sqlLog = assertNonNullValue(values, SQL_LOG);
8491

8592
// nullable values
93+
this.returningAnnot = returningAnnot;
8694
this.ignoreVersion = values.get(IGNORE_VERSION);
8795
this.excludeNull = values.get(EXCLUDE_NULL);
8896
this.suppressOptimisticLockException = values.get(SUPPRESS_OPTIMISTIC_LOCK_EXCEPTION);
@@ -93,6 +101,10 @@ public abstract class ModifyAnnot extends AbstractAnnot {
93101
this.duplicateKeys = values.get(DUPLICATE_KEYS);
94102
}
95103

104+
public ReturningAnnot getReturningAnnot() {
105+
return returningAnnot;
106+
}
107+
96108
public AnnotationValue getSqlFile() {
97109
return sqlFile;
98110
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright Doma Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.seasar.doma.internal.apt.annot;
17+
18+
import static org.seasar.doma.internal.util.AssertionUtil.assertNonNullValue;
19+
20+
import java.util.List;
21+
import java.util.Map;
22+
import javax.lang.model.element.AnnotationMirror;
23+
import javax.lang.model.element.AnnotationValue;
24+
import org.seasar.doma.internal.apt.util.AnnotationValueUtil;
25+
26+
public class ReturningAnnot extends AbstractAnnot {
27+
28+
private static final String INCLUDE = "include";
29+
30+
private static final String EXCLUDE = "exclude";
31+
32+
private final AnnotationValue include;
33+
34+
private final AnnotationValue exclude;
35+
36+
ReturningAnnot(AnnotationMirror annotationMirror, Map<String, AnnotationValue> values) {
37+
super(annotationMirror);
38+
this.include = assertNonNullValue(values, INCLUDE);
39+
this.exclude = assertNonNullValue(values, EXCLUDE);
40+
}
41+
42+
public AnnotationValue getInclude() {
43+
return include;
44+
}
45+
46+
public AnnotationValue getExclude() {
47+
return exclude;
48+
}
49+
50+
public List<String> getIncludeValue() {
51+
return AnnotationValueUtil.toStringList(include);
52+
}
53+
54+
public List<String> getExcludeValue() {
55+
return AnnotationValueUtil.toStringList(exclude);
56+
}
57+
}

0 commit comments

Comments
 (0)