@ -22,18 +22,22 @@ import java.util.List;
@@ -22,18 +22,22 @@ import java.util.List;
import org.bson.BsonNull ;
import org.bson.Document ;
import org.springframework.data.domain.Range ;
import org.springframework.data.domain.Range.Bound ;
import org.springframework.data.util.Streamable ;
import org.springframework.lang.Nullable ;
/ * *
* Encapsulation of individual { @link QueryCharacteristic query characteristics } used to define queries that can be
* executed when using queryable encryption .
*
* @author Christoph Strobl
* @since 4 . 5
* /
public class QueryCharacteristics implements Stream able< QueryCharacteristic > {
public class QueryCharacteristics implements Iter able< QueryCharacteristic > {
/ * *
* instance indicating none
* /
private static final QueryCharacteristics NONE = new QueryCharacteristics ( Collections . emptyList ( ) ) ;
private final List < QueryCharacteristic > characteristics ;
@ -42,18 +46,36 @@ public class QueryCharacteristics implements Streamable<QueryCharacteristic> {
@@ -42,18 +46,36 @@ public class QueryCharacteristics implements Streamable<QueryCharacteristic> {
this . characteristics = characteristics ;
}
/ * *
* @return marker instance indicating no characteristics have been defined .
* /
public static QueryCharacteristics none ( ) {
return NONE ;
}
/ * *
* Create new { @link QueryCharacteristics } from given list of { @link QueryCharacteristic characteristics } .
*
* @param characteristics must not be { @literal null } .
* @return new instance of { @link QueryCharacteristics } .
* /
public static QueryCharacteristics of ( List < QueryCharacteristic > characteristics ) {
return new QueryCharacteristics ( List . copyOf ( characteristics ) ) ;
}
/ * *
* Create new { @link QueryCharacteristics } from given { @link QueryCharacteristic characteristics } .
*
* @param characteristics must not be { @literal null } .
* @return new instance of { @link QueryCharacteristics } .
* /
public static QueryCharacteristics of ( QueryCharacteristic . . . characteristics ) {
return new QueryCharacteristics ( Arrays . asList ( characteristics ) ) ;
}
/ * *
* @return the list of { @link QueryCharacteristic characteristics } .
* /
public List < QueryCharacteristic > getCharacteristics ( ) {
return characteristics ;
}
@ -63,22 +85,50 @@ public class QueryCharacteristics implements Streamable<QueryCharacteristic> {
@@ -63,22 +85,50 @@ public class QueryCharacteristics implements Streamable<QueryCharacteristic> {
return this . characteristics . iterator ( ) ;
}
/ * *
* Create a new { @link RangeQuery range query characteristic } used to define range queries against an encrypted field .
*
* @param < T > targeted field type
* @return new instance of { @link RangeQuery } .
* /
public static < T > RangeQuery < T > range ( ) {
return new RangeQuery < > ( ) ;
}
/ * *
* Create a new { @link EqualityQuery equality query characteristic } used to define equality queries against an
* encrypted field .
*
* @param < T > targeted field type
* @return new instance of { @link EqualityQuery } .
* /
public static < T > EqualityQuery < T > equality ( ) {
return new EqualityQuery < > ( null ) ;
}
/ * *
* { @link QueryCharacteristic } for equality comparison .
*
* @param < T >
* @since 4 . 5
* /
public static class EqualityQuery < T > implements QueryCharacteristic {
private final @Nullable Long contention ;
/ * *
* Create new instance of { @link EqualityQuery } .
*
* @param contention can be { @literal null } .
* /
public EqualityQuery ( @Nullable Long contention ) {
this . contention = contention ;
}
/ * *
* @param contention concurrent counter partition factor .
* @return new instance of { @link EqualityQuery } .
* /
public EqualityQuery < T > contention ( long contention ) {
return new EqualityQuery < > ( contention ) ;
}
@ -94,64 +144,120 @@ public class QueryCharacteristics implements Streamable<QueryCharacteristic> {
@@ -94,64 +144,120 @@ public class QueryCharacteristics implements Streamable<QueryCharacteristic> {
}
}
/ * *
* { @link QueryCharacteristic } for range comparison .
*
* @param < T >
* @since 4 . 5
* /
public static class RangeQuery < T > implements QueryCharacteristic {
private final @Nullable Range < T > valueRange ;
private final @Nullable Integer trimFactor ;
private final @Nullable Long sparsity ;
private final @Nullable Long precision ;
private final @Nullable Long contention ;
private RangeQuery ( ) {
this ( Range . unbounded ( ) , null , null , null ) ;
this ( Range . unbounded ( ) , null , null , null , null ) ;
}
/ * *
* Create new instance of { @link RangeQuery } .
*
* @param valueRange
* @param trimFactor
* @param sparsity
* @param contention
* /
public RangeQuery ( @Nullable Range < T > valueRange , @Nullable Integer trimFactor , @Nullable Long sparsity ,
@Nullable Long contention ) {
@Nullable Long precision , @Nullable Long contention ) {
this . valueRange = valueRange ;
this . trimFactor = trimFactor ;
this . sparsity = sparsity ;
this . precision = precision ;
this . contention = contention ;
}
@Override
public String queryType ( ) {
return "range" ;
}
/ * *
* @param lower the lower value range boundary for the queryable field .
* @return new instance of { @link RangeQuery } .
* /
public RangeQuery < T > min ( T lower ) {
Range < T > range = Range . of ( Bound . inclusive ( lower ) ,
valueRange ! = null ? valueRange . getUpperBound ( ) : Bound . unbounded ( ) ) ;
return new RangeQuery < > ( range , trimFactor , sparsity , contention ) ;
return new RangeQuery < > ( range , trimFactor , sparsity , precision , contention ) ;
}
/ * *
* @param upper the upper value range boundary for the queryable field .
* @return new instance of { @link RangeQuery } .
* /
public RangeQuery < T > max ( T upper ) {
Range < T > range = Range . of ( valueRange ! = null ? valueRange . getLowerBound ( ) : Bound . unbounded ( ) ,
Bound . inclusive ( upper ) ) ;
return new RangeQuery < > ( range , trimFactor , sparsity , contention ) ;
return new RangeQuery < > ( range , trimFactor , sparsity , precision , contention ) ;
}
/ * *
* @param trimFactor value to control the throughput of concurrent inserts and updates .
* @return new instance of { @link RangeQuery } .
* /
public RangeQuery < T > trimFactor ( int trimFactor ) {
return new RangeQuery < > ( valueRange , trimFactor , sparsity , contention ) ;
return new RangeQuery < > ( valueRange , trimFactor , sparsity , precision , contention ) ;
}
/ * *
* @param sparsity value to control the value density within the index .
* @return new instance of { @link RangeQuery } .
* /
public RangeQuery < T > sparsity ( long sparsity ) {
return new RangeQuery < > ( valueRange , trimFactor , sparsity , contention ) ;
return new RangeQuery < > ( valueRange , trimFactor , sparsity , precision , contention ) ;
}
/ * *
* @param contention concurrent counter partition factor .
* @return new instance of { @link RangeQuery } .
* /
public RangeQuery < T > contention ( long contention ) {
return new RangeQuery < > ( valueRange , trimFactor , sparsity , contention ) ;
return new RangeQuery < > ( valueRange , trimFactor , sparsity , precision , contention ) ;
}
/ * *
* @param precision digits considered comparing floating point numbers .
* @return new instance of { @link RangeQuery } .
* /
public RangeQuery < T > precision ( long precision ) {
return new RangeQuery < > ( valueRange , trimFactor , sparsity , precision , contention ) ;
}
@Override
public String queryType ( ) {
return "range" ;
}
@Override
@SuppressWarnings ( "unchecked" )
public Document toDocument ( ) {
return QueryCharacteristic . super . toDocument ( ) . append ( "contention" , contention ) . append ( "trimFactor" , trimFactor )
. append ( "sparsity" , sparsity ) . append ( "min" , valueRange . getLowerBound ( ) . getValue ( ) . orElse ( ( T ) BsonNull . VALUE ) )
. append ( "max" , valueRange . getUpperBound ( ) . getValue ( ) . orElse ( ( T ) BsonNull . VALUE ) ) ;
Document target = QueryCharacteristic . super . toDocument ( ) ;
if ( contention ! = null ) {
target . append ( "contention" , contention ) ;
}
if ( trimFactor ! = null ) {
target . append ( "trimFactor" , trimFactor ) ;
}
if ( valueRange ! = null ) {
target . append ( "min" , valueRange . getLowerBound ( ) . getValue ( ) . orElse ( ( T ) BsonNull . VALUE ) ) . append ( "max" ,
valueRange . getUpperBound ( ) . getValue ( ) . orElse ( ( T ) BsonNull . VALUE ) ) ;
}
if ( sparsity ! = null ) {
target . append ( "sparsity" , sparsity ) ;
}
return target ;
}
}
}