33 |
33 |
34 /** |
34 /** |
35 * <p> |
35 * <p> |
36 * A set of {@link Operation}s that share certain properties, are managed as a |
36 * A set of {@link Operation}s that share certain properties, are managed as a |
37 * unit, and are executed as a unit. The {@link Operation}s created by an |
37 * unit, and are executed as a unit. The {@link Operation}s created by an |
38 * {@link OperationGroup} and submitted are the member {@link Operation}s of |
38 * {@code OperationGroup} and submitted are the member {@link Operation}s of |
39 * that {@link OperationGroup}. An {@link OperationGroup} is not a transaction |
39 * that {@code OperationGroup}. An {@code OperationGroup} is not a transaction |
40 * and is not related to a transaction in any way.</p> |
40 * and is not related to a transaction in any way.</p> |
41 * |
41 * |
42 * <p> |
42 * <p> |
43 * An {@link OperationGroup} conceptually has a collection of member |
43 * An {@link OperationGroup} provides conditional execution, control of error |
44 * {@link Operation}s. When an {@link OperationGroup} is submitted it is placed |
44 * response, and control of execution order.</p> |
45 * in the collection of the {@link OperationGroup} of which it is a member. The |
45 * |
46 * member {@link OperationGroup} is executed according to the attributes of the |
46 * <p> |
47 * {@link OperationGroup} of which it is a member. The member {@link Operation}s |
47 * Execution of one or more {@link Operation}s may depend on the result of a |
48 * of an {@link OperationGroup} are executed according to the attributes of that |
48 * previous {@link Operation}. Depending on the result of that previous |
49 * {@link OperationGroup}.</p> |
49 * {@link Operation} some other {@link Operation}s perhaps should not be |
50 * |
50 * executed. For example consider an account withdrawal. If the amount to |
51 * <p> |
51 * withdraw exceeds the account balance the withdrawal {@link Operation}s should |
52 * How an {@link OperationGroup} is executed depends on its attributes.</p> |
52 * not be executed and an overdraft {@link Operation} should be executed |
53 * |
53 * instead. It would be possible for the user thread to wait for the balance |
54 * <p> |
54 * check {@link Operation} but that would block. Better would be to use the |
55 * If an {@link OperationGroup} has a condition and the value of that condition |
55 * {@link java.util.concurrent.CompletionStage} of the balance check |
|
56 * {@link Operation} and submit the appropriate {@link Operation} in a |
|
57 * subsequent stage. But this is a common pattern and it is better still to |
|
58 * encapsulate that pattern, which conditional {@link OperationGroup} does.</p> |
|
59 * |
|
60 * <p> |
|
61 * Not all {@link Operation}s need to be executed in the order submitted. The |
|
62 * most common example is a mass insert. The order in which the records are |
|
63 * inserted doesn’t matter. A parallel {@link OperationGroup} gives the |
|
64 * implementation the freedom to execute the {@link Operation}s in any order. If |
|
65 * some of the {@link Operation}s have |
|
66 * {@link java.util.concurrent.CompletionStage} parameters this can be |
|
67 * especially valuable.</p> |
|
68 * |
|
69 * <p> |
|
70 * {@link OperationGroup} also allows control of error response. By default if |
|
71 * one {@link Operation} fails all subsequent {@link Operation}s are skipped. |
|
72 * That’s not always right. Consider the mass insert case. Just because one |
|
73 * insert fails doesn’t mean they should all fail. An independent |
|
74 * {@link OperationGroup} does this; the failure of one {@link Operation} has no |
|
75 * impact on the execution of the rest.</p> |
|
76 * |
|
77 * <p> |
|
78 * As an {@link OperationGroup} is an {@link Operation} it must be submitted |
|
79 * before its member {@link Operation}s are executed. Submitting an {@link OperationGroup} |
|
80 * allows its member {@link Operation}s to be executed but does not prohibit more |
|
81 * member {@link Operation}s from being submitted. Member {@link Operation}s may be |
|
82 * submitted before and after the containing {@link OperationGroup} is submitted.</p> |
|
83 * |
|
84 * <p> |
|
85 * The result of an {@link OperationGroup} depends on the results of its member |
|
86 * {@link Operation}s. Therefore an {@link OperationGroup} must know when all |
|
87 * member {@link Operation}s have been submitted. It cannot generate a |
|
88 * result until all member {@link Operation}s are completed. Since member {@link Operation}s can be |
|
89 * submitted after the {@link OperationGroup} has been submitted (see previous |
|
90 * paragraph) submitting the containing {@link OperationGroup} is not sufficient to mark that all member |
|
91 * {@link Operation}s have been submitted. Calling {@link OperationGroup#close} signals |
|
92 * that all member Operations have been submitted. After close is called, no |
|
93 * more member Operations may be submitted and the OperationGroup will complete |
|
94 * when all member Operations are complete.</p> |
|
95 * |
|
96 * <p> |
|
97 * An {@code OperationGroup} conceptually has a collection of member |
|
98 * {@link Operation}s. When an {@code OperationGroup} is submitted it is placed |
|
99 * in the collection of the {@code OperationGroup} of which it is a member. The |
|
100 * member {@code OperationGroup} is executed according to the attributes of the |
|
101 * {@code OperationGroup} of which it is a member. The member {@link Operation}s |
|
102 * of an {@code OperationGroup} are executed according to the attributes of that |
|
103 * {@code OperationGroup}.</p> |
|
104 * |
|
105 * <p> |
|
106 * How an {@code OperationGroup} is executed depends on its attributes.</p> |
|
107 * |
|
108 * <p> |
|
109 * If an {@code OperationGroup} has a condition and the value of that condition |
56 * is {@link Boolean#TRUE} then execute the member {@link Operation}s as below. |
110 * is {@link Boolean#TRUE} then execute the member {@link Operation}s as below. |
57 * If it is {@link Boolean#FALSE} then the {@link OperationGroup} is completed |
111 * If it is {@link Boolean#FALSE} then the {@code OperationGroup} is completed |
58 * with the value null. If the condition completed exceptionally then the |
112 * with the value null. If the condition completed exceptionally then the |
59 * {@link OperationGroup} is completed exceptionally with a |
113 * {@code OperationGroup} is completed exceptionally with a |
60 * {@link SqlSkippedException} that has that exception as its cause.</p> |
114 * {@link SqlSkippedException} that has that exception as its cause.</p> |
61 * |
115 * |
62 * <p> |
116 * <p> |
63 * If the {@link OperationGroup} is sequential the member {@link Operation}s are |
117 * If the {@code OperationGroup} is sequential the member {@link Operation}s are |
64 * executed in the order they were submitted. If it is parallel, they may be |
118 * executed in the order they were submitted. If it is parallel, they may be |
65 * executed in any order including simultaneously.</p> |
119 * executed in any order including simultaneously.</p> |
66 * |
120 * |
67 * <p> |
121 * <p> |
68 * If an {@link OperationGroup} is dependent and a member {@link Operation} |
122 * If an {@code OperationGroup} is dependent and a member {@link Operation} |
69 * completes exceptionally the remaining member {@link Operation}s in the |
123 * completes exceptionally the remaining member {@link Operation}s in the |
70 * collection are completed exceptionally with a {@link SqlSkippedException} |
124 * collection are completed exceptionally with a {@link SqlSkippedException} |
71 * that has the initial {@link Exception} as its cause and the {@link OperationGroup} |
125 * that has the initial {@link Exception} as its cause and the |
72 * is completed exceptionally with the initial {@link Exception}. A member |
126 * {@code OperationGroup} is completed exceptionally with the initial |
73 * {@link Operation} in-flight may either complete normally or be completed |
127 * {@link Exception}. A member {@link Operation} in-flight may either complete |
74 * exceptionally but must complete one way or the other. [NOTE: Too strong?]</p> |
128 * normally or be completed exceptionally but must complete one way or the |
75 * |
129 * other. [NOTE: Too strong?]</p> |
76 * <p> |
130 * |
77 * After a call to {@link OperationGroup#submitHoldingForMoreMembers} the |
131 * <p> |
78 * {@link OperationGroup} is submitted and held. After a call to |
132 * The result of this {@code OperationGroup} is the result of collecting the |
79 * {@link OperationGroup#releaseProhibitingMoreMembers} the {@link OperationGroup} |
133 * results of its member {@link Operation}s. If the {@code OperationGroup} is |
80 * is no longer held and is still submitted. Holding permits member {@link Operation}s |
|
81 * to be executed at the same time additional member {@link Operation}s are |
|
82 * submitted. Collecting the member {@link Operation}s' results does not begin |
|
83 * until the {@link OperationGroup} is no longer held.</p> |
|
84 * |
|
85 * <p> |
|
86 * If an {@link OperationGroup} is held additional member {@link Operation}s may |
|
87 * be submitted. If an {@link OperationGroup} is not held, no additional member |
|
88 * {@link Operation}s may be submitted after the {@link OperationGroup} is |
|
89 * submitted. If an {@link OperationGroup} is held it will be completed only after |
|
90 * it is released or if conditional and the condition is not {@link Boolean#TRUE}. |
|
91 * If a {@link OperationGroup} is dependent, held, one of its member |
|
92 * {@link Operation}s completed exceptionally, and its queue is empty then the |
|
93 * {@link OperationGroup} is released.</p> |
|
94 * |
|
95 * <p> |
|
96 * The result of this {@link OperationGroup} is the result of collecting the |
|
97 * results of its member {@link Operation}s. If the {@link OperationGroup} is |
|
98 * dependent and one of its member {@link Operation}s completes exceptionally, |
134 * dependent and one of its member {@link Operation}s completes exceptionally, |
99 * the {@link OperationGroup} is completed exceptionally.</p> |
135 * the {@code OperationGroup} is completed exceptionally.</p> |
100 * |
136 * |
101 * <p> |
137 * <p> |
102 * An implementation of this class must be thread safe as result and error |
138 * An implementation of this class must be thread safe as result and error |
103 * handlers running asynchronously may be accessing an {@link OperationGroup} in |
139 * handlers running asynchronously may be accessing an {@code OperationGroup} in |
104 * parallel with each other and with a user thread.</p> |
140 * parallel with each other and with a user thread.</p> |
105 |
141 * |
106 * <p> |
142 * <p> |
107 * ISSUE: Currently no way to create a nested {@link OperationGroup}. That is an |
143 * ISSUE: Currently no way to create a nested {@code OperationGroup}. That is an |
108 * intentional limitation but may be a simplification we can live with. Or not.</p> |
144 * intentional limitation but may be a simplification we can live with. Or |
|
145 * not.</p> |
109 * |
146 * |
110 * @param <S> The type of the result of the member {@link Operation}s |
147 * @param <S> The type of the result of the member {@link Operation}s |
111 * @param <T> The type of the collected results the member {@link Operation}s |
148 * @param <T> The type of the collected results the member {@link Operation}s |
112 */ |
149 */ |
113 public interface OperationGroup<S, T> extends Operation<T> { |
150 public interface OperationGroup<S, T> extends Operation<T>, AutoCloseable { |
114 |
151 |
115 /** |
152 /** |
116 * Mark this {@link OperationGroup} as parallel. If this method is not called |
153 * Mark this {@code OperationGroup} as parallel. If this method is not called |
117 * the {@link OperationGroup} is sequential. If an {@link OperationGroup} is |
154 * the {@code OperationGroup} is sequential. If an {@code OperationGroup} is |
118 * parallel, member {@link Operation}s may be executed in any order including |
155 * parallel, member {@link Operation}s may be executed in any order including |
119 * in parallel. If an {@link OperationGroup} is sequential, the default, |
156 * in parallel. If an {@code OperationGroup} is sequential, the default, |
120 * member {@link Operation}s are executed strictly in the order they are |
157 * member {@link Operation}s are executed strictly in the order they are |
121 * submitted. |
158 * submitted. |
122 * |
159 * |
123 * Note: There is no covariant override of this method in {@link Session} |
160 * Note: There is no covariant override of this method in {@link Session} as |
124 * as there is only a small likelihood of needing it. |
161 * there is only a small likelihood of needing it. |
125 * |
162 * |
126 * @return this {@link OperationGroup} |
163 * @return this {@code OperationGroup} |
127 * @throws IllegalStateException if this {@link OperationGroup} has been |
164 * @throws IllegalStateException if this {@code OperationGroup} has been |
128 * submitted, any member {@link Operation}s have been created, or this method |
165 * submitted, any member {@link Operation}s have been created, or this method |
129 * has been called previously |
166 * has been called previously |
130 */ |
167 */ |
131 public OperationGroup<S, T> parallel(); |
168 public OperationGroup<S, T> parallel(); |
132 |
169 |
133 /** |
170 /** |
134 * Mark this {@link OperationGroup} as independent. If this method is not |
171 * Mark this {@code OperationGroup} as independent. If this method is not |
135 * called the {@link OperationGroup} is dependent, the default. If an |
172 * called the {@code OperationGroup} is dependent, the default. If an |
136 * {@link OperationGroup} is independent then failure of one member |
173 * {@code OperationGroup} is independent then failure of one member |
137 * {@link Operation} does not affect the execution of other member |
174 * {@link Operation} does not affect the execution of other member |
138 * {@link Operation}s. If an {@link OperationGroup} is dependent then failure |
175 * {@link Operation}s. If an {@code OperationGroup} is dependent then failure |
139 * of one member {@link Operation} will cause all member {@link Operation}s |
176 * of one member {@link Operation} will cause all member {@link Operation}s |
140 * remaining in the queue to be completed exceptionally with a |
177 * remaining in the queue to be completed exceptionally with a |
141 * {@link SqlSkippedException} with the cause set to the original exception. |
178 * {@link SqlSkippedException} with the cause set to the original exception. |
142 * |
179 * |
143 * The result of this {@link OperationGroup}'s execution is the result of collecting the |
180 * The result of this {@code OperationGroup}'s execution is the result of |
144 * results of the member {@link Operation}s that complete normally. |
181 * collecting the results of the member {@link Operation}s that complete |
145 * |
182 * normally. |
146 * Note: There is no covariant override of this method in {@link Session} |
183 * |
147 * as there is only a small likelihood of needing it. |
184 * Note: There is no covariant override of this method in {@link Session} as |
148 * |
185 * there is only a small likelihood of needing it. |
149 * @return this {@link OperationGroup} |
186 * |
150 * @throws IllegalStateException if this {@link OperationGroup} has been |
187 * @return this {@code OperationGroup} |
|
188 * @throws IllegalStateException if this {@code OperationGroup} has been |
151 * submitted, any member {@link Operation}s have been created, or this method |
189 * submitted, any member {@link Operation}s have been created, or this method |
152 * has been called previously |
190 * has been called previously |
153 */ |
191 */ |
154 public OperationGroup<S, T> independent(); |
192 public OperationGroup<S, T> independent(); |
155 |
193 |
156 /** |
194 /** |
157 * Define a condition that determines whether the member {@link Operation}s of |
195 * Define a condition that determines whether the member {@link Operation}s of |
158 * this {@link OperationGroup} are executed or not. If and when this |
196 * this {@code OperationGroup} are executed or not. If and when this |
159 * {@link OperationGroup} is executed then if the condition argument is |
197 * {@code OperationGroup} is executed then if the condition argument is |
160 * completed with {@link Boolean#TRUE} the member {@link Operation}s are |
198 * completed with {@link Boolean#TRUE} the member {@link Operation}s are |
161 * executed. If {@link Boolean#FALSE} or if it is completed exceptionally the |
199 * executed. If {@link Boolean#FALSE} or if it is completed exceptionally the |
162 * member {@link Operation}s are not executed but are removed from the queue. |
200 * member {@link Operation}s are not executed but are removed from the queue. |
163 * After all member {@link Operation}s have been removed from the queue this |
201 * After all member {@link Operation}s have been removed from the queue this |
164 * {@link OperationGroup} is completed with {@code null}. |
202 * {@code OperationGroup} is completed with {@code null}. |
165 * |
203 * |
166 * Note: There is no covariant override of this method in Session as there |
204 * Note: There is no covariant override of this method in Session as there is |
167 * is only a small likelihood of needing it. |
205 * only a small likelihood of needing it. |
168 * |
206 * |
169 * ISSUE: Should the member Operations be skipped or otherwise completed |
207 * ISSUE: Should the member Operations be skipped or otherwise completed |
170 * exceptionally? |
208 * exceptionally? |
171 * |
209 * |
172 * @param condition a {@link CompletionStage} the value of which determines |
210 * @param condition a {@link CompletionStage} the value of which determines |
173 * whether this {@link OperationGroup} is executed or not |
211 * whether this {@code OperationGroup} is executed or not |
174 * @return this OperationGroup |
212 * @return this OperationGroup |
175 * @throws IllegalStateException if this {@link OperationGroup} has been |
213 * @throws IllegalStateException if this {@code OperationGroup} has been |
176 * submitted, any member {@link Operation}s have been created, or this method |
214 * submitted, any member {@link Operation}s have been created, or this method |
177 * has been called previously |
215 * has been called previously |
178 */ |
216 */ |
179 public OperationGroup<S, T> conditional(CompletionStage<Boolean> condition); |
217 public OperationGroup<S, T> conditional(CompletionStage<Boolean> condition); |
180 |
218 |
181 /** |
219 /** |
182 * Mark this {@link OperationGroup} as submitted and held. It can be executed but cannot be |
|
183 * completed. A {@link OperationGroup} that is held remains in the queue even |
|
184 * if all of its current member {@link Operation}s have completed. So long as |
|
185 * the {@link OperationGroup} is held new member {@link Operation}s can be |
|
186 * submitted. A {@link OperationGroup} that is held must be released before it |
|
187 * can be completed and removed from the queue. |
|
188 * |
|
189 * If the {@link OperationGroup} is dependent and one of its member {@link Operation}s |
|
190 * completes exceptionally and its queue is empty the {@link OperationGroup} |
|
191 * is completed. |
|
192 * |
|
193 * Note: There is no covariant override of this method in Session as there |
|
194 * is only a small likelihood of needing it. |
|
195 * |
|
196 * ISSUE: Need a better name. |
|
197 * |
|
198 * @return a Submission for this OperationGroup |
|
199 * @throws IllegalStateException if this {@link OperationGroup} has been |
|
200 * submitted |
|
201 */ |
|
202 public Submission<T> submitHoldingForMoreMembers(); |
|
203 |
|
204 /** |
|
205 * Allow this {@link OperationGroup} to be completed and removed from the |
|
206 * queue once all of its member {@link Operation}s have been completed. After |
|
207 * this method is called no additional member {@link Operation}s can be |
|
208 * submitted. Once all member {@link Operation}s have been removed from the |
|
209 * queue this {@link OperationGroup} will be completed and removed from the |
|
210 * queue. |
|
211 * |
|
212 * Note: There is no covariant override of this method in Session as there |
|
213 * is only a small likelihood of needing it. |
|
214 * |
|
215 * ISSUE: Need a better name. |
|
216 * |
|
217 * @return the same Submission that was returned by {@link OperationGroup#submitHoldingForMoreMembers} |
|
218 * @throws IllegalStateException if this {@link OperationGroup} has been |
|
219 * completed or is not held. |
|
220 */ |
|
221 public Submission<T> releaseProhibitingMoreMembers(); |
|
222 |
|
223 /** |
|
224 * Provides a {@link Collector} to reduce the results of the member |
220 * Provides a {@link Collector} to reduce the results of the member |
225 * {@link Operation}s. The result of this {@link OperationGroup} is the result |
221 * {@link Operation}s. The result of this {@code OperationGroup} is the result |
226 * of calling finisher on the final accumulated result.If the |
222 * of calling finisher on the final accumulated result.If the |
227 * {@link Collector} is {@link Collector.Characteristics#UNORDERED} the member |
223 * {@link Collector} is {@link Collector.Characteristics#UNORDERED} the member |
228 * {@link Operation} results may be accumulated out of order.If the |
224 * {@link Operation} results may be accumulated out of order.If the |
229 * {@link Collector} is {@link Collector.Characteristics#CONCURRENT} then the |
225 * {@link Collector} is {@link Collector.Characteristics#CONCURRENT} then the |
230 * member {@link Operation} results may be split into subsets that are reduced |
226 * member {@link Operation} results may be split into subsets that are reduced |
231 * separately and then combined. If this {@link OperationGroup} is sequential, |
227 * separately and then combined. If this {@code OperationGroup} is sequential, |
232 * the characteristics of the {@link Collector} only affect how the results of |
228 * the characteristics of the {@link Collector} only affect how the results of |
233 * the member {@link Operation}s are collected; the member {@link Operation}s |
229 * the member {@link Operation}s are collected; the member {@link Operation}s |
234 * are executed sequentially regardless. If this {@link OperationGroup} is |
230 * are executed sequentially regardless. If this {@code OperationGroup} is |
235 * parallel the characteristics of the {@link Collector} may influence the |
231 * parallel the characteristics of the {@link Collector} may influence the |
236 * execution order of the member {@link Operation}s. |
232 * execution order of the member {@link Operation}s. |
237 * |
233 * |
238 * The default value is |
234 * The default value is |
239 * {@code Collector.of(()->null, (a,t)->{}, (l,r)->null, a->null)}. |
235 * {@code Collector.of(()->null, (a,t)->{}, (l,r)->null, a->null)}. |
240 * |
236 * |
241 * @param c the Collector. Not null. |
237 * @param c the Collector. Not null. |
242 * @return This OperationGroup |
238 * @return This OperationGroup |
243 * @throws IllegalStateException if called more than once or if this |
239 * @throws IllegalStateException if called more than once or if this |
244 * {@link OperationGroup} has been submitted |
240 * {@code OperationGroup} has been submitted |
245 */ |
241 */ |
246 public OperationGroup<S, T> collect(Collector<S, ?, T> c); |
242 public OperationGroup<S, T> collect(Collector<S, ?, T> c); |
247 |
243 |
248 /** |
244 /** |
249 * Return a new member {@link PrimitiveOperation} that is never skipped. |
245 * Return a new member {@link PrimitiveOperation} that is never skipped. |
250 * Skipping of member {@link Operation}s stops with a catchOperation and the |
246 * Skipping of member {@link Operation}s stops with a catchOperation and the |
251 * subsequent {@link Operation} is executed normally. The value of a |
247 * subsequent {@link Operation} is executed normally. The value of a |
252 * catchOperation is always null. Since a catchOperation is never completed |
248 * catchOperation is always null. Since a catchOperation is never completed |
253 * exceptionally, it has no error handler or timeout. |
249 * exceptionally, it has no error handler or timeout. |
254 * |
250 * |
255 * @return an {@link PrimitiveOperation} that is never skipped; |
251 * @return an {@link PrimitiveOperation} that is never skipped; |
256 * @throws IllegalStateException if the {@link OperationGroup} has been |
252 * @throws IllegalStateException if this {@code OperationGroup} is closed |
257 * submitted and is not held or if the {@link OperationGroup} is parallel or |
253 * or if this {@code OperationGroup} is parallel or independent. |
258 * independent. |
|
259 */ |
254 */ |
260 public PrimitiveOperation<S> catchOperation(); |
255 public PrimitiveOperation<S> catchOperation(); |
261 |
256 |
262 /** |
257 /** |
263 * Creates and submits a catch Operation. Convenience method. |
258 * Creates and submits a catch Operation. Convenience method. |
264 * |
259 * |
265 * @return this OperationGroup |
260 * @return this OperationGroup |
266 * @throws IllegalStateException if the {@link OperationGroup} has been |
261 * @throws IllegalStateException if this {@code OperationGroup} is closed |
267 * submitted and is not held or if the {@link OperationGroup} is parallel or |
262 * or if this {@code OperationGroup} is parallel or independent. |
268 * independent. |
|
269 */ |
263 */ |
270 public default OperationGroup<S, T> catchErrors() { |
264 public default OperationGroup<S, T> catchErrors() { |
271 catchOperation().submit(); |
265 catchOperation().submit(); |
272 return this; |
266 return this; |
273 } |
267 } |
285 * </code></pre> |
279 * </code></pre> |
286 * |
280 * |
287 * @param <R> the result type of the returned {@link ArrayRowCountOperation} |
281 * @param <R> the result type of the returned {@link ArrayRowCountOperation} |
288 * @param sql SQL to be executed. Must return an update count. |
282 * @param sql SQL to be executed. Must return an update count. |
289 * @return a new {@link ArrayRowCountOperation} that is a member of this |
283 * @return a new {@link ArrayRowCountOperation} that is a member of this |
290 * {@link OperationGroup} |
284 * {@code OperationGroup} |
291 * @throws IllegalStateException if the {@link OperationGroup} has been |
285 * @throws IllegalStateException if this {@code OperationGroup} is closed. |
292 * submitted and is not held |
|
293 */ |
286 */ |
294 public <R extends S> ArrayRowCountOperation<R> arrayRowCountOperation(String sql); |
287 public <R extends S> ArrayRowCountOperation<R> arrayRowCountOperation(String sql); |
295 |
288 |
296 /** |
289 /** |
297 * Return a new {@link ParameterizedRowCountOperation}. |
290 * Return a new {@link ParameterizedRowCountOperation}. |
298 * |
291 * |
299 * @param <R> the result type of the returned {@link RowCountOperation} |
292 * @param <R> the result type of the returned {@link RowCountOperation} |
300 * @param sql SQL to be executed. Must return an update count. |
293 * @param sql SQL to be executed. Must return an update count. |
301 * @return an new {@link ParameterizedRowCountOperation} that is a member of this |
294 * @return an new {@link ParameterizedRowCountOperation} that is a member of |
302 * {@link OperationGroup} |
295 * this {@code OperationGroup} |
303 * @throws IllegalStateException if the {@link OperationGroup} has been |
296 * @throws IllegalStateException if this {@code OperationGroup} is closed. |
304 * submitted and is not held |
|
305 */ |
297 */ |
306 public <R extends S> ParameterizedRowCountOperation<R> rowCountOperation(String sql); |
298 public <R extends S> ParameterizedRowCountOperation<R> rowCountOperation(String sql); |
307 |
299 |
308 /** |
300 /** |
309 * Return a new {@link Operation} for a SQL that doesn't return any result, |
301 * Return a new {@link Operation} for a SQL that doesn't return any result, |
310 * for example DDL. The result of this Operation is always null. |
302 * for example DDL. The result of this Operation is always null. |
311 * |
303 * |
312 * The result of the returned Operation must be Void but specifying that here |
304 * The result of the returned Operation must be Void but specifying that here |
313 * causes problems. |
305 * causes problems. |
314 * |
306 * |
315 * @param sql SQL for the {@link Operation}. |
307 * @param sql SQL for the {@link Operation}. |
316 * @return a new {@link Operation} that is a member of this |
308 * @return a new {@link Operation} that is a member of this |
317 * {@link OperationGroup} |
309 * {@code OperationGroup} |
318 * @throws IllegalStateException if the {@link OperationGroup} has been |
310 * @throws IllegalStateException if this {@code OperationGroup} is closed. |
319 * submitted and is not held |
|
320 */ |
311 */ |
321 public Operation<S> operation(String sql); |
312 public Operation<S> operation(String sql); |
322 |
313 |
323 /** |
314 /** |
324 * Return a new {@link OutOperation} that is a member {@link Operation} of this |
315 * Return a new {@link OutOperation} that is a member {@link Operation} of |
325 * {@link OperationGroup}. The SQL must return a set of zero or more out |
316 * this {@code OperationGroup}. The SQL must return a set of zero or more out |
326 * parameters or function results. |
317 * parameters or function results. |
327 * |
318 * |
328 * @param <R> the result type of the returned {@link OutOperation} |
319 * @param <R> the result type of the returned {@link OutOperation} |
329 * @param sql SQL for the {@link Operation}. Must return zero or more out |
320 * @param sql SQL for the {@link Operation}. Must return zero or more out |
330 * parameters or function results. |
321 * parameters or function results. |
331 * @return a new {@link OutOperation} that is a member of this |
322 * @return a new {@link OutOperation} that is a member of this |
332 * {@link OperationGroup} |
323 * {@code OperationGroup} |
333 * @throws IllegalStateException if the {@link OperationGroup} has been |
324 * @throws IllegalStateException if this {@code OperationGroup} is closed. |
334 * submitted and is not held |
|
335 */ |
325 */ |
336 public <R extends S> OutOperation<R> outOperation(String sql); |
326 public <R extends S> OutOperation<R> outOperation(String sql); |
337 |
327 |
338 /** |
328 /** |
339 * Return a new {@link ParameterizedRowOperation} that is a member |
329 * Return a new {@link ParameterizedRowOperation} that is a member |
340 * {@link Operation} of this {@link OperationGroup}. |
330 * {@link Operation} of this {@code OperationGroup}. |
341 * |
331 * |
342 * @param <R> the type of the result of the returned |
332 * @param <R> the type of the result of the returned |
343 * {@link ParameterizedRowOperation} |
333 * {@link ParameterizedRowOperation} |
344 * @param sql SQL for the {@link Operation}. Must return a row sequence. |
334 * @param sql SQL for the {@link Operation}. Must return a row sequence. |
345 * @return a new {@link ParameterizedRowOperation} that is a member of this |
335 * @return a new {@link ParameterizedRowOperation} that is a member of this |
346 * {@link OperationGroup} |
336 * {@code OperationGroup} |
347 * @throws IllegalStateException if the {@link OperationGroup} has been |
337 * @throws IllegalStateException if this {@code OperationGroup} is closed. |
348 * submitted and is not held |
|
349 */ |
338 */ |
350 public <R extends S> ParameterizedRowOperation<R> rowOperation(String sql); |
339 public <R extends S> ParameterizedRowOperation<R> rowOperation(String sql); |
351 |
340 |
352 /** |
341 /** |
353 * Return a new {@link ParameterizedRowPublisherOperation} that is a member |
342 * Return a new {@link ParameterizedRowPublisherOperation} that is a member |
354 * {@link Operation} of this {@link OperationGroup}. |
343 * {@link Operation} of this {@code OperationGroup}. |
355 * |
344 * |
356 * @param <R> the type of the result of the returned |
345 * @param <R> the type of the result of the returned |
357 * {@link ParameterizedRowPublisherOperation} |
346 * {@link ParameterizedRowPublisherOperation} |
358 * @param sql SQL for the {@link Operation}. Must return a row sequence. |
347 * @param sql SQL for the {@link Operation}. Must return a row sequence. |
359 * @return a new {@link ParameterizedRowPublisherOperation} that is a member |
348 * @return a new {@link ParameterizedRowPublisherOperation} that is a member |
360 * of this {@link OperationGroup} |
349 * of this {@code OperationGroup} |
361 * @throws IllegalStateException if the {@link OperationGroup} has been |
350 * @throws IllegalStateException if this {@code OperationGroup} is closed. |
362 * submitted and is not held |
|
363 */ |
351 */ |
364 public <R extends S> ParameterizedRowPublisherOperation<R> rowPublisherOperation(String sql); |
352 public <R extends S> ParameterizedRowPublisherOperation<R> rowPublisherOperation(String sql); |
365 |
353 |
366 /** |
354 /** |
367 * Return a new {@link MultiOperation} that is a member |
355 * Return a new {@link MultiOperation} that is a member {@link Operation} of |
368 * {@link Operation} of this {@link OperationGroup}. |
356 * this {@code OperationGroup}. |
369 * |
357 * |
370 * @param <R> the type of the result of the returned |
358 * @param <R> the type of the result of the returned {@link MultiOperation} |
371 * {@link MultiOperation} |
|
372 * @param sql SQL for the {@link Operation} |
359 * @param sql SQL for the {@link Operation} |
373 * @return a new {@link MultiOperation} that is a member of this |
360 * @return a new {@link MultiOperation} that is a member of this |
374 * {@link OperationGroup} |
361 * {@code OperationGroup} |
375 * @throws IllegalStateException if the {@link OperationGroup} has been |
362 * @throws IllegalStateException if this {@code OperationGroup} is closed. |
376 * submitted and is not held |
|
377 */ |
363 */ |
378 public <R extends S> MultiOperation<R> multiOperation(String sql); |
364 public <R extends S> MultiOperation<R> multiOperation(String sql); |
379 |
365 |
380 /** |
366 /** |
381 * Return a new {@link Operation} that ends the database transaction. This |
367 * Return a new {@link Operation} that ends the database transaction. This |
382 * {@link Operation} is a member of the {@link OperationGroup}. The |
368 * {@link Operation} is a member of the {@code OperationGroup}. The |
383 * transaction is ended with a commit unless the {@link TransactionCompletion} |
369 * transaction is ended with a commit unless the {@link TransactionCompletion} |
384 * has been {@link TransactionCompletion#setRollbackOnly} in which case the |
370 * has been {@link TransactionCompletion#setRollbackOnly} in which case the |
385 * transaction is ended with a rollback. |
371 * transaction is ended with a rollback. |
386 * |
372 * |
387 * <p> |
373 * <p> |
388 * An endTransaction Operation may be skipped. To insure that it will not be |
374 * An endTransaction Operation may be skipped. To insure that it will not be |
389 * skipped it should immediately follow a catch Operation. All end transaction |
375 * skipped it should immediately follow a catch Operation. All end transaction |
390 * convenience methods do so.</p> |
376 * convenience methods do so.</p> |
391 * |
377 * |
392 * The type argument {@link S} of the containing {@link OperationGroup} must |
378 * The type argument {@link S} of the containing {@code OperationGroup} must |
393 * be a supertype of {@link TransactionOutcome}. |
379 * be a supertype of {@link TransactionOutcome}. |
394 * |
380 * |
395 * @param trans the TransactionCompletion that determines whether the Operation does a |
381 * @param trans the TransactionCompletion that determines whether the |
396 database commit or a database rollback. |
382 * Operation does a database commit or a database rollback. |
397 * @return an {@link Operation} that will end the database transaction. |
383 * @return an {@link Operation} that will end the database transaction. |
398 * @throws IllegalStateException if this {@link OperationGroup} has been |
384 * @throws IllegalStateException if this {@code OperationGroup} is closed |
399 * submitted and is not held or is parallel. |
385 * or is parallel. |
400 */ |
386 */ |
401 public Operation<TransactionOutcome> endTransactionOperation(TransactionCompletion trans); |
387 public Operation<TransactionOutcome> endTransactionOperation(TransactionCompletion trans); |
402 |
388 |
403 /** |
389 /** |
404 * Convenience method that creates and submits a endTransaction |
390 * Convenience method that creates and submits a endTransaction |
405 * {@link Operation} that commits by default but can be set to rollback by |
391 * {@link Operation} that commits by default but can be set to rollback by |
406 * calling {@link TransactionCompletion#setRollbackOnly}. The endTransaction Operation |
392 * calling {@link TransactionCompletion#setRollbackOnly}. The endTransaction |
407 * is never skipped. |
393 * Operation is never skipped. |
408 * |
394 * |
409 * @param trans the TransactionCompletion that determines whether the {@link Operation} is a |
395 * @param trans the TransactionCompletion that determines whether the |
410 * database commit or a database rollback. |
396 * {@link Operation} is a database commit or a database rollback. |
411 * @return a {@link CompletionStage} that is completed with the outcome of the |
397 * @return a {@link CompletionStage} that is completed with the outcome of the |
412 * transaction |
398 * transaction |
413 * @throws IllegalStateException if this {@link OperationGroup} has been |
399 * @throws IllegalStateException if this {@code OperationGroup} is closed |
414 * submitted and is not held or is parallel. |
400 * or is parallel. |
415 */ |
401 */ |
416 public default CompletionStage<TransactionOutcome> commitMaybeRollback(TransactionCompletion trans) { |
402 public default CompletionStage<TransactionOutcome> commitMaybeRollback(TransactionCompletion trans) { |
417 catchErrors(); |
403 catchErrors(); |
418 return this.endTransactionOperation(trans).submit().getCompletionStage(); |
404 return this.endTransactionOperation(trans).submit().getCompletionStage(); |
419 } |
405 } |
420 |
406 |
421 /** |
407 /** |
422 * Return a new {@link LocalOperation} that is a member {@link Operation} of |
408 * Return a new {@link LocalOperation} that is a member {@link Operation} of |
423 * this {@link OperationGroup}. |
409 * this {@code OperationGroup}. |
424 * |
410 * |
425 * @param <R> value type of the returned local {@link Operation} |
411 * @param <R> value type of the returned local {@link Operation} |
426 * @return a LocalOperation |
412 * @return a LocalOperation |
427 * @throws IllegalStateException if this {@link OperationGroup} has been submitted and |
413 * @throws IllegalStateException if this {@code OperationGroup} is closed. |
428 * is not held |
|
429 */ |
414 */ |
430 public <R extends S> LocalOperation<R> localOperation(); |
415 public <R extends S> LocalOperation<R> localOperation(); |
431 |
416 |
432 /** |
417 /** |
433 * Supply a {@link Logger} for the implementation of this |
418 * Supply a {@link Logger} for the implementation of this |
434 * {@link OperationGroup} to use to log significant events. Exactly what |
419 * {@code OperationGroup} to use to log significant events. Exactly what |
435 * events are logged, at what Level the events are logged and with what |
420 * events are logged, at what Level the events are logged and with what |
436 * parameters is implementation dependent. All member {@link Operation}s of |
421 * parameters is implementation dependent. All member {@link Operation}s of |
437 * this {@link OperationGroup} will use the same {@link Logger} except a |
422 * this {@code OperationGroup} will use the same {@link Logger} except a |
438 * member {@link OperationGroup} that is supplied with a different |
423 * member {@code OperationGroup} that is supplied with a different |
439 * {@link Logger} uses that {@link Logger}. |
424 * {@link Logger} uses that {@link Logger}. |
440 * |
425 * |
441 * Supplying a {@link Logger} configured with a |
426 * Supplying a {@link Logger} configured with a |
442 * {@link java.util.logging.MemoryHandler} with the |
427 * {@link java.util.logging.MemoryHandler} with the |
443 * {@link java.util.logging.MemoryHandler#pushLevel} set to |
428 * {@link java.util.logging.MemoryHandler#pushLevel} set to |
444 * {@link java.util.logging.Level#WARNING} will result in no log output in |
429 * {@link java.util.logging.Level#WARNING} will result in no log output in |
445 * normal operation. In the event of an error the actions leading up to the |
430 * normal operation. In the event of an error the actions leading up to the |
446 * error will be logged. |
431 * error will be logged. |
447 * |
432 * |
448 * Implementation Note: Implementations are encouraged to log the creation of |
433 * Implementation Note: Implementations are encouraged to log the creation of |
449 * this {@link OperationGroup} set to {@link java.util.logging.Level#INFO}, |
434 * this {@code OperationGroup} set to {@link java.util.logging.Level#INFO}, |
450 * the creation of member {@link Operation}s at the |
435 * the creation of member {@link Operation}s at the |
451 * {@link java.util.logging.Level#CONFIG} level, and execution of member |
436 * {@link java.util.logging.Level#CONFIG} level, and execution of member |
452 * {@link Operation}s at the {@link java.util.logging.Level#FINE} level. |
437 * {@link Operation}s at the {@link java.util.logging.Level#FINE} level. |
453 * Detailed information about the execution of member {@link Operation}s may |
438 * Detailed information about the execution of member {@link Operation}s may |
454 * be logged at the {@link java.util.logging.Level#FINER} and |
439 * be logged at the {@link java.util.logging.Level#FINER} and |