Skip to content

Commit

Permalink
MongoDB Update : Allow all update operators inside
Browse files Browse the repository at this point in the history
  • Loading branch information
loicmathieu committed Feb 12, 2021
1 parent 1822e0c commit c0ded6b
Show file tree
Hide file tree
Showing 14 changed files with 112 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@
public abstract class ReactiveMongoOperations<QueryType, UpdateType> {
public final String ID = "_id";
private static final Logger LOGGER = Logger.getLogger(ReactiveMongoOperations.class);

// update operators: https://docs.mongodb.com/manual/reference/operator/update/
private static final List<String> UPDATE_OPERATORS = Arrays.asList(
"$currentDate", "$inc", "$min", "$max", "$mul", "$rename", "$set", "$setOnInsert", "$unset",
"$addToSet", "$pop", "$pull", "$push", "$pullAll",
"$each", "$position", "$slice", "$sort",
"$bit");

private static final Map<String, String> defaultDatabaseName = new ConcurrentHashMap<>();

protected abstract QueryType createQuery(ReactiveMongoCollection collection, Document query, Document sortDoc);
Expand Down Expand Up @@ -369,11 +377,11 @@ public String bindFilter(Class<?> clazz, String query, Map<String, Object> param
/**
* We should have a query like <code>{'firstname': ?1, 'lastname': ?2}</code> for native one
* and like <code>firstname = ?1 and lastname = ?2</code> for PanacheQL one.
* As update document needs a <code>$set</code> operator we add it if needed.
* As update document needs an update operator, we add <code>$set</code> if none is provided.
*/
String bindUpdate(Class<?> clazz, String query, Object[] params) {
String bindUpdate = bindQuery(clazz, query, params);
if (!bindUpdate.contains("$set")) {
if (!containsUpdateOperator(query)) {
bindUpdate = "{'$set':" + bindUpdate + "}";
}
LOGGER.debug(bindUpdate);
Expand All @@ -383,17 +391,26 @@ String bindUpdate(Class<?> clazz, String query, Object[] params) {
/**
* We should have a query like <code>{'firstname': :firstname, 'lastname': :lastname}</code> for native one
* and like <code>firstname = :firstname and lastname = :lastname</code> for PanacheQL one.
* As update document needs a <code>$set</code> operator we add it if needed.
* As update document needs an update operator, we add <code>$set</code> if none is provided.
*/
String bindUpdate(Class<?> clazz, String query, Map<String, Object> params) {
String bindUpdate = bindQuery(clazz, query, params);
if (!bindUpdate.contains("$set")) {
if (!containsUpdateOperator(query)) {
bindUpdate = "{'$set':" + bindUpdate + "}";
}
LOGGER.debug(bindUpdate);
return bindUpdate;
}

private boolean containsUpdateOperator(String update) {
for (String operator : UPDATE_OPERATORS) {
if (update.contains(operator)) {
return true;
}
}
return false;
}

String bindQuery(Class<?> clazz, String query, Object[] params) {
String bindQuery = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ public abstract class MongoOperations<QueryType, UpdateType> {
public final String ID = "_id";
private static final Logger LOGGER = Logger.getLogger(MongoOperations.class);

// update operators: https://docs.mongodb.com/manual/reference/operator/update/
private static final List<String> UPDATE_OPERATORS = Arrays.asList(
"$currentDate", "$inc", "$min", "$max", "$mul", "$rename", "$set", "$setOnInsert", "$unset",
"$addToSet", "$pop", "$pull", "$push", "$pullAll",
"$each", "$position", "$slice", "$sort",
"$bit");

private final Map<String, String> defaultDatabaseName = new ConcurrentHashMap<>();

protected abstract QueryType createQuery(MongoCollection<?> collection, Document query, Document sortDoc);
Expand Down Expand Up @@ -343,11 +350,11 @@ public String bindFilter(Class<?> clazz, String query, Map<String, Object> param
/**
* We should have a query like <code>{'firstname': ?1, 'lastname': ?2}</code> for native one
* and like <code>firstname = ?1 and lastname = ?2</code> for PanacheQL one.
* As update document needs a <code>$set</code> operator we add it if needed.
* As update document needs an update operator, we add <code>$set</code> if none is provided.
*/
String bindUpdate(Class<?> clazz, String query, Object[] params) {
String bindUpdate = bindQuery(clazz, query, params);
if (!bindUpdate.contains("$set")) {
if (!containsUpdateOperator(query)) {
bindUpdate = "{'$set':" + bindUpdate + "}";
}
LOGGER.debug(bindUpdate);
Expand All @@ -357,17 +364,26 @@ String bindUpdate(Class<?> clazz, String query, Object[] params) {
/**
* We should have a query like <code>{'firstname': :firstname, 'lastname': :lastname}</code> for native one
* and like <code>firstname = :firstname and lastname = :lastname</code> for PanacheQL one.
* As update document needs a <code>$set</code> operator we add it if needed.
* As update document needs an update operator, we add <code>$set</code> if none is provided.
*/
String bindUpdate(Class<?> clazz, String query, Map<String, Object> params) {
String bindUpdate = bindQuery(clazz, query, params);
if (!bindUpdate.contains("$set")) {
if (!containsUpdateOperator(query)) {
bindUpdate = "{'$set':" + bindUpdate + "}";
}
LOGGER.debug(bindUpdate);
return bindUpdate;
}

private boolean containsUpdateOperator(String update) {
for (String operator : UPDATE_OPERATORS) {
if (update.contains(operator)) {
return true;
}
}
return false;
}

private String bindQuery(Class<?> clazz, String query, Object[] params) {
String bindQuery = null;
//determine the type of the query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,8 @@ interface PanacheMongoCompanionBase<Entity : PanacheMongoEntityBase, Id: Any> {
* Update all entities of this type using the given update document with optional indexed parameters.
* The returned [PanacheUpdate] object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it. It can also be expressed as a query string.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
* @param params optional sequence of indexed parameters
* @return a new [PanacheUpdate] instance for the given update document
* @see [update]
Expand All @@ -659,7 +660,7 @@ interface PanacheMongoCompanionBase<Entity : PanacheMongoEntityBase, Id: Any> {
* Update all entities of this type by the given update document with named parameters.
* The returned [PanacheUpdate] object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
*
* @param params map of named parameters
Expand All @@ -674,8 +675,8 @@ interface PanacheMongoCompanionBase<Entity : PanacheMongoEntityBase, Id: Any> {
* Update all entities of this type by the given update document, with named parameters.
* The returned [PanacheUpdate] object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it. It can also be expressed as a query
* string.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
*
* @param params [Parameters] of named parameters
* @return a new [PanacheUpdate] instance for the given update document
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ interface PanacheMongoRepositoryBase<Entity: Any, Id: Any> {
* Update all entities of this type by the given update document, with optional indexed parameters.
* The returned [PanacheUpdate] object will allow to restrict on which documents the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
* @param params optional sequence of indexed parameters
* @return a new [PanacheUpdate] instance for the given update document
Expand All @@ -691,7 +691,7 @@ interface PanacheMongoRepositoryBase<Entity: Any, Id: Any> {
* Update all entities of this type by the given update document, with named parameters.
* The returned [PanacheUpdate] object will allow to restrict on which documents the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
* @param params [Map] of named parameters
* @return a new [PanacheUpdate] instance for the given update document
Expand All @@ -705,7 +705,7 @@ interface PanacheMongoRepositoryBase<Entity: Any, Id: Any> {
* Update all entities of this type by the given update document, with named parameters.
* The returned [PanacheUpdate] object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
* @param params [Parameters] of named parameters
* @return a new [PanacheUpdate] instance for the given update document
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ interface ReactivePanacheMongoCompanionBase<Entity : ReactivePanacheMongoEntityB
* Update all entities of this type by the given update document, with optional indexed parameters.
* The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
* @param params optional sequence of indexed parameters
* @return a new [ReactivePanacheUpdate] instance for the given update document
Expand All @@ -734,7 +734,7 @@ interface ReactivePanacheMongoCompanionBase<Entity : ReactivePanacheMongoEntityB
* Update all entities of this type by the given update document, with named parameters.
* The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
* @param params [Map] of named parameters
* @return a new [ReactivePanacheUpdate] instance for the given update document
Expand All @@ -747,7 +747,7 @@ interface ReactivePanacheMongoCompanionBase<Entity : ReactivePanacheMongoEntityB
* Update all entities of this type by the given update document, with named parameters.
* The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
* @param params [Parameters] of named parameters
* @return a new [ReactivePanacheUpdate] instance for the given update document
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ interface ReactivePanacheMongoRepositoryBase<Entity: Any, Id: Any> {
* Update all entities of this type by the given update document, with optional indexed parameters.
* The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
* @param params optional sequence of indexed parameters
* @return a new [ReactivePanacheUpdate] instance for the given update document
Expand All @@ -699,7 +699,7 @@ interface ReactivePanacheMongoRepositoryBase<Entity: Any, Id: Any> {
* Update all entities of this type by the given update document, with named parameters.
* The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
* @param params [Map] of named parameters
* @return a new [ReactivePanacheUpdate] instance for the given update document
Expand All @@ -713,7 +713,7 @@ interface ReactivePanacheMongoRepositoryBase<Entity: Any, Id: Any> {
* Update all entities of this type by the given update document, with named parameters.
* The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain `$set` we add it.
* @param update the update document, if it didn't contain any update operator, we add `$set`.
* It can also be expressed as a query string.
* @param params [Parameters] of named parameters
* @return a new [ReactivePanacheUpdate] instance for the given update document
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ public static void persistOrUpdate(Object firstEntity, Object... entities) {
* Update all entities of this type by the given update document, with optional indexed parameters.
* The returned {@link PanacheUpdate} object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain <code>$set</code> we add it.
* @param update the update document, if it didn't contain any update operator, we add <code>$set</code>..
* It can also be expressed as a {@link io.quarkus.mongodb.panache query string}.
* @param params optional sequence of indexed parameters
* @return a new {@link PanacheUpdate} instance for the given update document
Expand All @@ -892,7 +892,7 @@ public static PanacheUpdate update(String update, Object... params) {
* Update all entities of this type by the given update document, with named parameters.
* The returned {@link PanacheUpdate} object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain <code>$set</code> we add it.
* @param update the update document, if it didn't contain any update operator, we add <code>$set</code>.
* It can also be expressed as a {@link io.quarkus.mongodb.panache query string}.
* @param params {@link Map} of named parameters
* @return a new {@link PanacheUpdate} instance for the given update document
Expand All @@ -909,7 +909,7 @@ public static PanacheUpdate update(String update, Map<String, Object> params) {
* Update all entities of this type by the given update document, with named parameters.
* The returned {@link PanacheUpdate} object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain <code>$set</code> we add it.
* @param update the update document, if it didn't contain any update operator, we add <code>$set</code>.
* It can also be expressed as a {@link io.quarkus.mongodb.panache query string}.
* @param params {@link Parameters} of named parameters
* @return a new {@link PanacheUpdate} instance for the given update document
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ default void persistOrUpdate(Entity firstEntity, @SuppressWarnings("unchecked")
* Update all entities of this type by the given update document, with optional indexed parameters.
* The returned {@link PanacheUpdate} object will allow to restrict on which documents the update should be applied.
*
* @param update the update document, if it didn't contain <code>$set</code> we add it.
* @param update the update document, if it didn't contain any update operator, we add <code>$set</code>.
* It can also be expressed as a {@link io.quarkus.mongodb.panache query string}.
* @param params optional sequence of indexed parameters
* @return a new {@link PanacheUpdate} instance for the given update document
Expand All @@ -899,7 +899,7 @@ default PanacheUpdate update(String update, Object... params) {
* Update all entities of this type by the given update document, with named parameters.
* The returned {@link PanacheUpdate} object will allow to restrict on which documents the update should be applied.
*
* @param update the update document, if it didn't contain <code>$set</code> we add it.
* @param update the update document, if it didn't contain any update operator, we add <code>$set</code>.
* It can also be expressed as a {@link io.quarkus.mongodb.panache query string}.
* @param params {@link Map} of named parameters
* @return a new {@link PanacheUpdate} instance for the given update document
Expand All @@ -916,7 +916,7 @@ default PanacheUpdate update(String update, Map<String, Object> params) {
* Update all entities of this type by the given update document, with named parameters.
* The returned {@link PanacheUpdate} object will allow to restrict on which document the update should be applied.
*
* @param update the update document, if it didn't contain <code>$set</code> we add it.
* @param update the update document, if it didn't contain any update operator, we add <code>$set</code>.
* It can also be expressed as a {@link io.quarkus.mongodb.panache query string}.
* @param params {@link Parameters} of named parameters
* @return a new {@link PanacheUpdate} instance for the given update document
Expand Down
Loading

0 comments on commit c0ded6b

Please sign in to comment.