#15 - Incorporate review feedback.
Improve Javadoc. Rename parameters for more expressiveness. Replace ASCII filtering with filter Function to move actual filtering into dialects. Original pull request: #19.
This commit is contained in:
@@ -24,13 +24,13 @@ public interface BindMarkers {
|
||||
BindMarker next();
|
||||
|
||||
/**
|
||||
* Creates a new {@link BindMarker} that accepts a {@code nameHint}. Implementations are allowed to consider/ignore
|
||||
* Creates a new {@link BindMarker} that accepts a {@code hint}. Implementations are allowed to consider/ignore/filter
|
||||
* the name hint to create more expressive bind markers.
|
||||
*
|
||||
* @param nameHint an optional name hint.
|
||||
* @param hint an optional name hint that can be used as part of the bind marker.
|
||||
* @return a new {@link BindMarker}.
|
||||
*/
|
||||
default BindMarker next(String nameHint) {
|
||||
default BindMarker next(String hint) {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
package org.springframework.data.r2dbc.dialect;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* This class creates new {@link BindMarkers} instances to bind parameter for a specific {@link io.r2dbc.spi.Statement}.
|
||||
* <p/>
|
||||
* Bind markers can be typically represented as placeholder and identifier. Placeholders are used within the query to
|
||||
* execute so the underlying database system can substitute the placeholder with the actual value. Identifiers are used
|
||||
* in R2DBC drivers to bind a value to a bind marker. Identifiers are typically a part of an entire bind marker when
|
||||
* using indexed or named bind markers.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @see BindMarkers
|
||||
@@ -20,11 +27,15 @@ public interface BindMarkersFactory {
|
||||
BindMarkers create();
|
||||
|
||||
/**
|
||||
* Create index-based {@link BindMarkers}.
|
||||
* Create index-based {@link BindMarkers} using indexes to bind parameters. Allow customization of the bind marker
|
||||
* placeholder {@code prefix} to represent the bind marker as placeholder within the query.
|
||||
*
|
||||
* @param prefix bind parameter prefix.
|
||||
* @param prefix bind parameter prefix that is included in {@link BindMarker#getPlaceholder()} but not the actual
|
||||
* identifier.
|
||||
* @param beginWith the first index to use.
|
||||
* @return a {@link BindMarkersFactory} using {@code prefix} and {@code beginWith}.
|
||||
* @see io.r2dbc.spi.Statement#bindNull(int, Class)
|
||||
* @see io.r2dbc.spi.Statement#bind(int, Object)
|
||||
*/
|
||||
static BindMarkersFactory indexed(String prefix, int beginWith) {
|
||||
|
||||
@@ -33,21 +44,49 @@ public interface BindMarkersFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create named {@link BindMarkers}. Named bind markers can support {@link BindMarkers#next(String) name hints}.
|
||||
* Typically, named markers use name hints. If no namehint is given, named bind markers use a counter to generate
|
||||
* unique bind markers.
|
||||
* Create named {@link BindMarkers} using identifiers to bind parameters. Named bind markers can support
|
||||
* {@link BindMarkers#next(String) name hints}. If no {@link BindMarkers#next(String) hint} is given, named bind
|
||||
* markers can use a counter or a random value source to generate unique bind markers.
|
||||
* <p/>
|
||||
* Allow customization of the bind marker placeholder {@code prefix} and {@code namePrefix} to represent the bind
|
||||
* marker as placeholder within the query.
|
||||
*
|
||||
* @param prefix bind parameter prefix.
|
||||
* @param indexPrefix prefix for bind markers that were created by incrementing a counter to generate a unique bind
|
||||
* marker.
|
||||
* @param nameLimit maximal length of parameter names when using name hints.
|
||||
* @param prefix bind parameter prefix that is included in {@link BindMarker#getPlaceholder()} but not the actual
|
||||
* identifier.
|
||||
* @param namePrefix prefix for bind marker name that is included in {@link BindMarker#getPlaceholder()} and the
|
||||
* actual identifier.
|
||||
* @param maxLength maximal length of parameter names when using name hints.
|
||||
* @return a {@link BindMarkersFactory} using {@code prefix} and {@code beginWith}.
|
||||
* @see io.r2dbc.spi.Statement#bindNull(Object, Class)
|
||||
* @see io.r2dbc.spi.Statement#bind(Object, Object)
|
||||
*/
|
||||
static BindMarkersFactory named(String prefix, String indexPrefix, int nameLimit) {
|
||||
static BindMarkersFactory named(String prefix, String namePrefix, int maxLength) {
|
||||
return named(prefix, namePrefix, maxLength, Function.identity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create named {@link BindMarkers} using identifiers to bind parameters. Named bind markers can support
|
||||
* {@link BindMarkers#next(String) name hints}. If no {@link BindMarkers#next(String) hint} is given, named bind
|
||||
* markers can use a counter or a random value source to generate unique bind markers.
|
||||
*
|
||||
* @param prefix bind parameter prefix that is included in {@link BindMarker#getPlaceholder()} but not the actual
|
||||
* identifier.
|
||||
* @param namePrefix prefix for bind marker name that is included in {@link BindMarker#getPlaceholder()} and the
|
||||
* actual identifier.
|
||||
* @param maxLength maximal length of parameter names when using name hints.
|
||||
* @param hintFilterFunction filter {@link Function} to consider database-specific limitations in bind marker/variable
|
||||
* names such as ASCII chars only.
|
||||
* @return a {@link BindMarkersFactory} using {@code prefix} and {@code beginWith}.
|
||||
* @see io.r2dbc.spi.Statement#bindNull(Object, Class)
|
||||
* @see io.r2dbc.spi.Statement#bind(Object, Object)
|
||||
*/
|
||||
static BindMarkersFactory named(String prefix, String namePrefix, int maxLength,
|
||||
Function<String, String> hintFilterFunction) {
|
||||
|
||||
Assert.notNull(prefix, "Prefix must not be null!");
|
||||
Assert.notNull(indexPrefix, "Index prefix must not be null!");
|
||||
Assert.notNull(namePrefix, "Index prefix must not be null!");
|
||||
Assert.notNull(hintFilterFunction, "Hint filter function must not be null!");
|
||||
|
||||
return () -> new NamedBindMarkers(prefix, indexPrefix, nameLimit);
|
||||
return () -> new NamedBindMarkers(prefix, namePrefix, maxLength, hintFilterFunction);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.springframework.data.r2dbc.dialect;
|
||||
import io.r2dbc.spi.Statement;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -21,17 +22,24 @@ class NamedBindMarkers implements BindMarkers {
|
||||
|
||||
private final String prefix;
|
||||
|
||||
private final String indexPrefix;
|
||||
private final String namePrefix;
|
||||
|
||||
private final int nameLimit;
|
||||
|
||||
NamedBindMarkers(String prefix, String indexPrefix, int nameLimit) {
|
||||
private final Function<String, String> hintFilterFunction;
|
||||
|
||||
NamedBindMarkers(String prefix, String namePrefix, int nameLimit, Function<String, String> hintFilterFunction) {
|
||||
|
||||
this.prefix = prefix;
|
||||
this.indexPrefix = indexPrefix;
|
||||
this.namePrefix = namePrefix;
|
||||
this.nameLimit = nameLimit;
|
||||
this.hintFilterFunction = hintFilterFunction;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.r2dbc.dialect.BindMarkers#next()
|
||||
*/
|
||||
@Override
|
||||
public BindMarker next() {
|
||||
|
||||
@@ -40,18 +48,16 @@ class NamedBindMarkers implements BindMarkers {
|
||||
return new NamedBindMarker(prefix + name, name);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.r2dbc.dialect.BindMarkers#next(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public BindMarker next(String nameHint) {
|
||||
public BindMarker next(String hint) {
|
||||
|
||||
Assert.notNull(nameHint, "Name hint must not be null");
|
||||
Assert.notNull(hint, "Name hint must not be null");
|
||||
|
||||
String name = nextName();
|
||||
|
||||
String filteredNameHint = filter(nameHint);
|
||||
|
||||
if (!filteredNameHint.isEmpty()) {
|
||||
name += "_" + filteredNameHint;
|
||||
}
|
||||
String name = nextName() + hintFilterFunction.apply(hint);
|
||||
|
||||
if (name.length() > nameLimit) {
|
||||
name = name.substring(0, nameLimit);
|
||||
@@ -63,25 +69,7 @@ class NamedBindMarkers implements BindMarkers {
|
||||
private String nextName() {
|
||||
|
||||
int index = COUNTER_INCREMENTER.getAndIncrement(this);
|
||||
return indexPrefix + index;
|
||||
}
|
||||
|
||||
private static String filter(CharSequence input) {
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
|
||||
char ch = input.charAt(i);
|
||||
|
||||
// ascii letter or digit
|
||||
if (Character.isLetterOrDigit(ch) && ch < 127) {
|
||||
builder.append(ch);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
return namePrefix + index;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user