Skip to content

Commit fd4472a

Browse files
mp911deodrotbohm
authored andcommitted
#64 - Add Criteria API.
We now support Criteria creation and mapping to express where conditions with a fluent API. databaseClient.select().from("legoset") .where(Criteria.of("name").like("John%").and("id").lessThanOrEquals(42055)); databaseClient.delete() .from(LegoSet.class) .where(Criteria.of("id").is(42055)) .then() databaseClient.delete() .from(LegoSet.class) .where(Criteria.of("id").is(42055)) .fetch() .rowsUpdated() Original pull request: #106.
1 parent 88945d7 commit fd4472a

22 files changed

+2640
-139
lines changed

src/main/java/org/springframework/data/r2dbc/function/BindableOperation.java renamed to src/main/java/org/springframework/data/r2dbc/domain/BindableOperation.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
1-
package org.springframework.data.r2dbc.function;
1+
/*
2+
* Copyright 2019 the original author or 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.springframework.data.r2dbc.domain;
217

318
import io.r2dbc.spi.Statement;
419

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
/*
2+
* Copyright 2019 the original author or 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.springframework.data.r2dbc.domain;
17+
18+
import io.r2dbc.spi.Statement;
19+
20+
import java.util.ArrayList;
21+
import java.util.Collection;
22+
import java.util.Collections;
23+
import java.util.Iterator;
24+
import java.util.LinkedHashMap;
25+
import java.util.List;
26+
import java.util.Map;
27+
import java.util.Spliterator;
28+
import java.util.function.Consumer;
29+
30+
import org.springframework.data.r2dbc.dialect.BindMarker;
31+
import org.springframework.data.r2dbc.dialect.BindMarkers;
32+
import org.springframework.data.util.Streamable;
33+
import org.springframework.lang.Nullable;
34+
import org.springframework.util.Assert;
35+
36+
/**
37+
* Value object representing value and {@code NULL} bindings for a {@link Statement} using {@link BindMarkers}.
38+
*
39+
* @author Mark Paluch
40+
*/
41+
public class Bindings implements Streamable<Bindings.Binding> {
42+
43+
private final Map<BindMarker, Binding> bindings;
44+
45+
/**
46+
* Create empty {@link Bindings}.
47+
*/
48+
public Bindings() {
49+
this.bindings = Collections.emptyMap();
50+
}
51+
52+
/**
53+
* Create {@link Bindings} from a {@link Map}.
54+
*
55+
* @param bindings must not be {@literal null}.
56+
*/
57+
public Bindings(Collection<Binding> bindings) {
58+
59+
Assert.notNull(bindings, "Bindings must not be null");
60+
61+
Map<BindMarker, Binding> mapping = new LinkedHashMap<>(bindings.size());
62+
bindings.forEach(it -> mapping.put(it.getBindMarker(), it));
63+
this.bindings = mapping;
64+
}
65+
66+
Bindings(Map<BindMarker, Binding> bindings) {
67+
this.bindings = bindings;
68+
}
69+
70+
protected Map<BindMarker, Binding> getBindings() {
71+
return bindings;
72+
}
73+
74+
/**
75+
* Merge this bindings with an other {@link Bindings} object and create a new merged {@link Bindings} object.
76+
*
77+
* @param left the left object to merge with.
78+
* @param right the right object to merge with.
79+
* @return a new, merged {@link Bindings} object.
80+
*/
81+
public static Bindings merge(Bindings left, Bindings right) {
82+
83+
Assert.notNull(left, "Left side Bindings must not be null");
84+
Assert.notNull(right, "Right side Bindings must not be null");
85+
86+
List<Binding> result = new ArrayList<>(left.getBindings().size() + right.getBindings().size());
87+
88+
result.addAll(left.getBindings().values());
89+
result.addAll(right.getBindings().values());
90+
91+
return new Bindings(result);
92+
}
93+
94+
/**
95+
* Apply the bindings to a {@link Statement}.
96+
*
97+
* @param statement the statement to apply to.
98+
*/
99+
public void apply(Statement statement) {
100+
101+
Assert.notNull(statement, "Statement must not be null");
102+
this.bindings.forEach((marker, binding) -> binding.apply(statement));
103+
}
104+
105+
/**
106+
* Performs the given action for each binding of this {@link Bindings} until all bindings have been processed or the
107+
* action throws an exception. Actions are performed in the order of iteration (if an iteration order is specified).
108+
* Exceptions thrown by the action are relayed to the
109+
*
110+
* @param action The action to be performed for each {@link Binding}.
111+
*/
112+
public void forEach(Consumer<? super Binding> action) {
113+
this.bindings.forEach((marker, binding) -> action.accept(binding));
114+
}
115+
116+
/*
117+
* (non-Javadoc)
118+
* @see java.lang.Iterable#iterator()
119+
*/
120+
@Override
121+
public Iterator<Binding> iterator() {
122+
return this.bindings.values().iterator();
123+
}
124+
125+
/*
126+
* (non-Javadoc)
127+
* @see java.lang.Iterable#spliterator()
128+
*/
129+
@Override
130+
public Spliterator<Binding> spliterator() {
131+
return this.bindings.values().spliterator();
132+
}
133+
134+
/**
135+
* Base class for value objects representing a value or a {@code NULL} binding.
136+
*/
137+
public abstract static class Binding {
138+
139+
private final BindMarker marker;
140+
141+
protected Binding(BindMarker marker) {
142+
this.marker = marker;
143+
}
144+
145+
/**
146+
* @return the associated {@link BindMarker}.
147+
*/
148+
public BindMarker getBindMarker() {
149+
return marker;
150+
}
151+
152+
/**
153+
* Return {@literal true} if there is a value present, otherwise {@literal false} for a {@code NULL} binding.
154+
*
155+
* @return {@literal true} if there is a value present, otherwise {@literal false} for a {@code NULL} binding.
156+
*/
157+
public abstract boolean hasValue();
158+
159+
/**
160+
* Return {@literal true} if this is is a {@code NULL} binding.
161+
*
162+
* @return {@literal true} if this is is a {@code NULL} binding.
163+
*/
164+
public boolean isNull() {
165+
return !hasValue();
166+
}
167+
168+
/**
169+
* Returns the value of this binding. Can be {@literal null} if this is a {@code NULL} binding.
170+
*
171+
* @return value of this binding. Can be {@literal null} if this is a {@code NULL} binding.
172+
*/
173+
@Nullable
174+
public abstract Object getValue();
175+
176+
/**
177+
* Applies the binding to a {@link Statement}.
178+
*
179+
* @param statement the statement to apply to.
180+
*/
181+
public abstract void apply(Statement statement);
182+
}
183+
184+
/**
185+
* Value binding.
186+
*/
187+
public static class ValueBinding extends Binding {
188+
189+
private final Object value;
190+
191+
public ValueBinding(BindMarker marker, Object value) {
192+
super(marker);
193+
this.value = value;
194+
}
195+
196+
/*
197+
* (non-Javadoc)
198+
* @see org.springframework.data.r2dbc.function.query.Bindings.Binding#hasValue()
199+
*/
200+
public boolean hasValue() {
201+
return true;
202+
}
203+
204+
/*
205+
* (non-Javadoc)
206+
* @see org.springframework.data.r2dbc.function.query.Bindings.Binding#getValue()
207+
*/
208+
public Object getValue() {
209+
return value;
210+
}
211+
212+
/*
213+
* (non-Javadoc)
214+
* @see org.springframework.data.r2dbc.function.query.Bindings.Binding#apply(io.r2dbc.spi.Statement)
215+
*/
216+
@Override
217+
public void apply(Statement statement) {
218+
getBindMarker().bind(statement, getValue());
219+
}
220+
}
221+
222+
/**
223+
* {@code NULL} binding.
224+
*/
225+
public static class NullBinding extends Binding {
226+
227+
private final Class<?> valueType;
228+
229+
public NullBinding(BindMarker marker, Class<?> valueType) {
230+
super(marker);
231+
this.valueType = valueType;
232+
}
233+
234+
/*
235+
* (non-Javadoc)
236+
* @see org.springframework.data.r2dbc.function.query.Bindings.Binding#hasValue()
237+
*/
238+
public boolean hasValue() {
239+
return false;
240+
}
241+
242+
/*
243+
* (non-Javadoc)
244+
* @see org.springframework.data.r2dbc.function.query.Bindings.Binding#getValue()
245+
*/
246+
@Nullable
247+
public Object getValue() {
248+
return null;
249+
}
250+
251+
public Class<?> getValueType() {
252+
return valueType;
253+
}
254+
255+
/*
256+
* (non-Javadoc)
257+
* @see org.springframework.data.r2dbc.function.query.Bindings.Binding#apply(io.r2dbc.spi.Statement)
258+
*/
259+
@Override
260+
public void apply(Statement statement) {
261+
getBindMarker().bindNull(statement, getValueType());
262+
}
263+
}
264+
}

0 commit comments

Comments
 (0)